2 * This file is part of the sigrok-cli project.
4 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <libsigrok/libsigrok.h>
24 #include <libsigrokdecode/libsigrokdecode.h> /* First, so we avoid a _POSIX_C_SOURCE warning. */
26 #include "sigrok-cli.h"
29 static GHashTable *pd_ann_visible = NULL;
30 static GHashTable *pd_meta_visible = NULL;
31 static GHashTable *pd_binary_visible = NULL;
33 extern struct srd_session *srd_sess;
34 extern gint opt_loglevel;
35 extern gchar *opt_pds;
36 extern gchar *opt_pd_stack;
37 extern gchar *opt_pd_annotations;
38 extern gchar *opt_pd_meta;
39 extern gchar *opt_pd_binary;
42 static int opts_to_gvar(struct srd_decoder *dec, GHashTable *hash,
45 struct srd_decoder_option *o;
53 *options = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
54 (GDestroyNotify)g_variant_unref);
56 for (optl = dec->options; optl; optl = optl->next) {
58 if (!(val_str = g_hash_table_lookup(hash, o->id)))
61 if (g_variant_is_of_type(o->def, G_VARIANT_TYPE_STRING)) {
62 gvar = g_variant_new_string(val_str);
63 } else if (g_variant_is_of_type(o->def, G_VARIANT_TYPE_INT64)) {
64 val_int = strtoll(val_str, &conv, 0);
65 if (!conv || conv == val_str) {
66 g_critical("Protocol decoder '%s' option '%s' "
67 "requires a number.", dec->name, o->id);
71 gvar = g_variant_new_int64(val_int);
73 g_critical("Unsupported type for option '%s' (%s)",
74 o->id, g_variant_get_type_string(o->def));
78 g_variant_ref_sink(gvar);
79 g_hash_table_insert(*options, g_strdup(o->id), gvar);
80 g_hash_table_remove(hash, o->id);
86 static int probes_to_gvar(struct srd_decoder *dec, GHashTable *hash,
90 GSList *all_probes, *l;
97 *probes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
98 (GDestroyNotify)g_variant_unref);
100 all_probes = g_slist_copy(dec->probes);
101 all_probes = g_slist_concat(all_probes, g_slist_copy(dec->opt_probes));
102 for (l = all_probes; l; l = l->next) {
104 if (!(val_str = g_hash_table_lookup(hash, p->id)))
107 val_int = strtoll(val_str, &conv, 10);
108 if (!conv || conv == val_str) {
109 g_critical("Protocol decoder '%s' probes '%s' "
110 "is not a number.", dec->name, p->id);
114 gvar = g_variant_new_int32(val_int);
115 g_variant_ref_sink(gvar);
116 g_hash_table_insert(*probes, g_strdup(p->id), gvar);
117 g_hash_table_remove(hash, p->id);
119 g_slist_free(all_probes);
124 /* Register the given PDs for this session.
125 * Accepts a string of the form: "spi:sck=3:sdata=4,spi:sck=3:sdata=5"
126 * That will instantiate two SPI decoders on the clock but different data
129 int register_pds(const char *pdstring)
131 struct srd_decoder *dec;
132 GHashTable *pd_opthash, *options, *probes;
134 struct srd_decoder_inst *di;
136 char **pdtokens, **pdtok, *pd_name;
138 pd_ann_visible = g_hash_table_new_full(g_str_hash, g_int_equal,
142 pd_opthash = options = probes = NULL;
143 pdtokens = g_strsplit(pdstring, ",", 0);
144 for (pdtok = pdtokens; *pdtok; pdtok++) {
145 if (!(pd_opthash = parse_generic_arg(*pdtok, TRUE))) {
146 g_critical("Invalid protocol decoder option '%s'.", *pdtok);
150 pd_name = g_strdup(g_hash_table_lookup(pd_opthash, "sigrok_key"));
151 g_hash_table_remove(pd_opthash, "sigrok_key");
152 if (srd_decoder_load(pd_name) != SRD_OK) {
153 g_critical("Failed to load protocol decoder %s.", pd_name);
157 dec = srd_decoder_get_by_id(pd_name);
159 /* Convert decoder option and probe values to GVariant. */
160 if (!opts_to_gvar(dec, pd_opthash, &options)) {
164 if (!probes_to_gvar(dec, pd_opthash, &probes)) {
168 if (g_hash_table_size(pd_opthash) > 0) {
169 leftover = g_hash_table_get_keys(pd_opthash);
170 for (l = leftover; l; l = l->next)
171 g_critical("Unknown option or probe '%s'", (char *)l->data);
172 g_list_free(leftover);
176 if (!(di = srd_inst_new(srd_sess, pd_name, options))) {
177 g_critical("Failed to instantiate protocol decoder %s.", pd_name);
182 /* If no annotation list was specified, add them all in now.
183 * This will be pared down later to leave only the last PD
186 if (!opt_pd_annotations)
187 g_hash_table_insert(pd_ann_visible,
188 g_strdup(di->inst_id), GINT_TO_POINTER(-1));
190 /* Remap the probes if needed. */
191 if (srd_inst_probe_set_all(di, probes) != SRD_OK) {
197 g_strfreev(pdtokens);
199 g_hash_table_destroy(pd_opthash);
201 g_hash_table_destroy(options);
203 g_hash_table_destroy(probes);
210 int setup_pd_stack(void)
212 struct srd_decoder_inst *di_from, *di_to;
216 /* Set up the protocol decoder stack. */
217 pds = g_strsplit(opt_pds, ",", 0);
218 if (g_strv_length(pds) > 1) {
220 /* A stack setup was specified, use that. */
222 pds = g_strsplit(opt_pd_stack, ",", 0);
223 if (g_strv_length(pds) < 2) {
225 g_critical("Specify at least two protocol decoders to stack.");
230 /* First PD goes at the bottom of the stack. */
231 ids = g_strsplit(pds[0], ":", 0);
232 if (!(di_from = srd_inst_find_by_id(srd_sess, ids[0]))) {
234 g_critical("Cannot stack protocol decoder '%s': "
235 "instance not found.", pds[0]);
240 /* Every subsequent PD goes on top. */
241 for (i = 1; pds[i]; i++) {
242 ids = g_strsplit(pds[i], ":", 0);
243 if (!(di_to = srd_inst_find_by_id(srd_sess, ids[0]))) {
245 g_critical("Cannot stack protocol decoder '%s': "
246 "instance not found.", pds[i]);
250 if ((ret = srd_inst_stack(srd_sess, di_from, di_to)) != SRD_OK)
253 /* Don't show annotation from this PD. Only the last PD in
254 * the stack will be left on the annotation list (unless
255 * the annotation list was specifically provided).
257 if (!opt_pd_annotations)
258 g_hash_table_remove(pd_ann_visible,
269 int setup_pd_annotations(void)
272 struct srd_decoder *dec;
274 char **pds, **pdtok, **keyval, **ann_descr;
276 /* Set up custom list of PDs and annotations to show. */
277 pds = g_strsplit(opt_pd_annotations, ",", 0);
278 for (pdtok = pds; *pdtok && **pdtok; pdtok++) {
279 keyval = g_strsplit(*pdtok, "=", 0);
280 if (!(dec = srd_decoder_get_by_id(keyval[0]))) {
281 g_critical("Protocol decoder '%s' not found.", keyval[0]);
284 if (!dec->annotations) {
285 g_critical("Protocol decoder '%s' has no annotations.", keyval[0]);
289 if (g_strv_length(keyval) == 2) {
290 for (l = dec->annotations; l; l = l->next, ann_class++) {
292 if (!canon_cmp(ann_descr[0], keyval[1]))
297 g_critical("Annotation '%s' not found "
298 "for protocol decoder '%s'.", keyval[1], keyval[0]);
301 g_debug("cli: Showing protocol decoder %s annotation "
302 "class %d (%s).", keyval[0], ann_class, ann_descr[0]);
304 /* No class specified: show all of them. */
306 g_debug("cli: Showing all annotation classes for protocol "
307 "decoder %s.", keyval[0]);
309 g_hash_table_insert(pd_ann_visible, g_strdup(keyval[0]), GINT_TO_POINTER(ann_class));
317 int setup_pd_meta(void)
319 struct srd_decoder *dec;
322 pd_meta_visible = g_hash_table_new_full(g_str_hash, g_int_equal,
324 pds = g_strsplit(opt_pd_meta, ",", 0);
325 for (pdtok = pds; *pdtok && **pdtok; pdtok++) {
326 if (!(dec = srd_decoder_get_by_id(*pdtok))) {
327 g_critical("Protocol decoder '%s' not found.", *pdtok);
330 g_debug("cli: Showing protocol decoder meta output from '%s'.", *pdtok);
331 g_hash_table_insert(pd_meta_visible, g_strdup(*pdtok), NULL);
338 int setup_pd_binary(void)
341 struct srd_decoder *dec;
343 char **pds, **pdtok, **keyval, *bin_name;
345 pd_binary_visible = g_hash_table_new_full(g_str_hash, g_int_equal,
347 pds = g_strsplit(opt_pd_binary, ",", 0);
348 for (pdtok = pds; *pdtok && **pdtok; pdtok++) {
349 keyval = g_strsplit(*pdtok, "=", 0);
350 if (!(dec = srd_decoder_get_by_id(keyval[0]))) {
351 g_critical("Protocol decoder '%s' not found.", keyval[0]);
355 g_critical("Protocol decoder '%s' has no binary output.", keyval[0]);
359 if (g_strv_length(keyval) == 2) {
360 for (l = dec->binary; l; l = l->next, bin_class++) {
362 if (!canon_cmp(bin_name, keyval[1]))
367 g_critical("binary output '%s' not found "
368 "for protocol decoder '%s'.", keyval[1], keyval[0]);
371 g_debug("cli: Showing protocol decoder %s binary class "
372 "%d (%s).", keyval[0], bin_class, bin_name);
374 /* No class specified: output all of them. */
376 g_debug("cli: Showing all binary classes for protocol "
377 "decoder %s.", keyval[0]);
379 g_hash_table_insert(pd_binary_visible, g_strdup(keyval[0]), GINT_TO_POINTER(bin_class));
387 void show_pd_annotations(struct srd_proto_data *pdata, void *cb_data)
389 struct srd_proto_data_annotation *pda;
393 /* 'cb_data' is not used in this specific callback. */
399 if (!g_hash_table_lookup_extended(pd_ann_visible, pdata->pdo->di->inst_id,
401 /* Not in the list of PDs whose annotations we're showing. */
404 format = GPOINTER_TO_INT(ann_format);
406 if (format != -1 && pda->ann_format != format)
407 /* We don't want this particular format from the PD. */
410 if (opt_loglevel > SR_LOG_WARN)
411 printf("%"PRIu64"-%"PRIu64" ", pdata->start_sample, pdata->end_sample);
412 printf("%s: ", pdata->pdo->proto_id);
413 /* Show only the longest annotation. */
414 printf("\"%s\" ", pda->ann_text[0]);
419 void show_pd_meta(struct srd_proto_data *pdata, void *cb_data)
422 /* 'cb_data' is not used in this specific callback. */
425 if (!g_hash_table_lookup_extended(pd_meta_visible,
426 pdata->pdo->di->decoder->id, NULL, NULL))
427 /* Not in the list of PDs whose meta output we're showing. */
430 if (opt_loglevel > SR_LOG_WARN)
431 printf("%"PRIu64"-%"PRIu64" ", pdata->start_sample, pdata->end_sample);
432 printf("%s: ", pdata->pdo->proto_id);
433 printf("%s: %s", pdata->pdo->meta_name, g_variant_print(pdata->data, FALSE));
438 void show_pd_binary(struct srd_proto_data *pdata, void *cb_data)
440 struct srd_proto_data_binary *pdb;
444 /* 'cb_data' is not used in this specific callback. */
447 if (!g_hash_table_lookup_extended(pd_binary_visible,
448 pdata->pdo->di->decoder->id, NULL, (void **)&classp))
449 /* Not in the list of PDs whose meta output we're showing. */
452 class = GPOINTER_TO_INT(classp);
454 if (class != -1 && class != pdb->bin_class)
455 /* Not showing this binary class. */
458 /* Just send the binary output to stdout, no embellishments. */
459 fwrite(pdb->data, pdb->size, 1, stdout);