* @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.
+ * @param unit_size Number of bytes per sample in the data stream to be passed
+ * to the decoder. The highest probe index specified in the
+ * probe map must lie within a sample unit.
*
* @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)
+ GHashTable *new_probes, int unit_size)
{
GVariant *probe_val;
GList *l;
GSList *sl;
struct srd_probe *p;
- int *new_probemap, new_probenum, num_required_probes, num_probes, i;
+ int *new_probemap, new_probenum, num_required_probes, i;
char *probe_id;
srd_dbg("set probes called for instance %s with list of %d probes",
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);
return SRD_ERR_ARG;
}
new_probenum = g_variant_get_int32(probe_val);
+ if (new_probenum >= 8 * unit_size) {
+ srd_err("Probe index %d not within data unit (%d bit).",
+ new_probenum, 8 * unit_size);
+ g_free(new_probemap);
+ return SRD_ERR_ARG;
+ }
if (!(sl = g_slist_find_custom(di->decoder->probes, probe_id,
(GCompareFunc)compare_probe_id))) {
/* Fall back on optional probes. */
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;
+ di->data_unitsize = unit_size;
srd_dbg("Final probe map:");
num_required_probes = g_slist_length(di->decoder->probes);
(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;
}
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;
+ }
}
- di->data_unitsize = (di->dec_num_probes + 7) / 8;
/* Create a new instance of this decoder class. */
if (!(di->py_inst = PyObject_CallObject(dec->py_dec, NULL))) {
* Stack a decoder instance on top of another.
*
* @param sess The session holding the protocol decoder instances.
- * @param di_from The instance to move.
- * @param di_to The instance on top of which di_from will be stacked.
+ * @param di_bottom The instance on top of which di_top will be stacked.
+ * @param di_top The instance to go on top.
*
* @return SRD_OK upon success, a (negative) error code otherwise.
*
* @since 0.3.0
*/
SRD_API int srd_inst_stack(struct srd_session *sess,
- struct srd_decoder_inst *di_from, struct srd_decoder_inst *di_to)
+ struct srd_decoder_inst *di_bottom,
+ struct srd_decoder_inst *di_top)
{
if (session_is_valid(sess) != SRD_OK) {
return SRD_ERR_ARG;
}
- if (!di_from || !di_to) {
+ if (!di_bottom || !di_top) {
srd_err("Invalid from/to instance pair.");
return SRD_ERR_ARG;
}
- if (g_slist_find(sess->di_list, di_to)) {
+ if (g_slist_find(sess->di_list, di_top)) {
/* Remove from the unstacked list. */
- sess->di_list = g_slist_remove(sess->di_list, di_to);
+ sess->di_list = g_slist_remove(sess->di_list, di_top);
}
/* Stack on top of source di. */
- di_from->next_di = g_slist_append(di_from->next_di, di_to);
+ di_bottom->next_di = g_slist_append(di_bottom->next_di, di_top);
+
+ srd_dbg("Stacked %s on top of %s.", di_top->inst_id, di_bottom->inst_id);
return SRD_OK;
}