]> sigrok.org Git - sigrok-cli.git/blob - session.c
show: add support for -i <fn> --show, provide details on input stream
[sigrok-cli.git] / session.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 <config.h>
21 #include <glib.h>
22 #include <glib/gstdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include "sigrok-cli.h"
26
27 static uint64_t limit_samples = 0;
28 static uint64_t limit_frames = 0;
29
30 #ifdef HAVE_SRD
31 extern struct srd_session *srd_sess;
32 #endif
33
34 static int set_limit_time(const struct sr_dev_inst *sdi)
35 {
36         GVariant *gvar;
37         uint64_t time_msec;
38         uint64_t samplerate;
39         struct sr_dev_driver *driver;
40
41         driver = sr_dev_inst_driver_get(sdi);
42
43         if (!(time_msec = sr_parse_timestring(opt_time))) {
44                 g_critical("Invalid time '%s'", opt_time);
45                 return SR_ERR;
46         }
47
48         if (sr_dev_config_capabilities_list(sdi, NULL, SR_CONF_LIMIT_MSEC)
49                         & SR_CONF_SET) {
50                 gvar = g_variant_new_uint64(time_msec);
51                 if (sr_config_set(sdi, NULL, SR_CONF_LIMIT_MSEC, gvar) != SR_OK) {
52                         g_critical("Failed to configure time limit.");
53                         return SR_ERR;
54                 }
55         } else if (sr_dev_config_capabilities_list(sdi, NULL, SR_CONF_SAMPLERATE)
56                         & (SR_CONF_GET | SR_CONF_SET)) {
57                 /* Convert to samples based on the samplerate. */
58                 sr_config_get(driver, sdi, NULL, SR_CONF_SAMPLERATE, &gvar);
59                 samplerate = g_variant_get_uint64(gvar);
60                 g_variant_unref(gvar);
61                 limit_samples = (samplerate) * time_msec / (uint64_t)1000;
62                 if (limit_samples == 0) {
63                         g_critical("Not enough time at this samplerate.");
64                         return SR_ERR;
65                 }
66                 gvar = g_variant_new_uint64(limit_samples);
67                 if (sr_config_set(sdi, NULL, SR_CONF_LIMIT_SAMPLES, gvar) != SR_OK) {
68                         g_critical("Failed to configure time-based sample limit.");
69                         return SR_ERR;
70                 }
71         } else {
72                 g_critical("This device does not support time limits.");
73                 return SR_ERR;
74         }
75
76         return SR_OK;
77 }
78
79 const struct sr_output *setup_output_format(const struct sr_dev_inst *sdi, FILE **outfile)
80 {
81         const struct sr_output_module *omod;
82         const struct sr_option **options;
83         const struct sr_output *o;
84         GHashTable *fmtargs, *fmtopts;
85         char *fmtspec;
86
87         if (!opt_output_format) {
88                 if (opt_output_file) {
89                         opt_output_format = DEFAULT_OUTPUT_FORMAT_FILE;
90                 } else {
91                         opt_output_format = DEFAULT_OUTPUT_FORMAT_NOFILE;
92                 }
93         }
94
95         fmtargs = parse_generic_arg(opt_output_format, TRUE);
96         fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key");
97         if (!fmtspec)
98                 g_critical("Invalid output format.");
99         if (!(omod = sr_output_find(fmtspec)))
100                 g_critical("Unknown output module '%s'.", fmtspec);
101         g_hash_table_remove(fmtargs, "sigrok_key");
102         if ((options = sr_output_options_get(omod))) {
103                 fmtopts = generic_arg_to_opt(options, fmtargs);
104                 sr_output_options_free(options);
105         } else
106                 fmtopts = NULL;
107         o = sr_output_new(omod, fmtopts, sdi, opt_output_file);
108
109         if (opt_output_file) {
110                 if (!sr_output_test_flag(omod, SR_OUTPUT_INTERNAL_IO_HANDLING))
111                         *outfile = g_fopen(opt_output_file, "wb");
112                 else
113                         *outfile = NULL;
114         } else {
115                 *outfile = stdout;
116         }
117
118         if (fmtopts)
119                 g_hash_table_destroy(fmtopts);
120         g_hash_table_destroy(fmtargs);
121
122         return o;
123 }
124
125 const struct sr_transform *setup_transform_module(const struct sr_dev_inst *sdi)
126 {
127         const struct sr_transform_module *tmod;
128         const struct sr_option **options;
129         const struct sr_transform *t;
130         GHashTable *fmtargs, *fmtopts;
131         char *fmtspec;
132
133         fmtargs = parse_generic_arg(opt_transform_module, TRUE);
134         fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key");
135         if (!fmtspec)
136                 g_critical("Invalid transform module.");
137         if (!(tmod = sr_transform_find(fmtspec)))
138                 g_critical("Unknown transform module '%s'.", fmtspec);
139         g_hash_table_remove(fmtargs, "sigrok_key");
140         if ((options = sr_transform_options_get(tmod))) {
141                 fmtopts = generic_arg_to_opt(options, fmtargs);
142                 sr_transform_options_free(options);
143         } else
144                 fmtopts = NULL;
145         t = sr_transform_new(tmod, fmtopts, sdi);
146         if (fmtopts)
147                 g_hash_table_destroy(fmtopts);
148         g_hash_table_destroy(fmtargs);
149
150         return t;
151 }
152
153 /* Get the input stream's list of channels and their types, once. */
154 static void props_get_channels(struct df_arg_desc *args,
155         const struct sr_dev_inst *sdi)
156 {
157         struct input_stream_props *props;
158         GSList *l;
159         const struct sr_channel *ch;
160
161         if (!args)
162                 return;
163         props = &args->props;
164         if (props->channels)
165                 return;
166
167         props->channels = g_slist_copy(sr_dev_inst_channels_get(sdi));
168         if (!props->channels)
169                 return;
170         for (l = props->channels; l; l = l->next) {
171                 ch = l->data;
172                 if (!ch->enabled)
173                         continue;
174                 if (ch->type != SR_CHANNEL_ANALOG)
175                         continue;
176                 props->first_analog_channel = ch;
177                 break;
178         }
179 }
180
181 static gboolean props_chk_1st_channel(struct df_arg_desc *args,
182         const struct sr_datafeed_analog *analog)
183 {
184         struct sr_channel *ch;
185
186         if (!args || !analog || !analog->meaning)
187                 return FALSE;
188         ch = g_slist_nth_data(analog->meaning->channels, 0);
189         if (!ch)
190                 return FALSE;
191         return ch == args->props.first_analog_channel;
192 }
193
194 static void props_dump_details(struct df_arg_desc *args)
195 {
196         struct input_stream_props *props;
197         size_t ch_count;
198         GSList *l;
199         const struct sr_channel *ch;
200         const char *type;
201
202         if (!args)
203                 return;
204         props = &args->props;
205         if (props->samplerate)
206                 printf("Samplerate: %" PRIu64 "\n", props->samplerate);
207         if (props->channels) {
208                 ch_count = g_slist_length(props->channels);
209                 printf("Channels: %zu\n", ch_count);
210                 for (l = props->channels; l; l = l->next) {
211                         ch = l->data;
212                         if (ch->type == SR_CHANNEL_ANALOG)
213                                 type = "analog";
214                         else
215                                 type = "logic";
216                         printf("- %s: %s\n", ch->name, type);
217                 }
218         }
219         if (props->unitsize)
220                 printf("Logic unitsize: %zu\n", props->unitsize);
221         if (props->sample_count_logic)
222                 printf("Logic sample count: %" PRIu64 "\n", props->sample_count_logic);
223         if (props->sample_count_analog)
224                 printf("Analog sample count: %" PRIu64 "\n", props->sample_count_analog);
225         if (props->frame_count)
226                 printf("Frame count: %" PRIu64 "\n", props->frame_count);
227         if (props->triggered)
228                 printf("Trigger count: %" PRIu64 "\n", props->triggered);
229 }
230
231 static void props_cleanup(struct df_arg_desc *args)
232 {
233         struct input_stream_props *props;
234
235         if (!args)
236                 return;
237         props = &args->props;
238         g_slist_free(props->channels);
239         props->channels = NULL;
240         props->first_analog_channel = NULL;
241 }
242
243 void datafeed_in(const struct sr_dev_inst *sdi,
244                 const struct sr_datafeed_packet *packet, void *cb_data)
245 {
246         static const struct sr_output *o = NULL;
247         static const struct sr_output *oa = NULL;
248         static uint64_t rcvd_samples_logic = 0;
249         static uint64_t rcvd_samples_analog = 0;
250         static uint64_t samplerate = 0;
251         static int triggered = 0;
252         static FILE *outfile = NULL;
253
254         const struct sr_datafeed_meta *meta;
255         const struct sr_datafeed_logic *logic;
256         const struct sr_datafeed_analog *analog;
257         struct df_arg_desc *df_arg;
258         int do_props;
259         struct input_stream_props *props;
260         struct sr_session *session;
261         struct sr_config *src;
262         GSList *l;
263         GString *out;
264         GVariant *gvar;
265         uint64_t end_sample;
266         uint64_t input_len;
267         struct sr_dev_driver *driver;
268
269         /* Avoid warnings when building without decoder support. */
270         (void)session;
271         (void)input_len;
272
273         driver = sr_dev_inst_driver_get(sdi);
274
275         /* Skip all packets before the first header. */
276         if (packet->type != SR_DF_HEADER && !o)
277                 return;
278
279         /* Prepare to either process data, or "just" gather properties. */
280         df_arg = cb_data;
281         session = df_arg->session;
282         do_props = df_arg->do_props;
283         props = &df_arg->props;
284
285         switch (packet->type) {
286         case SR_DF_HEADER:
287                 g_debug("cli: Received SR_DF_HEADER.");
288                 if (maybe_config_get(driver, sdi, NULL, SR_CONF_SAMPLERATE,
289                                 &gvar) == SR_OK) {
290                         samplerate = g_variant_get_uint64(gvar);
291                         g_variant_unref(gvar);
292                 }
293                 if (do_props) {
294                         /* Setup variables for maximum code path re-use. */
295                         o = (void *)-1;
296                         limit_samples = 0;
297                         /* Start collecting input stream properties. */
298                         memset(props, 0, sizeof(*props));
299                         props->samplerate = samplerate;
300                         props_get_channels(df_arg, sdi);
301                         break;
302                 }
303                 if (!(o = setup_output_format(sdi, &outfile)))
304                         g_critical("Failed to initialize output module.");
305
306                 /* Set up backup analog output module. */
307                 if (outfile)
308                         oa = sr_output_new(sr_output_find("analog"), NULL,
309                                         sdi, NULL);
310
311                 rcvd_samples_logic = rcvd_samples_analog = 0;
312
313 #ifdef HAVE_SRD
314                 if (opt_pds) {
315                         if (samplerate) {
316                                 if (srd_session_metadata_set(srd_sess, SRD_CONF_SAMPLERATE,
317                                                 g_variant_new_uint64(samplerate)) != SRD_OK) {
318                                         g_critical("Failed to configure decode session.");
319                                         break;
320                                 }
321                         }
322                         if (srd_session_start(srd_sess) != SRD_OK) {
323                                 g_critical("Failed to start decode session.");
324                                 break;
325                         }
326                 }
327 #endif
328                 break;
329
330         case SR_DF_META:
331                 g_debug("cli: Received SR_DF_META.");
332                 meta = packet->payload;
333                 for (l = meta->config; l; l = l->next) {
334                         src = l->data;
335                         switch (src->key) {
336                         case SR_CONF_SAMPLERATE:
337                                 samplerate = g_variant_get_uint64(src->data);
338                                 g_debug("cli: Got samplerate %"PRIu64" Hz.", samplerate);
339                                 if (do_props) {
340                                         props->samplerate = samplerate;
341                                         break;
342                                 }
343 #ifdef HAVE_SRD
344                                 if (opt_pds) {
345                                         if (srd_session_metadata_set(srd_sess, SRD_CONF_SAMPLERATE,
346                                                         g_variant_new_uint64(samplerate)) != SRD_OK) {
347                                                 g_critical("Failed to pass samplerate to decoder.");
348                                         }
349                                 }
350 #endif
351                                 break;
352                         case SR_CONF_SAMPLE_INTERVAL:
353                                 samplerate = g_variant_get_uint64(src->data);
354                                 g_debug("cli: Got sample interval %"PRIu64" ms.", samplerate);
355                                 if (do_props) {
356                                         props->samplerate = samplerate;
357                                         break;
358                                 }
359                                 break;
360                         default:
361                                 /* Unknown metadata is not an error. */
362                                 break;
363                         }
364                 }
365                 break;
366
367         case SR_DF_TRIGGER:
368                 g_debug("cli: Received SR_DF_TRIGGER.");
369                 if (do_props) {
370                         props->triggered++;
371                         break;
372                 }
373                 triggered = 1;
374                 break;
375
376         case SR_DF_LOGIC:
377                 logic = packet->payload;
378                 g_message("cli: Received SR_DF_LOGIC (%"PRIu64" bytes, unitsize = %d).",
379                                 logic->length, logic->unitsize);
380                 if (logic->length == 0)
381                         break;
382
383                 if (do_props) {
384                         props_get_channels(df_arg, sdi);
385                         props->unitsize = logic->unitsize;
386                         props->sample_count_logic += logic->length / logic->unitsize;
387                         break;
388                 }
389
390                 /* Don't store any samples until triggered. */
391                 if (opt_wait_trigger && !triggered)
392                         break;
393
394                 if (limit_samples && rcvd_samples_logic >= limit_samples)
395                         break;
396
397                 end_sample = rcvd_samples_logic + logic->length / logic->unitsize;
398                 /* Cut off last packet according to the sample limit. */
399                 if (limit_samples && end_sample > limit_samples)
400                         end_sample = limit_samples;
401                 input_len = (end_sample - rcvd_samples_logic) * logic->unitsize;
402
403                 if (opt_pds) {
404 #ifdef HAVE_SRD
405                         if (srd_session_send(srd_sess, rcvd_samples_logic, end_sample,
406                                         logic->data, input_len, logic->unitsize) != SRD_OK)
407                                 sr_session_stop(session);
408 #endif
409                 }
410
411                 rcvd_samples_logic = end_sample;
412                 break;
413
414         case SR_DF_ANALOG:
415                 analog = packet->payload;
416                 g_message("cli: Received SR_DF_ANALOG (%d samples).", analog->num_samples);
417                 if (analog->num_samples == 0)
418                         break;
419
420                 if (do_props) {
421                         /* Only count the first analog channel. */
422                         props_get_channels(df_arg, sdi);
423                         if (!props_chk_1st_channel(df_arg, analog))
424                                 break;
425                         props->sample_count_analog += analog->num_samples;
426                         break;
427                 }
428
429                 if (limit_samples && rcvd_samples_analog >= limit_samples)
430                         break;
431
432                 rcvd_samples_analog += analog->num_samples;
433                 break;
434
435         case SR_DF_FRAME_BEGIN:
436                 g_debug("cli: Received SR_DF_FRAME_BEGIN.");
437                 break;
438
439         case SR_DF_FRAME_END:
440                 g_debug("cli: Received SR_DF_FRAME_END.");
441                 if (do_props) {
442                         props->frame_count++;
443                         break;
444                 }
445                 break;
446
447         default:
448                 break;
449         }
450
451         if (!do_props && o && !opt_pds) {
452                 if (sr_output_send(o, packet, &out) == SR_OK) {
453                         if (oa && !out) {
454                                 /*
455                                  * The user didn't specify an output module,
456                                  * but needs to see this analog data.
457                                  */
458                                 sr_output_send(oa, packet, &out);
459                         }
460                         if (outfile && out && out->len > 0) {
461                                 fwrite(out->str, 1, out->len, outfile);
462                                 fflush(outfile);
463                         }
464                         if (out)
465                                 g_string_free(out, TRUE);
466                 }
467         }
468
469         /*
470          * SR_DF_END needs to be handled after the output module's receive()
471          * is called, so it can properly clean up that module.
472          */
473         if (packet->type == SR_DF_END) {
474                 g_debug("cli: Received SR_DF_END.");
475
476                 if (do_props) {
477                         props_dump_details(df_arg);
478                         props_cleanup(df_arg);
479                         o = NULL;
480                 }
481
482                 if (o)
483                         sr_output_free(o);
484                 o = NULL;
485
486                 if (oa)
487                         sr_output_free(oa);
488                 oa = NULL;
489
490                 if (outfile && outfile != stdout)
491                         fclose(outfile);
492
493                 if (limit_samples) {
494                         if (rcvd_samples_logic > 0 && rcvd_samples_logic < limit_samples)
495                                 g_warning("Device only sent %" PRIu64 " samples.",
496                                            rcvd_samples_logic);
497                         else if (rcvd_samples_analog > 0 && rcvd_samples_analog < limit_samples)
498                                 g_warning("Device only sent %" PRIu64 " samples.",
499                                            rcvd_samples_analog);
500                 }
501         }
502
503 }
504
505 int opt_to_gvar(char *key, char *value, struct sr_config *src)
506 {
507         const struct sr_key_info *srci, *srmqi;
508         double tmp_double, dlow, dhigh;
509         uint64_t tmp_u64, p, q, low, high, mqflags;
510         uint32_t mq;
511         GVariant *rational[2], *range[2], *gtup[2];
512         GVariantBuilder *vbl;
513         gboolean tmp_bool;
514         gchar **keyval;
515         int ret, i;
516
517         if (!(srci = sr_key_info_name_get(SR_KEY_CONFIG, key))) {
518                 g_critical("Unknown device option '%s'.", (char *) key);
519                 return -1;
520         }
521         src->key = srci->key;
522
523         if ((!value || strlen(value) == 0) &&
524                 (srci->datatype != SR_T_BOOL)) {
525                 g_critical("Option '%s' needs a value.", (char *)key);
526                 return -1;
527         }
528
529         ret = 0;
530         switch (srci->datatype) {
531         case SR_T_UINT64:
532                 ret = sr_parse_sizestring(value, &tmp_u64);
533                 if (ret != 0)
534                         break;
535                 src->data = g_variant_new_uint64(tmp_u64);
536                 break;
537         case SR_T_INT32:
538                 ret = sr_parse_sizestring(value, &tmp_u64);
539                 if (ret != 0)
540                         break;
541                 src->data = g_variant_new_int32(tmp_u64);
542                 break;
543         case SR_T_STRING:
544                 src->data = g_variant_new_string(value);
545                 break;
546         case SR_T_BOOL:
547                 if (!value)
548                         tmp_bool = TRUE;
549                 else
550                         tmp_bool = sr_parse_boolstring(value);
551                 src->data = g_variant_new_boolean(tmp_bool);
552                 break;
553         case SR_T_FLOAT:
554                 tmp_double = strtof(value, NULL);
555                 src->data = g_variant_new_double(tmp_double);
556                 break;
557         case SR_T_RATIONAL_PERIOD:
558                 if ((ret = sr_parse_period(value, &p, &q)) != SR_OK)
559                         break;
560                 rational[0] = g_variant_new_uint64(p);
561                 rational[1] = g_variant_new_uint64(q);
562                 src->data = g_variant_new_tuple(rational, 2);
563                 break;
564         case SR_T_RATIONAL_VOLT:
565                 if ((ret = sr_parse_voltage(value, &p, &q)) != SR_OK)
566                         break;
567                 rational[0] = g_variant_new_uint64(p);
568                 rational[1] = g_variant_new_uint64(q);
569                 src->data = g_variant_new_tuple(rational, 2);
570                 break;
571         case SR_T_UINT64_RANGE:
572                 if (sscanf(value, "%"PRIu64"-%"PRIu64, &low, &high) != 2) {
573                         ret = -1;
574                         break;
575                 } else {
576                         range[0] = g_variant_new_uint64(low);
577                         range[1] = g_variant_new_uint64(high);
578                         src->data = g_variant_new_tuple(range, 2);
579                 }
580                 break;
581         case SR_T_DOUBLE_RANGE:
582                 if (sscanf(value, "%lf-%lf", &dlow, &dhigh) != 2) {
583                         ret = -1;
584                         break;
585                 } else {
586                         range[0] = g_variant_new_double(dlow);
587                         range[1] = g_variant_new_double(dhigh);
588                         src->data = g_variant_new_tuple(range, 2);
589                 }
590                 break;
591         case SR_T_KEYVALUE:
592                 /* Expects the argument to be in the form of key=value. */
593                 keyval = g_strsplit(value, "=", 2);
594                 if (!keyval[0] || !keyval[1]) {
595                         g_strfreev(keyval);
596                         ret = -1;
597                         break;
598                 } else {
599                         vbl = g_variant_builder_new(G_VARIANT_TYPE_DICTIONARY);
600                         g_variant_builder_add(vbl, "{ss}",
601                                               keyval[0], keyval[1]);
602                         src->data = g_variant_builder_end(vbl);
603                         g_strfreev(keyval);
604                 }
605                 break;
606         case SR_T_MQ:
607                 /*
608                   Argument is MQ id e.g. ("voltage") optionally followed by one
609                   or more /<mqflag> e.g. "/ac".
610                  */
611                 keyval = g_strsplit(value, "/", 0);
612                 if (!keyval[0] || !(srmqi = sr_key_info_name_get(SR_KEY_MQ, keyval[0]))) {
613                         g_strfreev(keyval);
614                         ret = -1;
615                         break;
616                 }
617                 mq = srmqi->key;
618                 mqflags = 0;
619                 for (i = 1; keyval[i]; i++) {
620                         if (!(srmqi = sr_key_info_name_get(SR_KEY_MQFLAGS, keyval[i]))) {
621                                 ret = -1;
622                                 break;
623                         }
624                         mqflags |= srmqi->key;
625                 }
626                 g_strfreev(keyval);
627                 if (ret != -1) {
628                         gtup[0] = g_variant_new_uint32(mq);
629                         gtup[1] = g_variant_new_uint64(mqflags);
630                         src->data = g_variant_new_tuple(gtup, 2);
631                 }
632                 break;
633         default:
634                 g_critical("Unknown data type specified for option '%s' "
635                            "(driver implementation bug?).", key);
636                 ret = -1;
637         }
638
639         if (ret < 0)
640                 g_critical("Invalid value: '%s' for option '%s'", value, key);
641
642         return ret;
643 }
644
645 int set_dev_options(struct sr_dev_inst *sdi, GHashTable *args)
646 {
647         struct sr_config src;
648         struct sr_channel_group *cg;
649         GHashTableIter iter;
650         gpointer key, value;
651         int ret;
652
653         g_hash_table_iter_init(&iter, args);
654         while (g_hash_table_iter_next(&iter, &key, &value)) {
655                 if ((ret = opt_to_gvar(key, value, &src)) != 0)
656                         return ret;
657                 cg = select_channel_group(sdi);
658                 if ((ret = maybe_config_set(sr_dev_inst_driver_get(sdi), sdi, cg,
659                                 src.key, src.data)) != SR_OK) {
660                         g_critical("Failed to set device option '%s': %s.",
661                                    (char *)key, sr_strerror(ret));
662                         return ret;
663                 }
664         }
665
666         return SR_OK;
667 }
668
669 void run_session(void)
670 {
671         struct df_arg_desc df_arg;
672         GSList *devices, *real_devices, *sd;
673         GHashTable *devargs;
674         GVariant *gvar;
675         struct sr_session *session;
676         struct sr_trigger *trigger;
677         struct sr_dev_inst *sdi;
678         uint64_t min_samples, max_samples;
679         GArray *drv_opts;
680         guint i;
681         int is_demo_dev;
682         struct sr_dev_driver *driver;
683         const struct sr_transform *t;
684         GMainLoop *main_loop;
685
686         memset(&df_arg, 0, sizeof(df_arg));
687         df_arg.do_props = FALSE;
688
689         devices = device_scan();
690         if (!devices) {
691                 g_critical("No devices found.");
692                 return;
693         }
694
695         real_devices = NULL;
696         for (sd = devices; sd; sd = sd->next) {
697                 sdi = sd->data;
698
699                 driver = sr_dev_inst_driver_get(sdi);
700
701                 if (!(drv_opts = sr_dev_options(driver, NULL, NULL))) {
702                         g_critical("Failed to query list of driver options.");
703                         return;
704                 }
705
706                 is_demo_dev = 0;
707                 for (i = 0; i < drv_opts->len; i++) {
708                         if (g_array_index(drv_opts, uint32_t, i) == SR_CONF_DEMO_DEV)
709                                 is_demo_dev = 1;
710                 }
711
712                 g_array_free(drv_opts, TRUE);
713
714                 if (!is_demo_dev)
715                         real_devices = g_slist_append(real_devices, sdi);
716         }
717
718         if (g_slist_length(devices) > 1) {
719                 if (g_slist_length(real_devices) != 1) {
720                         g_critical("sigrok-cli only supports one device for capturing.");
721                         return;
722                 } else {
723                         /* We only have one non-demo device. */
724                         g_slist_free(devices);
725                         devices = real_devices;
726                         real_devices = NULL;
727                 }
728         }
729
730         /* This is unlikely to happen but it makes static analyzers stop complaining. */
731         if (!devices) {
732                 g_critical("No real devices found.");
733                 return;
734         }
735
736         sdi = devices->data;
737         g_slist_free(devices);
738         g_slist_free(real_devices);
739
740         sr_session_new(sr_ctx, &session);
741         df_arg.session = session;
742         sr_session_datafeed_callback_add(session, datafeed_in, &df_arg);
743         df_arg.session = NULL;
744
745         if (sr_dev_open(sdi) != SR_OK) {
746                 g_critical("Failed to open device.");
747                 return;
748         }
749
750         if (sr_session_dev_add(session, sdi) != SR_OK) {
751                 g_critical("Failed to add device to session.");
752                 sr_session_destroy(session);
753                 return;
754         }
755
756         if (opt_config) {
757                 if ((devargs = parse_generic_arg(opt_config, FALSE))) {
758                         if (set_dev_options(sdi, devargs) != SR_OK)
759                                 return;
760                         g_hash_table_destroy(devargs);
761                 }
762         }
763
764         if (select_channels(sdi) != SR_OK) {
765                 g_critical("Failed to set channels.");
766                 sr_session_destroy(session);
767                 return;
768         }
769
770         trigger = NULL;
771         if (opt_triggers) {
772                 if (!parse_triggerstring(sdi, opt_triggers, &trigger)) {
773                         sr_session_destroy(session);
774                         return;
775                 }
776                 if (sr_session_trigger_set(session, trigger) != SR_OK) {
777                         sr_session_destroy(session);
778                         return;
779                 }
780         }
781
782         if (opt_continuous) {
783                 if (!sr_dev_has_option(sdi, SR_CONF_CONTINUOUS)) {
784                         g_critical("This device does not support continuous sampling.");
785                         sr_session_destroy(session);
786                         return;
787                 }
788         }
789
790         if (opt_time) {
791                 if (set_limit_time(sdi) != SR_OK) {
792                         sr_session_destroy(session);
793                         return;
794                 }
795         }
796
797         if (opt_samples) {
798                 if ((sr_parse_sizestring(opt_samples, &limit_samples) != SR_OK)) {
799                         g_critical("Invalid sample limit '%s'.", opt_samples);
800                         sr_session_destroy(session);
801                         return;
802                 }
803                 if (maybe_config_list(driver, sdi, NULL, SR_CONF_LIMIT_SAMPLES,
804                                 &gvar) == SR_OK) {
805                         /*
806                          * The device has no compression, or compression is turned
807                          * off, and publishes its sample memory size.
808                          */
809                         g_variant_get(gvar, "(tt)", &min_samples, &max_samples);
810                         g_variant_unref(gvar);
811                         if (limit_samples < min_samples) {
812                                 g_critical("The device stores at least %"PRIu64
813                                                 " samples with the current settings.", min_samples);
814                         }
815                         if (limit_samples > max_samples) {
816                                 g_critical("The device can store only %"PRIu64
817                                                 " samples with the current settings.", max_samples);
818                         }
819                 }
820                 gvar = g_variant_new_uint64(limit_samples);
821                 if (maybe_config_set(sr_dev_inst_driver_get(sdi), sdi, NULL, SR_CONF_LIMIT_SAMPLES, gvar) != SR_OK) {
822                         g_critical("Failed to configure sample limit.");
823                         sr_session_destroy(session);
824                         return;
825                 }
826         }
827
828         if (opt_frames) {
829                 if ((sr_parse_sizestring(opt_frames, &limit_frames) != SR_OK)) {
830                         g_critical("Invalid frame limit '%s'.", opt_frames);
831                         sr_session_destroy(session);
832                         return;
833                 }
834                 gvar = g_variant_new_uint64(limit_frames);
835                 if (maybe_config_set(sr_dev_inst_driver_get(sdi), sdi, NULL, SR_CONF_LIMIT_FRAMES, gvar) != SR_OK) {
836                         g_critical("Failed to configure frame limit.");
837                         sr_session_destroy(session);
838                         return;
839                 }
840         }
841
842         if (opt_transform_module) {
843                 if (!(t = setup_transform_module(sdi)))
844                         g_critical("Failed to initialize transform module.");
845         }
846
847         main_loop = g_main_loop_new(NULL, FALSE);
848
849         sr_session_stopped_callback_set(session,
850                 (sr_session_stopped_callback)g_main_loop_quit, main_loop);
851
852         if (sr_session_start(session) != SR_OK) {
853                 g_critical("Failed to start session.");
854                 g_main_loop_unref(main_loop);
855                 sr_session_destroy(session);
856                 return;
857         }
858
859         if (opt_continuous)
860                 add_anykey(session);
861
862         g_main_loop_run(main_loop);
863
864         if (opt_continuous)
865                 clear_anykey();
866
867         if (trigger)
868                 sr_trigger_free(trigger);
869
870         sr_session_datafeed_callback_remove_all(session);
871         g_main_loop_unref(main_loop);
872         sr_session_destroy(session);
873 }