]> sigrok.org Git - sigrok-cli.git/blob - decode.c
session: Allow probe selection for session files.
[sigrok-cli.git] / decode.c
1 /*
2  * This file is part of the sigrok-cli project.
3  *
4  * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include "sigrok-cli.h"
21 #include "config.h"
22 #include <glib.h>
23
24 #ifdef HAVE_SRD
25 static GHashTable *pd_ann_visible = NULL;
26 static GHashTable *pd_meta_visible = NULL;
27 static GHashTable *pd_binary_visible = NULL;
28
29 extern struct srd_session *srd_sess;
30 extern gint opt_loglevel;
31
32
33 static int opts_to_gvar(struct srd_decoder *dec, GHashTable *hash,
34                 GHashTable **options)
35 {
36         struct srd_decoder_option *o;
37         GSList *optl;
38         GVariant *gvar;
39         gint64 val_int;
40         int ret;
41         char *val_str, *conv;
42
43         ret = TRUE;
44         *options = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
45                         (GDestroyNotify)g_variant_unref);
46
47         for (optl = dec->options; optl; optl = optl->next) {
48                 o = optl->data;
49                 if (!(val_str = g_hash_table_lookup(hash, o->id)))
50                         /* Not specified. */
51                         continue;
52                 if (g_variant_is_of_type(o->def, G_VARIANT_TYPE_STRING)) {
53                         gvar = g_variant_new_string(val_str);
54                 } else if (g_variant_is_of_type(o->def, G_VARIANT_TYPE_INT64)) {
55                         val_int = strtoll(val_str, &conv, 0);
56                         if (!conv || conv == val_str) {
57                                 g_critical("Protocol decoder '%s' option '%s' "
58                                                 "requires a number.", dec->name, o->id);
59                                 ret = FALSE;
60                                 break;
61                         }
62                         gvar = g_variant_new_int64(val_int);
63                 } else {
64                         g_critical("Unsupported type for option '%s' (%s)",
65                                         o->id, g_variant_get_type_string(o->def));
66                         ret = FALSE;
67                         break;
68                 }
69                 g_variant_ref_sink(gvar);
70                 g_hash_table_insert(*options, g_strdup(o->id), gvar);
71                 g_hash_table_remove(hash, o->id);
72         }
73
74         return ret;
75 }
76
77 static int probes_to_gvar(struct srd_decoder *dec, GHashTable *hash,
78                 GHashTable **probes)
79 {
80         struct srd_probe *p;
81         GSList *all_probes, *l;
82         GVariant *gvar;
83         gint32 val_int;
84         int ret;
85         char *val_str, *conv;
86
87         ret = TRUE;
88         *probes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
89                         (GDestroyNotify)g_variant_unref);
90
91         all_probes = g_slist_copy(dec->probes);
92         all_probes = g_slist_concat(all_probes, g_slist_copy(dec->opt_probes));
93         for (l = all_probes; l; l = l->next) {
94                 p = l->data;
95                 if (!(val_str = g_hash_table_lookup(hash, p->id)))
96                         /* Not specified. */
97                         continue;
98                 val_int = strtoll(val_str, &conv, 10);
99                 if (!conv || conv == val_str) {
100                         g_critical("Protocol decoder '%s' probes '%s' "
101                                         "is not a number.", dec->name, p->id);
102                         ret = FALSE;
103                         break;
104                 }
105                 gvar = g_variant_new_int32(val_int);
106                 g_variant_ref_sink(gvar);
107                 g_hash_table_insert(*probes, g_strdup(p->id), gvar);
108                 g_hash_table_remove(hash, p->id);
109         }
110         g_slist_free(all_probes);
111
112         return ret;
113 }
114
115 /* Register the given PDs for this session.
116  * Accepts a string of the form: "spi:sck=3:sdata=4,spi:sck=3:sdata=5"
117  * That will instantiate two SPI decoders on the clock but different data
118  * lines.
119  */
120 int register_pds(const char *opt_pds, char *opt_pd_annotations)
121 {
122         struct srd_decoder *dec;
123         GHashTable *pd_opthash, *options, *probes;
124         GList *leftover, *l;
125         struct srd_decoder_inst *di;
126         int ret;
127         char **pdtokens, **pdtok, *pd_name;
128
129         pd_ann_visible = g_hash_table_new_full(g_str_hash, g_int_equal,
130                         g_free, NULL);
131         ret = 0;
132         pd_name = NULL;
133         pd_opthash = options = probes = NULL;
134         pdtokens = g_strsplit(opt_pds, ",", 0);
135         for (pdtok = pdtokens; *pdtok; pdtok++) {
136                 if (!(pd_opthash = parse_generic_arg(*pdtok, TRUE))) {
137                         g_critical("Invalid protocol decoder option '%s'.", *pdtok);
138                         break;
139                 }
140
141                 pd_name = g_strdup(g_hash_table_lookup(pd_opthash, "sigrok_key"));
142                 g_hash_table_remove(pd_opthash, "sigrok_key");
143                 if (srd_decoder_load(pd_name) != SRD_OK) {
144                         g_critical("Failed to load protocol decoder %s.", pd_name);
145                         ret = 1;
146                         break;
147                 }
148                 dec = srd_decoder_get_by_id(pd_name);
149
150                 /* Convert decoder option and probe values to GVariant. */
151                 if (!opts_to_gvar(dec, pd_opthash, &options)) {
152                         ret = 1;
153                         break;
154                 }
155                 if (!probes_to_gvar(dec, pd_opthash, &probes)) {
156                         ret = 1;
157                         break;
158                 }
159                 if (g_hash_table_size(pd_opthash) > 0) {
160                         leftover = g_hash_table_get_keys(pd_opthash);
161                         for (l = leftover; l; l = l->next)
162                                 g_critical("Unknown option or probe '%s'", (char *)l->data);
163                         g_list_free(leftover);
164                         break;
165                 }
166
167                 if (!(di = srd_inst_new(srd_sess, pd_name, options))) {
168                         g_critical("Failed to instantiate protocol decoder %s.", pd_name);
169                         ret = 1;
170                         break;
171                 }
172
173                 /* If no annotation list was specified, add them all in now.
174                  * This will be pared down later to leave only the last PD
175                  * in the stack.
176                  */
177                 if (!opt_pd_annotations)
178                         g_hash_table_insert(pd_ann_visible,
179                                             g_strdup(di->inst_id), GINT_TO_POINTER(-1));
180
181                 /* Remap the probes if needed. */
182                 if (srd_inst_probe_set_all(di, probes, (g_hash_table_size(probes) + 7) / 8) != SRD_OK) {
183                         ret = 1;
184                         break;
185                 }
186         }
187
188         g_strfreev(pdtokens);
189         if (pd_opthash)
190                 g_hash_table_destroy(pd_opthash);
191         if (options)
192                 g_hash_table_destroy(options);
193         if (probes)
194                 g_hash_table_destroy(probes);
195         if (pd_name)
196                 g_free(pd_name);
197
198         return ret;
199 }
200
201 int setup_pd_stack(char *opt_pds, char *opt_pd_stack, char *opt_pd_annotations)
202 {
203         struct srd_decoder_inst *di_from, *di_to;
204         int ret, i;
205         char **pds, **ids;
206
207         /* Set up the protocol decoder stack. */
208         pds = g_strsplit(opt_pds, ",", 0);
209         if (g_strv_length(pds) > 1) {
210                 if (opt_pd_stack) {
211                         /* A stack setup was specified, use that. */
212                         g_strfreev(pds);
213                         pds = g_strsplit(opt_pd_stack, ",", 0);
214                         if (g_strv_length(pds) < 2) {
215                                 g_strfreev(pds);
216                                 g_critical("Specify at least two protocol decoders to stack.");
217                                 return 1;
218                         }
219                 }
220
221                 /* First PD goes at the bottom of the stack. */
222                 ids = g_strsplit(pds[0], ":", 0);
223                 if (!(di_from = srd_inst_find_by_id(srd_sess, ids[0]))) {
224                         g_strfreev(ids);
225                         g_critical("Cannot stack protocol decoder '%s': "
226                                         "instance not found.", pds[0]);
227                         return 1;
228                 }
229                 g_strfreev(ids);
230
231                 /* Every subsequent PD goes on top. */
232                 for (i = 1; pds[i]; i++) {
233                         ids = g_strsplit(pds[i], ":", 0);
234                         if (!(di_to = srd_inst_find_by_id(srd_sess, ids[0]))) {
235                                 g_strfreev(ids);
236                                 g_critical("Cannot stack protocol decoder '%s': "
237                                                 "instance not found.", pds[i]);
238                                 return 1;
239                         }
240                         g_strfreev(ids);
241                         if ((ret = srd_inst_stack(srd_sess, di_from, di_to)) != SRD_OK)
242                                 return 1;
243
244                         /* Don't show annotation from this PD. Only the last PD in
245                          * the stack will be left on the annotation list (unless
246                          * the annotation list was specifically provided).
247                          */
248                         if (!opt_pd_annotations)
249                                 g_hash_table_remove(pd_ann_visible,
250                                                     di_from->inst_id);
251
252                         di_from = di_to;
253                 }
254         }
255         g_strfreev(pds);
256
257         return 0;
258 }
259
260 int setup_pd_annotations(char *opt_pd_annotations)
261 {
262         GSList *l;
263         struct srd_decoder *dec;
264         int ann_class;
265         char **pds, **pdtok, **keyval, **ann_descr;
266
267         /* Set up custom list of PDs and annotations to show. */
268         pds = g_strsplit(opt_pd_annotations, ",", 0);
269         for (pdtok = pds; *pdtok && **pdtok; pdtok++) {
270                 keyval = g_strsplit(*pdtok, "=", 0);
271                 if (!(dec = srd_decoder_get_by_id(keyval[0]))) {
272                         g_critical("Protocol decoder '%s' not found.", keyval[0]);
273                         return 1;
274                 }
275                 if (!dec->annotations) {
276                         g_critical("Protocol decoder '%s' has no annotations.", keyval[0]);
277                         return 1;
278                 }
279                 ann_class = 0;
280                 if (g_strv_length(keyval) == 2) {
281                         for (l = dec->annotations; l; l = l->next, ann_class++) {
282                                 ann_descr = l->data;
283                                 if (!canon_cmp(ann_descr[0], keyval[1]))
284                                         /* Found it. */
285                                         break;
286                         }
287                         if (!l) {
288                                 g_critical("Annotation '%s' not found "
289                                                 "for protocol decoder '%s'.", keyval[1], keyval[0]);
290                                 return 1;
291                         }
292                         g_debug("cli: Showing protocol decoder %s annotation "
293                                         "class %d (%s).", keyval[0], ann_class, ann_descr[0]);
294                 } else {
295                         /* No class specified: show all of them. */
296                         ann_class = -1;
297                         g_debug("cli: Showing all annotation classes for protocol "
298                                         "decoder %s.", keyval[0]);
299                 }
300                 g_hash_table_insert(pd_ann_visible, g_strdup(keyval[0]), GINT_TO_POINTER(ann_class));
301                 g_strfreev(keyval);
302         }
303         g_strfreev(pds);
304
305         return 0;
306 }
307
308 int setup_pd_meta(char *opt_pd_meta)
309 {
310         struct srd_decoder *dec;
311         char **pds, **pdtok;
312
313         pd_meta_visible = g_hash_table_new_full(g_str_hash, g_int_equal,
314                         g_free, NULL);
315         pds = g_strsplit(opt_pd_meta, ",", 0);
316         for (pdtok = pds; *pdtok && **pdtok; pdtok++) {
317                 if (!(dec = srd_decoder_get_by_id(*pdtok))) {
318                         g_critical("Protocol decoder '%s' not found.", *pdtok);
319                         return 1;
320                 }
321                 g_debug("cli: Showing protocol decoder meta output from '%s'.", *pdtok);
322                 g_hash_table_insert(pd_meta_visible, g_strdup(*pdtok), NULL);
323         }
324         g_strfreev(pds);
325
326         return 0;
327 }
328
329 int setup_pd_binary(char *opt_pd_binary)
330 {
331         GSList *l;
332         struct srd_decoder *dec;
333         int bin_class;
334         char **pds, **pdtok, **keyval, **bin_name;
335
336         pd_binary_visible = g_hash_table_new_full(g_str_hash, g_int_equal,
337                         g_free, NULL);
338         pds = g_strsplit(opt_pd_binary, ",", 0);
339         for (pdtok = pds; *pdtok && **pdtok; pdtok++) {
340                 keyval = g_strsplit(*pdtok, "=", 0);
341                 if (!(dec = srd_decoder_get_by_id(keyval[0]))) {
342                         g_critical("Protocol decoder '%s' not found.", keyval[0]);
343                         return 1;
344                 }
345                 if (!dec->binary) {
346                         g_critical("Protocol decoder '%s' has no binary output.", keyval[0]);
347                         return 1;
348                 }
349                 bin_class = 0;
350                 if (g_strv_length(keyval) == 2) {
351                         for (l = dec->binary; l; l = l->next, bin_class++) {
352                                 bin_name = l->data;
353                                 if (!strcmp(bin_name[0], keyval[1]))
354                                         /* Found it. */
355                                         break;
356                         }
357                         if (!l) {
358                                 g_critical("binary output '%s' not found "
359                                                 "for protocol decoder '%s'.", keyval[1], keyval[0]);
360                                 return 1;
361                         }
362                         g_debug("cli: Showing protocol decoder %s binary class "
363                                         "%d (%s).", keyval[0], bin_class, bin_name[0]);
364                 } else {
365                         /* No class specified: output all of them. */
366                         bin_class = -1;
367                         g_debug("cli: Showing all binary classes for protocol "
368                                         "decoder %s.", keyval[0]);
369                 }
370                 g_hash_table_insert(pd_binary_visible, g_strdup(keyval[0]), GINT_TO_POINTER(bin_class));
371                 g_strfreev(keyval);
372         }
373         g_strfreev(pds);
374
375         return 0;
376 }
377
378 void show_pd_annotations(struct srd_proto_data *pdata, void *cb_data)
379 {
380         struct srd_decoder *dec;
381         struct srd_proto_data_annotation *pda;
382         gpointer ann_format;
383         int format, i;
384         char **ann_descr;
385
386         /* 'cb_data' is not used in this specific callback. */
387         (void)cb_data;
388
389         if (!pd_ann_visible)
390                 return;
391
392         if (!g_hash_table_lookup_extended(pd_ann_visible, pdata->pdo->di->inst_id,
393                         NULL, &ann_format))
394                 /* Not in the list of PDs whose annotations we're showing. */
395                 return;
396
397         format = GPOINTER_TO_INT(ann_format);
398         dec = pdata->pdo->di->decoder;
399         pda = pdata->data;
400         if (format != -1 && pda->ann_format != format)
401                 /* We don't want this particular format from the PD. */
402                 return;
403
404         if (opt_loglevel <= SR_LOG_WARN) {
405                 /* Show only the longest annotation. */
406                 printf("%s", pda->ann_text[0]);
407         } else if (opt_loglevel >= SR_LOG_INFO) {
408                 /* Sample numbers and quotes around the longest annotation. */
409                 printf("%"PRIu64"-%"PRIu64"", pdata->start_sample, pdata->end_sample);
410                 if (opt_loglevel == SR_LOG_INFO) {
411                         printf(" \"%s\"", pda->ann_text[0]);
412                 } else {
413                         /* Protocol decoder id, annotation class,
414                          * all annotation strings. */
415                         ann_descr = g_slist_nth_data(dec->annotations, pda->ann_format);
416                         printf(" %s: %s:", pdata->pdo->proto_id, ann_descr[0]);
417                         for (i = 0; pda->ann_text[i]; i++)
418                                 printf(" \"%s\"", pda->ann_text[i]);
419                 }
420         }
421         printf("\n");
422         fflush(stdout);
423 }
424
425 void show_pd_meta(struct srd_proto_data *pdata, void *cb_data)
426 {
427
428         /* 'cb_data' is not used in this specific callback. */
429         (void)cb_data;
430
431         if (!g_hash_table_lookup_extended(pd_meta_visible,
432                         pdata->pdo->di->decoder->id, NULL, NULL))
433                 /* Not in the list of PDs whose meta output we're showing. */
434                 return;
435
436         if (opt_loglevel > SR_LOG_WARN)
437                 printf("%"PRIu64"-%"PRIu64" ", pdata->start_sample, pdata->end_sample);
438         printf("%s: ", pdata->pdo->proto_id);
439         printf("%s: %s", pdata->pdo->meta_name, g_variant_print(pdata->data, FALSE));
440         printf("\n");
441         fflush(stdout);
442 }
443
444 void show_pd_binary(struct srd_proto_data *pdata, void *cb_data)
445 {
446         struct srd_proto_data_binary *pdb;
447         gpointer classp;
448         int class;
449
450         /* 'cb_data' is not used in this specific callback. */
451         (void)cb_data;
452
453         if (!g_hash_table_lookup_extended(pd_binary_visible,
454                         pdata->pdo->di->decoder->id, NULL, (void **)&classp))
455                 /* Not in the list of PDs whose meta output we're showing. */
456                 return;
457
458         class = GPOINTER_TO_INT(classp);
459         pdb = pdata->data;
460         if (class != -1 && class != pdb->bin_class)
461                 /* Not showing this binary class. */
462                 return;
463
464         /* Just send the binary output to stdout, no embellishments. */
465         fwrite(pdb->data, pdb->size, 1, stdout);
466         fflush(stdout);
467 }
468 #endif
469