static GString *gen_header(const struct sr_dev_inst *sdi, struct context *ctx) { struct sr_probe *probe; GSList *l; GString *s; GVariant *gvar; int num_enabled_probes; if (!ctx->samplerate && sr_config_get(sdi->driver, sdi, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { ctx->samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); } num_enabled_probes = 0; for (l = sdi->probes; l; l = l->next) { probe = l->data; if (probe->enabled) num_enabled_probes++; } s = g_string_sized_new(512); g_string_append_printf(s, ";Rate: %"PRIu64"\n", ctx->samplerate); g_string_append_printf(s, ";Channels: %d\n", num_enabled_probes); g_string_append_printf(s, ";EnabledChannels: -1\n"); g_string_append_printf(s, ";Compressed: true\n"); g_string_append_printf(s, ";CursorEnabled: false\n"); return s; }
static GString *gen_header(const struct sr_output *o) { struct context *ctx; GVariant *gvar; GString *header; int num_channels; char *samplerate_s; ctx = o->priv; if (ctx->samplerate == 0) { if (sr_config_get(o->sdi->driver, o->sdi, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { ctx->samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); } } header = g_string_sized_new(512); g_string_printf(header, "%s %s\n", PACKAGE_NAME, SR_PACKAGE_VERSION_STRING); num_channels = g_slist_length(o->sdi->channels); g_string_append_printf(header, "Acquisition with %d/%d channels", ctx->num_enabled_channels, num_channels); if (ctx->samplerate != 0) { samplerate_s = sr_samplerate_string(ctx->samplerate); g_string_append_printf(header, " at %s", samplerate_s); g_free(samplerate_s); } g_string_append_printf(header, "\n"); return header; }
int maybe_config_get(struct sr_dev_driver *driver, const struct sr_dev_inst *sdi, struct sr_channel_group *cg, uint32_t key, GVariant **gvar) { if (config_key_has_cap(driver, sdi, cg, key, SR_CONF_GET)) return sr_config_get(driver, sdi, cg, key, gvar); return SR_ERR_NA; }
GVariant* DevInst::get_config(const sr_probe_group *group, int key) { GVariant *data = NULL; assert(_owner); sr_dev_inst *const sdi = dev_inst(); assert(sdi); if (sr_config_get(sdi->driver, sdi, group, key, &data) != SR_OK) return NULL; return data; }
GVariant* DeviceOptions::config_getter( const struct sr_dev_inst *sdi, int key) { GVariant *data = NULL; if (sr_config_get(sdi->driver, key, &data, sdi) != SR_OK) { qDebug() << "WARNING: Failed to get value of config id" << key; return NULL; } return data; }
/** * Save a session to the specified file. * * @param session The session to save to the specified file. Must not be NULL. * @param filename The name of the filename to save the session as. * Must not be NULL. * @param sdi The device instance from which the data was captured. * @param buf The data to be saved. * @param unitsize The number of bytes per sample. * @param units The number of samples. * * @retval SR_OK Success * @retval SR_ERR_ARG Invalid arguments * @retval SR_ERR Other errors * * @since 0.2.0 */ SR_API int sr_session_save(struct sr_session *session, const char *filename, const struct sr_dev_inst *sdi, unsigned char *buf, int unitsize, int units) { struct sr_channel *ch; GSList *l; GVariant *gvar; uint64_t samplerate; int cnt, ret; char **channel_names; samplerate = 0; if (sr_dev_has_option(sdi, SR_CONF_SAMPLERATE)) { if (sr_config_get(sdi->driver, sdi, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); } } channel_names = g_malloc0(sizeof(char *) * (g_slist_length(sdi->channels) + 1)); cnt = 0; for (l = sdi->channels; l; l = l->next) { ch = l->data; if (ch->type != SR_CHANNEL_LOGIC) continue; if (ch->enabled != TRUE) continue; if (!ch->name) continue; /* Just borrowing the ptr. */ channel_names[cnt++] = ch->name; } if ((ret = sr_session_save_init(session, filename, samplerate, channel_names)) != SR_OK) return ret; ret = sr_session_append(session, filename, buf, unitsize, units); return ret; }
static void print_dev_line(const struct sr_dev_inst *sdi) { struct sr_channel *ch; GSList *sl, *l; GString *s; GVariant *gvar; s = g_string_sized_new(128); g_string_assign(s, sdi->driver->name); if (sr_config_get(sdi->driver, sdi, NULL, SR_CONF_CONN, &gvar) == SR_OK) { g_string_append(s, ":conn="); g_string_append(s, g_variant_get_string(gvar, NULL)); g_variant_unref(gvar); } g_string_append(s, " - "); if (sdi->vendor && sdi->vendor[0]) g_string_append_printf(s, "%s ", sdi->vendor); if (sdi->model && sdi->model[0]) g_string_append_printf(s, "%s ", sdi->model); if (sdi->version && sdi->version[0]) g_string_append_printf(s, "%s ", sdi->version); if (sdi->channels) { if (g_slist_length(sdi->channels) == 1) { ch = sdi->channels->data; g_string_append_printf(s, "with 1 channel: %s", ch->name); } else { sl = g_slist_sort(g_slist_copy(sdi->channels), sort_channels); g_string_append_printf(s, "with %d channels:", g_slist_length(sl)); for (l = sl; l; l = l->next) { ch = l->data; g_string_append_printf(s, " %s", ch->name); } g_slist_free(sl); } } g_string_append_printf(s, "\n"); printf("%s", s->str); g_string_free(s, TRUE); }
static int set_limit_time(const struct sr_dev_inst *sdi) { GVariant *gvar; uint64_t time_msec; uint64_t samplerate; if (!(time_msec = sr_parse_timestring(opt_time))) { g_critical("Invalid time '%s'", opt_time); return SR_ERR; } if (sr_dev_has_option(sdi, SR_CONF_LIMIT_MSEC)) { gvar = g_variant_new_uint64(time_msec); if (sr_config_set(sdi, NULL, SR_CONF_LIMIT_MSEC, gvar) != SR_OK) { g_critical("Failed to configure time limit."); return SR_ERR; } } else if (sr_dev_has_option(sdi, SR_CONF_SAMPLERATE)) { /* Convert to samples based on the samplerate. */ sr_config_get(sdi->driver, sdi, NULL, SR_CONF_SAMPLERATE, &gvar); samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); limit_samples = (samplerate) * time_msec / (uint64_t)1000; if (limit_samples == 0) { g_critical("Not enough time at this samplerate."); return SR_ERR; } gvar = g_variant_new_uint64(limit_samples); if (sr_config_set(sdi, NULL, SR_CONF_LIMIT_SAMPLES, gvar) != SR_OK) { g_critical("Failed to configure time-based sample limit."); return SR_ERR; } } else { g_critical("This device does not support time limits."); return SR_ERR; } return SR_OK; }
static int zip_create(const struct sr_output *o) { struct out_context *outc; struct sr_channel *ch; FILE *meta; struct zip *zipfile; struct zip_source *versrc, *metasrc; GVariant *gvar; GSList *l; int tmpfile, ret; char version[1], metafile[32], *s; outc = o->priv; if (outc->samplerate == 0) { if (sr_config_get(o->sdi->driver, o->sdi, NULL, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { outc->samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); } } /* Quietly delete it first, libzip wants replace ops otherwise. */ unlink(outc->filename); if (!(zipfile = zip_open(outc->filename, ZIP_CREATE, &ret))) return SR_ERR; /* "version" */ version[0] = '2'; if (!(versrc = zip_source_buffer(zipfile, version, 1, 0))) return SR_ERR; if (zip_add(zipfile, "version", versrc) == -1) { sr_info("Error saving version into zipfile: %s.", zip_strerror(zipfile)); return SR_ERR; } /* init "metadata" */ strcpy(metafile, "sigrok-meta-XXXXXX"); if ((tmpfile = g_mkstemp(metafile)) == -1) return SR_ERR; close(tmpfile); meta = g_fopen(metafile, "wb"); fprintf(meta, "[global]\n"); fprintf(meta, "sigrok version = %s\n", PACKAGE_VERSION); fprintf(meta, "[device 1]\ncapturefile = logic-1\n"); fprintf(meta, "total probes = %d\n", g_slist_length(o->sdi->channels)); s = sr_samplerate_string(outc->samplerate); fprintf(meta, "samplerate = %s\n", s); g_free(s); for (l = o->sdi->channels; l; l = l->next) { ch = l->data; if (ch->type != SR_CHANNEL_LOGIC) continue; if (!ch->enabled) continue; fprintf(meta, "probe%d = %s\n", ch->index + 1, ch->name); } fclose(meta); if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1))) { unlink(metafile); return SR_ERR; } if (zip_add(zipfile, "metadata", metasrc) == -1) { unlink(metafile); return SR_ERR; } if ((ret = zip_close(zipfile)) == -1) { sr_info("Error saving zipfile: %s.", zip_strerror(zipfile)); unlink(metafile); return SR_ERR; } unlink(metafile); return SR_OK; }
void datafeed_in(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *packet, void *cb_data) { const struct sr_datafeed_meta *meta; const struct sr_datafeed_logic *logic; const struct sr_datafeed_analog *analog; struct sr_config *src; struct sr_channel *ch; static struct sr_output *o = NULL; static uint64_t rcvd_samples_logic = 0; static uint64_t rcvd_samples_analog = 0; static uint64_t samplerate = 0; static int triggered = 0; static FILE *outfile = NULL; GSList *l; GString *out; GVariant *gvar; uint64_t end_sample; uint64_t input_len; int i; char **channels; (void) cb_data; /* If the first packet to come in isn't a header, don't even try. */ if (packet->type != SR_DF_HEADER && o == NULL) return; switch (packet->type) { case SR_DF_HEADER: g_debug("cli: Received SR_DF_HEADER."); o = setup_output_format(sdi); /* Prepare non-stdout output. */ outfile = stdout; if (opt_output_file) { if (default_output_format) { outfile = NULL; } else { /* saving to a file in whatever format was set * with --format, so all we need is a filehandle */ outfile = g_fopen(opt_output_file, "wb"); } } rcvd_samples_logic = rcvd_samples_analog = 0; if (sr_config_get(sdi->driver, sdi, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); } #ifdef HAVE_SRD if (opt_pds) { if (samplerate) { if (srd_session_metadata_set(srd_sess, SRD_CONF_SAMPLERATE, g_variant_new_uint64(samplerate)) != SRD_OK) { g_critical("Failed to configure decode session."); break; } } if (srd_session_start(srd_sess) != SRD_OK) { g_critical("Failed to start decode session."); break; } } #endif break; case SR_DF_META: g_debug("cli: Received SR_DF_META."); meta = packet->payload; for (l = meta->config; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_SAMPLERATE: samplerate = g_variant_get_uint64(src->data); g_debug("cli: Got samplerate %"PRIu64" Hz.", samplerate); #ifdef HAVE_SRD if (opt_pds) { if (srd_session_metadata_set(srd_sess, SRD_CONF_SAMPLERATE, g_variant_new_uint64(samplerate)) != SRD_OK) { g_critical("Failed to pass samplerate to decoder."); } } #endif break; case SR_CONF_SAMPLE_INTERVAL: samplerate = g_variant_get_uint64(src->data); g_debug("cli: Got sample interval %"PRIu64" ms.", samplerate); break; default: /* Unknown metadata is not an error. */ break; } } break; case SR_DF_TRIGGER: g_debug("cli: Received SR_DF_TRIGGER."); triggered = 1; break; case SR_DF_LOGIC: logic = packet->payload; g_message("cli: Received SR_DF_LOGIC (%"PRIu64" bytes, unitsize = %d).", logic->length, logic->unitsize); if (logic->length == 0) break; /* Don't store any samples until triggered. */ if (opt_wait_trigger && !triggered) break; if (limit_samples && rcvd_samples_logic >= limit_samples) break; end_sample = rcvd_samples_logic + logic->length / logic->unitsize; /* Cut off last packet according to the sample limit. */ if (limit_samples && end_sample > limit_samples) end_sample = limit_samples; input_len = (end_sample - rcvd_samples_logic) * logic->unitsize; if (opt_output_file && default_output_format) { /* Saving to a session file. */ if (rcvd_samples_logic == 0) { /* First packet with logic data, init session file. */ channels = g_malloc(sizeof(char *) * g_slist_length(sdi->channels)); for (i = 0, l = sdi->channels; l; l = l->next) { ch = l->data; if (ch->enabled && ch->type == SR_CHANNEL_LOGIC) channels[i++] = ch->name; } channels[i] = NULL; sr_session_save_init(opt_output_file, samplerate, channels); g_free(channels); } save_chunk_logic(logic->data, input_len, logic->unitsize); } else { if (opt_pds) { #ifdef HAVE_SRD if (srd_session_send(srd_sess, rcvd_samples_logic, end_sample, logic->data, input_len) != SRD_OK) sr_session_stop(); #endif } } rcvd_samples_logic = end_sample; break; case SR_DF_ANALOG: analog = packet->payload; g_message("cli: Received SR_DF_ANALOG (%d samples).", analog->num_samples); if (analog->num_samples == 0) break; if (limit_samples && rcvd_samples_analog >= limit_samples) break; rcvd_samples_analog += analog->num_samples; break; case SR_DF_FRAME_BEGIN: g_debug("cli: Received SR_DF_FRAME_BEGIN."); break; case SR_DF_FRAME_END: g_debug("cli: Received SR_DF_FRAME_END."); break; default: break; } if (o && outfile && !opt_pds) { if (sr_output_send(o, packet, &out) == SR_OK && out) { fwrite(out->str, 1, out->len, outfile); fflush(outfile); g_string_free(out, TRUE); } } /* SR_DF_END needs to be handled after the output module's receive() * is called, so it can properly clean up that module. */ if (packet->type == SR_DF_END) { g_debug("cli: Received SR_DF_END."); if (o) sr_output_free(o); o = NULL; if (outfile && outfile != stdout) fclose(outfile); if (opt_output_file && default_output_format) /* Flush whatever is left out to the session file. */ save_chunk_logic(NULL, 0, 0); if (limit_samples) { if (rcvd_samples_logic > 0 && rcvd_samples_logic < limit_samples) g_warning("Device only sent %" PRIu64 " samples.", rcvd_samples_logic); else if (rcvd_samples_analog > 0 && rcvd_samples_analog < limit_samples) g_warning("Device only sent %" PRIu64 " samples.", rcvd_samples_analog); } } }
/** * Save the current session to the specified file. * * @param filename The name of the filename to save the current session as. * Must not be NULL. * @param sdi The device instance from which the data was captured. * @param buf The data to be saved. * @param unitsize The number of bytes per sample. * @param units The number of samples. * * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or SR_ERR * upon other errors. */ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, unsigned char *buf, int unitsize, int units) { GSList *l; GVariant *gvar; FILE *meta; struct sr_channel *probe; struct zip *zipfile; struct zip_source *versrc, *metasrc, *logicsrc; int tmpfile, ret, probecnt; uint64_t samplerate, timeBase, tmp_u64; char rawname[16], metafile[32], *s; struct sr_status status; if (!filename) { sr_err("%s: filename was NULL", __func__); return SR_ERR_ARG; } /* Quietly delete it first, libzip wants replace ops otherwise. */ unlink(filename); if (!(zipfile = zip_open(filename, ZIP_CREATE, &ret))) return SR_ERR; /* init "metadata" */ strcpy(metafile, "DSView-meta-XXXXXX"); if ((tmpfile = g_mkstemp(metafile)) == -1) return SR_ERR; close(tmpfile); meta = g_fopen(metafile, "wb"); fprintf(meta, "[version]\n"); fprintf(meta, "DSView version = %s\n", PACKAGE_VERSION); /* metadata */ fprintf(meta, "[header]\n"); if (sdi->driver) { fprintf(meta, "driver = %s\n", sdi->driver->name); fprintf(meta, "device mode = %d\n", sdi->mode); } /* metadata */ fprintf(meta, "capturefile = data\n"); fprintf(meta, "unitsize = %d\n", unitsize); fprintf(meta, "total samples = %d\n", units); fprintf(meta, "total probes = %d\n", g_slist_length(sdi->channels)); if (sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { samplerate = g_variant_get_uint64(gvar); s = sr_samplerate_string(samplerate); fprintf(meta, "samplerate = %s\n", s); g_free(s); g_variant_unref(gvar); } if (sdi->mode == DSO && sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_TIMEBASE, &gvar) == SR_OK) { timeBase = g_variant_get_uint64(gvar); fprintf(meta, "hDiv = %d\n", timeBase); g_variant_unref(gvar); } probecnt = 1; for (l = sdi->channels; l; l = l->next) { probe = l->data; if (probe->enabled || sdi->mode == DSO) { if (probe->name) fprintf(meta, "probe%d = %s\n", probe->index, probe->name); if (probe->trigger) fprintf(meta, " trigger%d = %s\n", probe->index, probe->trigger); if (sdi->mode == DSO) { fprintf(meta, " enable%d = %d\n", probe->index, probe->enabled); fprintf(meta, " coupling%d = %d\n", probe->index, probe->coupling); fprintf(meta, " vDiv%d = %d\n", probe->index, probe->vdiv); fprintf(meta, " vFactor%d = %d\n", probe->index, probe->vfactor); fprintf(meta, " vPos%d = %lf\n", probe->index, probe->vpos); if (sr_status_get(sdi, &status, 0, 0) == SR_OK) { if (probe->index == 0) { fprintf(meta, " period%d = %d\n", probe->index, status.ch0_period); fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch0_pcnt); fprintf(meta, " max%d = %d\n", probe->index, status.ch0_max); fprintf(meta, " min%d = %d\n", probe->index, status.ch0_min); } else { fprintf(meta, " period%d = %d\n", probe->index, status.ch1_period); fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch1_pcnt); fprintf(meta, " max%d = %d\n", probe->index, status.ch1_max); fprintf(meta, " min%d = %d\n", probe->index, status.ch1_min); } } } probecnt++; } } if (!(logicsrc = zip_source_buffer(zipfile, buf, units * unitsize, FALSE))) return SR_ERR; snprintf(rawname, 15, "data"); if (zip_add(zipfile, rawname, logicsrc) == -1) return SR_ERR; fclose(meta); if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1))) return SR_ERR; if (zip_add(zipfile, "header", metasrc) == -1) return SR_ERR; if ((ret = zip_close(zipfile)) == -1) { sr_info("error saving zipfile: %s", zip_strerror(zipfile)); return SR_ERR; } unlink(metafile); return SR_OK; }
SR_PRIV int init(struct sr_output *o, int default_spl, enum outputmode mode) { struct context *ctx; struct sr_probe *probe; GSList *l; GVariant *gvar; uint64_t samplerate; int num_probes, ret; char *samplerate_s; if (!(ctx = g_try_malloc0(sizeof(struct context)))) { sr_err("%s: ctx malloc failed", __func__); return SR_ERR_MALLOC; } o->internal = ctx; ctx->num_enabled_probes = 0; ctx->probenames = NULL; for (l = o->sdi->probes; l; l = l->next) { probe = l->data; if (!probe->enabled) continue; ctx->probenames = g_slist_append(ctx->probenames, probe->name); ctx->num_enabled_probes++; } ctx->unitsize = (ctx->num_enabled_probes + 7) / 8; ctx->line_offset = 0; ctx->spl_cnt = 0; ctx->mark_trigger = -1; ctx->mode = mode; ret = SR_OK; if (o->param && o->param[0]) { ctx->samples_per_line = strtoul(o->param, NULL, 10); if (ctx->samples_per_line < 1) { ret = SR_ERR; goto err; } } else ctx->samples_per_line = default_spl; if (!(ctx->header = g_try_malloc0(512))) { sr_err("%s: ctx->header malloc failed", __func__); ret = SR_ERR_MALLOC; goto err; } snprintf(ctx->header, 511, "%s\n", PACKAGE_STRING); num_probes = g_slist_length(o->sdi->probes); if (sr_config_get(o->sdi->driver, o->sdi, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); if (!(samplerate_s = sr_samplerate_string(samplerate))) { ret = SR_ERR; goto err; } snprintf(ctx->header + strlen(ctx->header), 511 - strlen(ctx->header), "Acquisition with %d/%d probes at %s\n", ctx->num_enabled_probes, num_probes, samplerate_s); g_free(samplerate_s); } ctx->linebuf_len = ctx->samples_per_line * 2 + 4; if (!(ctx->linebuf = g_try_malloc0(num_probes * ctx->linebuf_len))) { sr_err("%s: ctx->linebuf malloc failed", __func__); ret = SR_ERR_MALLOC; goto err; } if (!(ctx->linevalues = g_try_malloc0(num_probes))) { sr_err("%s: ctx->linevalues malloc failed", __func__); ret = SR_ERR_MALLOC; } if (mode == MODE_ASCII && !(ctx->prevsample = g_try_malloc0(num_probes / 8))) { sr_err("%s: ctx->prevsample malloc failed", __func__); ret = SR_ERR_MALLOC; } err: if (ret != SR_OK) { g_free(ctx->header); g_free(ctx); } return ret; }
static int init(struct sr_output *o) { struct context *ctx; struct sr_probe *probe; GSList *l; GVariant *gvar; int num_probes; time_t t; if (!o) return SR_ERR_ARG; if (!o->sdi) return SR_ERR_ARG; ctx = g_try_malloc0(sizeof(struct context)); o->internal = ctx; /* Get the number of probes, and the unitsize. */ for (l = o->sdi->probes; l; l = l->next) { probe = l->data; if (probe->type != SR_PROBE_LOGIC) continue; if (!probe->enabled) continue; ctx->num_enabled_probes++; } ctx->unitsize = (ctx->num_enabled_probes + 7) / 8; num_probes = g_slist_length(o->sdi->probes); if (sr_config_get(o->sdi->driver, o->sdi, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { ctx->samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); } else ctx->samplerate = 0; ctx->separator = ','; ctx->header = g_string_sized_new(512); t = time(NULL); /* Some metadata */ g_string_append_printf(ctx->header, "; CSV, generated by %s on %s", PACKAGE_STRING, ctime(&t)); g_string_append_printf(ctx->header, "; Samplerate: %"PRIu64"\n", ctx->samplerate); /* Columns / channels */ g_string_append_printf(ctx->header, "; Channels (%d/%d):", ctx->num_enabled_probes, num_probes); for (l = o->sdi->probes; l; l = l->next) { probe = l->data; if (probe->type != SR_PROBE_LOGIC) continue; if (!probe->enabled) continue; g_string_append_printf(ctx->header, " %s,", probe->name); } if (o->sdi->probes) /* Drop last separator. */ g_string_truncate(ctx->header, ctx->header->len - 1); g_string_append_printf(ctx->header, "\n"); return SR_OK; }
void show_dev_detail(void) { struct sr_dev_inst *sdi; const struct sr_config_info *srci; struct sr_channel *ch; struct sr_channel_group *channel_group, *cg; GSList *devices, *cgl, *chl; GVariant *gvar_opts, *gvar_dict, *gvar_list, *gvar; gsize num_opts, num_elements; double dlow, dhigh, dcur_low, dcur_high; const uint64_t *uint64, p, q, low, high; uint64_t cur_low, cur_high; const int32_t *int32, *opts; unsigned int num_devices, o, i; char *tmp_str; char *s, c; const char **stropts; if (!(devices = device_scan())) { g_critical("No devices found."); return; } num_devices = g_slist_length(devices); if (num_devices > 1) { g_critical("%d devices found. Use --scan to show them, " "and select one to show.", num_devices); return; } sdi = devices->data; print_dev_line(sdi); if (sr_dev_open(sdi) != SR_OK) { g_critical("Failed to open device."); return; } if ((sr_config_list(sdi->driver, NULL, NULL, SR_CONF_SCAN_OPTIONS, &gvar_opts) == SR_OK)) { opts = g_variant_get_fixed_array(gvar_opts, &num_elements, sizeof(int32_t)); printf("Supported driver options:\n"); for (i = 0; i < num_elements; i++) { if (!(srci = sr_config_info_get(opts[i]))) continue; printf(" %s\n", srci->id); } g_variant_unref(gvar_opts); } /* Selected channels and channel group may affect which options are * returned, or which values for them. */ select_channels(sdi); channel_group = select_channel_group(sdi); if ((sr_config_list(sdi->driver, sdi, channel_group, SR_CONF_DEVICE_OPTIONS, &gvar_opts)) != SR_OK) /* Driver supports no device instance options. */ return; if (sdi->channel_groups) { printf("Channel groups:\n"); for (cgl = sdi->channel_groups; cgl; cgl = cgl->next) { cg = cgl->data; printf(" %s: channel%s", cg->name, g_slist_length(cg->channels) > 1 ? "s" : ""); for (chl = cg->channels; chl; chl = chl->next) { ch = chl->data; printf(" %s", ch->name); } printf("\n"); } } printf("Supported configuration options"); if (sdi->channel_groups) { if (!channel_group) printf(" across all channel groups"); else printf(" on channel group %s", channel_group->name); } printf(":\n"); opts = g_variant_get_fixed_array(gvar_opts, &num_opts, sizeof(int32_t)); for (o = 0; o < num_opts; o++) { if (!(srci = sr_config_info_get(opts[o]))) continue; if (srci->key == SR_CONF_TRIGGER_MATCH) { if (sr_config_list(sdi->driver, sdi, channel_group, srci->key, &gvar_list) != SR_OK) { printf("\n"); continue; } int32 = g_variant_get_fixed_array(gvar_list, &num_elements, sizeof(int32_t)); printf(" Supported triggers: "); for (i = 0; i < num_elements; i++) { switch(int32[i]) { case SR_TRIGGER_ZERO: c = '0'; break; case SR_TRIGGER_ONE: c = '1'; break; case SR_TRIGGER_RISING: c = 'r'; break; case SR_TRIGGER_FALLING: c = 'f'; break; case SR_TRIGGER_EDGE: c = 'e'; break; case SR_TRIGGER_OVER: c = 'o'; break; case SR_TRIGGER_UNDER: c = 'u'; break; default: c = 0; break; } if (c) printf("%c ", c); } printf("\n"); g_variant_unref(gvar_list); } else if (srci->key == SR_CONF_LIMIT_SAMPLES) { /* If implemented in config_list(), this denotes the * maximum number of samples a device can send. This * really applies only to logic analyzers, and then * only to those that don't support compression, or * have it turned off by default. The values returned * are the low/high limits. */ if (sr_config_list(sdi->driver, sdi, channel_group, srci->key, &gvar) != SR_OK) { continue; } g_variant_get(gvar, "(tt)", &low, &high); g_variant_unref(gvar); printf(" Maximum number of samples: %"PRIu64"\n", high); } else if (srci->key == SR_CONF_SAMPLERATE) { /* Supported samplerates */ printf(" %s", srci->id); if (sr_config_list(sdi->driver, sdi, channel_group, SR_CONF_SAMPLERATE, &gvar_dict) != SR_OK) { printf("\n"); continue; } if ((gvar_list = g_variant_lookup_value(gvar_dict, "samplerates", G_VARIANT_TYPE("at")))) { uint64 = g_variant_get_fixed_array(gvar_list, &num_elements, sizeof(uint64_t)); printf(" - supported samplerates:\n"); for (i = 0; i < num_elements; i++) { if (!(s = sr_samplerate_string(uint64[i]))) continue; printf(" %s\n", s); g_free(s); } g_variant_unref(gvar_list); } else if ((gvar_list = g_variant_lookup_value(gvar_dict, "samplerate-steps", G_VARIANT_TYPE("at")))) { uint64 = g_variant_get_fixed_array(gvar_list, &num_elements, sizeof(uint64_t)); /* low */ if (!(s = sr_samplerate_string(uint64[0]))) continue; printf(" (%s", s); g_free(s); /* high */ if (!(s = sr_samplerate_string(uint64[1]))) continue; printf(" - %s", s); g_free(s); /* step */ if (!(s = sr_samplerate_string(uint64[2]))) continue; printf(" in steps of %s)\n", s); g_free(s); g_variant_unref(gvar_list); } g_variant_unref(gvar_dict); } else if (srci->key == SR_CONF_BUFFERSIZE) { /* Supported buffer sizes */ printf(" %s", srci->id); if (sr_config_list(sdi->driver, sdi, channel_group, SR_CONF_BUFFERSIZE, &gvar_list) != SR_OK) { printf("\n"); continue; } uint64 = g_variant_get_fixed_array(gvar_list, &num_elements, sizeof(uint64_t)); printf(" - supported buffer sizes:\n"); for (i = 0; i < num_elements; i++) printf(" %"PRIu64"\n", uint64[i]); g_variant_unref(gvar_list); } else if (srci->key == SR_CONF_TIMEBASE) { /* Supported time bases */ printf(" %s", srci->id); if (sr_config_list(sdi->driver, sdi, channel_group, SR_CONF_TIMEBASE, &gvar_list) != SR_OK) { printf("\n"); continue; } printf(" - supported time bases:\n"); num_elements = g_variant_n_children(gvar_list); for (i = 0; i < num_elements; i++) { gvar = g_variant_get_child_value(gvar_list, i); g_variant_get(gvar, "(tt)", &p, &q); s = sr_period_string(p * q); printf(" %s\n", s); g_free(s); } g_variant_unref(gvar_list); } else if (srci->key == SR_CONF_VDIV) { /* Supported volts/div values */ printf(" %s", srci->id); if (sr_config_list(sdi->driver, sdi, channel_group, SR_CONF_VDIV, &gvar_list) != SR_OK) { printf("\n"); continue; } printf(" - supported volts/div:\n"); num_elements = g_variant_n_children(gvar_list); for (i = 0; i < num_elements; i++) { gvar = g_variant_get_child_value(gvar_list, i); g_variant_get(gvar, "(tt)", &p, &q); s = sr_voltage_string(p, q); printf(" %s\n", s); g_free(s); } g_variant_unref(gvar_list); } else if (srci->datatype == SR_T_STRING) { printf(" %s: ", srci->id); if (sr_config_get(sdi->driver, sdi, channel_group, srci->key, &gvar) == SR_OK) { tmp_str = g_strdup(g_variant_get_string(gvar, NULL)); g_variant_unref(gvar); } else tmp_str = NULL; if (sr_config_list(sdi->driver, sdi, channel_group, srci->key, &gvar) != SR_OK) { printf("\n"); continue; } stropts = g_variant_get_strv(gvar, &num_elements); for (i = 0; i < num_elements; i++) { if (i) printf(", "); printf("%s", stropts[i]); if (tmp_str && !strcmp(tmp_str, stropts[i])) printf(" (current)"); } printf("\n"); g_free(stropts); g_free(tmp_str); g_variant_unref(gvar); } else if (srci->datatype == SR_T_UINT64_RANGE) { printf(" %s: ", srci->id); if (sr_config_list(sdi->driver, sdi, channel_group, srci->key, &gvar_list) != SR_OK) { printf("\n"); continue; } if (sr_config_get(sdi->driver, sdi, NULL, srci->key, &gvar) == SR_OK) { g_variant_get(gvar, "(tt)", &cur_low, &cur_high); g_variant_unref(gvar); } else { cur_low = 0; cur_high = 0; } num_elements = g_variant_n_children(gvar_list); for (i = 0; i < num_elements; i++) { gvar = g_variant_get_child_value(gvar_list, i); g_variant_get(gvar, "(tt)", &low, &high); g_variant_unref(gvar); if (i) printf(", "); printf("%"PRIu64"-%"PRIu64, low, high); if (low == cur_low && high == cur_high) printf(" (current)"); } printf("\n"); g_variant_unref(gvar_list); } else if (srci->datatype == SR_T_BOOL) { printf(" %s: ", srci->id); if (sr_config_get(sdi->driver, sdi, NULL, srci->key, &gvar) == SR_OK) { if (g_variant_get_boolean(gvar)) printf("on (current), off\n"); else printf("on, off (current)\n"); g_variant_unref(gvar); } else printf("on, off\n"); } else if (srci->datatype == SR_T_DOUBLE_RANGE) { printf(" %s: ", srci->id); if (sr_config_list(sdi->driver, sdi, channel_group, srci->key, &gvar_list) != SR_OK) { printf("\n"); continue; } if (sr_config_get(sdi->driver, sdi, NULL, srci->key, &gvar) == SR_OK) { g_variant_get(gvar, "(dd)", &dcur_low, &dcur_high); g_variant_unref(gvar); } else { dcur_low = 0; dcur_high = 0; } num_elements = g_variant_n_children(gvar_list); for (i = 0; i < num_elements; i++) { gvar = g_variant_get_child_value(gvar_list, i); g_variant_get(gvar, "(dd)", &dlow, &dhigh); g_variant_unref(gvar); if (i) printf(", "); printf("%.1f-%.1f", dlow, dhigh); if (dlow == dcur_low && dhigh == dcur_high) printf(" (current)"); } printf("\n"); g_variant_unref(gvar_list); } else { /* Everything else */ printf(" %s\n", srci->id); } } g_variant_unref(gvar_opts); sr_dev_close(sdi); g_slist_free(devices); }