/** * Start a session. * * When this function returns with a status code indicating success, the * session is running. Use sr_session_stopped_callback_set() to receive * notification upon completion, or call sr_session_run() to block until * the session stops. * * Session events will be processed in the context of the current thread. * If a thread-default GLib main context has been set, and is not owned by * any other thread, it will be used. Otherwise, libsigrok will create its * own main context for the current thread. * * @param session The session to use. Must not be NULL. * * @retval SR_OK Success. * @retval SR_ERR_ARG Invalid session passed. * @retval SR_ERR Other error. * * @since 0.4.0 */ SR_API int sr_session_start(struct sr_session *session) { struct sr_dev_inst *sdi; struct sr_channel *ch; GSList *l, *c, *lend; int ret; if (!session) { sr_err("%s: session was NULL", __func__); return SR_ERR_ARG; } if (!session->devs) { sr_err("%s: session->devs was NULL; a session " "cannot be started without devices.", __func__); return SR_ERR_ARG; } if (session->running) { sr_err("Cannot (re-)start session while it is still running."); return SR_ERR; } if (session->trigger) { ret = verify_trigger(session->trigger); if (ret != SR_OK) return ret; } /* Check enabled channels and commit settings of all devices. */ for (l = session->devs; l; l = l->next) { sdi = l->data; for (c = sdi->channels; c; c = c->next) { ch = c->data; if (ch->enabled) break; } if (!c) { sr_err("%s device %s has no enabled channels.", sdi->driver->name, sdi->connection_id); return SR_ERR; } ret = sr_config_commit(sdi); if (ret != SR_OK) { sr_err("Failed to commit %s device %s settings " "before starting acquisition.", sdi->driver->name, sdi->connection_id); return ret; } } ret = set_main_context(session); if (ret != SR_OK) return ret; sr_info("Starting."); session->running = TRUE; /* Have all devices start acquisition. */ for (l = session->devs; l; l = l->next) { sdi = l->data; ret = sdi->driver->dev_acquisition_start(sdi, sdi); if (ret != SR_OK) { sr_err("Could not start %s device %s acquisition.", sdi->driver->name, sdi->connection_id); break; } } if (ret != SR_OK) { /* If there are multiple devices, some of them may already have * started successfully. Stop them now before returning. */ lend = l->next; for (l = session->devs; l != lend; l = l->next) { sdi = l->data; if (sdi->driver->dev_acquisition_stop) sdi->driver->dev_acquisition_stop(sdi, sdi); } /* TODO: Handle delayed stops. Need to iterate the event * sources... */ session->running = FALSE; unset_main_context(session); return ret; } if (g_hash_table_size(session->event_sources) == 0) stop_check_later(session); return SR_OK; }
/** * Start a session. * * When this function returns with a status code indicating success, the * session is running. Use sr_session_stopped_callback_set() to receive * notification upon completion, or call sr_session_run() to block until * the session stops. * * Session events will be processed in the context of the current thread. * If a thread-default GLib main context has been set, and is not owned by * any other thread, it will be used. Otherwise, libsigrok will create its * own main context for the current thread. * * @param session The session to use. Must not be NULL. * * @retval SR_OK Success. * @retval SR_ERR_ARG Invalid session passed. * @retval SR_ERR Other error. * * @since 0.4.0 */ SR_API int sr_session_start(struct sr_session *session) { struct sr_dev_inst *sdi; struct sr_channel *ch; GSList *l, *c, *lend; int ret; if (!session) { sr_err("%s: session was NULL", __func__); return SR_ERR_ARG; } if (!session->devs) { sr_err("%s: session->devs was NULL; a session " "cannot be started without devices.", __func__); return SR_ERR_ARG; } if (session->running) { sr_err("Cannot (re-)start session while it is still running."); return SR_ERR; } if (session->trigger) { ret = verify_trigger(session->trigger); if (ret != SR_OK) return ret; } /* Check enabled channels and commit settings of all devices. */ for (l = session->devs; l; l = l->next) { sdi = l->data; for (c = sdi->channels; c; c = c->next) { ch = c->data; if (ch->enabled) break; } if (!c) { sr_err("%s device %s has no enabled channels.", sdi->driver->name, sdi->connection_id); return SR_ERR; } ret = sr_config_commit(sdi); if (ret != SR_OK) { sr_err("Failed to commit %s device %s settings " "before starting acquisition.", sdi->driver->name, sdi->connection_id); return ret; } } ret = set_main_context(session); if (ret != SR_OK) return ret; sr_info("Starting."); session->running = TRUE; /* Have all devices start acquisition. */ for (l = session->devs; l; l = l->next) { sdi = l->data; ret = sdi->driver->dev_acquisition_start(sdi, sdi); if (ret != SR_OK) { sr_err("Could not start %s device %s acquisition.", sdi->driver->name, sdi->connection_id); break; } else { sr_info("Device started."); } } /* Have all devices fire. */ for (l = session->devs; l; l = l->next) { sdi = l->data; ret = sdi->driver->dev_acquisition_trigger(sdi); if (ret != SR_OK) { sr_err("Could not fire %s device %s acquisition.", sdi->driver->name, sdi->connection_id); break; } else { sr_info("Device fired."); } } return SR_OK; }
/** * Start a session. * * @param session The session to use. Must not be NULL. * * @retval SR_OK Success. * @retval SR_ERR_ARG Invalid session passed. * * @since 0.4.0 */ SR_API int sr_session_start(struct sr_session *session) { struct sr_dev_inst *sdi; struct sr_channel *ch; GSList *l, *c; int enabled_channels, ret; if (!session) { sr_err("%s: session was NULL", __func__); return SR_ERR_ARG; } if (!session->devs) { sr_err("%s: session->devs was NULL; a session " "cannot be started without devices.", __func__); return SR_ERR_ARG; } if (session->trigger && verify_trigger(session->trigger) != SR_OK) return SR_ERR; ret = set_main_context(session); if (ret != SR_OK) return ret; session->running = TRUE; sr_info("Starting."); for (l = session->devs; l; l = l->next) { sdi = l->data; enabled_channels = 0; for (c = sdi->channels; c; c = c->next) { ch = c->data; if (ch->enabled) { enabled_channels++; break; } } if (enabled_channels == 0) { ret = SR_ERR; sr_err("%s using connection %s has no enabled channels!", sdi->driver->name, sdi->connection_id); break; } if ((ret = sr_config_commit(sdi)) != SR_OK) { sr_err("Failed to commit device settings before " "starting acquisition (%s)", sr_strerror(ret)); break; } if ((ret = sdi->driver->dev_acquisition_start(sdi, sdi)) != SR_OK) { sr_err("%s: could not start an acquisition " "(%s)", __func__, sr_strerror(ret)); break; } } if (ret != SR_OK) { unset_main_context(session); session->running = FALSE; } /* TODO: What if there are multiple devices? Which return code? */ return ret; }