]> sigrok.org Git - libsigrok.git/blob - src/session.c
session: Return immediately if there are no event sources
[libsigrok.git] / src / session.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
5  * Copyright (C) 2015 Daniel Elstner <daniel.kitta@gmail.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <glib.h>
27 #include <libsigrok/libsigrok.h>
28 #include "libsigrok-internal.h"
29
30 /** @cond PRIVATE */
31 #define LOG_PREFIX "session"
32 /** @endcond */
33
34 /**
35  * @file
36  *
37  * Creating, using, or destroying libsigrok sessions.
38  */
39
40 /**
41  * @defgroup grp_session Session handling
42  *
43  * Creating, using, or destroying libsigrok sessions.
44  *
45  * @{
46  */
47
48 struct datafeed_callback {
49         sr_datafeed_callback cb;
50         void *cb_data;
51 };
52
53 /** Custom GLib event source for generic descriptor I/O.
54  * @internal
55  */
56 struct fd_source {
57         GSource base;
58
59         int64_t timeout_us;
60         int64_t due_us;
61
62         /* Meta-data needed to keep track of installed sources */
63         struct sr_session *session;
64         void *key;
65
66         GPollFD pollfd;
67 };
68
69 /** FD event source prepare() method.
70  */
71 static gboolean fd_source_prepare(GSource *source, int *timeout)
72 {
73         int64_t now_us;
74         struct fd_source *fsource;
75         int remaining_ms;
76
77         fsource = (struct fd_source *)source;
78
79         if (fsource->timeout_us >= 0) {
80                 now_us = g_source_get_time(source);
81
82                 if (fsource->due_us == 0) {
83                         /* First-time initialization of the expiration time */
84                         fsource->due_us = now_us + fsource->timeout_us;
85                 }
86                 remaining_ms = (MAX(0, fsource->due_us - now_us) + 999) / 1000;
87         } else {
88                 remaining_ms = -1;
89         }
90         *timeout = remaining_ms;
91
92         return (remaining_ms == 0);
93 }
94
95 /** FD event source check() method.
96  */
97 static gboolean fd_source_check(GSource *source)
98 {
99         struct fd_source *fsource;
100         unsigned int revents;
101
102         fsource = (struct fd_source *)source;
103         revents = fsource->pollfd.revents;
104
105         return (revents != 0 || (fsource->timeout_us >= 0
106                         && fsource->due_us <= g_source_get_time(source)));
107 }
108
109 /** FD event source dispatch() method.
110  */
111 static gboolean fd_source_dispatch(GSource *source,
112                 GSourceFunc callback, void *user_data)
113 {
114         struct fd_source *fsource;
115         const char *name;
116         unsigned int revents;
117         gboolean keep;
118
119         fsource = (struct fd_source *)source;
120         name = g_source_get_name(source);
121         revents = fsource->pollfd.revents;
122
123         if (revents != 0) {
124                 sr_spew("%s: %s " G_POLLFD_FORMAT ", revents 0x%.2X",
125                         __func__, name, fsource->pollfd.fd, revents);
126         } else {
127                 sr_spew("%s: %s " G_POLLFD_FORMAT ", timed out",
128                         __func__, name, fsource->pollfd.fd);
129         }
130         if (!callback) {
131                 sr_err("Callback not set, cannot dispatch event.");
132                 return G_SOURCE_REMOVE;
133         }
134         keep = (*(sr_receive_data_callback)callback)
135                         (fsource->pollfd.fd, revents, user_data);
136
137         if (fsource->timeout_us >= 0 && G_LIKELY(keep)
138                         && G_LIKELY(!g_source_is_destroyed(source)))
139                 fsource->due_us = g_source_get_time(source)
140                                 + fsource->timeout_us;
141         return keep;
142 }
143
144 /** FD event source finalize() method.
145  */
146 static void fd_source_finalize(GSource *source)
147 {
148         struct fd_source *fsource;
149
150         fsource = (struct fd_source *)source;
151
152         sr_dbg("%s: key %p", __func__, fsource->key);
153
154         sr_session_source_destroyed(fsource->session, fsource->key, source);
155 }
156
157 /** Create an event source for I/O on a file descriptor.
158  *
159  * In order to maintain API compatibility, this event source also doubles
160  * as a timer event source.
161  *
162  * @param session The session the event source belongs to.
163  * @param key The key used to identify this source.
164  * @param fd The file descriptor or HANDLE.
165  * @param timeout_ms The timeout interval in ms, or -1 to wait indefinitely.
166  * @return A new event source object, or NULL on failure.
167  */
168 static GSource *fd_source_new(struct sr_session *session, void *key,
169                 gintptr fd, int events, int timeout_ms)
170 {
171         static GSourceFuncs fd_source_funcs = {
172                 .prepare  = &fd_source_prepare,
173                 .check    = &fd_source_check,
174                 .dispatch = &fd_source_dispatch,
175                 .finalize = &fd_source_finalize
176         };
177         GSource *source;
178         struct fd_source *fsource;
179
180         source = g_source_new(&fd_source_funcs, sizeof(struct fd_source));
181         fsource = (struct fd_source *)source;
182
183         g_source_set_name(source, (fd < 0) ? "timer" : "fd");
184
185         if (timeout_ms >= 0) {
186                 fsource->timeout_us = 1000 * (int64_t)timeout_ms;
187                 fsource->due_us = 0;
188         } else {
189                 fsource->timeout_us = -1;
190                 fsource->due_us = INT64_MAX;
191         }
192         fsource->session = session;
193         fsource->key = key;
194
195         fsource->pollfd.fd = fd;
196         fsource->pollfd.events = events;
197         fsource->pollfd.revents = 0;
198
199         if (fd >= 0)
200                 g_source_add_poll(source, &fsource->pollfd);
201
202         return source;
203 }
204
205 /**
206  * Create a new session.
207  *
208  * @param ctx         The context in which to create the new session.
209  * @param new_session This will contain a pointer to the newly created
210  *                    session if the return value is SR_OK, otherwise the value
211  *                    is undefined and should not be used. Must not be NULL.
212  *
213  * @retval SR_OK Success.
214  * @retval SR_ERR_ARG Invalid argument.
215  *
216  * @since 0.4.0
217  */
218 SR_API int sr_session_new(struct sr_context *ctx,
219                 struct sr_session **new_session)
220 {
221         struct sr_session *session;
222
223         if (!new_session)
224                 return SR_ERR_ARG;
225
226         session = g_malloc0(sizeof(struct sr_session));
227
228         session->ctx = ctx;
229
230         g_mutex_init(&session->main_mutex);
231
232         /* To maintain API compatibility, we need a lookup table
233          * which maps poll_object IDs to GSource* pointers.
234          */
235         session->event_sources = g_hash_table_new(NULL, NULL);
236
237         *new_session = session;
238
239         return SR_OK;
240 }
241
242 /**
243  * Destroy a session.
244  * This frees up all memory used by the session.
245  *
246  * @param session The session to destroy. Must not be NULL.
247  *
248  * @retval SR_OK Success.
249  * @retval SR_ERR_ARG Invalid session passed.
250  *
251  * @since 0.4.0
252  */
253 SR_API int sr_session_destroy(struct sr_session *session)
254 {
255         if (!session) {
256                 sr_err("%s: session was NULL", __func__);
257                 return SR_ERR_ARG;
258         }
259
260         sr_session_dev_remove_all(session);
261         g_slist_free_full(session->owned_devs, (GDestroyNotify)sr_dev_inst_free);
262
263         g_hash_table_unref(session->event_sources);
264
265         g_mutex_clear(&session->main_mutex);
266
267         g_free(session);
268
269         return SR_OK;
270 }
271
272 /**
273  * Remove all the devices from a session.
274  *
275  * The session itself (i.e., the struct sr_session) is not free'd and still
276  * exists after this function returns.
277  *
278  * @param session The session to use. Must not be NULL.
279  *
280  * @retval SR_OK Success.
281  * @retval SR_ERR_BUG Invalid session passed.
282  *
283  * @since 0.4.0
284  */
285 SR_API int sr_session_dev_remove_all(struct sr_session *session)
286 {
287         struct sr_dev_inst *sdi;
288         GSList *l;
289
290         if (!session) {
291                 sr_err("%s: session was NULL", __func__);
292                 return SR_ERR_ARG;
293         }
294
295         for (l = session->devs; l; l = l->next) {
296                 sdi = (struct sr_dev_inst *) l->data;
297                 sdi->session = NULL;
298         }
299
300         g_slist_free(session->devs);
301         session->devs = NULL;
302
303         return SR_OK;
304 }
305
306 /**
307  * Add a device instance to a session.
308  *
309  * @param session The session to add to. Must not be NULL.
310  * @param sdi The device instance to add to a session. Must not
311  *            be NULL. Also, sdi->driver and sdi->driver->dev_open must
312  *            not be NULL.
313  *
314  * @retval SR_OK Success.
315  * @retval SR_ERR_ARG Invalid argument.
316  *
317  * @since 0.4.0
318  */
319 SR_API int sr_session_dev_add(struct sr_session *session,
320                 struct sr_dev_inst *sdi)
321 {
322         int ret;
323
324         if (!sdi) {
325                 sr_err("%s: sdi was NULL", __func__);
326                 return SR_ERR_ARG;
327         }
328
329         if (!session) {
330                 sr_err("%s: session was NULL", __func__);
331                 return SR_ERR_ARG;
332         }
333
334         /* If sdi->session is not NULL, the device is already in this or
335          * another session. */
336         if (sdi->session) {
337                 sr_err("%s: already assigned to session", __func__);
338                 return SR_ERR_ARG;
339         }
340
341         /* If sdi->driver is NULL, this is a virtual device. */
342         if (!sdi->driver) {
343                 /* Just add the device, don't run dev_open(). */
344                 session->devs = g_slist_append(session->devs, (gpointer)sdi);
345                 sdi->session = session;
346                 return SR_OK;
347         }
348
349         /* sdi->driver is non-NULL (i.e. we have a real device). */
350         if (!sdi->driver->dev_open) {
351                 sr_err("%s: sdi->driver->dev_open was NULL", __func__);
352                 return SR_ERR_BUG;
353         }
354
355         session->devs = g_slist_append(session->devs, (gpointer)sdi);
356         sdi->session = session;
357
358         if (session->running) {
359                 /* Adding a device to a running session. Commit settings
360                  * and start acquisition on that device now. */
361                 if ((ret = sr_config_commit(sdi)) != SR_OK) {
362                         sr_err("Failed to commit device settings before "
363                                "starting acquisition in running session (%s)",
364                                sr_strerror(ret));
365                         return ret;
366                 }
367                 if ((ret = sdi->driver->dev_acquisition_start(sdi,
368                                                 (void *)sdi)) != SR_OK) {
369                         sr_err("Failed to start acquisition of device in "
370                                "running session (%s)", sr_strerror(ret));
371                         return ret;
372                 }
373         }
374
375         return SR_OK;
376 }
377
378 /**
379  * List all device instances attached to a session.
380  *
381  * @param session The session to use. Must not be NULL.
382  * @param devlist A pointer where the device instance list will be
383  *                stored on return. If no devices are in the session,
384  *                this will be NULL. Each element in the list points
385  *                to a struct sr_dev_inst *.
386  *                The list must be freed by the caller, but not the
387  *                elements pointed to.
388  *
389  * @retval SR_OK Success.
390  * @retval SR_ERR_ARG Invalid argument.
391  *
392  * @since 0.4.0
393  */
394 SR_API int sr_session_dev_list(struct sr_session *session, GSList **devlist)
395 {
396         if (!session)
397                 return SR_ERR_ARG;
398
399         if (!devlist)
400                 return SR_ERR_ARG;
401
402         *devlist = g_slist_copy(session->devs);
403
404         return SR_OK;
405 }
406
407 /**
408  * Remove all datafeed callbacks in a session.
409  *
410  * @param session The session to use. Must not be NULL.
411  *
412  * @retval SR_OK Success.
413  * @retval SR_ERR_ARG Invalid session passed.
414  *
415  * @since 0.4.0
416  */
417 SR_API int sr_session_datafeed_callback_remove_all(struct sr_session *session)
418 {
419         if (!session) {
420                 sr_err("%s: session was NULL", __func__);
421                 return SR_ERR_ARG;
422         }
423
424         g_slist_free_full(session->datafeed_callbacks, g_free);
425         session->datafeed_callbacks = NULL;
426
427         return SR_OK;
428 }
429
430 /**
431  * Add a datafeed callback to a session.
432  *
433  * @param session The session to use. Must not be NULL.
434  * @param cb Function to call when a chunk of data is received.
435  *           Must not be NULL.
436  * @param cb_data Opaque pointer passed in by the caller.
437  *
438  * @retval SR_OK Success.
439  * @retval SR_ERR_BUG No session exists.
440  *
441  * @since 0.3.0
442  */
443 SR_API int sr_session_datafeed_callback_add(struct sr_session *session,
444                 sr_datafeed_callback cb, void *cb_data)
445 {
446         struct datafeed_callback *cb_struct;
447
448         if (!session) {
449                 sr_err("%s: session was NULL", __func__);
450                 return SR_ERR_BUG;
451         }
452
453         if (!cb) {
454                 sr_err("%s: cb was NULL", __func__);
455                 return SR_ERR_ARG;
456         }
457
458         cb_struct = g_malloc0(sizeof(struct datafeed_callback));
459         cb_struct->cb = cb;
460         cb_struct->cb_data = cb_data;
461
462         session->datafeed_callbacks =
463             g_slist_append(session->datafeed_callbacks, cb_struct);
464
465         return SR_OK;
466 }
467
468 /**
469  * Get the trigger assigned to this session.
470  *
471  * @param session The session to use.
472  *
473  * @retval NULL Invalid (NULL) session was passed to the function.
474  * @retval other The trigger assigned to this session (can be NULL).
475  *
476  * @since 0.4.0
477  */
478 SR_API struct sr_trigger *sr_session_trigger_get(struct sr_session *session)
479 {
480         if (!session)
481                 return NULL;
482
483         return session->trigger;
484 }
485
486 /**
487  * Set the trigger of this session.
488  *
489  * @param session The session to use. Must not be NULL.
490  * @param trig The trigger to assign to this session. Can be NULL.
491  *
492  * @retval SR_OK Success.
493  * @retval SR_ERR_ARG Invalid argument.
494  *
495  * @since 0.4.0
496  */
497 SR_API int sr_session_trigger_set(struct sr_session *session, struct sr_trigger *trig)
498 {
499         if (!session)
500                 return SR_ERR_ARG;
501
502         session->trigger = trig;
503
504         return SR_OK;
505 }
506
507 static int verify_trigger(struct sr_trigger *trigger)
508 {
509         struct sr_trigger_stage *stage;
510         struct sr_trigger_match *match;
511         GSList *l, *m;
512
513         if (!trigger->stages) {
514                 sr_err("No trigger stages defined.");
515                 return SR_ERR;
516         }
517
518         sr_spew("Checking trigger:");
519         for (l = trigger->stages; l; l = l->next) {
520                 stage = l->data;
521                 if (!stage->matches) {
522                         sr_err("Stage %d has no matches defined.", stage->stage);
523                         return SR_ERR;
524                 }
525                 for (m = stage->matches; m; m = m->next) {
526                         match = m->data;
527                         if (!match->channel) {
528                                 sr_err("Stage %d match has no channel.", stage->stage);
529                                 return SR_ERR;
530                         }
531                         if (!match->match) {
532                                 sr_err("Stage %d match is not defined.", stage->stage);
533                                 return SR_ERR;
534                         }
535                         sr_spew("Stage %d match on channel %s, match %d", stage->stage,
536                                         match->channel->name, match->match);
537                 }
538         }
539
540         return SR_OK;
541 }
542
543 /** Set up the main context the session will be executing in.
544  *
545  * Must be called just before the session starts, by the thread which
546  * will execute the session main loop. Once acquired, the main context
547  * pointer is immutable for the duration of the session run.
548  */
549 static int set_main_context(struct sr_session *session)
550 {
551         GMainContext *def_context;
552
553         /* May happen if sr_session_start() is called again after
554          * sr_session_run(), but the session hasn't been stopped yet.
555          */
556         if (session->main_loop) {
557                 sr_err("Cannot set main context; main loop already created.");
558                 return SR_ERR;
559         }
560
561         g_mutex_lock(&session->main_mutex);
562
563         def_context = g_main_context_get_thread_default();
564
565         if (!def_context)
566                 def_context = g_main_context_default();
567         /*
568          * Try to use an existing main context if possible, but only if we
569          * can make it owned by the current thread. Otherwise, create our
570          * own main context so that event source callbacks can execute in
571          * the session thread.
572          */
573         if (g_main_context_acquire(def_context)) {
574                 g_main_context_release(def_context);
575
576                 sr_dbg("Using thread-default main context.");
577
578                 session->main_context = def_context;
579                 session->main_context_is_default = TRUE;
580         } else {
581                 sr_dbg("Creating our own main context.");
582
583                 session->main_context = g_main_context_new();
584                 session->main_context_is_default = FALSE;
585         }
586         g_mutex_unlock(&session->main_mutex);
587
588         return SR_OK;
589 }
590
591 /** Unset the main context used for the current session run.
592  *
593  * Must be called right after stopping the session. Note that if the
594  * session is stopped asynchronously, the main loop may still be running
595  * after the main context has been unset. This is OK as long as no new
596  * event sources are created -- the main loop holds its own reference
597  * to the main context.
598  */
599 static int unset_main_context(struct sr_session *session)
600 {
601         int ret;
602
603         g_mutex_lock(&session->main_mutex);
604
605         if (session->main_context) {
606                 if (!session->main_context_is_default)
607                         g_main_context_unref(session->main_context);
608
609                 session->main_context = NULL;
610                 ret = SR_OK;
611         } else {
612                 /* May happen if the set/unset calls are not matched.
613                  */
614                 sr_err("No main context to unset.");
615                 ret = SR_ERR;
616         }
617         g_mutex_unlock(&session->main_mutex);
618
619         return ret;
620 }
621
622 /**
623  * Start a session.
624  *
625  * @param session The session to use. Must not be NULL.
626  *
627  * @retval SR_OK Success.
628  * @retval SR_ERR_ARG Invalid session passed.
629  *
630  * @since 0.4.0
631  */
632 SR_API int sr_session_start(struct sr_session *session)
633 {
634         struct sr_dev_inst *sdi;
635         struct sr_channel *ch;
636         GSList *l, *c;
637         int enabled_channels, ret;
638
639         if (!session) {
640                 sr_err("%s: session was NULL", __func__);
641                 return SR_ERR_ARG;
642         }
643
644         if (!session->devs) {
645                 sr_err("%s: session->devs was NULL; a session "
646                        "cannot be started without devices.", __func__);
647                 return SR_ERR_ARG;
648         }
649
650         if (session->trigger && verify_trigger(session->trigger) != SR_OK)
651                 return SR_ERR;
652
653         ret = set_main_context(session);
654         if (ret != SR_OK)
655                 return ret;
656
657         session->running = TRUE;
658
659         sr_info("Starting.");
660
661         for (l = session->devs; l; l = l->next) {
662                 sdi = l->data;
663                 enabled_channels = 0;
664                 for (c = sdi->channels; c; c = c->next) {
665                         ch = c->data;
666                         if (ch->enabled) {
667                                 enabled_channels++;
668                                 break;
669                         }
670                 }
671                 if (enabled_channels == 0) {
672                         ret = SR_ERR;
673                         sr_err("%s using connection %s has no enabled channels!",
674                                         sdi->driver->name, sdi->connection_id);
675                         break;
676                 }
677
678                 if ((ret = sr_config_commit(sdi)) != SR_OK) {
679                         sr_err("Failed to commit device settings before "
680                                "starting acquisition (%s)", sr_strerror(ret));
681                         break;
682                 }
683                 if ((ret = sdi->driver->dev_acquisition_start(sdi, sdi)) != SR_OK) {
684                         sr_err("%s: could not start an acquisition "
685                                "(%s)", __func__, sr_strerror(ret));
686                         break;
687                 }
688         }
689
690         if (ret != SR_OK) {
691                 unset_main_context(session);
692                 session->running = FALSE;
693         }
694         /* TODO: What if there are multiple devices? Which return code? */
695
696         return ret;
697 }
698
699 /**
700  * Run a session.
701  *
702  * @param session The session to use. Must not be NULL.
703  *
704  * @retval SR_OK Success.
705  * @retval SR_ERR_ARG Invalid session passed.
706  * @retval SR_ERR Error during event processing.
707  *
708  * @since 0.4.0
709  */
710 SR_API int sr_session_run(struct sr_session *session)
711 {
712         if (!session) {
713                 sr_err("%s: session was NULL", __func__);
714                 return SR_ERR_ARG;
715         }
716         if (!session->devs) {
717                 /* TODO: Actually the case? */
718                 sr_err("%s: session->devs was NULL; a session "
719                        "cannot be run without devices.", __func__);
720                 return SR_ERR_ARG;
721         }
722         if (session->main_loop) {
723                 sr_err("Main loop already created.");
724                 return SR_ERR;
725         }
726         if (g_hash_table_size(session->event_sources) == 0) {
727                 sr_warn("No event sources, returning immediately.");
728                 return SR_OK;
729         }
730
731         g_mutex_lock(&session->main_mutex);
732         if (!session->main_context) {
733                 sr_err("Cannot run without main context.");
734                 g_mutex_unlock(&session->main_mutex);
735                 return SR_ERR;
736         }
737         sr_info("Running.");
738
739         session->main_loop = g_main_loop_new(session->main_context, FALSE);
740         g_mutex_unlock(&session->main_mutex);
741
742         g_main_loop_run(session->main_loop);
743
744         g_main_loop_unref(session->main_loop);
745         session->main_loop = NULL;
746
747         return SR_OK;
748 }
749
750 static gboolean session_stop_sync(void *user_data)
751 {
752         struct sr_session *session;
753         struct sr_dev_inst *sdi;
754         GSList *node;
755
756         session = user_data;
757
758         if (!session->running)
759                 return G_SOURCE_REMOVE;
760
761         sr_info("Stopping.");
762
763         for (node = session->devs; node; node = node->next) {
764                 sdi = node->data;
765                 if (sdi->driver && sdi->driver->dev_acquisition_stop)
766                         sdi->driver->dev_acquisition_stop(sdi, sdi);
767         }
768         session->running = FALSE;
769
770         return G_SOURCE_REMOVE;
771 }
772
773 /**
774  * Stop a session.
775  *
776  * The session is stopped immediately, with all acquisition sessions being
777  * stopped and hardware drivers cleaned up.
778  *
779  * If the session is run in a separate thread, this function will not block
780  * until the session is finished executing. It is the caller's responsibility
781  * to wait for the session thread to return before assuming that the session is
782  * completely decommissioned.
783  *
784  * @param session The session to use. Must not be NULL.
785  *
786  * @retval SR_OK Success.
787  * @retval SR_ERR_ARG Invalid session passed.
788  * @retval SR_ERR Other error.
789  *
790  * @since 0.4.0
791  */
792 SR_API int sr_session_stop(struct sr_session *session)
793 {
794         if (!session) {
795                 sr_err("%s: session was NULL", __func__);
796                 return SR_ERR_ARG;
797         }
798         g_mutex_lock(&session->main_mutex);
799
800         if (session->main_context) {
801                 g_main_context_invoke(session->main_context,
802                                 &session_stop_sync, session);
803         } else {
804                 sr_err("No main context set; already stopped?");
805         }
806         g_mutex_unlock(&session->main_mutex);
807
808         return unset_main_context(session);
809 }
810
811 /**
812  * Debug helper.
813  *
814  * @param packet The packet to show debugging information for.
815  */
816 static void datafeed_dump(const struct sr_datafeed_packet *packet)
817 {
818         const struct sr_datafeed_logic *logic;
819         const struct sr_datafeed_analog *analog;
820         const struct sr_datafeed_analog2 *analog2;
821
822         /* Please use the same order as in libsigrok.h. */
823         switch (packet->type) {
824         case SR_DF_HEADER:
825                 sr_dbg("bus: Received SR_DF_HEADER packet.");
826                 break;
827         case SR_DF_END:
828                 sr_dbg("bus: Received SR_DF_END packet.");
829                 break;
830         case SR_DF_META:
831                 sr_dbg("bus: Received SR_DF_META packet.");
832                 break;
833         case SR_DF_TRIGGER:
834                 sr_dbg("bus: Received SR_DF_TRIGGER packet.");
835                 break;
836         case SR_DF_LOGIC:
837                 logic = packet->payload;
838                 sr_dbg("bus: Received SR_DF_LOGIC packet (%" PRIu64 " bytes, "
839                        "unitsize = %d).", logic->length, logic->unitsize);
840                 break;
841         case SR_DF_ANALOG:
842                 analog = packet->payload;
843                 sr_dbg("bus: Received SR_DF_ANALOG packet (%d samples).",
844                        analog->num_samples);
845                 break;
846         case SR_DF_FRAME_BEGIN:
847                 sr_dbg("bus: Received SR_DF_FRAME_BEGIN packet.");
848                 break;
849         case SR_DF_FRAME_END:
850                 sr_dbg("bus: Received SR_DF_FRAME_END packet.");
851                 break;
852         case SR_DF_ANALOG2:
853                 analog2 = packet->payload;
854                 sr_dbg("bus: Received SR_DF_ANALOG2 packet (%d samples).",
855                        analog2->num_samples);
856                 break;
857         default:
858                 sr_dbg("bus: Received unknown packet type: %d.", packet->type);
859                 break;
860         }
861 }
862
863 /**
864  * Send a packet to whatever is listening on the datafeed bus.
865  *
866  * Hardware drivers use this to send a data packet to the frontend.
867  *
868  * @param sdi TODO.
869  * @param packet The datafeed packet to send to the session bus.
870  *
871  * @retval SR_OK Success.
872  * @retval SR_ERR_ARG Invalid argument.
873  *
874  * @private
875  */
876 SR_PRIV int sr_session_send(const struct sr_dev_inst *sdi,
877                 const struct sr_datafeed_packet *packet)
878 {
879         GSList *l;
880         struct datafeed_callback *cb_struct;
881         struct sr_datafeed_packet *packet_in, *packet_out;
882         struct sr_transform *t;
883         int ret;
884
885         if (!sdi) {
886                 sr_err("%s: sdi was NULL", __func__);
887                 return SR_ERR_ARG;
888         }
889
890         if (!packet) {
891                 sr_err("%s: packet was NULL", __func__);
892                 return SR_ERR_ARG;
893         }
894
895         if (!sdi->session) {
896                 sr_err("%s: session was NULL", __func__);
897                 return SR_ERR_BUG;
898         }
899
900         /*
901          * Pass the packet to the first transform module. If that returns
902          * another packet (instead of NULL), pass that packet to the next
903          * transform module in the list, and so on.
904          */
905         packet_in = (struct sr_datafeed_packet *)packet;
906         for (l = sdi->session->transforms; l; l = l->next) {
907                 t = l->data;
908                 sr_spew("Running transform module '%s'.", t->module->id);
909                 ret = t->module->receive(t, packet_in, &packet_out);
910                 if (ret < 0) {
911                         sr_err("Error while running transform module: %d.", ret);
912                         return SR_ERR;
913                 }
914                 if (!packet_out) {
915                         /*
916                          * If any of the transforms don't return an output
917                          * packet, abort.
918                          */
919                         sr_spew("Transform module didn't return a packet, aborting.");
920                         return SR_OK;
921                 } else {
922                         /*
923                          * Use this transform module's output packet as input
924                          * for the next transform module.
925                          */
926                         packet_in = packet_out;
927                 }
928         }
929         packet = packet_in;
930
931         /*
932          * If the last transform did output a packet, pass it to all datafeed
933          * callbacks.
934          */
935         for (l = sdi->session->datafeed_callbacks; l; l = l->next) {
936                 if (sr_log_loglevel_get() >= SR_LOG_DBG)
937                         datafeed_dump(packet);
938                 cb_struct = l->data;
939                 cb_struct->cb(sdi, packet, cb_struct->cb_data);
940         }
941
942         return SR_OK;
943 }
944
945 /**
946  * Add an event source for a file descriptor.
947  *
948  * @param session The session to use. Must not be NULL.
949  * @param key The key which identifies the event source.
950  * @param source An event source object. Must not be NULL.
951  * @retval SR_OK Success.
952  * @retval SR_ERR_ARG Invalid argument.
953  * @retval SR_ERR_BUG Event source with @a key already installed.
954  * @retval SR_ERR Other error.
955  */
956 SR_PRIV int sr_session_source_add_internal(struct sr_session *session,
957                 void *key, GSource *source)
958 {
959         int ret;
960         /*
961          * This must not ever happen, since the source has already been
962          * created and its finalize() method will remove the key for the
963          * already installed source. (Well it would, if we did not have
964          * another sanity check there.)
965          */
966         if (g_hash_table_contains(session->event_sources, key)) {
967                 sr_err("Event source with key %p already exists.", key);
968                 return SR_ERR_BUG;
969         }
970         g_hash_table_insert(session->event_sources, key, source);
971
972         g_mutex_lock(&session->main_mutex);
973
974         if (session->main_context) {
975                 if (g_source_attach(source, session->main_context) > 0)
976                         ret = SR_OK;
977                 else
978                         ret = SR_ERR;
979         } else {
980                 sr_err("Cannot add event source without main context.");
981                 ret = SR_ERR;
982         }
983         g_mutex_unlock(&session->main_mutex);
984
985         return ret;
986 }
987
988 static int attach_fd_source(struct sr_session *session,
989                 void *key, int fd, int events, int timeout,
990                 sr_receive_data_callback cb, void *cb_data)
991 {
992         GSource *source;
993         int ret;
994
995         source = fd_source_new(session, key, fd, events, timeout);
996         if (!source)
997                 return SR_ERR;
998
999         g_source_set_callback(source, (GSourceFunc)cb, cb_data, NULL);
1000
1001         ret = sr_session_source_add_internal(session, key, source);
1002         g_source_unref(source);
1003
1004         return ret;
1005 }
1006
1007 /**
1008  * Add an event source for a file descriptor.
1009  *
1010  * @param session The session to use. Must not be NULL.
1011  * @param fd The file descriptor, or a negative value to create a timer source.
1012  * @param events Events to check for.
1013  * @param timeout Max time in ms to wait before the callback is called,
1014  *                or -1 to wait indefinitely.
1015  * @param cb Callback function to add. Must not be NULL.
1016  * @param cb_data Data for the callback function. Can be NULL.
1017  *
1018  * @retval SR_OK Success.
1019  * @retval SR_ERR_ARG Invalid argument.
1020  *
1021  * @since 0.3.0
1022  */
1023 SR_API int sr_session_source_add(struct sr_session *session, int fd,
1024                 int events, int timeout, sr_receive_data_callback cb, void *cb_data)
1025 {
1026         if (fd < 0 && timeout < 0) {
1027                 sr_err("Cannot create timer source without timeout.");
1028                 return SR_ERR_ARG;
1029         }
1030         return attach_fd_source(session, GINT_TO_POINTER(fd),
1031                         fd, events, timeout, cb, cb_data);
1032 }
1033
1034 /**
1035  * Add an event source for a GPollFD.
1036  *
1037  * @param session The session to use. Must not be NULL.
1038  * @param pollfd The GPollFD. Must not be NULL.
1039  * @param timeout Max time in ms to wait before the callback is called,
1040  *                or -1 to wait indefinitely.
1041  * @param cb Callback function to add. Must not be NULL.
1042  * @param cb_data Data for the callback function. Can be NULL.
1043  *
1044  * @retval SR_OK Success.
1045  * @retval SR_ERR_ARG Invalid argument.
1046  *
1047  * @since 0.3.0
1048  */
1049 SR_API int sr_session_source_add_pollfd(struct sr_session *session,
1050                 GPollFD *pollfd, int timeout, sr_receive_data_callback cb,
1051                 void *cb_data)
1052 {
1053         if (!pollfd) {
1054                 sr_err("%s: pollfd was NULL", __func__);
1055                 return SR_ERR_ARG;
1056         }
1057         return attach_fd_source(session, pollfd, pollfd->fd,
1058                         pollfd->events, timeout, cb, cb_data);
1059 }
1060
1061 /**
1062  * Add an event source for a GIOChannel.
1063  *
1064  * @param session The session to use. Must not be NULL.
1065  * @param channel The GIOChannel.
1066  * @param events Events to poll on.
1067  * @param timeout Max time in ms to wait before the callback is called,
1068  *                or -1 to wait indefinitely.
1069  * @param cb Callback function to add. Must not be NULL.
1070  * @param cb_data Data for the callback function. Can be NULL.
1071  *
1072  * @retval SR_OK Success.
1073  * @retval SR_ERR_ARG Invalid argument.
1074  *
1075  * @since 0.3.0
1076  */
1077 SR_API int sr_session_source_add_channel(struct sr_session *session,
1078                 GIOChannel *channel, int events, int timeout,
1079                 sr_receive_data_callback cb, void *cb_data)
1080 {
1081         GPollFD pollfd;
1082
1083         if (!channel) {
1084                 sr_err("%s: channel was NULL", __func__);
1085                 return SR_ERR_ARG;
1086         }
1087         /* We should be using g_io_create_watch(), but can't without
1088          * changing the driver API, as the callback signature is different.
1089          */
1090 #ifdef G_OS_WIN32
1091         g_io_channel_win32_make_pollfd(channel, events, &pollfd);
1092 #else
1093         pollfd.fd = g_io_channel_unix_get_fd(channel);
1094         pollfd.events = events;
1095 #endif
1096         return attach_fd_source(session, channel, pollfd.fd,
1097                         pollfd.events, timeout, cb, cb_data);
1098 }
1099
1100 /**
1101  * Remove the source identified by the specified poll object.
1102  *
1103  * @param session The session to use. Must not be NULL.
1104  * @param key The key by which the source is identified.
1105  *
1106  * @retval SR_OK Success
1107  * @retval SR_ERR_BUG No event source for poll_object found.
1108  */
1109 SR_PRIV int sr_session_source_remove_internal(struct sr_session *session,
1110                 void *key)
1111 {
1112         GSource *source;
1113
1114         source = g_hash_table_lookup(session->event_sources, key);
1115         /*
1116          * Trying to remove an already removed event source is problematic
1117          * since the poll_object handle may have been reused in the meantime.
1118          */
1119         if (!source) {
1120                 sr_warn("Cannot remove non-existing event source %p.", key);
1121                 return SR_ERR_BUG;
1122         }
1123         g_source_destroy(source);
1124
1125         return SR_OK;
1126 }
1127
1128 /**
1129  * Remove the source belonging to the specified file descriptor.
1130  *
1131  * @param session The session to use. Must not be NULL.
1132  * @param fd The file descriptor for which the source should be removed.
1133  *
1134  * @retval SR_OK Success
1135  * @retval SR_ERR_ARG Invalid argument
1136  * @retval SR_ERR_BUG Internal error.
1137  *
1138  * @since 0.3.0
1139  */
1140 SR_API int sr_session_source_remove(struct sr_session *session, int fd)
1141 {
1142         return sr_session_source_remove_internal(session, GINT_TO_POINTER(fd));
1143 }
1144
1145 /**
1146  * Remove the source belonging to the specified poll descriptor.
1147  *
1148  * @param session The session to use. Must not be NULL.
1149  * @param pollfd The poll descriptor for which the source should be removed.
1150  *               Must not be NULL.
1151  * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
1152  *         SR_ERR_MALLOC upon memory allocation errors, SR_ERR_BUG upon
1153  *         internal errors.
1154  *
1155  * @since 0.2.0
1156  */
1157 SR_API int sr_session_source_remove_pollfd(struct sr_session *session,
1158                 GPollFD *pollfd)
1159 {
1160         if (!pollfd) {
1161                 sr_err("%s: pollfd was NULL", __func__);
1162                 return SR_ERR_ARG;
1163         }
1164         return sr_session_source_remove_internal(session, pollfd);
1165 }
1166
1167 /**
1168  * Remove the source belonging to the specified channel.
1169  *
1170  * @param session The session to use. Must not be NULL.
1171  * @param channel The channel for which the source should be removed.
1172  *                Must not be NULL.
1173  * @retval SR_OK Success.
1174  * @retval SR_ERR_ARG Invalid argument.
1175  * @return SR_ERR_BUG Internal error.
1176  *
1177  * @since 0.2.0
1178  */
1179 SR_API int sr_session_source_remove_channel(struct sr_session *session,
1180                 GIOChannel *channel)
1181 {
1182         if (!channel) {
1183                 sr_err("%s: channel was NULL", __func__);
1184                 return SR_ERR_ARG;
1185         }
1186         return sr_session_source_remove_internal(session, channel);
1187 }
1188
1189 /** Unregister an event source that has been destroyed.
1190  *
1191  * This is intended to be called from a source's finalize() method.
1192  *
1193  * @param session The session to use. Must not be NULL.
1194  * @param key The key used to identify @a source.
1195  * @param source The source object that was destroyed.
1196  *
1197  * @retval SR_OK Success.
1198  * @retval SR_ERR_BUG Event source for @a key does not match @a source.
1199  */
1200 SR_PRIV int sr_session_source_destroyed(struct sr_session *session,
1201                 void *key, GSource *source)
1202 {
1203         GSource *registered_source;
1204
1205         registered_source = g_hash_table_lookup(session->event_sources, key);
1206         /*
1207          * Trying to remove an already removed event source is problematic
1208          * since the poll_object handle may have been reused in the meantime.
1209          */
1210         if (!registered_source) {
1211                 sr_err("No event source for key %p found.", key);
1212                 return SR_ERR_BUG;
1213         }
1214         if (registered_source != source) {
1215                 sr_err("Event source for key %p does not match"
1216                         " destroyed source.", key);
1217                 return SR_ERR_BUG;
1218         }
1219         g_hash_table_remove(session->event_sources, key);
1220         /*
1221          * Quit the main loop if we just removed the last event source.
1222          * TODO: This may need an idle callback depending on when event
1223          * sources are finalized. (The issue is remove followed by add
1224          * within the same main loop iteration.)
1225          */
1226         if (session->main_loop
1227                         && g_hash_table_size(session->event_sources) == 0) {
1228                 sr_dbg("Stopping main loop...");
1229                 g_main_loop_quit(session->main_loop);
1230         }
1231         return SR_OK;
1232 }
1233
1234 static void copy_src(struct sr_config *src, struct sr_datafeed_meta *meta_copy)
1235 {
1236         g_variant_ref(src->data);
1237         meta_copy->config = g_slist_append(meta_copy->config,
1238                                            g_memdup(src, sizeof(struct sr_config)));
1239 }
1240
1241 SR_PRIV int sr_packet_copy(const struct sr_datafeed_packet *packet,
1242                 struct sr_datafeed_packet **copy)
1243 {
1244         const struct sr_datafeed_meta *meta;
1245         struct sr_datafeed_meta *meta_copy;
1246         const struct sr_datafeed_logic *logic;
1247         struct sr_datafeed_logic *logic_copy;
1248         const struct sr_datafeed_analog *analog;
1249         struct sr_datafeed_analog *analog_copy;
1250         uint8_t *payload;
1251
1252         *copy = g_malloc0(sizeof(struct sr_datafeed_packet));
1253         (*copy)->type = packet->type;
1254
1255         switch (packet->type) {
1256         case SR_DF_TRIGGER:
1257         case SR_DF_END:
1258                 /* No payload. */
1259                 break;
1260         case SR_DF_HEADER:
1261                 payload = g_malloc(sizeof(struct sr_datafeed_header));
1262                 memcpy(payload, packet->payload, sizeof(struct sr_datafeed_header));
1263                 (*copy)->payload = payload;
1264                 break;
1265         case SR_DF_META:
1266                 meta = packet->payload;
1267                 meta_copy = g_malloc0(sizeof(struct sr_datafeed_meta));
1268                 g_slist_foreach(meta->config, (GFunc)copy_src, meta_copy->config);
1269                 (*copy)->payload = meta_copy;
1270                 break;
1271         case SR_DF_LOGIC:
1272                 logic = packet->payload;
1273                 logic_copy = g_malloc(sizeof(logic));
1274                 logic_copy->length = logic->length;
1275                 logic_copy->unitsize = logic->unitsize;
1276                 memcpy(logic_copy->data, logic->data, logic->length * logic->unitsize);
1277                 (*copy)->payload = logic_copy;
1278                 break;
1279         case SR_DF_ANALOG:
1280                 analog = packet->payload;
1281                 analog_copy = g_malloc(sizeof(analog));
1282                 analog_copy->channels = g_slist_copy(analog->channels);
1283                 analog_copy->num_samples = analog->num_samples;
1284                 analog_copy->mq = analog->mq;
1285                 analog_copy->unit = analog->unit;
1286                 analog_copy->mqflags = analog->mqflags;
1287                 memcpy(analog_copy->data, analog->data,
1288                                 analog->num_samples * sizeof(float));
1289                 (*copy)->payload = analog_copy;
1290                 break;
1291         default:
1292                 sr_err("Unknown packet type %d", packet->type);
1293                 return SR_ERR;
1294         }
1295
1296         return SR_OK;
1297 }
1298
1299 void sr_packet_free(struct sr_datafeed_packet *packet)
1300 {
1301         const struct sr_datafeed_meta *meta;
1302         const struct sr_datafeed_logic *logic;
1303         const struct sr_datafeed_analog *analog;
1304         struct sr_config *src;
1305         GSList *l;
1306
1307         switch (packet->type) {
1308         case SR_DF_TRIGGER:
1309         case SR_DF_END:
1310                 /* No payload. */
1311                 break;
1312         case SR_DF_HEADER:
1313                 /* Payload is a simple struct. */
1314                 g_free((void *)packet->payload);
1315                 break;
1316         case SR_DF_META:
1317                 meta = packet->payload;
1318                 for (l = meta->config; l; l = l->next) {
1319                         src = l->data;
1320                         g_variant_unref(src->data);
1321                         g_free(src);
1322                 }
1323                 g_slist_free(meta->config);
1324                 g_free((void *)packet->payload);
1325                 break;
1326         case SR_DF_LOGIC:
1327                 logic = packet->payload;
1328                 g_free(logic->data);
1329                 g_free((void *)packet->payload);
1330                 break;
1331         case SR_DF_ANALOG:
1332                 analog = packet->payload;
1333                 g_slist_free(analog->channels);
1334                 g_free(analog->data);
1335                 g_free((void *)packet->payload);
1336                 break;
1337         default:
1338                 sr_err("Unknown packet type %d", packet->type);
1339         }
1340         g_free(packet);
1341
1342 }
1343
1344 /** @} */