X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=session_driver.c;h=69a53c6867102903fb22bee900b3eec652b348c9;hb=8d9c8554a53d3c22305558e6064a6a4873e83fe1;hp=9df848d4fdfc1a5267db82f3bc5951e04eabda3d;hpb=29a27196a13de2ffd9b671185e4b464b9db9b549;p=libsigrok.git diff --git a/session_driver.c b/session_driver.c index 9df848d4..69a53c68 100644 --- a/session_driver.c +++ b/session_driver.c @@ -26,14 +26,7 @@ #include "libsigrok.h" #include "libsigrok-internal.h" -/* Message logging helpers with subsystem-specific prefix string. */ -#define LOG_PREFIX "virtual-session: " -#define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args) -#define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args) -#define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args) -#define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args) -#define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args) -#define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args) +#define LOG_PREFIX "virtual-session" /* size of payloads sent across the session bus */ /** @cond PRIVATE */ @@ -49,13 +42,15 @@ struct session_vdev { uint64_t samplerate; int unitsize; int num_probes; + 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) @@ -64,30 +59,80 @@ static int receive_data(int fd, int revents, void *cb_data) struct session_vdev *vdev; struct sr_datafeed_packet packet; struct sr_datafeed_logic logic; + struct zip_stat zs; GSList *l; - void *buf; int ret, got_data; + char capturefile[16]; + void *buf; (void)fd; (void)revents; - sr_dbg("Feed chunk."); - got_data = FALSE; for (l = dev_insts; l; l = l->next) { sdi = l->data; vdev = sdi->priv; - if (!vdev) - /* already done with this instance */ + if (vdev->finished) + /* Already done with this instance. */ continue; + if (!vdev->capfile) { + /* No capture file opened yet, or finished with the last + * chunked one. */ + if (vdev->cur_chunk == 0) { + /* capturefile is always the unchunked base name. */ + if (zip_stat(vdev->archive, vdev->capturefile, 0, &zs) != -1) { + /* No chunks, just a single capture file. */ + vdev->cur_chunk = 0; + if (!(vdev->capfile = zip_fopen(vdev->archive, + vdev->capturefile, 0))) + return FALSE; + sr_dbg("Opened %s.", vdev->capturefile); + } else { + /* Try as first chunk filename. */ + snprintf(capturefile, 15, "%s-1", vdev->capturefile); + if (zip_stat(vdev->archive, capturefile, 0, &zs) != -1) { + vdev->cur_chunk = 1; + if (!(vdev->capfile = zip_fopen(vdev->archive, + capturefile, 0))) + return FALSE; + sr_dbg("Opened %s.", capturefile); + } else { + sr_err("No capture file '%s' in " "session file '%s'.", + vdev->capturefile, vdev->sessionfile); + return FALSE; + } + } + } else { + /* Capture data is chunked, advance to the next chunk. */ + vdev->cur_chunk++; + snprintf(capturefile, 15, "%s-%d", vdev->capturefile, + vdev->cur_chunk); + if (zip_stat(vdev->archive, capturefile, 0, &zs) != -1) { + if (!(vdev->capfile = zip_fopen(vdev->archive, + capturefile, 0))) + return FALSE; + sr_dbg("Opened %s.", capturefile); + } else { + /* We got all the chunks, finish up. */ + g_free(vdev->capturefile); + vdev->finished = TRUE; + continue; + } + } + } + if (!(buf = g_try_malloc(CHUNKSIZE))) { sr_err("%s: buf malloc failed", __func__); 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; @@ -99,10 +144,19 @@ static int receive_data(int fd, int revents, void *cb_data) } else { /* done with this capture file */ zip_fclose(vdev->capfile); - g_free(vdev->capturefile); - g_free(vdev); - sdi->priv = NULL; + vdev->capfile = NULL; + if (vdev->cur_chunk == 0) { + /* It was the only file. */ + g_free(vdev->capturefile); + vdev->finished = TRUE; + } else { + /* There might be more chunks, so don't fall through + * to the SR_DF_END here. */ + g_free(buf); + return TRUE; + } } + g_free(buf); } if (!got_data) { @@ -115,16 +169,15 @@ static int receive_data(int fd, int revents, void *cb_data) } /* driver callbacks */ -static int hw_cleanup(void); -static int hw_init(struct sr_context *sr_ctx) +static int init(struct sr_context *sr_ctx) { (void)sr_ctx; return SR_OK; } -static int hw_cleanup(void) +static int dev_clear(void) { GSList *l; @@ -136,22 +189,32 @@ static int hw_cleanup(void) return SR_OK; } -static int hw_dev_open(struct sr_dev_inst *sdi) +static int dev_open(struct sr_dev_inst *sdi) { - if (!(sdi->priv = g_try_malloc0(sizeof(struct session_vdev)))) { - sr_err("%s: sdi->priv malloc failed", __func__); - return SR_ERR_MALLOC; - } + struct session_vdev *vdev; + vdev = g_try_malloc0(sizeof(struct session_vdev)); + sdi->priv = vdev; dev_insts = g_slist_append(dev_insts, sdi); return SR_OK; } -static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) +static int dev_close(struct sr_dev_inst *sdi) +{ + 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) { struct session_vdev *vdev; + (void)probe_group; + switch (id) { case SR_CONF_SAMPLERATE: if (sdi) { @@ -161,16 +224,19 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) return SR_ERR; break; default: - return SR_ERR_ARG; + return SR_ERR_NA; } return SR_OK; } -static int config_set(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) { struct session_vdev *vdev; + (void)probe_group; + vdev = sdi->priv; switch (id) { @@ -189,21 +255,21 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) case SR_CONF_CAPTURE_UNITSIZE: vdev->unitsize = g_variant_get_uint64(data); break; - case SR_CONF_CAPTURE_NUM_PROBES: + case SR_CONF_NUM_LOGIC_PROBES: vdev->num_probes = g_variant_get_uint64(data); break; default: - sr_err("Unknown capability: %d.", id); - return SR_ERR; + return SR_ERR_NA; } return SR_OK; } -static int config_list(int key, 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) { - (void)sdi; + (void)probe_group; switch (key) { case SR_CONF_DEVICE_OPTIONS: @@ -211,16 +277,14 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi) hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t)); break; default: - return SR_ERR_ARG; + return SR_ERR_NA; } return SR_OK; } -static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, - void *cb_data) +static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) { - struct zip_stat zs; struct session_vdev *vdev; int ret; @@ -231,19 +295,7 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, if (!(vdev->archive = zip_open(vdev->sessionfile, 0, &ret))) { sr_err("Failed to open session file '%s': " - "zip error %d\n", vdev->sessionfile, ret); - return SR_ERR; - } - - if (zip_stat(vdev->archive, vdev->capturefile, 0, &zs) == -1) { - sr_err("Failed to check capture file '%s' in " - "session file '%s'.", vdev->capturefile, vdev->sessionfile); - return SR_ERR; - } - - if (!(vdev->capfile = zip_fopen(vdev->archive, vdev->capturefile, 0))) { - sr_err("Failed to open capture file '%s' in " - "session file '%s'.", vdev->capturefile, vdev->sessionfile); + "zip error %d.", vdev->sessionfile, ret); return SR_ERR; } @@ -261,13 +313,17 @@ SR_PRIV struct sr_dev_driver session_driver = { .name = "virtual-session", .longname = "Session-emulating driver", .api_version = 1, - .init = hw_init, - .cleanup = hw_cleanup, + .init = init, + .cleanup = dev_clear, + .scan = NULL, + .dev_list = NULL, + .dev_clear = dev_clear, .config_get = config_get, .config_set = config_set, .config_list = config_list, - .dev_open = hw_dev_open, - .dev_close = NULL, - .dev_acquisition_start = hw_dev_acquisition_start, + .dev_open = dev_open, + .dev_close = dev_close, + .dev_acquisition_start = dev_acquisition_start, .dev_acquisition_stop = NULL, + .priv = NULL, };