]> sigrok.org Git - libsigrok.git/blobdiff - src/session.c
Various #include file cosmetic fixes.
[libsigrok.git] / src / session.c
index f325e78b4e6b6ee9c504f66c0433e2f0d4dfc6a0..765a20c451471b1266be4103544ad77f0979c1d1 100644 (file)
@@ -316,13 +316,40 @@ SR_API int sr_session_datafeed_callback_add(struct sr_session *session,
        return SR_OK;
 }
 
+/**
+ * Get the trigger assigned to this session.
+ *
+ * @param session The session to use.
+ *
+ * @retval NULL Invalid (NULL) session was passed to the function.
+ * @retval other The trigger assigned to this session (can be NULL).
+ *
+ * @since 0.4.0
+ */
 SR_API struct sr_trigger *sr_session_trigger_get(struct sr_session *session)
 {
+       if (!session)
+               return NULL;
+
        return session->trigger;
 }
 
+/**
+ * Set the trigger of this session.
+ *
+ * @param session The session to use. Must not be NULL.
+ * @param trig The trigger to assign to this session. Can be NULL.
+ *
+ * @retval SR_OK Success.
+ * @retval SR_ERR_ARG Invalid argument.
+ *
+ * @since 0.4.0
+ */
 SR_API int sr_session_trigger_set(struct sr_session *session, struct sr_trigger *trig)
 {
+       if (!session)
+               return SR_ERR_ARG;
+
        session->trigger = trig;
 
        return SR_OK;
@@ -344,7 +371,7 @@ SR_API int sr_session_trigger_set(struct sr_session *session, struct sr_trigger
  *              of file descriptor or timeout status.
  *
  * @retval SR_OK Success.
- * @retval SR_ERR Error occured.
+ * @retval SR_ERR Error occurred.
  */
 static int sr_session_iteration(struct sr_session *session, gboolean block)
 {
@@ -385,7 +412,6 @@ static int sr_session_iteration(struct sr_session *session, gboolean block)
        return SR_OK;
 }
 
-
 static int verify_trigger(struct sr_trigger *trigger)
 {
        struct sr_trigger_stage *stage;
@@ -421,6 +447,7 @@ static int verify_trigger(struct sr_trigger *trigger)
 
        return SR_OK;
 }
+
 /**
  * Start a session.
  *
@@ -671,6 +698,9 @@ SR_PRIV int sr_session_send(const struct sr_dev_inst *sdi,
 {
        GSList *l;
        struct datafeed_callback *cb_struct;
+       struct sr_datafeed_packet *packet_in, *packet_out;
+       struct sr_transform *t;
+       int ret;
 
        if (!sdi) {
                sr_err("%s: sdi was NULL", __func__);
@@ -687,6 +717,40 @@ SR_PRIV int sr_session_send(const struct sr_dev_inst *sdi,
                return SR_ERR_BUG;
        }
 
+       /*
+        * Pass the packet to the first transform module. If that returns
+        * another packet (instead of NULL), pass that packet to the next
+        * transform module in the list, and so on.
+        */
+       packet_in = (struct sr_datafeed_packet *)packet;
+       for (l = sdi->session->transforms; l; l = l->next) {
+               t = l->data;
+               sr_spew("Running transform module '%s'.", t->module->id);
+               ret = t->module->receive(t, packet_in, &packet_out);
+               if (ret < 0) {
+                       sr_err("Error while running transform module: %d.", ret);
+                       return SR_ERR;
+               }
+               if (!packet_out) {
+                       /*
+                        * If any of the transforms don't return an output
+                        * packet, abort.
+                        */
+                       sr_spew("Transform module didn't return a packet, aborting.");
+                       return SR_OK;
+               } else {
+                       /*
+                        * Use this transform module's output packet as input
+                        * for the next transform module.
+                        */
+                       packet_in = packet_out;
+               }
+       }
+
+       /*
+        * If the last transform did output a packet, pass it to all datafeed
+        * callbacks.
+        */
        for (l = sdi->session->datafeed_callbacks; l; l = l->next) {
                if (sr_log_loglevel_get() >= SR_LOG_DBG)
                        datafeed_dump(packet);
@@ -920,15 +984,11 @@ SR_API int sr_session_source_remove_channel(struct sr_session *session,
        return _sr_session_source_remove(session, (gintptr)channel);
 }
 
-static void *copy_src(struct sr_config *src)
+static void copy_src(struct sr_config *src, struct sr_datafeed_meta *meta_copy)
 {
-       struct sr_config *new_src;
-
-       new_src = g_malloc(sizeof(struct sr_config));
-       memcpy(new_src, src, sizeof(struct sr_config));
        g_variant_ref(src->data);
-
-       return new_src;
+       meta_copy->config = g_slist_append(meta_copy->config,
+                                          g_memdup(src, sizeof(struct sr_config)));
 }
 
 SR_PRIV int sr_packet_copy(const struct sr_datafeed_packet *packet,
@@ -957,9 +1017,8 @@ SR_PRIV int sr_packet_copy(const struct sr_datafeed_packet *packet,
                break;
        case SR_DF_META:
                meta = packet->payload;
-               meta_copy = g_malloc(sizeof(struct sr_datafeed_meta));
-               meta_copy->config = g_slist_copy_deep(meta->config,
-                               (GCopyFunc)copy_src, NULL);
+               meta_copy = g_malloc0(sizeof(struct sr_datafeed_meta));
+               g_slist_foreach(meta->config, (GFunc)copy_src, meta_copy->config);
                (*copy)->payload = meta_copy;
                break;
        case SR_DF_LOGIC: