X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=session.c;h=090fdce8f32fea1b408f25e6199ff446d2472db1;hb=abb036855e8a35ddeaf7c8bcba02741d78bc25ba;hp=fb9ebb6d4def3d4a384b8847f60b9bcf510408f9;hpb=fea5acabffd4f51c9c6bed25612172bf2727cbde;p=sigrok-cli.git diff --git a/session.c b/session.c index fb9ebb6..090fdce 100644 --- a/session.c +++ b/session.c @@ -45,13 +45,14 @@ static int set_limit_time(const struct sr_dev_inst *sdi) return SR_ERR; } - if (sr_dev_has_option(sdi, SR_CONF_LIMIT_MSEC)) { + if (config_key_has_cap(driver, sdi, NULL, SR_CONF_LIMIT_MSEC, SR_CONF_SET)) { 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)) { + } else if (config_key_has_cap(driver, sdi, NULL, SR_CONF_SAMPLERATE, + SR_CONF_GET | SR_CONF_SET)) { /* Convert to samples based on the samplerate. */ sr_config_get(driver, sdi, NULL, SR_CONF_SAMPLERATE, &gvar); samplerate = g_variant_get_uint64(gvar); @@ -114,6 +115,37 @@ const struct sr_output *setup_output_format(const struct sr_dev_inst *sdi) return o; } +const struct sr_transform *setup_transform_module(const struct sr_dev_inst *sdi) +{ + const struct sr_transform_module *tmod; + const struct sr_option **options; + const struct sr_transform *t; + GHashTable *fmtargs, *fmtopts; + char *fmtspec; + + if (!opt_transform_module) + opt_transform_module = "nop"; + + fmtargs = parse_generic_arg(opt_transform_module, TRUE); + fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key"); + if (!fmtspec) + g_critical("Invalid transform module."); + if (!(tmod = sr_transform_find(fmtspec))) + g_critical("Unknown transform module '%s'.", fmtspec); + g_hash_table_remove(fmtargs, "sigrok_key"); + if ((options = sr_transform_options_get(tmod))) { + fmtopts = generic_arg_to_opt(options, fmtargs); + sr_transform_options_free(options); + } else + fmtopts = NULL; + t = sr_transform_new(tmod, fmtopts, sdi); + if (fmtopts) + g_hash_table_destroy(fmtopts); + g_hash_table_destroy(fmtargs); + + return t; +} + void datafeed_in(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *packet, void *cb_data) { @@ -159,7 +191,7 @@ void datafeed_in(const struct sr_dev_inst *sdi, rcvd_samples_logic = rcvd_samples_analog = 0; - if (sr_config_get(driver, sdi, NULL, SR_CONF_SAMPLERATE, + if (maybe_config_get(driver, sdi, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); @@ -325,7 +357,9 @@ int opt_to_gvar(char *key, char *value, struct sr_config *src) double tmp_double, dlow, dhigh; uint64_t tmp_u64, p, q, low, high; GVariant *rational[2], *range[2]; + GVariantBuilder *vbl; gboolean tmp_bool; + gchar **keyval; int ret; if (!(srci = sr_config_info_name_get(key))) { @@ -334,7 +368,7 @@ int opt_to_gvar(char *key, char *value, struct sr_config *src) } src->key = srci->key; - if ((value == NULL) && + if ((value == NULL || strlen(value) == 0) && (srci->datatype != SR_T_BOOL)) { g_critical("Option '%s' needs a value.", (char *)key); return -1; @@ -402,10 +436,30 @@ int opt_to_gvar(char *key, char *value, struct sr_config *src) src->data = g_variant_new_tuple(range, 2); } break; + case SR_T_KEYVALUE: + /* Expects the argument to be in the form of key=value. */ + keyval = g_strsplit(value, "=", 2); + if (!keyval[0] || !keyval[1]) { + g_strfreev(keyval); + ret = -1; + break; + } else { + vbl = g_variant_builder_new(G_VARIANT_TYPE_DICTIONARY); + g_variant_builder_add(vbl, "{ss}", + keyval[0], keyval[1]); + src->data = g_variant_builder_end(vbl); + g_strfreev(keyval); + } + break; default: + g_critical("Unknown data type specified for option '%s' " + "(driver implementation bug?).", key); ret = -1; } + if (ret < 0) + g_critical("Invalid value: '%s' for option '%s'", value, key); + return ret; } @@ -422,9 +476,10 @@ int set_dev_options(struct sr_dev_inst *sdi, GHashTable *args) if ((ret = opt_to_gvar(key, value, &src)) != 0) return ret; cg = select_channel_group(sdi); - ret = sr_config_set(sdi, cg, src.key, src.data); - if (ret != SR_OK) { - g_critical("Failed to set device option '%s'.", (char *)key); + if ((ret = maybe_config_set(sr_dev_inst_driver_get(sdi), sdi, cg, + src.key, src.data)) != SR_OK) { + g_critical("Failed to set device option '%s': %s.", + (char *)key, sr_strerror(ret)); return ret; } } @@ -445,6 +500,7 @@ void run_session(void) const uint32_t *dev_opts; int is_demo_dev; struct sr_dev_driver *driver; + const struct sr_transform *t; devices = device_scan(); if (!devices) { @@ -459,7 +515,7 @@ void run_session(void) driver = sr_dev_inst_driver_get(sdi); if (sr_config_list(driver, sdi, NULL, SR_CONF_DEVICE_OPTIONS, &gvar) != SR_OK) { - g_critical("Failed to query sr_config_list(SR_CONF_DEVICE_OPTIONS)."); + g_critical("Failed to query list device options."); return; } @@ -553,8 +609,8 @@ void run_session(void) sr_session_destroy(session); return; } - if (sr_config_list(driver, sdi, NULL, - SR_CONF_LIMIT_SAMPLES, &gvar) == SR_OK) { + if (maybe_config_list(driver, sdi, NULL, SR_CONF_LIMIT_SAMPLES, + &gvar) == SR_OK) { /* The device has no compression, or compression is turned * off, and publishes its sample memory size. */ g_variant_get(gvar, "(tt)", &min_samples, &max_samples); @@ -569,7 +625,7 @@ void run_session(void) } } gvar = g_variant_new_uint64(limit_samples); - if (sr_config_set(sdi, NULL, SR_CONF_LIMIT_SAMPLES, gvar) != SR_OK) { + if (maybe_config_set(sr_dev_inst_driver_get(sdi), sdi, NULL, SR_CONF_LIMIT_SAMPLES, gvar) != SR_OK) { g_critical("Failed to configure sample limit."); sr_session_destroy(session); return; @@ -583,13 +639,16 @@ void run_session(void) return; } gvar = g_variant_new_uint64(limit_frames); - if (sr_config_set(sdi, NULL, SR_CONF_LIMIT_FRAMES, gvar) != SR_OK) { + if (maybe_config_set(sr_dev_inst_driver_get(sdi), sdi, NULL, SR_CONF_LIMIT_FRAMES, gvar) != SR_OK) { g_critical("Failed to configure frame limit."); sr_session_destroy(session); return; } } + if (!(t = setup_transform_module(sdi))) + g_critical("Failed to initialize transform module."); + if (sr_session_start(session) != SR_OK) { g_critical("Failed to start session."); sr_session_destroy(session);