예제 #1
0
/**
 * Initialize libsigrokdecode.
 *
 * This initializes the Python interpreter, and creates and initializes
 * a "sigrokdecode" Python module.
 *
 * Then, it searches for sigrok protocol decoder files (*.py) in the
 * "decoders" subdirectory of the the sigrok installation directory.
 * All decoders that are found are loaded into memory and added to an
 * internal list of decoders, which can be queried via srd_decoders_list().
 *
 * The caller is responsible for calling the clean-up function srd_exit(),
 * which will properly shut down libsigrokdecode and free its allocated memory.
 *
 * Multiple calls to srd_init(), without calling srd_exit() in between,
 * are not allowed.
 *
 * @param path Path to an extra directory containing protocol decoders
 *             which will be added to the Python sys.path, or NULL.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 *         Upon Python errors, return SRD_ERR_PYTHON. If the sigrok decoders
 *         directory cannot be accessed, return SRD_ERR_DECODERS_DIR.
 *         If not enough memory could be allocated, return SRD_ERR_MALLOC.
 */
SRD_API int srd_init(const char *path)
{
	int ret;
	char *env_path;

	srd_dbg("Initializing libsigrokdecode.");

	/* Add our own module to the list of built-in modules. */
	PyImport_AppendInittab("sigrokdecode", PyInit_sigrokdecode);

	/* Initialize the Python interpreter. */
	Py_Initialize();

	/* Installed decoders. */
	if ((ret = srd_decoder_searchpath_add(DECODERS_DIR)) != SRD_OK) {
		Py_Finalize();
		return ret;
	}

	/* Path specified by the user. */
	if (path) {
		if ((ret = srd_decoder_searchpath_add(path)) != SRD_OK) {
			Py_Finalize();
			return ret;
		}
	}

	/* Environment variable overrides everything, for debugging. */
	if ((env_path = getenv("SIGROKDECODE_DIR"))) {
		if ((ret = srd_decoder_searchpath_add(env_path)) != SRD_OK) {
			Py_Finalize();
			return ret;
		}
	}

	return SRD_OK;
}
예제 #2
0
/** @private */
SRD_PRIV int srd_inst_start(struct srd_decoder_inst *di)
{
	PyObject *py_res;
	GSList *l;
	struct srd_decoder_inst *next_di;
	int ret;

	srd_dbg("Calling start() method on protocol decoder instance %s.",
			di->inst_id);

	/* Run self.start(). */
	if (!(py_res = PyObject_CallMethod(di->py_inst, "start", NULL))) {
		srd_exception_catch("Protocol decoder instance %s",
				di->inst_id);
		return SRD_ERR_PYTHON;
	}
	Py_DecRef(py_res);

	/* Set the initial pins based on self.initial_pins. */
	set_initial_pin_values(di);

	/* Set self.samplenum to 0. */
	PyObject_SetAttrString(di->py_inst, "samplenum", PyLong_FromLong(0));

	/* Set self.matches to None. */
	PyObject_SetAttrString(di->py_inst, "matches", Py_None);

	/* Start all the PDs stacked on top of this one. */
	for (l = di->next_di; l; l = l->next) {
		next_di = l->data;
		if ((ret = srd_inst_start(next_di)) != SRD_OK)
			return ret;
	}

	return SRD_OK;
}
예제 #3
0
/**
 * Send a chunk of logic sample data to a running decoder session.
 *
 * If no channel map has been set up, the logic samples must be arranged
 * in channel order, in the least amount of space possible. The default
 * channel set consists of all required channels + all optional channels.
 *
 * The size of a sample in inbuf is the unit size passed to
 * srd_inst_channel_set_all(). If no channel map has been configured, it is
 * the minimum number of bytes needed to store the default channels.
 *
 * @param sess The session to use.
 * @param start_samplenum The sample number of the first sample in this chunk.
 * @param end_samplenum The sample number of the last sample in this chunk.
 * @param inbuf Pointer to sample data.
 * @param inbuflen Length in bytes of the buffer.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 *
 * @since 0.3.0
 */
SRD_API int srd_session_send(struct srd_session *sess,
		uint64_t start_samplenum, uint64_t end_samplenum,
		const uint8_t *inbuf, uint64_t inbuflen)
{
	GSList *d;
	int ret;

	if (session_is_valid(sess) != SRD_OK) {
		srd_err("Invalid session.");
		return SRD_ERR_ARG;
	}

	srd_dbg("Calling decode() on all instances with starting sample "
			"number %" PRIu64 ", %" PRIu64 " bytes at 0x%p",
			start_samplenum, inbuflen, inbuf);

	for (d = sess->di_list; d; d = d->next) {
		if ((ret = srd_inst_decode(d->data, start_samplenum,
				end_samplenum, inbuf, inbuflen)) != SRD_OK)
			return ret;
	}

	return SRD_OK;
}
예제 #4
0
/**
 * Create a new protocol decoder instance.
 *
 * @param sess The session holding the protocol decoder instance.
 * @param decoder_id Decoder 'id' field.
 * @param options GHashtable of options which override the defaults set in
 *                the decoder class. May be NULL.
 *
 * @return Pointer to a newly allocated struct srd_decoder_inst, or
 *         NULL in case of failure.
 *
 * @since 0.3.0
 */
SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess,
		const char *decoder_id, GHashTable *options)
{
	int i;
	struct srd_decoder *dec;
	struct srd_decoder_inst *di;
	char *inst_id;

	srd_dbg("Creating new %s instance.", decoder_id);

	if (session_is_valid(sess) != SRD_OK) {
		srd_err("Invalid session.");
		return NULL;
	}

	if (!(dec = srd_decoder_get_by_id(decoder_id))) {
		srd_err("Protocol decoder %s not found.", decoder_id);
		return NULL;
	}

	if (!(di = g_try_malloc0(sizeof(struct srd_decoder_inst)))) {
		srd_err("Failed to g_malloc() instance.");
		return NULL;
	}

	di->decoder = dec;
	di->sess = sess;
	if (options) {
		inst_id = g_hash_table_lookup(options, "id");
		di->inst_id = g_strdup(inst_id ? inst_id : decoder_id);
		g_hash_table_remove(options, "id");
	} else
		di->inst_id = g_strdup(decoder_id);

	/*
	 * Prepare a default probe map, where samples come in the
	 * order in which the decoder class defined them.
	 */
	di->dec_num_probes = g_slist_length(di->decoder->probes) +
			g_slist_length(di->decoder->opt_probes);
	if (di->dec_num_probes) {
		if (!(di->dec_probemap =
				g_try_malloc(sizeof(int) * di->dec_num_probes))) {
			srd_err("Failed to g_malloc() probe map.");
			g_free(di);
			return NULL;
		}
		for (i = 0; i < di->dec_num_probes; i++)
			di->dec_probemap[i] = i;
		di->data_unitsize = (di->dec_num_probes + 7) / 8;
		/*
		 * Will be used to prepare a sample at every iteration
		 * of the instance's decode() method.
		 */
		if (!(di->probe_samples = g_try_malloc(di->dec_num_probes))) {
			srd_err("Failed to g_malloc() sample buffer.");
			g_free(di->dec_probemap);
			g_free(di);
			return NULL;
		}
	}

	/* Create a new instance of this decoder class. */
	if (!(di->py_inst = PyObject_CallObject(dec->py_dec, NULL))) {
		if (PyErr_Occurred())
			srd_exception_catch("failed to create %s instance: ",
					decoder_id);
		g_free(di->dec_probemap);
		g_free(di);
		return NULL;
	}

	if (options && srd_inst_option_set(di, options) != SRD_OK) {
		g_free(di->dec_probemap);
		g_free(di);
		return NULL;
	}

	/* Instance takes input from a frontend by default. */
	sess->di_list = g_slist_append(sess->di_list, di);

	return di;
}
예제 #5
0
/**
 * Set all probes in a decoder instance.
 *
 * This function sets _all_ probes for the specified decoder instance, i.e.,
 * it overwrites any probes that were already defined (if any).
 *
 * @param di Decoder instance.
 * @param new_probes A GHashTable of probes to set. Key is probe name, value is
 *                   the probe number. Samples passed to this instance will be
 *                   arranged in this order.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 *
 * @since 0.1.0
 */
SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di,
		GHashTable *new_probes)
{
	GVariant *probe_val;
	GList *l;
	GSList *sl;
	struct srd_probe *p;
	int *new_probemap, new_probenum, num_required_probes, num_probes, i;
	char *probe_id;

	srd_dbg("set probes called for instance %s with list of %d probes",
		di->inst_id, g_hash_table_size(new_probes));

	if (g_hash_table_size(new_probes) == 0)
		/* No probes provided. */
		return SRD_OK;

	if (di->dec_num_probes == 0) {
		/* Decoder has no probes. */
		srd_err("Protocol decoder %s has no probes to define.",
			di->decoder->name);
		return SRD_ERR_ARG;
	}

	new_probemap = NULL;

	if (!(new_probemap = g_try_malloc(sizeof(int) * di->dec_num_probes))) {
		srd_err("Failed to g_malloc() new probe map.");
		return SRD_ERR_MALLOC;
	}

	/*
	 * For now, map all indexes to probe -1 (can be overridden later).
	 * This -1 is interpreted as an unspecified probe later.
	 */
	for (i = 0; i < di->dec_num_probes; i++)
		new_probemap[i] = -1;

	num_probes = 0;
	for (l = g_hash_table_get_keys(new_probes); l; l = l->next) {
		probe_id = l->data;
		probe_val = g_hash_table_lookup(new_probes, probe_id);
		if (!g_variant_is_of_type(probe_val, G_VARIANT_TYPE_INT32)) {
			/* Probe name was specified without a value. */
			srd_err("No probe number was specified for %s.",
					probe_id);
			g_free(new_probemap);
			return SRD_ERR_ARG;
		}
		new_probenum = g_variant_get_int32(probe_val);
		if (!(sl = g_slist_find_custom(di->decoder->probes, probe_id,
				(GCompareFunc)compare_probe_id))) {
			/* Fall back on optional probes. */
			if (!(sl = g_slist_find_custom(di->decoder->opt_probes,
			     probe_id, (GCompareFunc) compare_probe_id))) {
				srd_err("Protocol decoder %s has no probe "
						"'%s'.", di->decoder->name, probe_id);
				g_free(new_probemap);
				return SRD_ERR_ARG;
			}
		}
		p = sl->data;
		new_probemap[p->order] = new_probenum;
		srd_dbg("Setting probe mapping: %s (index %d) = probe %d.",
			p->id, p->order, new_probenum);
		num_probes++;
	}
	di->data_unitsize = (num_probes + 7) / 8;

	srd_dbg("Final probe map:");
	num_required_probes = g_slist_length(di->decoder->probes);
	for (i = 0; i < di->dec_num_probes; i++) {
		srd_dbg(" - index %d = probe %d (%s)", i, new_probemap[i],
		        (i < num_required_probes) ? "required" : "optional");
	}

	/* Report an error if not all required probes were specified. */
	for (i = 0; i < num_required_probes; i++) {
		if (new_probemap[i] != -1)
			continue;
		p = g_slist_nth(di->decoder->probes, i)->data;
		srd_err("Required probe '%s' (index %d) was not specified.",
			p->id, i);
		return SRD_ERR;
	}

	g_free(di->dec_probemap);
	di->dec_probemap = new_probemap;

	return SRD_OK;
}
예제 #6
0
/**
 * Decode a chunk of samples.
 *
 * @param di The decoder instance to call. Must not be NULL.
 * @param start_samplenum The starting sample number for the buffer's sample
 * 			  set, relative to the start of capture.
 * @param end_samplenum The ending sample number for the buffer's sample
 * 			  set, relative to the start of capture.
 * @param inbuf The buffer to decode. Must not be NULL.
 * @param inbuflen Length of the buffer. Must be > 0.
 * @param unitsize The number of bytes per sample. Must be > 0.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 *
 * @private
 */
SRD_PRIV int srd_inst_decode(const struct srd_decoder_inst *di,
		uint64_t start_samplenum, uint64_t end_samplenum,
		const uint8_t *inbuf, uint64_t inbuflen, uint64_t unitsize)
{
	PyObject *py_res;
	srd_logic *logic;
	long apiver;

	/* Return an error upon unusable input. */
	if (!di) {
		srd_dbg("empty decoder instance");
		return SRD_ERR_ARG;
	}
	if (!inbuf) {
		srd_dbg("NULL buffer pointer");
		return SRD_ERR_ARG;
	}
	if (inbuflen == 0) {
		srd_dbg("empty buffer");
		return SRD_ERR_ARG;
	}
	if (unitsize == 0) {
		srd_dbg("unitsize 0");
		return SRD_ERR_ARG;
	}

	((struct srd_decoder_inst *)di)->data_unitsize = unitsize;

	srd_dbg("Decoding: start sample %" PRIu64 ", end sample %"
		PRIu64 " (%" PRIu64 " samples, %" PRIu64 " bytes, unitsize = "
		"%d), instance %s.", start_samplenum, end_samplenum,
		end_samplenum - start_samplenum, inbuflen, di->data_unitsize,
		di->inst_id);

	apiver = srd_decoder_apiver(di->decoder);

	if (apiver == 2) {
		/*
		 * Create new srd_logic object. Each iteration around the PD's
		 * loop will fill one sample into this object.
		 */
		logic = PyObject_New(srd_logic, (PyTypeObject *)srd_logic_type);
		Py_INCREF(logic);
		logic->di = (struct srd_decoder_inst *)di;
		logic->start_samplenum = start_samplenum;
		logic->itercnt = 0;
		logic->inbuf = (uint8_t *)inbuf;
		logic->inbuflen = inbuflen;
		logic->sample = PyList_New(2);
		Py_INCREF(logic->sample);

		Py_IncRef(di->py_inst);
		if (!(py_res = PyObject_CallMethod(di->py_inst, "decode",
			"KKO", start_samplenum, end_samplenum, logic))) {
			srd_exception_catch("Protocol decoder instance %s",
					di->inst_id);
			return SRD_ERR_PYTHON;
		}
		Py_DecRef(py_res);
	}

	return SRD_OK;
}
예제 #7
0
/**
 * Set all channels in a decoder instance.
 *
 * This function sets _all_ channels for the specified decoder instance, i.e.,
 * it overwrites any channels that were already defined (if any).
 *
 * @param di Decoder instance.
 * @param new_channels A GHashTable of channels to set. Key is channel name,
 *                     value is the channel number. Samples passed to this
 *                     instance will be arranged in this order.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 *
 * @since 0.4.0
 */
SRD_API int srd_inst_channel_set_all(struct srd_decoder_inst *di,
		GHashTable *new_channels)
{
	GVariant *channel_val;
	GList *l;
	GSList *sl;
	struct srd_channel *pdch;
	int *new_channelmap, new_channelnum, num_required_channels, i;
	char *channel_id;

	srd_dbg("Setting channels for instance %s with list of %d channels.",
		di->inst_id, g_hash_table_size(new_channels));

	if (g_hash_table_size(new_channels) == 0)
		/* No channels provided. */
		return SRD_OK;

	if (di->dec_num_channels == 0) {
		/* Decoder has no channels. */
		srd_err("Protocol decoder %s has no channels to define.",
			di->decoder->name);
		return SRD_ERR_ARG;
	}

	new_channelmap = g_malloc(sizeof(int) * di->dec_num_channels);

	/*
	 * For now, map all indexes to channel -1 (can be overridden later).
	 * This -1 is interpreted as an unspecified channel later.
	 */
	for (i = 0; i < di->dec_num_channels; i++)
		new_channelmap[i] = -1;

	for (l = g_hash_table_get_keys(new_channels); l; l = l->next) {
		channel_id = l->data;
		channel_val = g_hash_table_lookup(new_channels, channel_id);
		if (!g_variant_is_of_type(channel_val, G_VARIANT_TYPE_INT32)) {
			/* Channel name was specified without a value. */
			srd_err("No channel number was specified for %s.",
					channel_id);
			g_free(new_channelmap);
			return SRD_ERR_ARG;
		}
		new_channelnum = g_variant_get_int32(channel_val);
		if (!(sl = g_slist_find_custom(di->decoder->channels, channel_id,
				(GCompareFunc)compare_channel_id))) {
			/* Fall back on optional channels. */
			if (!(sl = g_slist_find_custom(di->decoder->opt_channels,
			     channel_id, (GCompareFunc)compare_channel_id))) {
				srd_err("Protocol decoder %s has no channel "
					"'%s'.", di->decoder->name, channel_id);
				g_free(new_channelmap);
				return SRD_ERR_ARG;
			}
		}
		pdch = sl->data;
		new_channelmap[pdch->order] = new_channelnum;
		srd_dbg("Setting channel mapping: %s (index %d) = channel %d.",
			pdch->id, pdch->order, new_channelnum);
	}

	srd_dbg("Final channel map:");
	num_required_channels = g_slist_length(di->decoder->channels);
	for (i = 0; i < di->dec_num_channels; i++) {
		srd_dbg(" - index %d = channel %d (%s)", i, new_channelmap[i],
			(i < num_required_channels) ? "required" : "optional");
	}

	/* Report an error if not all required channels were specified. */
	for (i = 0; i < num_required_channels; i++) {
		if (new_channelmap[i] != -1)
			continue;
		pdch = g_slist_nth(di->decoder->channels, i)->data;
		srd_err("Required channel '%s' (index %d) was not specified.",
			pdch->id, i);
		return SRD_ERR;
	}

	g_free(di->dec_channelmap);
	di->dec_channelmap = new_channelmap;

	return SRD_OK;
}
예제 #8
0
파일: decoder.c 프로젝트: jeras/sigrok
/**
 * Load a protocol decoder module into the embedded Python interpreter.
 *
 * @param module_name The module name to be loaded.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 */
SRD_API int srd_decoder_load(const char *module_name)
{
	PyObject *py_basedec, *py_method, *py_attr, *py_annlist, *py_ann;
	struct srd_decoder *d;
	int alen, ret, i;
	char **ann;
	struct srd_probe *p;
	GSList *l;

	srd_dbg("Loading protocol decoder '%s'.", module_name);

	py_basedec = py_method = py_attr = NULL;

	if (!(d = g_try_malloc0(sizeof(struct srd_decoder)))) {
		srd_dbg("Failed to g_malloc() struct srd_decoder.");
		ret = SRD_ERR_MALLOC;
		goto err_out;
	}

	ret = SRD_ERR_PYTHON;

	/* Import the Python module. */
	if (!(d->py_mod = PyImport_ImportModule(module_name))) {
		srd_exception_catch("Import of '%s' failed.", module_name);
		goto err_out;
	}

	/* Get the 'Decoder' class as Python object. */
	if (!(d->py_dec = PyObject_GetAttrString(d->py_mod, "Decoder"))) {
		/* This generated an AttributeError exception. */
		PyErr_Clear();
		srd_err("Decoder class not found in protocol decoder %s.",
			module_name);
		goto err_out;
	}

	if (!(py_basedec = PyObject_GetAttrString(mod_sigrokdecode, "Decoder"))) {
		srd_dbg("sigrokdecode module not loaded.");
		goto err_out;
	}

	if (!PyObject_IsSubclass(d->py_dec, py_basedec)) {
		srd_err("Decoder class in protocol decoder module %s is not "
			"a subclass of sigrokdecode.Decoder.", module_name);
		goto err_out;
	}
	Py_CLEAR(py_basedec);

	/* Check for a proper start() method. */
	if (!PyObject_HasAttrString(d->py_dec, "start")) {
		srd_err("Protocol decoder %s has no start() method Decoder "
			"class.", module_name);
		goto err_out;
	}
	py_method = PyObject_GetAttrString(d->py_dec, "start");
	if (!PyFunction_Check(py_method)) {
		srd_err("Protocol decoder %s Decoder class attribute 'start' "
			"is not a method.", module_name);
		goto err_out;
	}
	Py_CLEAR(py_method);

	/* Check for a proper decode() method. */
	if (!PyObject_HasAttrString(d->py_dec, "decode")) {
		srd_err("Protocol decoder %s has no decode() method Decoder "
			"class.", module_name);
		goto err_out;
	}
	py_method = PyObject_GetAttrString(d->py_dec, "decode");
	if (!PyFunction_Check(py_method)) {
		srd_err("Protocol decoder %s Decoder class attribute 'decode' "
			"is not a method.", module_name);
		goto err_out;
	}
	Py_CLEAR(py_method);

	/* If present, options must be a dictionary. */
	if (PyObject_HasAttrString(d->py_dec, "options")) {
		py_attr = PyObject_GetAttrString(d->py_dec, "options");
		if (!PyDict_Check(py_attr)) {
			srd_err("Protocol decoder %s options attribute is not "
				"a dictionary.", d->name);
			Py_DecRef(py_attr);
			goto err_out;
		}
		Py_DecRef(py_attr);
	}

	/* Check and import required probes. */
	if (get_probes(d, "probes", &d->probes) != SRD_OK)
		goto err_out;

	/* Check and import optional probes. */
	if (get_probes(d, "optional_probes", &d->opt_probes) != SRD_OK)
		goto err_out;

	/*
	 * Fix order numbers for the optional probes.
	 *
	 * Example:
	 * Required probes: r1, r2, r3. Optional: o1, o2, o3, o4.
	 * 'order' fields in the d->probes list = 0, 1, 2.
	 * 'order' fields in the d->opt_probes list = 3, 4, 5, 6.
	 */
	for (l = d->opt_probes; l; l = l->next) {
		p = l->data;
		p->order += g_slist_length(d->probes);
	}

	/* Store required fields in newly allocated strings. */
	if (py_attr_as_str(d->py_dec, "id", &(d->id)) != SRD_OK)
		goto err_out;

	if (py_attr_as_str(d->py_dec, "name", &(d->name)) != SRD_OK)
		goto err_out;

	if (py_attr_as_str(d->py_dec, "longname", &(d->longname)) != SRD_OK)
		goto err_out;

	if (py_attr_as_str(d->py_dec, "desc", &(d->desc)) != SRD_OK)
		goto err_out;

	if (py_attr_as_str(d->py_dec, "license", &(d->license)) != SRD_OK)
		goto err_out;

	/* Convert class annotation attribute to GSList of **char. */
	d->annotations = NULL;
	if (PyObject_HasAttrString(d->py_dec, "annotations")) {
		py_annlist = PyObject_GetAttrString(d->py_dec, "annotations");
		if (!PyList_Check(py_annlist)) {
			srd_err("Protocol decoder module %s annotations "
				"should be a list.", module_name);
			goto err_out;
		}
		alen = PyList_Size(py_annlist);
		for (i = 0; i < alen; i++) {
			py_ann = PyList_GetItem(py_annlist, i);
			if (!PyList_Check(py_ann) || PyList_Size(py_ann) != 2) {
				srd_err("Protocol decoder module %s "
					"annotation %d should be a list with "
					"two elements.", module_name, i + 1);
				goto err_out;
			}

			if (py_strlist_to_char(py_ann, &ann) != SRD_OK) {
				goto err_out;
			}
			d->annotations = g_slist_append(d->annotations, ann);
		}
	}

	/* Append it to the list of supported/loaded decoders. */
	pd_list = g_slist_append(pd_list, d);

	ret = SRD_OK;

err_out:
	if (ret != SRD_OK) {
		Py_XDECREF(py_method);
		Py_XDECREF(py_basedec);
		Py_XDECREF(d->py_dec);
		Py_XDECREF(d->py_mod);
		g_free(d);
	}

	return ret;
}
예제 #9
0
static PyObject *Decoder_wait(PyObject *self, PyObject *args)
{
	int ret;
	unsigned int i;
	gboolean found_match;
	struct srd_decoder_inst *di;
	PyObject *py_pinvalues, *py_matched;

	if (!self || !args)
		return NULL;

	if (!(di = srd_inst_find_by_obj(NULL, self))) {
		PyErr_SetString(PyExc_Exception, "decoder instance not found");
		Py_RETURN_NONE;
	}

	ret = set_new_condition_list(self, args);
	if (ret < 0) {
		srd_dbg("%s: %s: Aborting wait().", di->inst_id, __func__);
		return NULL;
	}
	if (ret == 9999) {
		/* Empty condition list, automatic match. */
		PyObject_SetAttrString(di->py_inst, "matched", Py_None);
		/* Leave self.samplenum unchanged (== di->abs_cur_samplenum). */
		return get_current_pinvalues(di);
	}

	while (1) {
		/* Wait for new samples to process, or termination request. */
		g_mutex_lock(&di->data_mutex);
		while (!di->got_new_samples && !di->want_wait_terminate)
			g_cond_wait(&di->got_new_samples_cond, &di->data_mutex);

		/*
		 * Check whether any of the current condition(s) match.
		 * Arrange for termination requests to take a code path which
		 * won't find new samples to process, pretends to have processed
		 * previously stored samples, and returns to the main thread,
		 * while the termination request still gets signalled.
		 */
		found_match = FALSE;
		ret = process_samples_until_condition_match(di, &found_match);

		/* If there's a match, set self.samplenum etc. and return. */
		if (found_match) {
			/* Set self.samplenum to the (absolute) sample number that matched. */
			PyObject_SetAttrString(di->py_inst, "samplenum",
				PyLong_FromLong(di->abs_cur_samplenum));

			if (di->match_array && di->match_array->len > 0) {
				py_matched = PyTuple_New(di->match_array->len);
				for (i = 0; i < di->match_array->len; i++)
					PyTuple_SetItem(py_matched, i, PyBool_FromLong(di->match_array->data[i]));
				PyObject_SetAttrString(di->py_inst, "matched", py_matched);
				match_array_free(di);
			} else {
				PyObject_SetAttrString(di->py_inst, "matched", Py_None);
			}
	
			py_pinvalues = get_current_pinvalues(di);

			g_mutex_unlock(&di->data_mutex);

			return py_pinvalues;
		}

		/* No match, reset state for the next chunk. */
		di->got_new_samples = FALSE;
		di->handled_all_samples = TRUE;
		di->abs_start_samplenum = 0;
		di->abs_end_samplenum = 0;
		di->inbuf = NULL;
		di->inbuflen = 0;

		/* Signal the main thread that we handled all samples. */
		g_cond_signal(&di->handled_all_samples_cond);

		/*
		 * When termination of wait() and decode() was requested,
		 * then exit the loop after releasing the mutex.
		 */
		if (di->want_wait_terminate) {
			srd_dbg("%s: %s: Will return from wait().",
				di->inst_id, __func__);
			g_mutex_unlock(&di->data_mutex);
			return NULL;
		}

		g_mutex_unlock(&di->data_mutex);
	}

	Py_RETURN_NONE;
}
예제 #10
0
파일: srd.c 프로젝트: LeSpocky/DSLogic
/**
 * Initialize libsigrokdecode.
 *
 * This initializes the Python interpreter, and creates and initializes
 * a "sigrokdecode" Python module.
 *
 * Then, it searches for sigrok protocol decoders in the "decoders"
 * subdirectory of the the libsigrokdecode installation directory.
 * All decoders that are found are loaded into memory and added to an
 * internal list of decoders, which can be queried via srd_decoder_list().
 *
 * The caller is responsible for calling the clean-up function srd_exit(),
 * which will properly shut down libsigrokdecode and free its allocated memory.
 *
 * Multiple calls to srd_init(), without calling srd_exit() in between,
 * are not allowed.
 *
 * @param path Path to an extra directory containing protocol decoders
 *             which will be added to the Python sys.path. May be NULL.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 *         Upon Python errors, SRD_ERR_PYTHON is returned. If the decoders
 *         directory cannot be accessed, SRD_ERR_DECODERS_DIR is returned.
 *         If not enough memory could be allocated, SRD_ERR_MALLOC is returned.
 *
 * @since 0.1.0
 */
SRD_API int srd_init(const char *path)
{
	const char *const *sys_datadirs;
	size_t i;
	int ret;
	const char *env_path;

	if (max_session_id != -1) {
		srd_err("libsigrokdecode is already initialized.");
		return SRD_ERR;
	}

	srd_dbg("Initializing libsigrokdecode.");

	/* Add our own module to the list of built-in modules. */
	PyImport_AppendInittab("sigrokdecode", PyInit_sigrokdecode);

	/* Initialize the Python interpreter. */
	Py_InitializeEx(0);
	/* Locations relative to the XDG system data directories. */
	sys_datadirs = g_get_system_data_dirs();
	for (i = g_strv_length((char **)sys_datadirs); i > 0; i--) {
		ret = searchpath_add_xdg_dir(sys_datadirs[i-1]);
		if (ret != SRD_OK) {
			Py_Finalize();
			return ret;
		}
	}
	#ifdef DECODERS_DIR
	/* Hardcoded decoders install location, if defined. */
	if ((ret = srd_decoder_searchpath_add(DECODERS_DIR)) != SRD_OK) {
		Py_Finalize();
		return ret;
	}
	#endif
	/* Location relative to the XDG user data directory. */
	ret = searchpath_add_xdg_dir(g_get_user_data_dir());
	if (ret != SRD_OK) {
		Py_Finalize();
		return ret;
	}

	/* Path specified by the user. */
	if (path) {
		if ((ret = srd_decoder_searchpath_add(path)) != SRD_OK) {
			Py_Finalize();
			return ret;
		}
	}

	/* Environment variable overrides everything, for debugging. */
	if ((env_path = g_getenv("SIGROKDECODE_DIR"))) {
		if ((ret = srd_decoder_searchpath_add(env_path)) != SRD_OK) {
			Py_Finalize();
			return ret;
		}
	}

	max_session_id = 0;

	return SRD_OK;
}
예제 #11
0
/**
 * Set all probes in a decoder instance.
 *
 * This function sets _all_ probes for the specified decoder instance, i.e.,
 * it overwrites any probes that were already defined (if any).
 *
 * @param di Decoder instance.
 * @param probes A GHashTable of probes to set. Key is probe name, value is
 *               the probe number. Samples passed to this instance will be
 *               arranged in this order.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 */
SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di,
			           GHashTable *new_probes)
{
	GList *l;
	GSList *sl;
	struct srd_probe *p;
	int *new_probemap, new_probenum;
	char *probe_id, *probenum_str;

	srd_dbg("set probes called for instance %s with list of %d probes",
		di->inst_id, g_hash_table_size(new_probes));

	if (g_hash_table_size(new_probes) == 0)
		/* No probes provided. */
		return SRD_OK;

	if (di->dec_num_probes == 0) {
		/* Decoder has no probes. */
		srd_err("Protocol decoder %s has no probes to define.",
			di->decoder->name);
		return SRD_ERR_ARG;
	}

	new_probemap = NULL;

	if (!(new_probemap = g_try_malloc(sizeof(int) * di->dec_num_probes))) {
		srd_err("Failed to g_malloc() new probe map.");
		return SRD_ERR_MALLOC;
	}

	for (l = g_hash_table_get_keys(new_probes); l; l = l->next) {
		probe_id = l->data;
		probenum_str = g_hash_table_lookup(new_probes, probe_id);
		if (!probenum_str) {
			/* Probe name was specified without a value. */
			srd_err("No probe number was specified for %s.",
				probe_id);
			g_free(new_probemap);
			return SRD_ERR_ARG;
		}
		new_probenum = strtol(probenum_str, NULL, 10);
		if (!(sl = g_slist_find_custom(di->decoder->probes, probe_id,
				(GCompareFunc)compare_probe_id))) {
			/* Fall back on optional probes. */
			if (!(sl = g_slist_find_custom(di->decoder->opt_probes,
			     probe_id, (GCompareFunc) compare_probe_id))) {
				srd_err("Protocol decoder %s has no probe "
					"'%s'.", di->decoder->name, probe_id);
				g_free(new_probemap);
				return SRD_ERR_ARG;
			}
		}
		p = sl->data;
		new_probemap[p->order] = new_probenum;
		srd_dbg("setting probe mapping for %d = probe %d", p->order,
			new_probenum);
	}
	g_free(di->dec_probemap);
	di->dec_probemap = new_probemap;

	return SRD_OK;
}
예제 #12
0
static PyObject *Decoder_put(PyObject *self, PyObject *args)
{
	GSList *l;
	PyObject *data, *py_res;
	struct srd_decoder_inst *di, *next_di;
	struct srd_pd_output *pdo;
	struct srd_proto_data *pdata;
	uint64_t start_sample, end_sample;
	int output_id;
	void (*cb)();

	if (!(di = srd_inst_find_by_obj(NULL, self))) {
		/* Shouldn't happen. */
		srd_dbg("put(): self instance not found.");
		return NULL;
	}

	if (!PyArg_ParseTuple(args, "KKiO", &start_sample, &end_sample,
	    &output_id, &data)) {
		/*
		 * This throws an exception, but by returning NULL here we let
		 * Python raise it. This results in a much better trace in
		 * controller.c on the decode() method call.
		 */
		return NULL;
	}

	if (!(l = g_slist_nth(di->pd_output, output_id))) {
		srd_err("Protocol decoder %s submitted invalid output ID %d.",
			di->decoder->name, output_id);
		return NULL;
	}
	pdo = l->data;

	srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s on oid %d.",
		 di->inst_id, start_sample, end_sample,
		 OUTPUT_TYPES[pdo->output_type], output_id);

	if (!(pdata = g_try_malloc0(sizeof(struct srd_proto_data)))) {
		srd_err("Failed to g_malloc() struct srd_proto_data.");
		return NULL;
	}
	pdata->start_sample = start_sample;
	pdata->end_sample = end_sample;
	pdata->pdo = pdo;

	switch (pdo->output_type) {
	case SRD_OUTPUT_ANN:
		/* Annotations are only fed to callbacks. */
		if ((cb = srd_pd_output_callback_find(pdo->output_type))) {
			/* Annotations need converting from PyObject. */
			if (convert_pyobj(di, data, &pdata->ann_format,
					  (char ***)&pdata->data) != SRD_OK) {
				/* An error was already logged. */
				break;
			}
			cb(pdata);
		}
		break;
	case SRD_OUTPUT_PROTO:
		for (l = di->next_di; l; l = l->next) {
			next_di = l->data;
			/* TODO: Is this needed? */
			Py_XINCREF(next_di->py_inst);
			srd_spew("Sending %d-%d to instance %s",
				 start_sample, end_sample,
				 next_di->inst_id);
			if (!(py_res = PyObject_CallMethod(
			    next_di->py_inst, "decode", "KKO", start_sample,
			    end_sample, data))) {
				srd_exception_catch("Calling %s decode(): ",
						    next_di->inst_id);
			}
			Py_XDECREF(py_res);
		}
		break;
	case SRD_OUTPUT_BINARY:
		srd_err("SRD_OUTPUT_BINARY not yet supported.");
		break;
	default:
		srd_err("Protocol decoder %s submitted invalid output type %d.",
			di->decoder->name, pdo->output_type);
		break;
	}

	g_free(pdata);

	Py_RETURN_NONE;
}
예제 #13
0
/**
 * Decode a chunk of samples.
 *
 * The calls to this function must provide the samples that shall be
 * used by the protocol decoder
 *  - in the correct order ([...]5, 6, 4, 7, 8[...] is a bug),
 *  - starting from sample zero (2, 3, 4, 5, 6[...] is a bug),
 *  - consecutively, with no gaps (0, 1, 2, 4, 5[...] is a bug).
 *
 * The start- and end-sample numbers are absolute sample numbers (relative
 * to the start of the whole capture/file/stream), i.e. they are not relative
 * sample numbers within the chunk specified by 'inbuf' and 'inbuflen'.
 *
 * Correct example (4096 samples total, 4 chunks @ 1024 samples each):
 *   srd_inst_decode(di, 0,    1023, inbuf, 1024, 1);
 *   srd_inst_decode(di, 1024, 2047, inbuf, 1024, 1);
 *   srd_inst_decode(di, 2048, 3071, inbuf, 1024, 1);
 *   srd_inst_decode(di, 3072, 4095, inbuf, 1024, 1);
 *
 * The chunk size ('inbuflen') can be arbitrary and can differ between calls.
 *
 * Correct example (4096 samples total, 7 chunks @ various samples each):
 *   srd_inst_decode(di, 0,    1023, inbuf, 1024, 1);
 *   srd_inst_decode(di, 1024, 1123, inbuf,  100, 1);
 *   srd_inst_decode(di, 1124, 1423, inbuf,  300, 1);
 *   srd_inst_decode(di, 1424, 1642, inbuf,  219, 1);
 *   srd_inst_decode(di, 1643, 2047, inbuf,  405, 1);
 *   srd_inst_decode(di, 2048, 3071, inbuf, 1024, 1);
 *   srd_inst_decode(di, 3072, 4095, inbuf, 1024, 1);
 *
 * INCORRECT example (4096 samples total, 4 chunks @ 1024 samples each, but
 * the start- and end-samplenumbers are not absolute):
 *   srd_inst_decode(di, 0,    1023, inbuf, 1024, 1);
 *   srd_inst_decode(di, 0,    1023, inbuf, 1024, 1);
 *   srd_inst_decode(di, 0,    1023, inbuf, 1024, 1);
 *   srd_inst_decode(di, 0,    1023, inbuf, 1024, 1);
 *
 * @param di The decoder instance to call. Must not be NULL.
 * @param abs_start_samplenum The absolute starting sample number for the
 * 		buffer's sample set, relative to the start of capture.
 * @param abs_end_samplenum The absolute ending sample number for the
 * 		buffer's sample set, relative to the start of capture.
 * @param inbuf The buffer to decode. Must not be NULL.
 * @param inbuflen Length of the buffer. Must be > 0.
 * @param unitsize The number of bytes per sample. Must be > 0.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 *
 * @private
 */
SRD_PRIV int srd_inst_decode(struct srd_decoder_inst *di,
		uint64_t abs_start_samplenum, uint64_t abs_end_samplenum,
		const uint8_t *inbuf, uint64_t inbuflen, uint64_t unitsize)
{
	PyObject *py_res;
	srd_logic *logic;
	long apiver;

	/* Return an error upon unusable input. */
	if (!di) {
		srd_dbg("empty decoder instance");
		return SRD_ERR_ARG;
	}
	if (!inbuf) {
		srd_dbg("NULL buffer pointer");
		return SRD_ERR_ARG;
	}
	if (inbuflen == 0) {
		srd_dbg("empty buffer");
		return SRD_ERR_ARG;
	}
	if (unitsize == 0) {
		srd_dbg("unitsize 0");
		return SRD_ERR_ARG;
	}

	di->data_unitsize = unitsize;

	srd_dbg("Decoding: abs start sample %" PRIu64 ", abs end sample %"
		PRIu64 " (%" PRIu64 " samples, %" PRIu64 " bytes, unitsize = "
		"%d), instance %s.", abs_start_samplenum, abs_end_samplenum,
		abs_end_samplenum - abs_start_samplenum, inbuflen, di->data_unitsize,
		di->inst_id);

	apiver = srd_decoder_apiver(di->decoder);

	if (apiver == 2) {
		/*
		 * Create new srd_logic object. Each iteration around the PD's
		 * loop will fill one sample into this object.
		 */
		logic = PyObject_New(srd_logic, (PyTypeObject *)srd_logic_type);
		Py_INCREF(logic);
		logic->di = (struct srd_decoder_inst *)di;
		logic->abs_start_samplenum = abs_start_samplenum;
		logic->itercnt = 0;
		logic->inbuf = (uint8_t *)inbuf;
		logic->inbuflen = inbuflen;
		logic->sample = PyList_New(2);
		Py_INCREF(logic->sample);

		Py_IncRef(di->py_inst);
		if (!(py_res = PyObject_CallMethod(di->py_inst, "decode",
			"KKO", abs_start_samplenum, abs_end_samplenum, logic))) {
			srd_exception_catch("Protocol decoder instance %s",
					di->inst_id);
			return SRD_ERR_PYTHON;
		}
		Py_DecRef(py_res);
	} else {
		/* If this is the first call, start the worker thread. */
		if (!di->thread_handle)
			di->thread_handle = g_thread_new("di_thread",
							 di_thread, di);

		/* Push the new sample chunk to the worker thread. */
		g_mutex_lock(&di->data_mutex);
		di->abs_start_samplenum = abs_start_samplenum;
		di->abs_end_samplenum = abs_end_samplenum;
		di->inbuf = inbuf;
		di->inbuflen = inbuflen;
		di->got_new_samples = TRUE;
		di->handled_all_samples = FALSE;

		/* Signal the thread that we have new data. */
		g_cond_signal(&di->got_new_samples_cond);
		g_mutex_unlock(&di->data_mutex);

		/* When all samples in this chunk were handled, return. */
		g_mutex_lock(&di->data_mutex);
		while (!di->handled_all_samples)
			g_cond_wait(&di->handled_all_samples_cond, &di->data_mutex);
		g_mutex_unlock(&di->data_mutex);
	}

	return SRD_OK;
}
예제 #14
0
/**
 * Create a new protocol decoder instance.
 *
 * @param sess The session holding the protocol decoder instance.
 * @param decoder_id Decoder 'id' field.
 * @param options GHashtable of options which override the defaults set in
 *                the decoder class. May be NULL.
 *
 * @return Pointer to a newly allocated struct srd_decoder_inst, or
 *         NULL in case of failure.
 *
 * @since 0.3.0
 */
SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess,
		const char *decoder_id, GHashTable *options)
{
	int i;
	struct srd_decoder *dec;
	struct srd_decoder_inst *di;
	char *inst_id;

	i = 1;
	srd_dbg("Creating new %s instance.", decoder_id);

	if (session_is_valid(sess) != SRD_OK) {
		srd_err("Invalid session.");
		return NULL;
	}

	if (!(dec = srd_decoder_get_by_id(decoder_id))) {
		srd_err("Protocol decoder %s not found.", decoder_id);
		return NULL;
	}

	di = g_malloc0(sizeof(struct srd_decoder_inst));

	di->decoder = dec;
	di->sess = sess;

	if (options) {
		inst_id = g_hash_table_lookup(options, "id");
		if (inst_id)
			di->inst_id = g_strdup(inst_id);
		g_hash_table_remove(options, "id");
	}

	/* Create a unique instance ID (as none was provided). */
	if (!di->inst_id) {
		di->inst_id = g_strdup_printf("%s-%d", decoder_id, i++);
		while (srd_inst_find_by_id(sess, di->inst_id)) {
			g_free(di->inst_id);
			di->inst_id = g_strdup_printf("%s-%d", decoder_id, i++);
		}
	}

	/*
	 * Prepare a default channel map, where samples come in the
	 * order in which the decoder class defined them.
	 */
	di->dec_num_channels = g_slist_length(di->decoder->channels) +
			g_slist_length(di->decoder->opt_channels);
	if (di->dec_num_channels) {
		di->dec_channelmap =
				g_malloc(sizeof(int) * di->dec_num_channels);
		for (i = 0; i < di->dec_num_channels; i++)
			di->dec_channelmap[i] = i;
		/*
		 * Will be used to prepare a sample at every iteration
		 * of the instance's decode() method.
		 */
		di->channel_samples = g_malloc(di->dec_num_channels);
	}

	/* Create a new instance of this decoder class. */
	if (!(di->py_inst = PyObject_CallObject(dec->py_dec, NULL))) {
		if (PyErr_Occurred())
			srd_exception_catch("Failed to create %s instance",
					decoder_id);
		g_free(di->dec_channelmap);
		g_free(di);
		return NULL;
	}

	if (options && srd_inst_option_set(di, options) != SRD_OK) {
		g_free(di->dec_channelmap);
		g_free(di);
		return NULL;
	}

	di->condition_list = NULL;
	di->match_array = NULL;
	di->abs_start_samplenum = 0;
	di->abs_end_samplenum = 0;
	di->inbuf = NULL;
	di->inbuflen = 0;
	di->abs_cur_samplenum = 0;
	di->old_pins_array = NULL;
	di->thread_handle = NULL;
	di->got_new_samples = FALSE;
	di->handled_all_samples = FALSE;

	/* Instance takes input from a frontend by default. */
	sess->di_list = g_slist_append(sess->di_list, di);
	srd_dbg("Created new %s instance with ID %s.", decoder_id, di->inst_id);

	return di;
}
예제 #15
0
파일: controller.c 프로젝트: jeras/sigrok
/**
 * Set all probes in a decoder instance.
 *
 * This function sets _all_ probes for the specified decoder instance, i.e.,
 * it overwrites any probes that were already defined (if any).
 *
 * @param di Decoder instance.
 * @param new_probes A GHashTable of probes to set. Key is probe name, value is
 *                   the probe number. Samples passed to this instance will be
 *                   arranged in this order.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 */
SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di,
			           GHashTable *new_probes)
{
	GList *l;
	GSList *sl;
	struct srd_probe *p;
	int *new_probemap, new_probenum;
	char *probe_id, *probenum_str;
	int i, num_required_probes;

	srd_dbg("set probes called for instance %s with list of %d probes",
		di->inst_id, g_hash_table_size(new_probes));

	if (g_hash_table_size(new_probes) == 0)
		/* No probes provided. */
		return SRD_OK;

	if (di->dec_num_probes == 0) {
		/* Decoder has no probes. */
		srd_err("Protocol decoder %s has no probes to define.",
			di->decoder->name);
		return SRD_ERR_ARG;
	}

	new_probemap = NULL;

	if (!(new_probemap = g_try_malloc(sizeof(int) * di->dec_num_probes))) {
		srd_err("Failed to g_malloc() new probe map.");
		return SRD_ERR_MALLOC;
	}

	/*
	 * For now, map all indexes to probe -1 (can be overridden later).
	 * This -1 is interpreted as an unspecified probe later.
	 */
	for (i = 0; i < di->dec_num_probes; i++)
		new_probemap[i] = -1;

	for (l = g_hash_table_get_keys(new_probes); l; l = l->next) {
		probe_id = l->data;
		probenum_str = g_hash_table_lookup(new_probes, probe_id);
		if (!probenum_str) {
			/* Probe name was specified without a value. */
			srd_err("No probe number was specified for %s.",
				probe_id);
			g_free(new_probemap);
			return SRD_ERR_ARG;
		}
		new_probenum = strtol(probenum_str, NULL, 10);
		if (!(sl = g_slist_find_custom(di->decoder->probes, probe_id,
				(GCompareFunc)compare_probe_id))) {
			/* Fall back on optional probes. */
			if (!(sl = g_slist_find_custom(di->decoder->opt_probes,
			     probe_id, (GCompareFunc) compare_probe_id))) {
				srd_err("Protocol decoder %s has no probe "
					"'%s'.", di->decoder->name, probe_id);
				g_free(new_probemap);
				return SRD_ERR_ARG;
			}
		}
		p = sl->data;
		new_probemap[p->order] = new_probenum;
		srd_dbg("Setting probe mapping: %s (index %d) = probe %d.",
			p->id, p->order, new_probenum);
	}

	srd_dbg("Final probe map:");
	num_required_probes = g_slist_length(di->decoder->probes);
	for (i = 0; i < di->dec_num_probes; i++) {
		srd_dbg(" - index %d = probe %d (%s)", i, new_probemap[i],
		        (i < num_required_probes) ? "required" : "optional");
	}

	g_free(di->dec_probemap);
	di->dec_probemap = new_probemap;

	return SRD_OK;
}
예제 #16
0
/**
 * Set one or more options in a decoder instance.
 *
 * Handled options are removed from the hash.
 *
 * @param di Decoder instance.
 * @param options A GHashTable of options to set.
 *
 * @return SRD_OK upon success, a (negative) error code otherwise.
 *
 * @since 0.1.0
 */
SRD_API int srd_inst_option_set(struct srd_decoder_inst *di,
		GHashTable *options)
{
	PyObject *py_dec_options, *py_dec_optkeys, *py_di_options, *py_optval;
	PyObject *py_optlist, *py_classval;
	Py_UNICODE *py_ustr;
	GVariant *value;
	unsigned long long int val_ull;
	gint64 val_int;
	int num_optkeys, ret, size, i;
	const char *val_str;
	char *dbg, *key;

	if (!di) {
		srd_err("Invalid decoder instance.");
		return SRD_ERR_ARG;
	}

	if (!options) {
		srd_err("Invalid options GHashTable.");
		return SRD_ERR_ARG;
	}

	if (!PyObject_HasAttrString(di->decoder->py_dec, "options")) {
		/* Decoder has no options. */
		if (g_hash_table_size(options) == 0) {
			/* No options provided. */
			return SRD_OK;
		} else {
			srd_err("Protocol decoder has no options.");
			return SRD_ERR_ARG;
		}
		return SRD_OK;
	}

	ret = SRD_ERR_PYTHON;
	key = NULL;
	py_dec_options = py_dec_optkeys = py_di_options = py_optval = NULL;
	py_optlist = py_classval = NULL;
	py_dec_options = PyObject_GetAttrString(di->decoder->py_dec, "options");

	/* All of these are synthesized objects, so they're good. */
	py_dec_optkeys = PyDict_Keys(py_dec_options);
	num_optkeys = PyList_Size(py_dec_optkeys);

	/*
	 * The 'options' dictionary is a class variable, but we need to
	 * change it. Changing it directly will affect the entire class,
	 * so we need to create a new object for it, and populate that
	 * instead.
	 */
	if (!(py_di_options = PyObject_GetAttrString(di->py_inst, "options")))
		goto err_out;
	Py_DECREF(py_di_options);
	py_di_options = PyDict_New();
	PyObject_SetAttrString(di->py_inst, "options", py_di_options);
	for (i = 0; i < num_optkeys; i++) {
		/* Get the default class value for this option. */
		py_str_as_str(PyList_GetItem(py_dec_optkeys, i), &key);
		if (!(py_optlist = PyDict_GetItemString(py_dec_options, key)))
			goto err_out;
		if (!(py_classval = PyList_GetItem(py_optlist, 1)))
			goto err_out;
		if (!PyUnicode_Check(py_classval) && !PyLong_Check(py_classval)) {
			srd_err("Options of type %s are not yet supported.",
				Py_TYPE(py_classval)->tp_name);
			goto err_out;
		}

		if ((value = g_hash_table_lookup(options, key))) {
			dbg = g_variant_print(value, TRUE);
			srd_dbg("got option '%s' = %s", key, dbg);
			g_free(dbg);
			/* An override for this option was provided. */
			if (PyUnicode_Check(py_classval)) {
				if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
					srd_err("Option '%s' requires a string value.", key);
					goto err_out;
				}
				val_str = g_variant_get_string(value, NULL);
				if (!(py_optval = PyUnicode_FromString(val_str))) {
					/* Some UTF-8 encoding error. */
					PyErr_Clear();
					srd_err("Option '%s' requires a UTF-8 string value.", key);
					goto err_out;
				}
			} else if (PyLong_Check(py_classval)) {
				if (!g_variant_is_of_type(value, G_VARIANT_TYPE_INT64)) {
					srd_err("Option '%s' requires an integer value.", key);
					goto err_out;
				}
				val_int = g_variant_get_int64(value);
				if (!(py_optval = PyLong_FromLong(val_int))) {
					/* ValueError Exception */
					PyErr_Clear();
					srd_err("Option '%s' has invalid integer value.", key);
					goto err_out;
				}
			}
			g_hash_table_remove(options, key);
		} else {
			/* Use the class default for this option. */
			if (PyUnicode_Check(py_classval)) {
				/* Make a brand new copy of the string. */
				py_ustr = PyUnicode_AS_UNICODE(py_classval);
				size = PyUnicode_GET_SIZE(py_classval);
				py_optval = PyUnicode_FromUnicode(py_ustr, size);
			} else if (PyLong_Check(py_classval)) {
				/* Make a brand new copy of the integer. */
				val_ull = PyLong_AsUnsignedLongLong(py_classval);
				if (val_ull == (unsigned long long)-1) {
					/* OverFlowError exception */
					PyErr_Clear();
					srd_err("Invalid integer value for %s: "
						"expected integer.", key);
					goto err_out;
				}
				if (!(py_optval = PyLong_FromUnsignedLongLong(val_ull)))
					goto err_out;
			}
		}

		/*
		 * If we got here, py_optval holds a known good new reference
		 * to the instance option to set.
		 */
		if (PyDict_SetItemString(py_di_options, key, py_optval) == -1)
			goto err_out;
		g_free(key);
		key = NULL;
	}

	ret = SRD_OK;

err_out:
	Py_XDECREF(py_di_options);
	Py_XDECREF(py_dec_optkeys);
	Py_XDECREF(py_dec_options);
	g_free(key);
	if (PyErr_Occurred()) {
		srd_exception_catch("Stray exception in srd_inst_option_set().");
		ret = SRD_ERR_PYTHON;
	}

	return ret;
}
예제 #17
0
static PyObject *Decoder_put(PyObject *self, PyObject *args)
{
	GSList *l;
	PyObject *py_data, *py_res;
	struct srd_decoder_inst *di, *next_di;
	struct srd_pd_output *pdo;
	struct srd_proto_data *pdata;
	uint64_t start_sample, end_sample;
	int output_id;
	struct srd_pd_callback *cb;

	if (!(di = srd_inst_find_by_obj(NULL, self))) {
		/* Shouldn't happen. */
		srd_dbg("put(): self instance not found.");
		return NULL;
	}

	if (!PyArg_ParseTuple(args, "KKiO", &start_sample, &end_sample,
		&output_id, &py_data)) {
		/*
		 * This throws an exception, but by returning NULL here we let
		 * Python raise it. This results in a much better trace in
		 * controller.c on the decode() method call.
		 */
		return NULL;
	}

	if (!(l = g_slist_nth(di->pd_output, output_id))) {
		srd_err("Protocol decoder %s submitted invalid output ID %d.",
			di->decoder->name, output_id);
		return NULL;
	}
	pdo = l->data;

	srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s on oid %d.",
		 di->inst_id, start_sample, end_sample,
		 OUTPUT_TYPES[pdo->output_type], output_id);

	if (!(pdata = g_try_malloc0(sizeof(struct srd_proto_data)))) {
		srd_err("Failed to g_malloc() struct srd_proto_data.");
		return NULL;
	}
	pdata->start_sample = start_sample;
	pdata->end_sample = end_sample;
	pdata->pdo = pdo;

	switch (pdo->output_type) {
	case SRD_OUTPUT_ANN:
		/* Annotations are only fed to callbacks. */
		if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
			/* Convert from PyDict to srd_proto_data_annotation. */
			if (convert_annotation(di, py_data, pdata) != SRD_OK) {
				/* An error was already logged. */
				break;
			}
			cb->cb(pdata, cb->cb_data);
		}
		break;
	case SRD_OUTPUT_PYTHON:
		for (l = di->next_di; l; l = l->next) {
			next_di = l->data;
			srd_spew("Sending %d-%d to instance %s",
				 start_sample, end_sample, next_di->inst_id);
			if (!(py_res = PyObject_CallMethod(
				next_di->py_inst, "decode", "KKO", start_sample,
				end_sample, py_data))) {
				srd_exception_catch("Calling %s decode(): ",
							next_di->inst_id);
			}
			Py_XDECREF(py_res);
		}
		if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
			/* Frontends aren't really supposed to get Python
			 * callbacks, but it's useful for testing. */
			pdata->data = py_data;
			cb->cb(pdata, cb->cb_data);
		}
		break;
	case SRD_OUTPUT_BINARY:
		if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
			/* Convert from PyDict to srd_proto_data_binary. */
			if (convert_binary(di, py_data, pdata) != SRD_OK) {
				/* An error was already logged. */
				break;
			}
			cb->cb(pdata, cb->cb_data);
		}
		break;
	case SRD_OUTPUT_META:
		if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
			/* Annotations need converting from PyObject. */
			if (convert_meta(pdata, py_data) != SRD_OK) {
				/* An exception was already set up. */
				break;
			}
			cb->cb(pdata, cb->cb_data);
		}
		break;
	default:
		srd_err("Protocol decoder %s submitted invalid output type %d.",
			di->decoder->name, pdo->output_type);
		break;
	}

	g_free(pdata);

	Py_RETURN_NONE;
}
예제 #18
0
static PyObject *Decoder_register(PyObject *self, PyObject *args,
		PyObject *kwargs)
{
	struct srd_decoder_inst *di;
	struct srd_pd_output *pdo;
	PyObject *py_new_output_id;
	PyTypeObject *meta_type_py;
	const GVariantType *meta_type_gv;
	int output_type;
	char *proto_id, *meta_name, *meta_descr;
	char *keywords[] = {"output_type", "proto_id", "meta", NULL};

	meta_type_py = NULL;
	meta_type_gv = NULL;
	meta_name = meta_descr = NULL;

	if (!(di = srd_inst_find_by_obj(NULL, self))) {
		PyErr_SetString(PyExc_Exception, "decoder instance not found");
		return NULL;
	}

	/* Default to instance id, which defaults to class id. */
	proto_id = di->inst_id;
	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|s(Oss)", keywords,
			&output_type, &proto_id,
			&meta_type_py, &meta_name, &meta_descr)) {
		/* Let Python raise this exception. */
		return NULL;
	}

	/* Check if the meta value's type is supported. */
	if (output_type == SRD_OUTPUT_META) {
		if (meta_type_py == &PyLong_Type)
			meta_type_gv = G_VARIANT_TYPE_INT64;
		else if (meta_type_py == &PyFloat_Type)
			meta_type_gv = G_VARIANT_TYPE_DOUBLE;
		else {
			PyErr_Format(PyExc_TypeError, "Unsupported type '%s'.",
					meta_type_py->tp_name);
			return NULL;
		}
	}

	srd_dbg("Instance %s creating new output type %d for %s.",
		di->inst_id, output_type, proto_id);

	if (!(pdo = g_try_malloc(sizeof(struct srd_pd_output)))) {
		PyErr_SetString(PyExc_MemoryError, "struct srd_pd_output");
		return NULL;
	}

	/* pdo_id is just a simple index, nothing is deleted from this list anyway. */
	pdo->pdo_id = g_slist_length(di->pd_output);
	pdo->output_type = output_type;
	pdo->di = di;
	pdo->proto_id = g_strdup(proto_id);

	if (output_type == SRD_OUTPUT_META) {
		pdo->meta_type = meta_type_gv;
		pdo->meta_name = g_strdup(meta_name);
		pdo->meta_descr = g_strdup(meta_descr);
	}

	di->pd_output = g_slist_append(di->pd_output, pdo);
	py_new_output_id = Py_BuildValue("i", pdo->pdo_id);

	return py_new_output_id;
}
예제 #19
0
/** @private */
SRD_PRIV void srd_exception_catch(const char *format, ...)
{
	PyObject *etype, *evalue, *etb, *py_str;
	PyTracebackObject *py_tb;
	GString *msg;
	va_list args;
	char *ename, *str, *tracestr;

	if (!PyErr_Occurred())
		/* Nothing is wrong. */
		return;

	PyErr_Fetch(&etype, &evalue, &etb);
	PyErr_NormalizeException(&etype, &evalue, &etb);

	if (!(py_str = PyObject_Str(evalue))) {
		/* Shouldn't happen. */
		srd_dbg("Failed to convert exception value to string.");
		return;
	}

	/* Send the exception error message(s) to srd_err(). */
	if (evalue)
		ename = (char *)Py_TYPE(evalue)->tp_name;
	else
		/* Can be NULL. */
		ename = "(unknown exception)";

	msg = g_string_sized_new(128);
	g_string_append(msg, ename);
	g_string_append(msg, ": ");
	va_start(args, format);
	g_string_append_vprintf(msg, format, args);
	va_end(args);
	py_str_as_str(py_str, &str);
	g_string_append(msg, str);
	Py_DecRef(py_str);
	srd_err(msg->str);

	/* Send a more precise error location to srd_dbg(), if we have it. */
	if (etb && etb != Py_None) {
		tracestr = NULL;
		py_tb = (PyTracebackObject *)etb;
		py_str = PyUnicode_FromFormat("%U:%d in %U",
					py_tb->tb_frame->f_code->co_filename,
					py_tb->tb_frame->f_lineno,
					py_tb->tb_frame->f_code->co_name);
		py_str_as_str(py_str, &tracestr);
		Py_DecRef(py_str);
		g_string_printf(msg, "%s in %s: %s", ename, tracestr, str);
		srd_dbg(msg->str);
		g_free(tracestr);
	}
	g_free(str);
	g_string_free(msg, TRUE);

	Py_XDECREF(etype);
	Py_XDECREF(evalue);
	Py_XDECREF(etb);

	/* Just in case. */
	PyErr_Clear();
}
예제 #20
0
/**
 * Replace the current condition list with the new one.
 *
 * @param self TODO. Must not be NULL.
 * @param args TODO. Must not be NULL.
 *
 * @retval SRD_OK The new condition list was set successfully.
 * @retval SRD_ERR There was an error setting the new condition list.
 *                 The contents of di->condition_list are undefined.
 * @retval 9999 TODO.
 */
static int set_new_condition_list(PyObject *self, PyObject *args)
{
	struct srd_decoder_inst *di;
	GSList *term_list;
	PyObject *py_conditionlist, *py_conds, *py_dict;
	int i, num_conditions, ret;

	if (!self || !args)
		return SRD_ERR_ARG;

	/* Get the decoder instance. */
	if (!(di = srd_inst_find_by_obj(NULL, self))) {
		PyErr_SetString(PyExc_Exception, "decoder instance not found");
		return SRD_ERR;
	}

	/*
	 * Return an error condition from .wait() when termination is
	 * requested, such that decode() will terminate.
	 */
	if (di->want_wait_terminate) {
		srd_dbg("%s: %s: Skip (want_term).", di->inst_id, __func__);
		return SRD_ERR;
	}

	/* Parse the argument of self.wait() into 'py_conds'. */
	if (!PyArg_ParseTuple(args, "O", &py_conds)) {
		/* Let Python raise this exception. */
		return SRD_ERR;
	}

	/* Check whether 'py_conds' is a dict or a list. */
	if (PyList_Check(py_conds)) {
		/* 'py_conds' is a list. */
		py_conditionlist = py_conds;
		num_conditions = PyList_Size(py_conditionlist);
		if (num_conditions == 0)
			return 9999; /* The PD invoked self.wait([]). */
		Py_IncRef(py_conditionlist);
	} else if (PyDict_Check(py_conds)) {
		/* 'py_conds' is a dict. */
		if (PyDict_Size(py_conds) == 0)
			return 9999; /* The PD invoked self.wait({}). */
		/* Make a list and put the dict in there for convenience. */
		py_conditionlist = PyList_New(1);
		Py_IncRef(py_conds);
		PyList_SetItem(py_conditionlist, 0, py_conds);
		num_conditions = 1;
	} else {
		srd_err("Condition list is neither a list nor a dict.");
		return SRD_ERR;
	}

	/* Free the old condition list. */
	condition_list_free(di);

	ret = SRD_OK;

	/* Iterate over the conditions, set di->condition_list accordingly. */
	for (i = 0; i < num_conditions; i++) {
		/* Get a condition (dict) from the condition list. */
		py_dict = PyList_GetItem(py_conditionlist, i);
		if (!PyDict_Check(py_dict)) {
			srd_err("Condition is not a dict.");
			ret = SRD_ERR;
			break;
		}

		/* Create the list of terms in this condition. */
		if ((ret = create_term_list(py_dict, &term_list)) < 0)
			break;

		/* Add the new condition to the PD instance's condition list. */
		di->condition_list = g_slist_append(di->condition_list, term_list);
	}

	Py_DecRef(py_conditionlist);

	return ret;
}