Hi

I had a binary file that I needed to decode using UART decoder. UART
decoder needs to know the sample rate for the data, but currently it's
not possible to pass parameters to input formats and so the "binary"
file format always sets the samplerate to 0.

This patch adds the possibility to append a colon-separated list of
key=value options to the -I argument, in the same way -d supports it.
Also, it makes the "binary" format support the "samplerate" option.

I included the GHashTable containing input format options directly in
the sr_input struct. I'm not sure if that's the right way to do it. I
saw that -d uses a much more elaborate system with device capabilities
and typed options, but that seemed like an overkill for input formats.

Best regards
Tomaž
>From 135e5b9035e68cca9d8d1a57a9c1bf10973b378d Mon Sep 17 00:00:00 2001
From: Tomaz Solc <[email protected]>
Date: Mon, 2 Jul 2012 15:04:24 +0200
Subject: [PATCH 2/3] Allow setting samplerate when reading binary files.

---
 libsigrok/input/binary.c       |   44 +++++++++++++++++++++++++++++++++------
 libsigrok/input/chronovu_la8.c |   20 ++++++++++-------
 sigrok-cli/doc/sigrok-cli.1    |    7 +++++-
 sigrok-cli/sigrok-cli.c        |   23 ++++++++++++++++----
 4 files changed, 73 insertions(+), 21 deletions(-)

diff --git a/libsigrok/input/binary.c b/libsigrok/input/binary.c
index 4d6c424..e50871a 100644
--- a/libsigrok/input/binary.c
+++ b/libsigrok/input/binary.c
@@ -29,6 +29,10 @@
 #define CHUNKSIZE             (512 * 1024)
 #define DEFAULT_NUM_PROBES    8
 
+struct context {
+	int samplerate;
+};
+
 static int format_match(const char *filename)
 {
 	/* suppress compiler warning */
@@ -42,17 +46,37 @@ static int init(struct sr_input *in)
 {
 	int num_probes, i;
 	char name[SR_MAX_PROBENAME_LEN + 1];
+	char *param;
+	struct context *ctx;
+
+	if (!(ctx = g_try_malloc0(sizeof(*ctx)))) {
+		sr_err("binary in: %s: ctx malloc failed", __func__);
+		return SR_ERR_MALLOC;
+	}
 
-	if (in->param && in->param[0]) {
-		num_probes = strtoul(in->param, NULL, 10);
-		if (num_probes < 1)
-			return SR_ERR;
-	} else {
-		num_probes = DEFAULT_NUM_PROBES;
+	num_probes = DEFAULT_NUM_PROBES;
+	ctx->samplerate = 0;
+
+	if(in->param) {
+		param = g_hash_table_lookup(in->param, "numprobes");
+		if (param) {
+			num_probes = strtoul(param, NULL, 10);
+			if (num_probes < 1)
+				return SR_ERR;
+		}
+
+		param = g_hash_table_lookup(in->param, "samplerate");
+		if (param) {
+			ctx->samplerate = strtoul(param, NULL, 10);
+			if (ctx->samplerate < 1) {
+				return SR_ERR;
+			}
+		}
 	}
 
 	/* Create a virtual device. */
 	in->vdev = sr_dev_new(NULL, 0);
+	in->internal = ctx;
 
 	for (i = 0; i < num_probes; i++) {
 		snprintf(name, SR_MAX_PROBENAME_LEN, "%d", i);
@@ -71,6 +95,9 @@ static int loadfile(struct sr_input *in, const char *filename)
 	struct sr_datafeed_logic logic;
 	unsigned char buffer[CHUNKSIZE];
 	int fd, size, num_probes;
+	struct context *ctx;
+
+	ctx = in->internal;
 
 	if ((fd = open(filename, O_RDONLY)) == -1)
 		return SR_ERR;
@@ -87,7 +114,7 @@ static int loadfile(struct sr_input *in, const char *filename)
 	/* Send metadata about the SR_DF_LOGIC packets to come. */
 	packet.type = SR_DF_META_LOGIC;
 	packet.payload = &meta;
-	meta.samplerate = 0;
+	meta.samplerate = ctx->samplerate;
 	meta.num_probes = num_probes;
 	sr_session_send(in->vdev, &packet);
 
@@ -106,6 +133,9 @@ static int loadfile(struct sr_input *in, const char *filename)
 	packet.type = SR_DF_END;
 	sr_session_send(in->vdev, &packet);
 
+	g_free(ctx);
+	in->internal = NULL;
+
 	return SR_OK;
 }
 
diff --git a/libsigrok/input/chronovu_la8.c b/libsigrok/input/chronovu_la8.c
index 79f83cc..6d25979 100644
--- a/libsigrok/input/chronovu_la8.c
+++ b/libsigrok/input/chronovu_la8.c
@@ -96,15 +96,19 @@ static int init(struct sr_input *in)
 {
 	int num_probes, i;
 	char name[SR_MAX_PROBENAME_LEN + 1];
-
-	if (in->param && in->param[0]) {
-		num_probes = strtoul(in->param, NULL, 10);
-		if (num_probes < 1) {
-			sr_err("la8 in: %s: strtoul failed", __func__);
-			return SR_ERR;
+	char *param;
+
+	num_probes = DEFAULT_NUM_PROBES;
+
+	if (in->param) {
+		param = g_hash_table_lookup(in->param, "numprobes");
+		if (param) {
+			num_probes = strtoul(param, NULL, 10);
+			if (num_probes < 1) {
+				sr_err("la8 in: %s: strtoul failed", __func__);
+				return SR_ERR;
+			}
 		}
-	} else {
-		num_probes = DEFAULT_NUM_PROBES;
 	}
 
 	/* Create a virtual device. */
diff --git a/sigrok-cli/doc/sigrok-cli.1 b/sigrok-cli/doc/sigrok-cli.1
index cc13722..d86e53b 100644
--- a/sigrok-cli/doc/sigrok-cli.1
+++ b/sigrok-cli/doc/sigrok-cli.1
@@ -76,7 +76,12 @@ the input file.
 When loading an input file, assume it's in the specified format. If this
 option is not supplied (in addition to
 .BR \-\-input\-file ),
-sigrok-cli attempts to autodetect the file format of the input file.
+sigrok-cli attempts to autodetect the file format of the input file. Use the
+.B \-V
+option to see a list of available input formats. The format name may
+optionally be followed by a colon-separated list of options, where each
+option takes the form
+.BR "key=value" .
 .TP
 .BR "\-o, \-\-output\-file " <filename>
 Save output to a file instead of writing it to stdout. The default format
diff --git a/sigrok-cli/sigrok-cli.c b/sigrok-cli/sigrok-cli.c
index a1cb674..ffd6605 100644
--- a/sigrok-cli/sigrok-cli.c
+++ b/sigrok-cli/sigrok-cli.c
@@ -43,7 +43,6 @@ static uint64_t limit_frames = 0;
 static struct sr_output_format *output_format = NULL;
 static int default_output_format = FALSE;
 static char *output_format_param = NULL;
-static char *input_format_param = NULL;
 static GHashTable *pd_ann_visible = NULL;
 
 static gboolean opt_version = FALSE;
@@ -991,7 +990,7 @@ static struct sr_input_format *determine_input_file_format(
 	/* If the user specified -I / --input-format, use that one. */
 	if (opt) {
 		for (i = 0; inputs[i]; i++) {
-			if (strcasecmp(inputs[i]->id, opt_input_format))
+			if (strcasecmp(inputs[i]->id, opt))
 				continue;
 			g_debug("Using user-specified input file format '%s'.",
 					inputs[i]->id);
@@ -1000,7 +999,7 @@ static struct sr_input_format *determine_input_file_format(
 
 		/* The user specified an unknown input format, return NULL. */
 		g_critical("Error: specified input file format '%s' is "
-			"unknown.", opt_input_format);
+			"unknown.", opt);
 		return NULL;
 	}
 
@@ -1024,14 +1023,25 @@ static struct sr_input_format *determine_input_file_format(
 
 static void load_input_file_format(void)
 {
+	GHashTable *fmtargs = NULL;
 	struct stat st;
 	struct sr_input *in;
 	struct sr_input_format *input_format;
+	char *fmtspec = NULL;
+
+	if (opt_input_format) {
+		fmtargs = parse_generic_arg(opt_input_format);
+		fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key");
+	}
 
 	if (!(input_format = determine_input_file_format(opt_input_file,
-						   opt_input_format)))
+						   fmtspec))) {
 		/* The exact cause was already logged. */
 		return;
+	}
+;
+	if (fmtargs)
+		g_hash_table_remove(fmtargs, "sigrok_key");
 
 	if (stat(opt_input_file, &st) == -1) {
 		g_critical("Failed to load %s: %s", opt_input_file,
@@ -1045,7 +1055,7 @@ static void load_input_file_format(void)
 		exit(1);
 	}
 	in->format = input_format;
-	in->param = input_format_param;
+	in->param = fmtargs;
 	if (in->format->init) {
 		if (in->format->init(in) != SR_OK) {
 			g_critical("Input format init failed.");
@@ -1070,6 +1080,9 @@ static void load_input_file_format(void)
 			g_critical("Failed to save session.");
 	}
 	sr_session_destroy();
+
+	if (fmtargs)
+		g_hash_table_destroy(fmtargs);
 }
 
 static void load_input_file(void)
-- 
1.7.2.5

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
sigrok-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sigrok-devel

Reply via email to