26 #include "libsigrok-internal.h"
29 #define LOG_PREFIX "session"
57 struct datafeed_callback {
79 if (!(session = g_try_malloc0(
sizeof(
struct sr_session)))) {
80 sr_err(
"Session malloc failed.");
84 session->source_timeout = -1;
85 session->running = FALSE;
86 session->abort_session = FALSE;
87 g_mutex_init(&session->stop_mutex);
104 sr_err(
"%s: session was NULL", __func__);
112 g_mutex_clear(&session->stop_mutex);
134 sr_err(
"%s: session was NULL", __func__);
138 g_slist_free(session->devs);
139 session->devs = NULL;
162 sr_err(
"%s: sdi was NULL", __func__);
167 sr_err(
"%s: session was NULL", __func__);
173 sr_dbg(
"%s: sdi->driver was NULL, this seems to be "
174 "a virtual device; continuing", __func__);
176 session->devs = g_slist_append(session->devs, (gpointer)sdi);
182 sr_err(
"%s: sdi->driver->dev_open was NULL", __func__);
186 session->devs = g_slist_append(session->devs, (gpointer)sdi);
188 if (session->running) {
192 sr_err(
"Failed to commit device settings before "
193 "starting acquisition in running session (%s)",
197 if ((ret = sdi->driver->dev_acquisition_start(sdi,
198 (
void *)sdi)) !=
SR_OK) {
199 sr_err(
"Failed to start acquisition of device in "
231 *devlist = g_slist_copy(session->devs);
247 sr_err(
"%s: session was NULL", __func__);
251 g_slist_free_full(session->datafeed_callbacks, g_free);
252 session->datafeed_callbacks = NULL;
271 struct datafeed_callback *cb_struct;
274 sr_err(
"%s: session was NULL", __func__);
279 sr_err(
"%s: cb was NULL", __func__);
283 if (!(cb_struct = g_try_malloc0(
sizeof(
struct datafeed_callback))))
287 cb_struct->cb_data = cb_data;
289 session->datafeed_callbacks =
290 g_slist_append(session->datafeed_callbacks, cb_struct);
312 static int sr_session_iteration(gboolean block)
317 ret = g_poll(session->pollfds, session->num_sources,
318 block ? session->source_timeout : 0);
319 for (i = 0; i < session->num_sources; i++) {
320 if (session->pollfds[i].revents > 0 || (ret == 0
321 && session->source_timeout == session->sources[i].timeout)) {
327 if (!session->sources[i].cb(session->pollfds[i].fd,
328 session->pollfds[i].revents,
329 session->sources[i].cb_data))
338 g_mutex_lock(&session->stop_mutex);
339 if (session->abort_session) {
340 sr_session_stop_sync();
342 session->abort_session = FALSE;
344 g_mutex_unlock(&session->stop_mutex);
367 sr_err(
"%s: session was NULL; a session must be "
368 "created before starting it.", __func__);
372 if (!session->devs) {
373 sr_err(
"%s: session->devs was NULL; a session "
374 "cannot be started without devices.", __func__);
378 sr_info(
"Starting.");
381 for (l = session->devs; l; l = l->next) {
384 sr_err(
"Failed to commit device settings before "
389 sr_err(
"%s: could not start an acquisition "
411 sr_err(
"%s: session was NULL; a session must be "
412 "created first, before running it.", __func__);
416 if (!session->devs) {
418 sr_err(
"%s: session->devs was NULL; a session "
419 "cannot be run without devices.", __func__);
422 session->running = TRUE;
427 if (session->num_sources == 1 && session->pollfds[0].fd == -1) {
429 while (session->num_sources)
430 session->sources[0].cb(-1, 0, session->sources[0].cb_data);
433 while (session->num_sources)
434 sr_session_iteration(TRUE);
454 SR_PRIV int sr_session_stop_sync(
void)
460 sr_err(
"%s: session was NULL", __func__);
464 sr_info(
"Stopping.");
466 for (l = session->devs; l; l = l->next) {
473 session->running = FALSE;
497 sr_err(
"%s: session was NULL", __func__);
501 g_mutex_lock(&session->stop_mutex);
502 session->abort_session = TRUE;
503 g_mutex_unlock(&session->stop_mutex);
518 switch (packet->
type) {
520 sr_dbg(
"bus: Received SR_DF_HEADER packet.");
523 sr_dbg(
"bus: Received SR_DF_TRIGGER packet.");
526 sr_dbg(
"bus: Received SR_DF_META packet.");
530 sr_dbg(
"bus: Received SR_DF_LOGIC packet (%" PRIu64
" bytes, "
535 sr_dbg(
"bus: Received SR_DF_ANALOG packet (%d samples).",
539 sr_dbg(
"bus: Received SR_DF_END packet.");
542 sr_dbg(
"bus: Received SR_DF_FRAME_BEGIN packet.");
545 sr_dbg(
"bus: Received SR_DF_FRAME_END packet.");
548 sr_dbg(
"bus: Received unknown packet type: %d.", packet->
type);
570 struct datafeed_callback *cb_struct;
573 sr_err(
"%s: sdi was NULL", __func__);
578 sr_err(
"%s: packet was NULL", __func__);
582 for (l = session->datafeed_callbacks; l; l = l->next) {
584 datafeed_dump(packet);
586 cb_struct->cb(sdi, packet, cb_struct->cb_data);
606 static int _sr_session_source_add(GPollFD *pollfd,
int timeout,
609 struct source *new_sources, *s;
610 GPollFD *new_pollfds;
613 sr_err(
"%s: cb was NULL", __func__);
619 new_pollfds = g_try_realloc(session->pollfds,
620 sizeof(GPollFD) * (session->num_sources + 1));
622 sr_err(
"%s: new_pollfds malloc failed", __func__);
626 new_sources = g_try_realloc(session->sources,
sizeof(
struct source) *
627 (session->num_sources + 1));
629 sr_err(
"%s: new_sources malloc failed", __func__);
633 new_pollfds[session->num_sources] = *pollfd;
634 s = &new_sources[session->num_sources++];
635 s->timeout = timeout;
637 s->cb_data = cb_data;
638 s->poll_object = poll_object;
639 session->pollfds = new_pollfds;
640 session->sources = new_sources;
642 if (timeout != session->source_timeout && timeout > 0
643 && (session->source_timeout == -1 || timeout < session->source_timeout))
644 session->source_timeout = timeout;
672 return _sr_session_source_add(&p, timeout, cb, cb_data, (gintptr)fd);
692 return _sr_session_source_add(pollfd, timeout, cb,
693 cb_data, (gintptr)pollfd);
717 g_io_channel_win32_make_pollfd(channel, events, &p);
719 p.fd = g_io_channel_unix_get_fd(channel);
723 return _sr_session_source_add(&p, timeout, cb, cb_data, (gintptr)channel);
738 static int _sr_session_source_remove(gintptr poll_object)
740 struct source *new_sources;
741 GPollFD *new_pollfds;
744 if (!session->sources || !session->num_sources) {
745 sr_err(
"%s: sources was NULL", __func__);
749 for (old = 0; old < session->num_sources; old++) {
750 if (session->sources[old].poll_object == poll_object)
755 if (old == session->num_sources)
758 session->num_sources -= 1;
760 if (old != session->num_sources) {
761 memmove(&session->pollfds[old], &session->pollfds[old+1],
762 (session->num_sources - old) *
sizeof(GPollFD));
763 memmove(&session->sources[old], &session->sources[old+1],
764 (session->num_sources - old) *
sizeof(
struct source));
767 new_pollfds = g_try_realloc(session->pollfds,
sizeof(GPollFD) * session->num_sources);
768 if (!new_pollfds && session->num_sources > 0) {
769 sr_err(
"%s: new_pollfds malloc failed", __func__);
773 new_sources = g_try_realloc(session->sources,
sizeof(
struct source) * session->num_sources);
774 if (!new_sources && session->num_sources > 0) {
775 sr_err(
"%s: new_sources malloc failed", __func__);
779 session->pollfds = new_pollfds;
780 session->sources = new_sources;
799 return _sr_session_source_remove((gintptr)fd);
815 return _sr_session_source_remove((gintptr)pollfd);
832 return _sr_session_source_remove((gintptr)channel);
Generic/unspecified error.
struct sr_session * session
Packet in a sigrok data feed.
Payload is struct sr_datafeed_meta.
int(* dev_acquisition_stop)(struct sr_dev_inst *sdi, void *cb_data)
End data acquisition on the specified device.
int sr_session_dev_add(const struct sr_dev_inst *sdi)
Add a device instance to the current session.
Payload is struct sr_datafeed_analog.
Payload is struct sr_datafeed_logic.
int sr_session_stop(void)
Stop the current session.
The public libsigrok header file to be used by frontends.
int(* dev_acquisition_start)(const struct sr_dev_inst *sdi, void *cb_data)
Begin data acquisition on the specified device.
int sr_session_start(void)
Start a session.
int sr_session_destroy(void)
Destroy the current session.
void(* sr_datafeed_callback)(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *packet, void *cb_data)
End of stream (no further data).
int(* sr_receive_data_callback)(int fd, int revents, void *cb_data)
Type definition for callback function for data reception.
int sr_session_run(void)
Run the session.
Analog datafeed payload for type SR_DF_ANALOG.
The trigger matched at this point in the data feed.
int num_samples
Number of samples in data.
int sr_config_commit(const struct sr_dev_inst *sdi)
Apply configuration settings to the device hardware.
int sr_session_datafeed_callback_add(sr_datafeed_callback cb, void *cb_data)
Add a datafeed callback to the current session.
int sr_session_source_add_pollfd(GPollFD *pollfd, int timeout, sr_receive_data_callback cb, void *cb_data)
Add an event source for a GPollFD.
int sr_log_loglevel_get(void)
Get the libsigrok loglevel.
Opaque data structure representing a libsigrok session.
int sr_session_source_add_channel(GIOChannel *channel, int events, int timeout, sr_receive_data_callback cb, void *cb_data)
Add an event source for a GIOChannel.
Malloc/calloc/realloc error.
int(* dev_open)(struct sr_dev_inst *sdi)
Open device.
int sr_session_source_remove_pollfd(GPollFD *pollfd)
Remove the source belonging to the specified poll descriptor.
Payload is sr_datafeed_header.
int sr_session_source_remove_channel(GIOChannel *channel)
Remove the source belonging to the specified channel.
Logic datafeed payload for type SR_DF_LOGIC.
int sr_session_source_remove(int fd)
Remove the source belonging to the specified file descriptor.
struct sr_dev_driver * driver
Device driver.
const char * sr_strerror(int error_code)
Return a human-readable error string for the given libsigrok error code.
struct sr_session * sr_session_new(void)
Create a new session.
int sr_session_datafeed_callback_remove_all(void)
Remove all datafeed callbacks in the current session.
int sr_session_dev_list(GSList **devlist)
List all device instances attached to the current session.
Errors hinting at internal bugs.
int sr_session_source_add(int fd, int events, int timeout, sr_receive_data_callback cb, void *cb_data)
Add an event source for a file descriptor.
int sr_session_dev_remove_all(void)
Remove all the devices from the current session.