Example #1
0
int setup_pd_stack(void)
{
	struct srd_decoder_inst *di_from, *di_to;
	int ret, i;
	char **pds, **ids;

	/* Set up the protocol decoder stack. */
	pds = g_strsplit(opt_pds, ",", 0);
	if (g_strv_length(pds) > 1) {
		if (opt_pd_stack) {
			/* A stack setup was specified, use that. */
			g_strfreev(pds);
			pds = g_strsplit(opt_pd_stack, ",", 0);
			if (g_strv_length(pds) < 2) {
				g_strfreev(pds);
				g_critical("Specify at least two protocol decoders to stack.");
				return 1;
			}
		}

		/* First PD goes at the bottom of the stack. */
		ids = g_strsplit(pds[0], ":", 0);
		if (!(di_from = srd_inst_find_by_id(ids[0]))) {
			g_strfreev(ids);
			g_critical("Cannot stack protocol decoder '%s': "
					"instance not found.", pds[0]);
			return 1;
		}
		g_strfreev(ids);

		/* Every subsequent PD goes on top. */
		for (i = 1; pds[i]; i++) {
			ids = g_strsplit(pds[i], ":", 0);
			if (!(di_to = srd_inst_find_by_id(ids[0]))) {
				g_strfreev(ids);
				g_critical("Cannot stack protocol decoder '%s': "
						"instance not found.", pds[i]);
				return 1;
			}
			g_strfreev(ids);
			if ((ret = srd_inst_stack(di_from, di_to)) != SRD_OK)
				return 1;

			/* Don't show annotation from this PD. Only the last PD in
			 * the stack will be left on the annotation list (unless
			 * the annotation list was specifically provided).
			 */
			if (!opt_pd_annotations)
				g_hash_table_remove(pd_ann_visible,
						    di_from->inst_id);

			di_from = di_to;
		}
	}
	g_strfreev(pds);

	return 0;
}
Example #2
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;
}