]> sigrok.org Git - libsigrok.git/blob - src/input/saleae.c
f63181b3716a12bc2523a00fd81342061751c469
[libsigrok.git] / src / input / saleae.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2020 Gerhard Sittig <gerhard.sittig@gmx.net>
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 2 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 /*
21  * See the vendor's FAQ on file format details for exported files and
22  * different software versions:
23  *
24  * https://support.saleae.com/faq/technical-faq/binary-data-export-format
25  * https://support.saleae.com/faq/technical-faq/data-export-format-analog-binary
26  * https://support.saleae.com/faq/technical-faq/binary-export-format-logic-2
27  *
28  * All data is in little endian representation, floating point values
29  * in IEEE754 format. Recent versions add header information, while
30  * previous versions tend to "raw" formats. This input module is about
31  * digital and analog data in their "binary presentation". CSV and VCD
32  * exports are handled by other input modules.
33  *
34  * Saleae Logic applications typically export one file per channel. The
35  * sigrok input modules exclusively handle an individual file, existing
36  * applications may not be prepared to handle a set of files, or handle
37  * "special" file types like directories. Some of them will even actively
38  * reject such input specs. Merging multiple exported channels into either
39  * another input file or a sigrok session is supposed to be done outside
40  * of this input module. Support for ZIP archives is currently missing.
41  *
42  * TODO
43  * - Need to create a channel group in addition to channels?
44  * - Check file re-load and channel references. See bug #1241.
45  * - Fixup 'digits' use for analog data. The current implementation made
46  *   an educated guess, assuming some 12bit resolution and logic levels
47  *   which roughly results in the single digit mV range.
48  * - Add support for "local I/O" in the input module when the common
49  *   support code becomes available. The .sal save files of the Logic
50  *   application appears to be a ZIP archive with *.bin files in it
51  *   plus some meta.json dictionary. This will also introduce a new
52  *   JSON reader dependency.
53  * - When ZIP support gets added and .sal files become accepted, this
54  *   import module needs to merge the content of several per-channel
55  *   files, which may be of different types (mixed signal), and/or may
56  *   even differ in their samplerate (which becomes complex, similar to
57  *   VCD or CSV input). Given the .sal archive's layout this format may
58  *   even only become attractive when common sigrok infrastructure has
59  *   support for per-channel compression and rate(?).
60  */
61
62 #include <config.h>
63 #include <glib.h>
64 #include <stdint.h>
65 #include <stdlib.h>
66 #include <string.h>
67 #include <libsigrok/libsigrok.h>
68 #include "libsigrok-internal.h"
69
70 #define LOG_PREFIX "input/saleae"
71
72 /*
73  * Saleae Logic "save files" (ZIP archives with .sal file extension)
74  * could get detected, but are not yet supported. Usability would be
75  * rather limited when the current development support gets enabled.
76  * This compile time switch is strictly for internal developer use.
77  */
78 #define SALEAE_WITH_SAL_SUPPORT 0
79
80 #define CHUNK_SIZE  (4 * 1024 * 1024)
81
82 #define LOGIC2_MAGIC "<SALEAE>"
83 #define LOGIC2_VERSION 0
84 #define LOGIC2_TYPE_DIGITAL 0
85 #define LOGIC2_TYPE_ANALOG 1
86
87 /* Simple header check approach. Assume minimum file size for all formats. */
88 #define LOGIC2_MIN_SIZE 0x30
89
90 enum logic_format {
91         FMT_UNKNOWN,
92         FMT_AUTO_DETECT,
93         FMT_LOGIC1_DIGITAL,
94         FMT_LOGIC1_ANALOG,
95         FMT_LOGIC2_DIGITAL,
96         FMT_LOGIC2_ANALOG,
97         FMT_LOGIC2_ARCHIVE,
98 };
99
100 enum input_stage {
101         STAGE_ALL_WAIT_HEADER,
102         STAGE_ALL_DETECT_TYPE,
103         STAGE_ALL_READ_HEADER,
104         STAGE_L1D_EVERY_VALUE,
105         STAGE_L1D_CHANGE_INIT,
106         STAGE_L1D_CHANGE_VALUE,
107         STAGE_L1A_NEW_CHANNEL,
108         STAGE_L1A_SAMPLE,
109         STAGE_L2D_CHANGE_VALUE,
110         STAGE_L2A_FIRST_VALUE,
111         STAGE_L2A_EVERY_VALUE,
112 };
113
114 struct context {
115         struct context_options {
116                 enum logic_format format;
117                 gboolean when_changed;
118                 size_t word_size;
119                 size_t channel_count;
120                 uint64_t sample_rate;
121         } options;
122         struct {
123                 gboolean got_header;
124                 gboolean header_sent;
125                 gboolean rate_sent;
126                 GSList *prev_channels;
127         } module_state;
128         struct {
129                 enum logic_format format;
130                 gboolean when_changed;
131                 size_t word_size;
132                 size_t channel_count;
133                 uint64_t sample_rate;
134                 enum input_stage stage;
135                 struct {
136                         uint64_t samples_per_channel;
137                         uint64_t current_channel_idx;
138                         uint64_t current_per_channel;
139                 } l1a;
140                 struct {
141                         uint32_t init_state;
142                         double begin_time;
143                         double end_time;
144                         uint64_t transition_count;
145                         double sample_period;
146                         double min_time_step;
147                 } l2d;
148                 struct {
149                         double begin_time;
150                         uint64_t sample_rate;
151                         uint64_t down_sample;
152                         uint64_t sample_count;
153                 } l2a;
154         } logic_state;
155         struct {
156                 GSList *channels;
157                 gboolean is_analog;
158                 size_t unit_size;
159                 size_t samples_per_chunk;
160                 size_t samples_in_buffer;
161                 uint8_t *buffer_digital;
162                 float *buffer_analog;
163                 uint8_t *write_pos;
164                 struct {
165                         uint64_t stamp;
166                         double time;
167                         uint32_t digital;
168                         float analog;
169                 } last;
170         } feed;
171 };
172
173 static const char *format_texts[] = {
174         [FMT_UNKNOWN] = "unknown",
175         [FMT_AUTO_DETECT] = "auto-detect",
176         [FMT_LOGIC1_DIGITAL] = "logic1-digital",
177         [FMT_LOGIC1_ANALOG] = "logic1-analog",
178         [FMT_LOGIC2_DIGITAL] = "logic2-digital",
179         [FMT_LOGIC2_ANALOG] = "logic2-analog",
180 #if SALEAE_WITH_SAL_SUPPORT
181         [FMT_LOGIC2_ARCHIVE] = "logic2-archive",
182 #endif
183 };
184
185 static const char *get_format_text(enum logic_format fmt)
186 {
187         const char *text;
188
189         if (fmt >= ARRAY_SIZE(format_texts))
190                 return NULL;
191         text = format_texts[fmt];
192         if (!text || !*text)
193                 return NULL;
194         return text;
195 }
196
197 static int create_channels(struct sr_input *in)
198 {
199         struct context *inc;
200         int type;
201         size_t count, idx;
202         char name[24];
203         struct sr_channel *ch;
204
205         inc = in->priv;
206
207         if (in->sdi->channels)
208                 return SR_OK;
209
210         count = inc->logic_state.channel_count;
211         switch (inc->logic_state.format) {
212         case FMT_LOGIC1_DIGITAL:
213         case FMT_LOGIC2_DIGITAL:
214                 type = SR_CHANNEL_LOGIC;
215                 break;
216         case FMT_LOGIC1_ANALOG:
217         case FMT_LOGIC2_ANALOG:
218                 type = SR_CHANNEL_ANALOG;
219                 break;
220         default:
221                 return SR_ERR_NA;
222         }
223
224         /* TODO Need to create a channel group? */
225         for (idx = 0; idx < count; idx++) {
226                 snprintf(name, sizeof(name), "%zu", idx);
227                 ch = sr_channel_new(in->sdi, idx, type, TRUE, name);
228                 if (!ch)
229                         return SR_ERR_MALLOC;
230         }
231
232         return SR_OK;
233 }
234
235 static int alloc_feed_buffer(struct sr_input *in)
236 {
237         struct context *inc;
238         size_t alloc_size;
239
240         inc = in->priv;
241
242         inc->feed.is_analog = FALSE;
243         alloc_size = CHUNK_SIZE;
244         switch (inc->logic_state.format) {
245         case FMT_LOGIC1_DIGITAL:
246         case FMT_LOGIC2_DIGITAL:
247                 inc->feed.unit_size = sizeof(inc->feed.last.digital);
248                 alloc_size /= inc->feed.unit_size;
249                 inc->feed.samples_per_chunk = alloc_size;
250                 alloc_size *= inc->feed.unit_size;
251                 inc->feed.buffer_digital = g_try_malloc(alloc_size);
252                 if (!inc->feed.buffer_digital)
253                         return SR_ERR_MALLOC;
254                 inc->feed.write_pos = inc->feed.buffer_digital;
255                 break;
256         case FMT_LOGIC1_ANALOG:
257         case FMT_LOGIC2_ANALOG:
258                 inc->feed.is_analog = TRUE;
259                 alloc_size /= sizeof(inc->feed.last.analog);
260                 inc->feed.samples_per_chunk = alloc_size;
261                 alloc_size *= sizeof(inc->feed.last.analog);
262                 inc->feed.buffer_analog = g_try_malloc(alloc_size);
263                 if (!inc->feed.buffer_analog)
264                         return SR_ERR_MALLOC;
265                 inc->feed.write_pos = (void *)inc->feed.buffer_analog;
266                 break;
267         default:
268                 return SR_ERR_NA;
269         }
270         inc->feed.samples_in_buffer = 0;
271
272         return SR_OK;
273 }
274
275 static int relse_feed_buffer(struct sr_input *in)
276 {
277         struct context *inc;
278
279         inc = in->priv;
280
281         inc->feed.is_analog = FALSE;
282         inc->feed.unit_size = 0;
283         inc->feed.samples_per_chunk = 0;
284         inc->feed.samples_in_buffer = 0;
285         g_free(inc->feed.buffer_digital);
286         inc->feed.buffer_digital = NULL;
287         g_free(inc->feed.buffer_analog);
288         inc->feed.buffer_analog = NULL;
289         inc->feed.write_pos = NULL;
290
291         return SR_OK;
292 }
293
294 static int setup_feed_buffer_channel(struct sr_input *in, size_t ch_idx)
295 {
296         struct context *inc;
297         struct sr_channel *ch;
298
299         inc = in->priv;
300
301         g_slist_free(inc->feed.channels);
302         inc->feed.channels = NULL;
303         if (ch_idx >= inc->logic_state.channel_count)
304                 return SR_OK;
305
306         ch = g_slist_nth_data(in->sdi->channels, ch_idx);
307         if (!ch)
308                 return SR_ERR_ARG;
309         inc->feed.channels = g_slist_append(NULL, ch);
310         return SR_OK;
311 }
312
313 static int flush_feed_buffer(struct sr_input *in)
314 {
315         struct context *inc;
316         struct sr_datafeed_packet packet;
317         struct sr_datafeed_logic logic;
318         struct sr_datafeed_analog analog;
319         struct sr_analog_encoding encoding;
320         struct sr_analog_meaning meaning;
321         struct sr_analog_spec spec;
322         int rc;
323
324         inc = in->priv;
325
326         if (!inc->feed.samples_in_buffer)
327                 return SR_OK;
328
329         /* Automatically send a datafeed header before meta and samples. */
330         if (!inc->module_state.header_sent) {
331                 rc = std_session_send_df_header(in->sdi);
332                 if (rc)
333                         return rc;
334                 inc->module_state.header_sent = TRUE;
335         }
336
337         /* Automatically send the samplerate (when available). */
338         if (inc->logic_state.sample_rate && !inc->module_state.rate_sent) {
339                 rc = sr_session_send_meta(in->sdi, SR_CONF_SAMPLERATE,
340                         g_variant_new_uint64(inc->logic_state.sample_rate));
341                 inc->module_state.rate_sent = TRUE;
342         }
343
344         /*
345          * Create a packet with either logic or analog payload. Rewind
346          * the caller's write position.
347          */
348         memset(&packet, 0, sizeof(packet));
349         if (inc->feed.is_analog) {
350                 /* TODO: Use proper 'digits' value for this input module. */
351                 sr_analog_init(&analog, &encoding, &meaning, &spec, 3);
352                 analog.data = inc->feed.buffer_analog;
353                 analog.num_samples = inc->feed.samples_in_buffer;
354                 analog.meaning->channels = inc->feed.channels;
355                 analog.meaning->mq = SR_MQ_VOLTAGE;
356                 analog.meaning->mqflags |= SR_MQFLAG_DC;
357                 analog.meaning->unit = SR_UNIT_VOLT;
358                 packet.type = SR_DF_ANALOG;
359                 packet.payload = &analog;
360                 inc->feed.write_pos = (void *)inc->feed.buffer_analog;
361         } else {
362                 memset(&logic, 0, sizeof(logic));
363                 logic.length = inc->feed.samples_in_buffer;
364                 logic.length *= inc->feed.unit_size;
365                 logic.unitsize = inc->feed.unit_size;
366                 logic.data = inc->feed.buffer_digital;
367                 packet.type = SR_DF_LOGIC;
368                 packet.payload = &logic;
369                 inc->feed.write_pos = inc->feed.buffer_digital;
370         }
371         inc->feed.samples_in_buffer = 0;
372
373         /* Send the packet to the session feed. */
374         return sr_session_send(in->sdi, &packet);
375 }
376
377 static int addto_feed_buffer_logic(struct sr_input *in,
378         uint64_t data, size_t count)
379 {
380         struct context *inc;
381
382         inc = in->priv;
383
384         if (inc->feed.is_analog)
385                 return SR_ERR_ARG;
386
387         while (count--) {
388                 if (inc->feed.unit_size == sizeof(uint64_t))
389                         write_u64le_inc(&inc->feed.write_pos, data);
390                 else if (inc->feed.unit_size == sizeof(uint32_t))
391                         write_u32le_inc(&inc->feed.write_pos, data);
392                 else if (inc->feed.unit_size == sizeof(uint16_t))
393                         write_u16le_inc(&inc->feed.write_pos, data);
394                 else if (inc->feed.unit_size == sizeof(uint8_t))
395                         write_u8_inc(&inc->feed.write_pos, data);
396                 else
397                         return SR_ERR_BUG;
398                 inc->feed.samples_in_buffer++;
399                 if (inc->feed.samples_in_buffer == inc->feed.samples_per_chunk)
400                         flush_feed_buffer(in);
401         }
402
403         return SR_OK;
404 }
405
406 static int addto_feed_buffer_analog(struct sr_input *in,
407         float data, size_t count)
408 {
409         struct context *inc;
410
411         inc = in->priv;
412
413         if (!inc->feed.is_analog)
414                 return SR_ERR_ARG;
415
416         while (count--) {
417                 if (sizeof(inc->feed.buffer_analog[0]) == sizeof(float))
418                         write_fltle_inc(&inc->feed.write_pos, data);
419                 else if (sizeof(inc->feed.buffer_analog[0]) == sizeof(double))
420                         write_dblle_inc(&inc->feed.write_pos, data);
421                 else
422                         return SR_ERR_BUG;
423                 inc->feed.samples_in_buffer++;
424                 if (inc->feed.samples_in_buffer == inc->feed.samples_per_chunk)
425                         flush_feed_buffer(in);
426         }
427
428         return SR_OK;
429 }
430
431 static enum logic_format check_format(const uint8_t *data, size_t dlen)
432 {
433         const char *s;
434         uint32_t v, t;
435
436         /* TODO
437          * Can we check ZIP content here in useful ways? Probably only
438          * when the input module got extended to optionally handle local
439          * file I/O, and passes some archive handle to this routine.
440          */
441
442         /* Check for the magic literal. */
443         s = (void *)data;
444         if (dlen < strlen(LOGIC2_MAGIC))
445                 return FMT_UNKNOWN;
446         if (strncmp(s, LOGIC2_MAGIC, strlen(LOGIC2_MAGIC)) != 0)
447                 return FMT_UNKNOWN;
448         data += strlen(LOGIC2_MAGIC);
449         dlen -= strlen(LOGIC2_MAGIC);
450
451         /* Get the version and type fields. */
452         if (dlen < 2 * sizeof(uint32_t))
453                 return FMT_UNKNOWN;
454         v = read_u32le_inc(&data);
455         t = read_u32le_inc(&data);
456         if (v != LOGIC2_VERSION)
457                 return FMT_UNKNOWN;
458         switch (t) {
459         case LOGIC2_TYPE_DIGITAL:
460                 return FMT_LOGIC2_DIGITAL;
461         case LOGIC2_TYPE_ANALOG:
462                 return FMT_LOGIC2_ANALOG;
463         default:
464                 return FMT_UNKNOWN;
465         }
466
467         return FMT_UNKNOWN;
468 }
469
470 /* Check for availability of required header data. */
471 static gboolean have_header(struct context *inc, GString *buf)
472 {
473
474         /*
475          * The amount of required data depends on the file format. Which
476          * either was specified before, or is yet to get determined. The
477          * input module ideally would apply a sequence of checks for the
478          * currently available (partial) data, access a few first header
479          * fields, before checking for a little more receive data, before
480          * accessing more fields, until the input file's type was found,
481          * and its header length is known, and can get checked.
482          *
483          * This simple implementation just assumes that any input file
484          * has at least a given number of bytes, which should not be an
485          * issue for typical use cases. Only extremely short yet valid
486          * input files with just a few individual samples may fail this
487          * check. It's assumed that these files are very rare, and may
488          * be of types which are covered by other input modules (raw
489          * binary).
490          */
491         (void)inc;
492         return buf->len >= LOGIC2_MIN_SIZE;
493 }
494
495 /* Process/inspect previously received input data. Get header parameters. */
496 static int parse_header(struct sr_input *in)
497 {
498         struct context *inc;
499         const uint8_t *read_pos, *start_pos;
500         size_t read_len, want_len;
501         uint64_t samples_per_channel;
502         size_t channel_count;
503         double sample_period;
504         uint64_t sample_rate;
505
506         inc = in->priv;
507         read_pos = (const uint8_t *)in->buf->str;
508         read_len = in->buf->len;
509
510         /*
511          * Clear internal state. Normalize user specified option values
512          * before amending them from the input file's header information.
513          */
514         memset(&inc->logic_state, 0, sizeof(inc->logic_state));
515         inc->logic_state.format = inc->options.format;
516         inc->logic_state.when_changed = inc->options.when_changed;
517         inc->logic_state.word_size = inc->options.word_size;
518         if (!inc->logic_state.word_size) {
519                 sr_err("Need a word size.");
520                 return SR_ERR_ARG;
521         }
522         inc->logic_state.word_size += 8 - 1;
523         inc->logic_state.word_size /= 8; /* Sample width in bytes. */
524         if (inc->logic_state.word_size > sizeof(inc->feed.last.digital)) {
525                 sr_err("Excessive word size %zu.", inc->logic_state.word_size);
526                 return SR_ERR_ARG;
527         }
528         inc->logic_state.channel_count = inc->options.channel_count;
529         inc->logic_state.sample_rate = inc->options.sample_rate;
530         if (inc->logic_state.format == FMT_AUTO_DETECT)
531                 inc->logic_state.stage = STAGE_ALL_DETECT_TYPE;
532         else
533                 inc->logic_state.stage = STAGE_ALL_READ_HEADER;
534
535         /*
536          * Optionally auto-detect the format if none was specified yet.
537          * This only works for some of the supported formats. ZIP support
538          * requires local I/O in the input module (won't work on memory
539          * buffers).
540          */
541         if (inc->logic_state.stage == STAGE_ALL_DETECT_TYPE) {
542                 inc->logic_state.format = check_format(read_pos, read_len);
543                 if (inc->logic_state.format == FMT_UNKNOWN) {
544                         sr_err("Unknown or unsupported file format.");
545                         return SR_ERR_DATA;
546                 }
547                 sr_info("Detected file format: '%s'.",
548                         get_format_text(inc->logic_state.format));
549                 inc->logic_state.stage = STAGE_ALL_READ_HEADER;
550         }
551
552         /*
553          * Read the header fields, depending on the specific file format.
554          * Arrange for the subsequent inspection of sample data items.
555          */
556         start_pos = read_pos;
557         switch (inc->logic_state.format) {
558         case FMT_LOGIC1_DIGITAL:
559                 channel_count = inc->logic_state.channel_count;
560                 if (!channel_count) {
561                         channel_count = inc->logic_state.word_size;
562                         channel_count *= 8;
563                         inc->logic_state.channel_count = channel_count;
564                 }
565                 /* EMPTY */ /* No header fields to read here. */
566                 sr_dbg("L1D, empty header, changed %d.",
567                         inc->logic_state.when_changed ? 1 : 0);
568                 if (inc->logic_state.when_changed)
569                         inc->logic_state.stage = STAGE_L1D_CHANGE_INIT;
570                 else
571                         inc->logic_state.stage = STAGE_L1D_EVERY_VALUE;
572                 break;
573         case FMT_LOGIC1_ANALOG:
574                 want_len = sizeof(uint64_t) + sizeof(uint32_t) + sizeof(double);
575                 if (read_len < want_len)
576                         return SR_ERR_DATA;
577                 samples_per_channel = read_u64le_inc(&read_pos);
578                 channel_count = read_u32le_inc(&read_pos);
579                 sample_period = read_dblle_inc(&read_pos);
580                 inc->logic_state.l1a.samples_per_channel = samples_per_channel;
581                 inc->logic_state.channel_count = channel_count;
582                 sample_rate = 0;
583                 if (sample_period) {
584                         sample_period = 1.0 / sample_period;
585                         sample_period += 0.5;
586                         sample_rate = (uint64_t)sample_period;
587                         inc->logic_state.sample_rate = sample_rate;
588                 }
589                 sr_dbg("L1A header, smpls %zu, chans %zu, per %lf, rate %zu.",
590                         (size_t)samples_per_channel, (size_t)channel_count,
591                         sample_period, (size_t)sample_rate);
592                 inc->logic_state.stage = STAGE_L1A_NEW_CHANNEL;
593                 inc->logic_state.l1a.current_channel_idx = 0;
594                 inc->logic_state.l1a.current_per_channel = 0;
595                 break;
596         case FMT_LOGIC2_DIGITAL:
597                 inc->logic_state.channel_count = 1;
598                 want_len = sizeof(uint64_t); /* magic */
599                 want_len += 2 * sizeof(uint32_t); /* version, type */
600                 want_len += sizeof(uint32_t); /* initial state */
601                 want_len += 2 * sizeof(double); /* begin time, end time */
602                 want_len += sizeof(uint64_t); /* transition count */
603                 if (read_len < want_len)
604                         return SR_ERR_DATA;
605                 if (check_format(read_pos, read_len) != FMT_LOGIC2_DIGITAL)
606                         return SR_ERR_DATA;
607                 (void)read_u64le_inc(&read_pos);
608                 (void)read_u32le_inc(&read_pos);
609                 (void)read_u32le_inc(&read_pos);
610                 inc->logic_state.l2d.init_state = read_u32le_inc(&read_pos);
611                 inc->logic_state.l2d.begin_time = read_dblle_inc(&read_pos);
612                 inc->logic_state.l2d.end_time = read_dblle_inc(&read_pos);
613                 inc->logic_state.l2d.transition_count = read_u64le_inc(&read_pos);
614                 sr_dbg("L2D header, init %u, begin %lf, end %lf, transitions %" PRIu64 ".",
615                         (unsigned)inc->logic_state.l2d.init_state,
616                         inc->logic_state.l2d.begin_time,
617                         inc->logic_state.l2d.end_time,
618                         inc->logic_state.l2d.transition_count);
619                 if (!inc->logic_state.sample_rate) {
620                         sr_err("Need a samplerate.");
621                         return SR_ERR_ARG;
622                 }
623                 inc->feed.last.time = inc->logic_state.l2d.begin_time;
624                 inc->feed.last.digital = inc->logic_state.l2d.init_state ? 1 : 0;
625                 inc->logic_state.l2d.sample_period = inc->logic_state.sample_rate;
626                 inc->logic_state.l2d.sample_period = 1.0 / inc->logic_state.l2d.sample_period;
627                 inc->logic_state.l2d.min_time_step = inc->logic_state.l2d.end_time;
628                 inc->logic_state.l2d.min_time_step -= inc->logic_state.l2d.begin_time;
629                 inc->logic_state.stage = STAGE_L2D_CHANGE_VALUE;
630                 break;
631         case FMT_LOGIC2_ANALOG:
632                 inc->logic_state.channel_count = 1;
633                 want_len = sizeof(uint64_t); /* magic */
634                 want_len += 2 * sizeof(uint32_t); /* version, type */
635                 want_len += sizeof(double); /* begin time */
636                 want_len += 2 * sizeof(uint64_t); /* sample rate, down sample */
637                 want_len += sizeof(uint64_t); /* sample count */
638                 if (read_len < want_len)
639                         return SR_ERR_DATA;
640                 if (check_format(read_pos, read_len) != FMT_LOGIC2_ANALOG)
641                         return SR_ERR_DATA;
642                 (void)read_u64le_inc(&read_pos);
643                 (void)read_u32le_inc(&read_pos);
644                 (void)read_u32le_inc(&read_pos);
645                 inc->logic_state.l2a.begin_time = read_dblle_inc(&read_pos);
646                 inc->logic_state.l2a.sample_rate = read_u64le_inc(&read_pos);
647                 inc->logic_state.l2a.down_sample = read_u64le_inc(&read_pos);
648                 inc->logic_state.l2a.sample_count = read_u64le_inc(&read_pos);
649                 if (!inc->logic_state.sample_rate)
650                         inc->logic_state.sample_rate = inc->logic_state.l2a.sample_rate;
651                 sr_dbg("L2A header, begin %lf, rate %" PRIu64 ", down %" PRIu64 ", samples %" PRIu64 ".",
652                         inc->logic_state.l2a.begin_time,
653                         inc->logic_state.l2a.sample_rate,
654                         inc->logic_state.l2a.down_sample,
655                         inc->logic_state.l2a.sample_count);
656                 inc->feed.last.time = inc->logic_state.l2a.begin_time;
657                 inc->logic_state.stage = STAGE_L2A_FIRST_VALUE;
658                 break;
659         case FMT_LOGIC2_ARCHIVE:
660                 sr_err("Support for .sal archives not implemented yet.");
661                 return SR_ERR_NA;
662         default:
663                 sr_err("Unknown or unsupported file format.");
664                 return SR_ERR_NA;
665         }
666
667         /* Remove the consumed header fields from the receive buffer. */
668         read_len = read_pos - start_pos;
669         g_string_erase(in->buf, 0, read_len);
670
671         return SR_OK;
672 }
673
674 /* Check availablity of the next sample data item. */
675 static gboolean have_next_item(struct sr_input *in,
676         const uint8_t *buff, size_t blen,
677         const uint8_t **curr, const uint8_t **next)
678 {
679         struct context *inc;
680         size_t want_len;
681         const uint8_t *pos;
682
683         inc = in->priv;
684         if (curr)
685                 *curr = NULL;
686         if (next)
687                 *next = NULL;
688
689         /*
690          * The amount of required data depends on the file format and
691          * the current state. Wait for the availabilty of the desired
692          * data before processing it (to simplify data inspection
693          * code paths).
694          */
695         switch (inc->logic_state.stage) {
696         case STAGE_L1D_EVERY_VALUE:
697                 want_len = inc->logic_state.word_size;
698                 break;
699         case STAGE_L1D_CHANGE_INIT:
700         case STAGE_L1D_CHANGE_VALUE:
701                 want_len = sizeof(uint64_t);
702                 want_len += inc->logic_state.word_size;
703                 break;
704         case STAGE_L1A_NEW_CHANNEL:
705                 want_len = 0;
706                 break;
707         case STAGE_L1A_SAMPLE:
708                 want_len = sizeof(float);
709                 break;
710         case STAGE_L2D_CHANGE_VALUE:
711                 want_len = sizeof(double);
712                 break;
713         case STAGE_L2A_FIRST_VALUE:
714         case STAGE_L2A_EVERY_VALUE:
715                 want_len = sizeof(float);
716                 break;
717         default:
718                 return FALSE;
719         }
720         if (blen < want_len)
721                 return FALSE;
722
723         /* Provide references to the next item, and the position after it. */
724         pos = buff;
725         if (curr)
726                 *curr = pos;
727         pos += want_len;
728         if (next)
729                 *next = pos;
730         return TRUE;
731 }
732
733 /* Process the next sample data item after it became available. */
734 static int parse_next_item(struct sr_input *in,
735         const uint8_t *curr, size_t len)
736 {
737         struct context *inc;
738         uint64_t next_stamp, count;
739         uint64_t digital;
740         float analog;
741         double next_time, diff_time;
742         int rc;
743
744         inc = in->priv;
745         (void)len;
746
747         /*
748          * The specific item to get processed next depends on the file
749          * format and current state.
750          */
751         switch (inc->logic_state.stage) {
752         case STAGE_L1D_CHANGE_INIT:
753         case STAGE_L1D_CHANGE_VALUE:
754                 next_stamp = read_u64le_inc(&curr);
755                 if (inc->logic_state.stage == STAGE_L1D_CHANGE_INIT) {
756                         inc->feed.last.stamp = next_stamp;
757                         inc->logic_state.stage = STAGE_L1D_CHANGE_VALUE;
758                 }
759                 count = next_stamp - inc->feed.last.stamp;
760                 digital = inc->feed.last.digital;
761                 rc = addto_feed_buffer_logic(in, digital, count);
762                 if (rc)
763                         return rc;
764                 inc->feed.last.stamp = next_stamp - 1;
765                 /* FALLTHROUGH */
766         case STAGE_L1D_EVERY_VALUE:
767                 if (inc->logic_state.word_size == sizeof(uint8_t)) {
768                         digital = read_u8_inc(&curr);
769                 } else if (inc->logic_state.word_size == sizeof(uint16_t)) {
770                         digital = read_u16le_inc(&curr);
771                 } else if (inc->logic_state.word_size == sizeof(uint32_t)) {
772                         digital = read_u32le_inc(&curr);
773                 } else if (inc->logic_state.word_size == sizeof(uint64_t)) {
774                         digital = read_u64le_inc(&curr);
775                 } else {
776                         /*
777                          * In theory the sigrok input module could support
778                          * arbitrary word sizes, but the Saleae exporter
779                          * only provides the 8/16/32/64 choices anyway.
780                          */
781                         sr_err("Unsupported word size %zu.", inc->logic_state.word_size);
782                         return SR_ERR_ARG;
783                 }
784                 rc = addto_feed_buffer_logic(in, digital, 1);
785                 if (rc)
786                         return rc;
787                 inc->feed.last.digital = digital;
788                 inc->feed.last.stamp++;
789                 return SR_OK;
790         case STAGE_L1A_NEW_CHANNEL:
791                 /* Just select the channel. Don't consume any data. */
792                 rc = setup_feed_buffer_channel(in, inc->logic_state.l1a.current_channel_idx);
793                 if (rc)
794                         return rc;
795                 inc->logic_state.l1a.current_channel_idx++;
796                 inc->logic_state.l1a.current_per_channel = 0;
797                 inc->logic_state.stage = STAGE_L1A_SAMPLE;
798                 return SR_OK;
799         case STAGE_L1A_SAMPLE:
800                 analog = read_fltle_inc(&curr);
801                 rc = addto_feed_buffer_analog(in, analog, 1);
802                 if (rc)
803                         return rc;
804                 inc->logic_state.l1a.current_per_channel++;
805                 if (inc->logic_state.l1a.current_channel_idx == inc->logic_state.l1a.samples_per_channel)
806                         inc->logic_state.stage = STAGE_L1A_NEW_CHANNEL;
807                 return SR_OK;
808         case STAGE_L2D_CHANGE_VALUE:
809                 next_time = read_dblle_inc(&curr);
810                 diff_time = next_time - inc->feed.last.time;
811                 if (inc->logic_state.l2d.min_time_step > diff_time)
812                         inc->logic_state.l2d.min_time_step = diff_time;
813                 diff_time /= inc->logic_state.l2d.sample_period;
814                 diff_time += 0.5;
815                 count = (uint64_t)diff_time;
816                 if (count) {
817                         digital = inc->feed.last.digital;
818                         rc = addto_feed_buffer_logic(in, digital, count);
819                         if (rc)
820                                 return rc;
821                         inc->feed.last.time = next_time;
822                 }
823                 inc->feed.last.digital = 1 - inc->feed.last.digital;
824                 return SR_OK;
825         case STAGE_L2A_FIRST_VALUE:
826         case STAGE_L2A_EVERY_VALUE:
827                 analog = read_fltle_inc(&curr);
828                 if (inc->logic_state.stage == STAGE_L2A_FIRST_VALUE) {
829                         rc = setup_feed_buffer_channel(in, 0);
830                         if (rc)
831                                 return rc;
832                         count = 1;
833                 } else {
834                         count = inc->logic_state.l2a.down_sample;
835                 }
836                 rc = addto_feed_buffer_analog(in, analog, 1);
837                 if (rc)
838                         return rc;
839                 return SR_OK;
840
841         default:
842                 (void)analog;
843                 return SR_ERR_NA;
844         }
845         /* UNREACH */
846 }
847
848 static int parse_samples(struct sr_input *in)
849 {
850         const uint8_t *buff, *start;
851         size_t blen;
852
853         const uint8_t *curr, *next;
854         size_t len;
855         int rc;
856
857         start = (const uint8_t *)in->buf->str;
858         buff = start;
859         blen = in->buf->len;
860         while (have_next_item(in, buff, blen, &curr, &next)) {
861                 len = next - curr;
862                 rc = parse_next_item(in, curr, len);
863                 if (rc)
864                         return rc;
865                 buff += len;
866                 blen -= len;
867         }
868         len = buff - start;
869         g_string_erase(in->buf, 0, len);
870
871         return SR_OK;
872 }
873
874 /*
875  * Try to auto detect an input's file format. Mismatch is non-fatal.
876  * Silent operation by design. Not all details need to be available.
877  * Get the strongest possible match in a best-effort manner.
878  *
879  * TODO Extend the .sal check when local file I/O becomes available.
880  * File extensions can lie, and need not be available. Check for a
881  * ZIP archive and the meta.json member in it.
882  */
883 static int format_match(GHashTable *metadata, unsigned int *confidence)
884 {
885         static const char *zip_ext = ".sal";
886         static const char *bin_ext = ".bin";
887
888         gboolean matched;
889         const char *fn;
890         size_t fn_len, ext_len;
891         const char *ext_pos;
892         GString *buf;
893
894         matched = FALSE;
895
896         /* Weak match on the filename (when available). */
897         fn = g_hash_table_lookup(metadata, GINT_TO_POINTER(SR_INPUT_META_FILENAME));
898         if (fn && *fn) {
899                 fn_len = strlen(fn);
900                 ext_len = strlen(zip_ext);
901                 ext_pos = &fn[fn_len - ext_len];
902                 if (fn_len >= ext_len && g_ascii_strcasecmp(ext_pos, zip_ext) == 0) {
903                         if (SALEAE_WITH_SAL_SUPPORT) {
904                                 *confidence = 10;
905                                 matched = TRUE;
906                         }
907                 }
908                 ext_len = strlen(bin_ext);
909                 ext_pos = &fn[fn_len - ext_len];
910                 if (fn_len >= ext_len && g_ascii_strcasecmp(ext_pos, bin_ext) == 0) {
911                         *confidence = 50;
912                         matched = TRUE;
913                 }
914         }
915
916         /* Stronger match when magic literals are found in file content. */
917         buf = g_hash_table_lookup(metadata, GINT_TO_POINTER(SR_INPUT_META_HEADER));
918         if (!buf || !buf->len || !buf->str)
919                 return SR_ERR_ARG;
920         switch (check_format((const uint8_t *)buf->str, buf->len)) {
921         case FMT_LOGIC2_DIGITAL:
922         case FMT_LOGIC2_ANALOG:
923                 *confidence = 1;
924                 matched = TRUE;
925                 break;
926         default:
927                 /* EMPTY */
928                 break;
929         }
930
931         return matched ? SR_OK : SR_ERR_DATA;
932 }
933
934 static int init(struct sr_input *in, GHashTable *options)
935 {
936         struct context *inc;
937         const char *type, *fmt_text;
938         enum logic_format format, fmt_idx;
939         gboolean changed;
940         size_t size, count;
941         uint64_t rate;
942
943         /* Allocate resources. */
944         in->sdi = g_malloc0(sizeof(*in->sdi));
945         inc = g_malloc0(sizeof(*inc));
946         in->priv = inc;
947
948         /* Get caller provided specs, dump before check. */
949         type = g_variant_get_string(g_hash_table_lookup(options, "format"), NULL);
950         changed = g_variant_get_boolean(g_hash_table_lookup(options, "changed"));
951         size = g_variant_get_uint32(g_hash_table_lookup(options, "wordsize"));
952         count = g_variant_get_uint32(g_hash_table_lookup(options, "logic_channels"));
953         rate = g_variant_get_uint64(g_hash_table_lookup(options, "samplerate"));
954         sr_dbg("Caller options: type '%s', changed %d, wordsize %zu, channels %zu, rate %" PRIu64 ".",
955                 type, changed ? 1 : 0, size, count, rate);
956
957         /* Run a few simple checks. Normalization is done in .init(). */
958         format = FMT_UNKNOWN;
959         for (fmt_idx = FMT_AUTO_DETECT; fmt_idx < ARRAY_SIZE(format_texts); fmt_idx++) {
960                 fmt_text = format_texts[fmt_idx];
961                 if (!fmt_text || !*fmt_text)
962                         continue;
963                 if (g_ascii_strcasecmp(type, fmt_text) != 0)
964                         continue;
965                 format = fmt_idx;
966                 break;
967         }
968         if (format == FMT_UNKNOWN) {
969                 sr_err("Unknown file type name: '%s'.", type);
970                 return SR_ERR_ARG;
971         }
972         if (!size) {
973                 sr_err("Need a word size.");
974                 return SR_ERR_ARG;
975         }
976
977         /*
978          * Keep input specs around. We never get back to .init() even
979          * when input files are re-read later.
980          */
981         inc->options.format = format;
982         inc->options.when_changed = !!changed;
983         inc->options.word_size = size;
984         inc->options.channel_count = count;
985         inc->options.sample_rate = rate;
986         sr_dbg("Resulting options: type '%s', changed %d",
987                 get_format_text(format), changed ? 1 : 0);
988
989         return SR_OK;
990 }
991
992 static int receive(struct sr_input *in, GString *buf)
993 {
994         struct context *inc;
995         int rc;
996         const char *text;
997
998         inc = in->priv;
999
1000         /* Accumulate another chunk of input data. */
1001         g_string_append_len(in->buf, buf->str, buf->len);
1002
1003         /*
1004          * Wait for the full header's availability, then process it in
1005          * a single call, and set the "ready" flag. Make sure sample data
1006          * and the header get processed in disjoint receive() calls, the
1007          * backend requires those separate phases.
1008          */
1009         if (!inc->module_state.got_header) {
1010                 if (!have_header(inc, in->buf))
1011                         return SR_OK;
1012                 rc = parse_header(in);
1013                 if (rc)
1014                         return rc;
1015                 inc->module_state.got_header = TRUE;
1016                 text = get_format_text(inc->logic_state.format) ? : "<unknown>";
1017                 sr_info("Using file format: '%s'.", text);
1018                 rc = create_channels(in);
1019                 if (rc)
1020                         return rc;
1021                 rc = alloc_feed_buffer(in);
1022                 if (rc)
1023                         return rc;
1024                 in->sdi_ready = TRUE;
1025                 return SR_OK;
1026         }
1027
1028         /* Process sample data, after the header got processed. */
1029         return parse_samples(in);
1030 }
1031
1032 static int end(struct sr_input *in)
1033 {
1034         struct context *inc;
1035         int rc;
1036
1037         /* Nothing to do here if we never started feeding the session. */
1038         if (!in->sdi_ready)
1039                 return SR_OK;
1040
1041         /*
1042          * Process input data which may not have been inspected before.
1043          * Flush any potentially queued samples.
1044          */
1045         rc = parse_samples(in);
1046         if (rc)
1047                 return rc;
1048         rc = flush_feed_buffer(in);
1049         if (rc)
1050                 return rc;
1051
1052         /* End the session feed if one was started. */
1053         inc = in->priv;
1054         if (inc->module_state.header_sent) {
1055                 rc = std_session_send_df_end(in->sdi);
1056                 if (rc)
1057                         return rc;
1058                 inc->module_state.header_sent = FALSE;
1059         }
1060
1061         /* Input data shall be exhausted by now. Non-fatal condition. */
1062         if (in->buf->len)
1063                 sr_warn("Unprocessed remaining input: %zu bytes.", in->buf->len);
1064
1065         return SR_OK;
1066 }
1067
1068 static void cleanup(struct sr_input *in)
1069 {
1070         struct context *inc;
1071         struct context_options save_opts;
1072         GSList *save_channels;
1073
1074         if (!in)
1075                 return;
1076         inc = in->priv;
1077         if (!inc)
1078                 return;
1079
1080         /* Keep references to previously created channels. */
1081         g_slist_free_full(inc->module_state.prev_channels, sr_channel_free_cb);
1082         inc->module_state.prev_channels = in->sdi->channels;
1083         in->sdi->channels = NULL;
1084
1085         /* Release dynamically allocated resources. */
1086         relse_feed_buffer(in);
1087
1088         /* Clear internal state, but keep what .init() has provided. */
1089         save_opts = inc->options;
1090         save_channels = inc->module_state.prev_channels;
1091         memset(inc, 0, sizeof(*inc));
1092         inc->options = save_opts;
1093         inc->module_state.prev_channels = save_channels;
1094 }
1095
1096 static int reset(struct sr_input *in)
1097 {
1098         struct context *inc;
1099
1100         inc = in->priv;
1101
1102         /*
1103          * The input module's .reset() routine clears the 'inc' context.
1104          * But 'in' is kept which contains channel groups which reference
1105          * channels. We cannot re-create the channels, since applications
1106          * still reference them and expect us to keep them. The .cleanup()
1107          * routine also keeps the user specified option values, the module
1108          * will derive internal state again when the input gets re-read.
1109          */
1110         cleanup(in);
1111         in->sdi->channels = inc->module_state.prev_channels;
1112         inc->module_state.prev_channels = NULL;
1113
1114         inc->module_state.got_header = FALSE;
1115         inc->module_state.header_sent = FALSE;
1116         inc->module_state.rate_sent = FALSE;
1117         g_string_truncate(in->buf, 0);
1118
1119         return SR_OK;
1120 }
1121
1122 enum option_index {
1123         OPT_FMT_TYPE,
1124         OPT_CHANGE,
1125         OPT_WORD_SIZE,
1126         OPT_NUM_LOGIC,
1127         OPT_SAMPLERATE,
1128         OPT_MAX,
1129 };
1130
1131 static struct sr_option options[] = {
1132         [OPT_FMT_TYPE] = {
1133                 "format", "File format.",
1134                 "Type of input file format. Not all types can get auto-detected.",
1135                 NULL, NULL,
1136         },
1137         [OPT_CHANGE] = {
1138                 "changed", "Save when changed.",
1139                 "Sample value was saved when changed (in contrast to: every sample).",
1140                 NULL, NULL,
1141         },
1142         [OPT_WORD_SIZE] = {
1143                 "wordsize", "Word size.",
1144                 "The number of bits per set of samples for digital data.",
1145                 NULL, NULL,
1146         },
1147         [OPT_NUM_LOGIC] = {
1148                 "logic_channels", "Channel count.",
1149                 "The number of digital channels. Word size is used when not specified.",
1150                 NULL, NULL,
1151         },
1152         [OPT_SAMPLERATE] = {
1153                 "samplerate", "Samplerate.",
1154                 "The samplerate. Needed when the file content lacks this information.",
1155                 NULL, NULL,
1156         },
1157         [OPT_MAX] = ALL_ZERO,
1158 };
1159
1160 static const struct sr_option *get_options(void)
1161 {
1162         enum logic_format fmt_idx;
1163         const char *fmt_text;
1164         size_t word_size;
1165         GSList *l;
1166
1167         /* Been here before? Already assigned default values? */
1168         if (options[0].def)
1169                 return options;
1170
1171         /* Assign default values, and list choices to select from. */
1172         fmt_text = format_texts[FMT_AUTO_DETECT];
1173         options[OPT_FMT_TYPE].def = g_variant_ref_sink(g_variant_new_string(fmt_text));
1174         l = NULL;
1175         for (fmt_idx = FMT_AUTO_DETECT; fmt_idx < ARRAY_SIZE(format_texts); fmt_idx++) {
1176                 fmt_text = format_texts[fmt_idx];
1177                 if (!fmt_text || !*fmt_text)
1178                         continue;
1179                 l = g_slist_append(l, g_variant_ref_sink(g_variant_new_string(fmt_text)));
1180         }
1181         options[OPT_FMT_TYPE].values = l;
1182         options[OPT_CHANGE].def = g_variant_ref_sink(g_variant_new_boolean(FALSE));
1183         options[OPT_WORD_SIZE].def = g_variant_ref_sink(g_variant_new_uint32(8));
1184         l = NULL;
1185         for (word_size = sizeof(uint8_t); word_size <= sizeof(uint64_t); word_size *= 2)
1186                 l = g_slist_append(l, g_variant_ref_sink(g_variant_new_uint32(8 * word_size)));
1187         options[OPT_WORD_SIZE].values = l;
1188         options[OPT_NUM_LOGIC].def = g_variant_ref_sink(g_variant_new_uint32(0));
1189         options[OPT_SAMPLERATE].def = g_variant_ref_sink(g_variant_new_uint64(0));
1190
1191         return options;
1192 }
1193
1194 SR_PRIV struct sr_input_module input_saleae = {
1195         .id = "saleae",
1196         .name = "Saleae",
1197 #if SALEAE_WITH_SAL_SUPPORT
1198         .desc = "Saleae Logic software export/save files",
1199         .exts = (const char *[]){"bin", "sal", NULL},
1200 #else
1201         .desc = "Saleae Logic software export files",
1202         .exts = (const char *[]){"bin", NULL},
1203 #endif
1204         .metadata = {
1205                 SR_INPUT_META_FILENAME,
1206                 SR_INPUT_META_HEADER | SR_INPUT_META_REQUIRED
1207         },
1208         .options = get_options,
1209         .format_match = format_match,
1210         .init = init,
1211         .receive = receive,
1212         .end = end,
1213         .cleanup = cleanup,
1214         .reset = reset,
1215 };