+/* Helper GComparefunc for g_slist_find_custom() in srd_inst_probe_set_all() */
+static gint compare_probe_id(const struct srd_probe *a, const char *probe_id)
+{
+ return strcmp(a->id, probe_id);
+}
+
+/**
+ * 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");
+ }
+
+ g_free(di->dec_probemap);
+ di->dec_probemap = new_probemap;
+
+ return SRD_OK;
+}