X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=session_driver.c;h=9120ea14575b4f2e71fbfa3d0fcdfc28100b8467;hb=3337e9a1c9e853a57beed80084d1f5ca93e0a3db;hp=b023cbc0fc8401449cca2024249ee00d8200c01f;hpb=3544f848e0d7f67af8e11ce7ec344b34cd797df3;p=libsigrok.git diff --git a/session_driver.c b/session_driver.c index b023cbc0..9120ea14 100644 --- a/session_driver.c +++ b/session_driver.c @@ -33,6 +33,9 @@ #define CHUNKSIZE (512 * 1024) /** @endcond */ +SR_PRIV struct sr_dev_driver session_driver_info; +static struct sr_dev_driver *di = &session_driver_info; + struct session_vdev { char *sessionfile; char *capturefile; @@ -41,15 +44,15 @@ struct session_vdev { int bytes_read; uint64_t samplerate; int unitsize; - int num_probes; + int num_channels; int cur_chunk; + gboolean finished; }; -static GSList *dev_insts = NULL; static const int hwcaps[] = { SR_CONF_CAPTUREFILE, SR_CONF_CAPTURE_UNITSIZE, - 0, + SR_CONF_SAMPLERATE, }; static int receive_data(int fd, int revents, void *cb_data) @@ -59,7 +62,6 @@ static int receive_data(int fd, int revents, void *cb_data) struct sr_datafeed_packet packet; struct sr_datafeed_logic logic; struct zip_stat zs; - GSList *l; int ret, got_data; char capturefile[16]; void *buf; @@ -67,13 +69,10 @@ static int receive_data(int fd, int revents, void *cb_data) (void)fd; (void)revents; + sdi = cb_data; got_data = FALSE; - for (l = dev_insts; l; l = l->next) { - sdi = l->data; - if (!(vdev = sdi->priv)) - /* Already done with this instance. */ - continue; - + vdev = sdi->priv; + if (!vdev->finished) { if (!vdev->capfile) { /* No capture file opened yet, or finished with the last * chunked one. */ @@ -113,10 +112,8 @@ static int receive_data(int fd, int revents, void *cb_data) sr_dbg("Opened %s.", capturefile); } else { /* We got all the chunks, finish up. */ - g_free(vdev->capturefile); - g_free(vdev); - sdi->priv = NULL; - continue; + vdev->finished = TRUE; + return TRUE; } } } @@ -126,8 +123,12 @@ static int receive_data(int fd, int revents, void *cb_data) return FALSE; } - ret = zip_fread(vdev->capfile, buf, CHUNKSIZE); + ret = zip_fread(vdev->capfile, buf, + CHUNKSIZE / vdev->unitsize * vdev->unitsize); if (ret > 0) { + if (ret % vdev->unitsize != 0) + sr_warn("Read size %d not a multiple of the" + " unit size %d.", ret, vdev->unitsize); got_data = TRUE; packet.type = SR_DF_LOGIC; packet.payload = &logic; @@ -135,16 +136,14 @@ static int receive_data(int fd, int revents, void *cb_data) logic.unitsize = vdev->unitsize; logic.data = buf; vdev->bytes_read += ret; - sr_session_send(cb_data, &packet); + sr_session_send(sdi, &packet); } else { /* done with this capture file */ zip_fclose(vdev->capfile); vdev->capfile = NULL; if (vdev->cur_chunk == 0) { /* It was the only file. */ - g_free(vdev->capturefile); - g_free(vdev); - sdi->priv = NULL; + vdev->finished = TRUE; } else { /* There might be more chunks, so don't fall through * to the SR_DF_END here. */ @@ -157,8 +156,8 @@ static int receive_data(int fd, int revents, void *cb_data) if (!got_data) { packet.type = SR_DF_END; - sr_session_send(cb_data, &packet); - sr_session_source_remove(-1); + sr_session_send(sdi, &packet); + sr_session_source_remove(sdi->session, -1); } return TRUE; @@ -168,41 +167,54 @@ static int receive_data(int fd, int revents, void *cb_data) static int init(struct sr_context *sr_ctx) { - (void)sr_ctx; - - return SR_OK; + return std_init(sr_ctx, di, LOG_PREFIX); } -static int cleanup(void) +static int dev_clear(void) { + struct drv_context *drvc; GSList *l; - for (l = dev_insts; l; l = l->next) + drvc = di->priv; + for (l = drvc->instances; l; l = l->next) sr_dev_inst_free(l->data); - g_slist_free(dev_insts); - dev_insts = NULL; + g_slist_free(drvc->instances); + drvc->instances = NULL; return SR_OK; } static int dev_open(struct sr_dev_inst *sdi) { - if (!(sdi->priv = g_try_malloc0(sizeof(struct session_vdev)))) { - sr_err("Device context malloc failed."); - return SR_ERR_MALLOC; - } + struct drv_context *drvc; + struct session_vdev *vdev; - dev_insts = g_slist_append(dev_insts, sdi); + drvc = di->priv; + vdev = g_malloc0(sizeof(struct session_vdev)); + sdi->priv = vdev; + drvc->instances = g_slist_append(drvc->instances, sdi); + + return SR_OK; +} + +static int dev_close(struct sr_dev_inst *sdi) +{ + const struct session_vdev *const vdev = sdi->priv; + g_free(vdev->sessionfile); + g_free(vdev->capturefile); + + g_free(sdi->priv); + sdi->priv = NULL; return SR_OK; } static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, - const struct sr_probe_group *probe_group) + const struct sr_channel_group *cg) { struct session_vdev *vdev; - (void)probe_group; + (void)cg; switch (id) { case SR_CONF_SAMPLERATE: @@ -220,11 +232,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, } static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi, - const struct sr_probe_group *probe_group) + const struct sr_channel_group *cg) { struct session_vdev *vdev; - (void)probe_group; + (void)cg; vdev = sdi->priv; @@ -234,18 +246,20 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi, sr_info("Setting samplerate to %" PRIu64 ".", vdev->samplerate); break; case SR_CONF_SESSIONFILE: + g_free(vdev->sessionfile); vdev->sessionfile = g_strdup(g_variant_get_string(data, NULL)); sr_info("Setting sessionfile to '%s'.", vdev->sessionfile); break; case SR_CONF_CAPTUREFILE: + g_free(vdev->capturefile); vdev->capturefile = g_strdup(g_variant_get_string(data, NULL)); sr_info("Setting capturefile to '%s'.", vdev->capturefile); break; case SR_CONF_CAPTURE_UNITSIZE: vdev->unitsize = g_variant_get_uint64(data); break; - case SR_CONF_CAPTURE_NUM_PROBES: - vdev->num_probes = g_variant_get_uint64(data); + case SR_CONF_NUM_LOGIC_CHANNELS: + vdev->num_channels = g_variant_get_uint64(data); break; default: return SR_ERR_NA; @@ -255,10 +269,10 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi, } static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, - const struct sr_probe_group *probe_group) + const struct sr_channel_group *cg) { (void)sdi; - (void)probe_group; + (void)cg; switch (key) { case SR_CONF_DEVICE_OPTIONS: @@ -277,7 +291,12 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) struct session_vdev *vdev; int ret; + (void)cb_data; + vdev = sdi->priv; + vdev->bytes_read = 0; + vdev->cur_chunk = 0; + vdev->finished = FALSE; sr_info("Opening archive %s file %s", vdev->sessionfile, vdev->capturefile); @@ -289,10 +308,10 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) } /* Send header packet to the session bus. */ - std_session_send_df_header(cb_data, LOG_PREFIX); + std_session_send_df_header(sdi, LOG_PREFIX); /* freewheeling source */ - sr_session_source_add(-1, 0, 0, receive_data, cb_data); + sr_session_source_add(sdi->session, -1, 0, 0, receive_data, (void *)sdi); return SR_OK; } @@ -303,15 +322,15 @@ SR_PRIV struct sr_dev_driver session_driver = { .longname = "Session-emulating driver", .api_version = 1, .init = init, - .cleanup = cleanup, + .cleanup = dev_clear, .scan = NULL, .dev_list = NULL, - .dev_clear = NULL, + .dev_clear = dev_clear, .config_get = config_get, .config_set = config_set, .config_list = config_list, .dev_open = dev_open, - .dev_close = NULL, + .dev_close = dev_close, .dev_acquisition_start = dev_acquisition_start, .dev_acquisition_stop = NULL, .priv = NULL,