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; }
/** * 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; }