1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2018 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 LA1034 vendor's http://www.pctestinstruments.com/ website.
22  *
23  * The hardware comes with (Windows only) software which uses the .lpf
24  * ("LogicPort File") filename extension for project files, which hold
25  * both the configuration as well as sample data (up to 2K samples). In
26  * the absence of an attached logic analyzer, the software provides a
27  * demo mode which generates random input signals. The software installs
28  * example project files (with samples), too.
29  *
30  * The file format is "mostly text", is line oriented, though it uses
31  * funny DC1 separator characters as well as line continuation by means
32  * of a combination of DC1 and slashes. Fortunately the last text line
33  * is terminated by means of CRLF.
34  *
35  * The software is rather complex and has features which don't easily
36  * translate to sigrok semantics (like one signal being a member of
37  * multiple groups, display format specs for groups' values).
38  *
39  * This input module implementation supports the following features:
40  * - input format auto detection
41  * - sample period to sample rate conversion
42  * - wire names, acquisition filters ("enabled") and inversion flags
43  * - decompression (repetition counters for sample data)
44  * - strict '0' and '1' levels (as well as ignoring 'U' values)
45  * - signal names (user assigned names, "aliases" for "wires")
46  * - signal groups (no support for multiple assignments, no support for
47  *   display format specs)
48  * - "logic" channels (mere bits, no support for analog channels, also
49  *   nothing analog "gets derived from" any signal groups) -- libsigrok
50  *   using applications might provide such a feature if they want to
51  */
52 
53 #include <config.h>
54 #include <ctype.h>
55 #include <glib.h>
56 #include <stdint.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <unistd.h>
60 #include <libsigrok/libsigrok.h>
61 #include "libsigrok-internal.h"
62 
63 /* TODO: Move these helpers to some library API routine group. */
64 struct sr_channel_group *sr_channel_group_new(const char *name, void *priv);
65 void sr_channel_group_free(struct sr_channel_group *cg);
66 
67 #define LOG_PREFIX	"input/logicport"
68 
69 #define MAX_CHANNELS	34
70 #define CHUNK_SIZE	(4 * 1024 * 1024)
71 
72 #define CRLF		"\r\n"
73 #define DC1_CHR		'\x11'
74 #define DC1_STR		"\x11"
75 #define CONT_OPEN	"/" DC1_STR
76 #define CONT_CLOSE	DC1_STR "/"
77 
78 /*
79  * This is some heuristics (read: a HACK). The current implementation
80  * neither processes nor displays the user's notes, but takes their
81  * presence as a hint that all relevant input was seen, and sample data
82  * can get forwarded to the session bus.
83  */
84 #define LAST_KEYWORD	"NotesString"
85 
86 /*
87  * The vendor software supports signal groups, and a single signal can
88  * be a member in multiple groups at the same time. The sigrok project
89  * does not support that configuration. Let's ignore the "All Signals"
90  * group by default, thus reducing the probability of a conflict.
91  */
92 #define SKIP_SIGNAL_GROUP	"All Signals"
93 
94 struct signal_group_desc {
95 	char *name;
96 	uint64_t mask;
97 };
98 
99 struct context {
100 	gboolean got_header;
101 	gboolean ch_feed_prep;
102 	gboolean header_sent;
103 	gboolean rate_sent;
104 	char *sw_version;
105 	size_t sw_build;
106 	GString *cont_buff;
107 	size_t channel_count;
108 	size_t sample_lines_total;
109 	size_t sample_lines_read;
110 	size_t sample_lines_fed;
111 	uint64_t samples_got_uncomp;
112 	enum {
113 		SAMPLEDATA_NONE,
114 		SAMPLEDATA_OPEN_BRACE,
115 		SAMPLEDATA_WIRES_COUNT,
116 		SAMPLEDATA_DATA_LINES,
117 		SAMPLEDATA_CLOSE_BRACE,
118 	} in_sample_data;
119 	struct sample_data_entry {
120 		uint64_t bits;
121 		size_t repeat;
122 	} *sample_data_queue;
123 	uint64_t sample_rate;
124 	uint64_t wires_all_mask;
125 	uint64_t wires_enabled;
126 	uint64_t wires_inverted;
127 	uint64_t wires_undefined;
128 	char *wire_names[MAX_CHANNELS];
129 	char *signal_names[MAX_CHANNELS];
130 	uint64_t wires_grouped;
131 	GSList *signal_groups;
132 	GSList *channels;
133 	size_t unitsize;
134 	size_t samples_per_chunk;
135 	size_t samples_in_buffer;
136 	uint8_t *feed_buffer;
137 };
138 
alloc_signal_group(const char * name)139 static struct signal_group_desc *alloc_signal_group(const char *name)
140 {
141 	struct signal_group_desc *desc;
142 
143 	desc = g_malloc0(sizeof(*desc));
144 	if (name)
145 		desc->name = g_strdup(name);
146 
147 	return desc;
148 }
149 
free_signal_group(struct signal_group_desc * desc)150 static void free_signal_group(struct signal_group_desc *desc)
151 {
152 	if (!desc)
153 		return;
154 	g_free(desc->name);
155 	g_free(desc);
156 }
157 
sr_channel_group_new(const char * name,void * priv)158 struct sr_channel_group *sr_channel_group_new(const char *name, void *priv)
159 {
160 	struct sr_channel_group *cg;
161 
162 	cg = g_malloc0(sizeof(*cg));
163 	if (name && *name)
164 		cg->name = g_strdup(name);
165 	cg->priv = priv;
166 
167 	return cg;
168 }
169 
sr_channel_group_free(struct sr_channel_group * cg)170 void sr_channel_group_free(struct sr_channel_group *cg)
171 {
172 	if (!cg)
173 		return;
174 	g_free(cg->name);
175 	g_slist_free(cg->channels);
176 }
177 
178 /* Wrapper for GDestroyNotify compatibility. */
sg_free(void * p)179 static void sg_free(void *p)
180 {
181 	return free_signal_group(p);
182 }
183 
check_vers_line(char * line,int need_key,gchar ** version,gchar ** build)184 static int check_vers_line(char *line, int need_key,
185 	gchar **version, gchar **build)
186 {
187 	static const char *keyword = "Version";
188 	static const char *caution = " CAUTION: Do not change the contents of this file.";
189 	char *read_ptr;
190 	const char *prev_ptr;
191 
192 	read_ptr = line;
193 	if (version)
194 		*version = NULL;
195 	if (build)
196 		*build = NULL;
197 
198 	/* Expect the 'Version' literal, followed by a DC1 separator. */
199 	if (need_key) {
200 		if (strncmp(read_ptr, keyword, strlen(keyword)) != 0)
201 			return SR_ERR_DATA;
202 		read_ptr += strlen(keyword);
203 		if (*read_ptr != DC1_CHR)
204 			return SR_ERR_DATA;
205 		read_ptr++;
206 	}
207 
208 	/* Expect some "\d+\.\d+" style version string and DC1. */
209 	if (!*read_ptr)
210 		return SR_ERR_DATA;
211 	if (version)
212 		*version = read_ptr;
213 	prev_ptr = read_ptr;
214 	read_ptr += strspn(read_ptr, "0123456789.");
215 	if (read_ptr == prev_ptr)
216 		return SR_ERR_DATA;
217 	if (*read_ptr != DC1_CHR)
218 		return SR_ERR_DATA;
219 	*read_ptr++ = '\0';
220 
221 	/* Expect some "\d+" style build number and DC1. */
222 	if (!*read_ptr)
223 		return SR_ERR_DATA;
224 	if (build)
225 		*build = read_ptr;
226 	prev_ptr = read_ptr;
227 	read_ptr += strspn(read_ptr, "0123456789");
228 	if (read_ptr == prev_ptr)
229 		return SR_ERR_DATA;
230 	if (*read_ptr != DC1_CHR)
231 		return SR_ERR_DATA;
232 	*read_ptr++ = '\0';
233 
234 	/* Expect the 'CAUTION...' text (weak test, only part of the text). */
235 	if (strncmp(read_ptr, caution, strlen(caution)) != 0)
236 		return SR_ERR_DATA;
237 	read_ptr += strlen(caution);
238 
239 	/* No check for CRLF, due to the weak CAUTION test. */
240 	return SR_OK;
241 }
242 
process_wire_names(struct context * inc,char ** names)243 static int process_wire_names(struct context *inc, char **names)
244 {
245 	size_t count, idx;
246 
247 	/*
248 	 * The 'names' array contains the *wire* names, plus a 'Count'
249 	 * label for the last column.
250 	 */
251 	count = g_strv_length(names);
252 	if (count != inc->channel_count + 1)
253 		return SR_ERR_DATA;
254 	if (strcmp(names[inc->channel_count], "Count") != 0)
255 		return SR_ERR_DATA;
256 
257 	for (idx = 0; idx < inc->channel_count; idx++)
258 		inc->wire_names[idx] = g_strdup(names[idx]);
259 
260 	return SR_OK;
261 }
262 
process_signal_names(struct context * inc,char ** names)263 static int process_signal_names(struct context *inc, char **names)
264 {
265 	size_t count, idx;
266 
267 	/*
268 	 * The 'names' array contains the *signal* names (and no other
269 	 * entries, unlike the *wire* names).
270 	 */
271 	count = g_strv_length(names);
272 	if (count != inc->channel_count)
273 		return SR_ERR_DATA;
274 
275 	for (idx = 0; idx < inc->channel_count; idx++)
276 		inc->signal_names[idx] = g_strdup(names[idx]);
277 
278 	return SR_OK;
279 }
280 
process_signal_group(struct context * inc,char ** args)281 static int process_signal_group(struct context *inc, char **args)
282 {
283 	char *name, *wires;
284 	struct signal_group_desc *desc;
285 	uint64_t bit_mask;
286 	char *p, *endp;
287 	size_t idx;
288 
289 	/*
290 	 * List of arguments that we receive:
291 	 * - [0] group name
292 	 * - [1] - [5] uncertain meaning, four integers and one boolean
293 	 * - [6] comma separated list of wire indices (zero based)
294 	 * - [7] - [9] uncertain meaning, a boolean, two integers
295 	 * - [10] - [35] uncertain meaning, 26 empty columns
296 	 */
297 
298 	/* Check for the minimum amount of input data. */
299 	if (!args)
300 		return SR_ERR_DATA;
301 	if (g_strv_length(args) < 7)
302 		return SR_ERR_DATA;
303 	name = args[0];
304 	wires = args[6];
305 
306 	/* Accept empty names and empty signal lists. Silently ignore. */
307 	if (!name || !*name)
308 		return SR_OK;
309 	if (!wires || !*wires)
310 		return SR_OK;
311 	/*
312 	 * TODO: Introduce a user configurable "ignore" option? Skip the
313 	 * "All Signals" group by default, and in addition whatever
314 	 * the user specified?
315 	 */
316 	if (strcmp(name, SKIP_SIGNAL_GROUP) == 0) {
317 		sr_info("Skipping signal group '%s'", name);
318 		return SR_OK;
319 	}
320 
321 	/*
322 	 * Create the descriptor here to store the member list to. We
323 	 * cannot access signal names and sigrok channels yet, they
324 	 * only become avilable at a later point in time.
325 	 */
326 	desc = alloc_signal_group(name);
327 	if (!desc)
328 		return SR_ERR_MALLOC;
329 	inc->signal_groups = g_slist_append(inc->signal_groups, desc);
330 
331 	/* Determine the bit mask of the group's signals' indices. */
332 	bit_mask = 0;
333 	p = wires;
334 	while (p && *p) {
335 		endp = NULL;
336 		idx = strtoul(p, &endp, 0);
337 		if (!endp || endp == p)
338 			return SR_ERR_DATA;
339 		if (*endp && *endp != ',')
340 			return SR_ERR_DATA;
341 		p = endp;
342 		if (*p == ',')
343 			p++;
344 		if (idx >= MAX_CHANNELS)
345 			return SR_ERR_DATA;
346 		bit_mask = UINT64_C(1) << idx;
347 		if (inc->wires_grouped & bit_mask) {
348 			sr_warn("Not adding signal at index %zu to group %s (multiple assignments)",
349 				idx, name);
350 		} else {
351 			desc->mask |= bit_mask;
352 			inc->wires_grouped |= bit_mask;
353 		}
354 	}
355 	sr_dbg("'Group' done, name '%s', mask 0x%" PRIx64 ".",
356 		desc->name, desc->mask);
357 
358 	return SR_OK;
359 }
360 
process_ungrouped_signals(struct context * inc)361 static int process_ungrouped_signals(struct context *inc)
362 {
363 	uint64_t bit_mask;
364 	struct signal_group_desc *desc;
365 
366 	/*
367 	 * Only create the "ungrouped" channel group if there are any
368 	 * groups of other signals already.
369 	 */
370 	if (!inc->signal_groups)
371 		return SR_OK;
372 
373 	/*
374 	 * Determine the bit mask of signals that are part of the
375 	 * acquisition and are not a member of any other group.
376 	 */
377 	bit_mask = inc->wires_all_mask;
378 	bit_mask &= inc->wires_enabled;
379 	bit_mask &= ~inc->wires_grouped;
380 	sr_dbg("'ungrouped' check: all 0x%" PRIx64 ", en 0x%" PRIx64 ", grp 0x%" PRIx64 " -> un 0x%" PRIx64 ".",
381 		inc->wires_all_mask, inc->wires_enabled,
382 		inc->wires_grouped, bit_mask);
383 	if (!bit_mask)
384 		return SR_OK;
385 
386 	/* Create a sigrok channel group without a name. */
387 	desc = alloc_signal_group(NULL);
388 	if (!desc)
389 		return SR_ERR_MALLOC;
390 	inc->signal_groups = g_slist_append(inc->signal_groups, desc);
391 	desc->mask = bit_mask;
392 
393 	return SR_OK;
394 }
395 
process_enabled_channels(struct context * inc,char ** flags)396 static int process_enabled_channels(struct context *inc, char **flags)
397 {
398 	size_t count, idx;
399 	uint64_t bits, mask;
400 
401 	/*
402 	 * The 'flags' array contains (the textual representation of)
403 	 * the "enabled" state of the acquisition device's channels.
404 	 */
405 	count = g_strv_length(flags);
406 	if (count != inc->channel_count)
407 		return SR_ERR_DATA;
408 	bits = 0;
409 	mask = UINT64_C(1);
410 	for (idx = 0; idx < inc->channel_count; idx++, mask <<= 1) {
411 		if (strcmp(flags[idx], "True") == 0)
412 			bits |= mask;
413 	}
414 	inc->wires_enabled = bits;
415 
416 	return SR_OK;
417 }
418 
process_inverted_channels(struct context * inc,char ** flags)419 static int process_inverted_channels(struct context *inc, char **flags)
420 {
421 	size_t count, idx;
422 	uint64_t bits, mask;
423 
424 	/*
425 	 * The 'flags' array contains (the textual representation of)
426 	 * the "inverted" state of the acquisition device's channels.
427 	 */
428 	count = g_strv_length(flags);
429 	if (count != inc->channel_count)
430 		return SR_ERR_DATA;
431 	bits = 0;
432 	mask = UINT64_C(1);
433 	for (idx = 0; idx < inc->channel_count; idx++, mask <<= 1) {
434 		if (strcmp(flags[idx], "True") == 0)
435 			bits |= mask;
436 	}
437 	inc->wires_inverted = bits;
438 
439 	return SR_OK;
440 }
441 
process_sample_line(struct context * inc,char ** values)442 static int process_sample_line(struct context *inc, char **values)
443 {
444 	size_t count, idx;
445 	struct sample_data_entry *entry;
446 	uint64_t mask;
447 	long conv_ret;
448 	int rc;
449 
450 	/*
451 	 * The 'values' array contains '0'/'1' text representation of
452 	 * wire's values, as well as a (a textual representation of a)
453 	 * repeat counter for that set of samples.
454 	 */
455 	count = g_strv_length(values);
456 	if (count != inc->channel_count + 1)
457 		return SR_ERR_DATA;
458 	entry = &inc->sample_data_queue[inc->sample_lines_read];
459 	entry->bits = 0;
460 	mask = UINT64_C(1);
461 	for (idx = 0; idx < inc->channel_count; idx++, mask <<= 1) {
462 		if (strcmp(values[idx], "1") == 0)
463 			entry->bits |= mask;
464 		if (strcmp(values[idx], "U") == 0)
465 			inc->wires_undefined |= mask;
466 	}
467 	rc = sr_atol(values[inc->channel_count], &conv_ret);
468 	if (rc != SR_OK)
469 		return rc;
470 	entry->repeat = conv_ret;
471 	inc->samples_got_uncomp += entry->repeat;
472 
473 	return SR_OK;
474 }
475 
process_keyvalue_line(struct context * inc,char * line)476 static int process_keyvalue_line(struct context *inc, char *line)
477 {
478 	char *sep, *key, *arg;
479 	char **args;
480 	int rc;
481 	char *version, *build;
482 	long build_num;
483 	int wires, samples;
484 	size_t alloc_size;
485 	double period, dbl_rate;
486 	uint64_t int_rate;
487 
488 	/*
489 	 * Process lines of the 'SampleData' block. Inspection of the
490 	 * block got started below in the "regular keyword line" section.
491 	 * The code here handles the remaining number of lines: Opening
492 	 * and closing braces, wire names, and sample data sets. Note
493 	 * that the wire names and sample values are separated by comma,
494 	 * not by DC1 like other key/value pairs and argument lists.
495 	 */
496 	switch (inc->in_sample_data) {
497 	case SAMPLEDATA_OPEN_BRACE:
498 		if (strcmp(line, "{") != 0)
499 			return SR_ERR_DATA;
500 		inc->in_sample_data++;
501 		return SR_OK;
502 	case SAMPLEDATA_WIRES_COUNT:
503 		while (isspace(*line))
504 			line++;
505 		args = g_strsplit(line, ",", 0);
506 		rc = process_wire_names(inc, args);
507 		g_strfreev(args);
508 		if (rc)
509 			return rc;
510 		inc->in_sample_data++;
511 		inc->sample_lines_read = 0;
512 		return SR_OK;
513 	case SAMPLEDATA_DATA_LINES:
514 		while (isspace(*line))
515 			line++;
516 		args = g_strsplit(line, ",", 0);
517 		rc = process_sample_line(inc, args);
518 		g_strfreev(args);
519 		if (rc)
520 			return rc;
521 		inc->sample_lines_read++;
522 		if (inc->sample_lines_read == inc->sample_lines_total)
523 			inc->in_sample_data++;
524 		return SR_OK;
525 	case SAMPLEDATA_CLOSE_BRACE:
526 		if (strcmp(line, "}") != 0)
527 			return SR_ERR_DATA;
528 		sr_dbg("'SampleData' done: samples count %" PRIu64 ".",
529 			inc->samples_got_uncomp);
530 		inc->sample_lines_fed = 0;
531 		inc->in_sample_data = SAMPLEDATA_NONE;
532 		return SR_OK;
533 	case SAMPLEDATA_NONE:
534 		/* EMPTY */ /* Fall through to regular keyword-line logic. */
535 		break;
536 	}
537 
538 	/* Process regular key/value lines separated by DC1. */
539 	key = line;
540 	sep = strchr(line, DC1_CHR);
541 	if (!sep)
542 		return SR_ERR_DATA;
543 	*sep++ = '\0';
544 	arg = sep;
545 	if (strcmp(key, "Version") == 0) {
546 		rc = check_vers_line(arg, 0, &version, &build);
547 		if (rc == SR_OK) {
548 			inc->sw_version = g_strdup(version ? version : "?");
549 			rc = sr_atol(build, &build_num);
550 			inc->sw_build = build_num;
551 		}
552 		sr_dbg("'Version' line: version %s, build %zu.",
553 			inc->sw_version, inc->sw_build);
554 		return rc;
555 	}
556 	if (strcmp(key, "AcquiredSamplePeriod") == 0) {
557 		rc = sr_atod(arg, &period);
558 		if (rc != SR_OK)
559 			return rc;
560 		/*
561 		 * Implementation detail: The vendor's software provides
562 		 * 1/2/5 choices in the 1kHz - 500MHz range. Unfortunately
563 		 * the choice of saving the sample _period_ as a floating
564 		 * point number in the text file yields inaccurate results
565 		 * for naive implementations of the conversion (0.1 is an
566 		 * "odd number" in the computer's internal representation).
567 		 * The below logic of rounding to integer and then rounding
568 		 * to full kHz works for the samplerate value's range.
569 		 * "Simplifying" the implementation will introduce errors.
570 		 */
571 		dbl_rate = 1.0 / period;
572 		int_rate = (uint64_t)(dbl_rate + 0.5);
573 		int_rate += 500;
574 		int_rate /= 1000;
575 		int_rate *= 1000;
576 		inc->sample_rate = int_rate;
577 		if (!inc->sample_rate)
578 			return SR_ERR_DATA;
579 		sr_dbg("Sample rate: %" PRIu64 ".", inc->sample_rate);
580 		return SR_OK;
581 	}
582 	if (strcmp(key, "AcquiredChannelList") == 0) {
583 		args = g_strsplit(arg, DC1_STR, 0);
584 		rc = process_enabled_channels(inc, args);
585 		g_strfreev(args);
586 		if (rc)
587 			return rc;
588 		sr_dbg("Enabled channels: 0x%" PRIx64 ".",
589 			inc->wires_enabled);
590 		return SR_OK;
591 	}
592 	if (strcmp(key, "InvertedChannelList") == 0) {
593 		args = g_strsplit(arg, DC1_STR, 0);
594 		rc = process_inverted_channels(inc, args);
595 		g_strfreev(args);
596 		sr_dbg("Inverted channels: 0x%" PRIx64 ".",
597 			inc->wires_inverted);
598 		return SR_OK;
599 	}
600 	if (strcmp(key, "Signals") == 0) {
601 		args = g_strsplit(arg, DC1_STR, 0);
602 		rc = process_signal_names(inc, args);
603 		g_strfreev(args);
604 		if (rc)
605 			return rc;
606 		sr_dbg("Got signal names.");
607 		return SR_OK;
608 	}
609 	if (strcmp(key, "SampleData") == 0) {
610 		args = g_strsplit(arg, DC1_STR, 3);
611 		if (!args || !args[0] || !args[1]) {
612 			g_strfreev(args);
613 			return SR_ERR_DATA;
614 		}
615 		rc = sr_atoi(args[0], &wires);
616 		if (rc) {
617 			g_strfreev(args);
618 			return SR_ERR_DATA;
619 		}
620 		rc = sr_atoi(args[1], &samples);
621 		if (rc) {
622 			g_strfreev(args);
623 			return SR_ERR_DATA;
624 		}
625 		g_strfreev(args);
626 		if (!wires || !samples)
627 			return SR_ERR_DATA;
628 		inc->channel_count = wires;
629 		inc->sample_lines_total = samples;
630 		sr_dbg("'SampleData' start: wires %zu, sample lines %zu.",
631 			inc->channel_count, inc->sample_lines_total);
632 		if (inc->channel_count > MAX_CHANNELS)
633 			return SR_ERR_DATA;
634 		inc->in_sample_data = SAMPLEDATA_OPEN_BRACE;
635 		alloc_size = sizeof(inc->sample_data_queue[0]);
636 		alloc_size *= inc->sample_lines_total;
637 		inc->sample_data_queue = g_malloc0(alloc_size);
638 		if (!inc->sample_data_queue)
639 			return SR_ERR_DATA;
640 		inc->sample_lines_fed = 0;
641 		return SR_OK;
642 	}
643 	if (strcmp(key, "Group") == 0) {
644 		args = g_strsplit(arg, DC1_STR, 0);
645 		rc = process_signal_group(inc, args);
646 		g_strfreev(args);
647 		if (rc)
648 			return rc;
649 		return SR_OK;
650 	}
651 	if (strcmp(key, LAST_KEYWORD) == 0) {
652 		sr_dbg("'" LAST_KEYWORD "' seen, assuming \"header done\".");
653 		inc->got_header = TRUE;
654 		return SR_OK;
655 	}
656 
657 	/* Unsupported keyword, silently ignore the line. */
658 	return SR_OK;
659 }
660 
661 /* Check for, and isolate another line of text input. */
have_text_line(struct sr_input * in,char ** line,char ** next)662 static int have_text_line(struct sr_input *in, char **line, char **next)
663 {
664 	char *sol_ptr, *eol_ptr;
665 
666 	if (!in || !in->buf || !in->buf->str)
667 		return 0;
668 	sol_ptr = in->buf->str;
669 	eol_ptr = strstr(sol_ptr, CRLF);
670 	if (!eol_ptr)
671 		return 0;
672 	if (line)
673 		*line = sol_ptr;
674 	*eol_ptr = '\0';
675 	eol_ptr += strlen(CRLF);
676 	if (next)
677 		*next = eol_ptr;
678 
679 	return 1;
680 }
681 
682 /* Handle line continuation. Have logical lines processed. */
process_text_line(struct context * inc,char * line)683 static int process_text_line(struct context *inc, char *line)
684 {
685 	char *p;
686 	int is_cont_end;
687 	int rc;
688 
689 	/*
690 	 * Handle line continuation in the input stream. Notice that
691 	 * continued lines can start and end on the same input line.
692 	 * The text between the markers can be empty, too.
693 	 *
694 	 * Make the result look like a regular line. Put a DC1 delimiter
695 	 * between the keyword and the right hand side. Strip the /<DC1>
696 	 * and <DC1>/ "braces". Put CRLF between all continued parts,
697 	 * this makes the data appear "most intuitive and natural"
698 	 * should we e.g. pass on user's notes in a future version.
699 	 */
700 	is_cont_end = 0;
701 	if (!inc->cont_buff) {
702 		p = strstr(line, CONT_OPEN);
703 		if (p) {
704 			/* Start of continuation. */
705 			inc->cont_buff = g_string_new_len(line, p - line + 1);
706 			inc->cont_buff->str[inc->cont_buff->len - 1] = DC1_CHR;
707 			line = p + strlen(CONT_OPEN);
708 		}
709 		/* Regular line, fall through to below regular logic. */
710 	}
711 	if (inc->cont_buff) {
712 		p = strstr(line, CONT_CLOSE);
713 		is_cont_end = p != NULL;
714 		if (is_cont_end)
715 			*p = '\0';
716 		g_string_append_len(inc->cont_buff, line, strlen(line));
717 		if (!is_cont_end) {
718 			/* Keep accumulating. */
719 			g_string_append_len(inc->cont_buff, CRLF, strlen(CRLF));
720 			return SR_OK;
721 		}
722 		/* End of continuation. */
723 		line = inc->cont_buff->str;
724 	}
725 
726 	/*
727 	 * Process a logical line of input. It either was received from
728 	 * the caller, or is the result of accumulating continued lines.
729 	 */
730 	rc = process_keyvalue_line(inc, line);
731 
732 	/* Release the accumulation buffer when a continuation ended. */
733 	if (is_cont_end) {
734 		g_string_free(inc->cont_buff, TRUE);
735 		inc->cont_buff = NULL;
736 	}
737 
738 	return rc;
739 }
740 
741 /* Tell whether received data is sufficient for session feed preparation. */
have_header(GString * buf)742 static int have_header(GString *buf)
743 {
744 	const char *assumed_last_key = CRLF LAST_KEYWORD CONT_OPEN;
745 
746 	if (strstr(buf->str, assumed_last_key))
747 		return TRUE;
748 
749 	return FALSE;
750 }
751 
752 /* Process/inspect previously received input data. Get header parameters. */
parse_header(struct sr_input * in)753 static int parse_header(struct sr_input *in)
754 {
755 	struct context *inc;
756 	char *line, *next;
757 	int rc;
758 
759 	inc = in->priv;
760 	while (have_text_line(in, &line, &next)) {
761 		rc = process_text_line(inc, line);
762 		g_string_erase(in->buf, 0, next - line);
763 		if (rc)
764 			return rc;
765 	}
766 
767 	return SR_OK;
768 }
769 
770 /* Create sigrok channels and groups. */
create_channels_groups(struct sr_input * in)771 static int create_channels_groups(struct sr_input *in)
772 {
773 	struct context *inc;
774 	uint64_t mask;
775 	size_t idx;
776 	const char *name;
777 	gboolean enabled;
778 	struct sr_channel *ch;
779 	struct sr_dev_inst *sdi;
780 	GSList *l;
781 	struct signal_group_desc *desc;
782 	struct sr_channel_group *cg;
783 
784 	inc = in->priv;
785 
786 	if (inc->channels)
787 		return SR_OK;
788 
789 	mask = UINT64_C(1);
790 	for (idx = 0; idx < inc->channel_count; idx++, mask <<= 1) {
791 		name = inc->signal_names[idx];
792 		if (!name || !*name)
793 			name = inc->wire_names[idx];
794 		enabled = (inc->wires_enabled & mask) ? TRUE : FALSE;
795 		ch = sr_channel_new(in->sdi, idx,
796 			SR_CHANNEL_LOGIC, enabled, name);
797 		if (!ch)
798 			return SR_ERR_MALLOC;
799 		inc->channels = g_slist_append(inc->channels, ch);
800 	}
801 
802 	sdi = in->sdi;
803 	for (l = inc->signal_groups; l; l = l->next) {
804 		desc = l->data;
805 		cg = sr_channel_group_new(desc->name, NULL);
806 		if (!cg)
807 			return SR_ERR_MALLOC;
808 		sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
809 		mask = UINT64_C(1);
810 		for (idx = 0; idx < inc->channel_count; idx++, mask <<= 1) {
811 			if (!(desc->mask & mask))
812 				continue;
813 			ch = g_slist_nth_data(inc->channels, idx);
814 			if (!ch)
815 				return SR_ERR_DATA;
816 			cg->channels = g_slist_append(cg->channels, ch);
817 		}
818 	}
819 
820 	return SR_OK;
821 }
822 
823 /* Allocate the session feed buffer. */
create_feed_buffer(struct sr_input * in)824 static int create_feed_buffer(struct sr_input *in)
825 {
826 	struct context *inc;
827 
828 	inc = in->priv;
829 
830 	inc->unitsize = (inc->channel_count + 7) / 8;
831 	inc->samples_per_chunk = CHUNK_SIZE / inc->unitsize;
832 	inc->samples_in_buffer = 0;
833 	inc->feed_buffer = g_malloc0(inc->samples_per_chunk * inc->unitsize);
834 	if (!inc->feed_buffer)
835 		return SR_ERR_MALLOC;
836 
837 	return SR_OK;
838 }
839 
840 /* Send all accumulated sample data values to the session. */
send_buffer(struct sr_input * in)841 static int send_buffer(struct sr_input *in)
842 {
843 	struct context *inc;
844 	struct sr_datafeed_packet packet;
845 	struct sr_datafeed_meta meta;
846 	struct sr_config *src;
847 	struct sr_datafeed_logic logic;
848 	int rc;
849 
850 	inc = in->priv;
851 	if (!inc->samples_in_buffer)
852 		return SR_OK;
853 
854 	if (!inc->header_sent) {
855 		rc = std_session_send_df_header(in->sdi);
856 		if (rc)
857 			return rc;
858 		inc->header_sent = TRUE;
859 	}
860 
861 	if (inc->sample_rate && !inc->rate_sent) {
862 		packet.type = SR_DF_META;
863 		packet.payload = &meta;
864 		src = sr_config_new(SR_CONF_SAMPLERATE,
865 			g_variant_new_uint64(inc->sample_rate));
866 		meta.config = g_slist_append(NULL, src);
867 		rc = sr_session_send(in->sdi, &packet);
868 		g_slist_free(meta.config);
869 		sr_config_free(src);
870 		if (rc)
871 			return rc;
872 		inc->rate_sent = TRUE;
873 	}
874 
875 	packet.type = SR_DF_LOGIC;
876 	packet.payload = &logic;
877 	logic.unitsize = inc->unitsize;
878 	logic.data = inc->feed_buffer;
879 	logic.length = inc->unitsize * inc->samples_in_buffer;
880 	rc = sr_session_send(in->sdi, &packet);
881 
882 	inc->samples_in_buffer = 0;
883 
884 	if (rc)
885 		return rc;
886 
887 	return SR_OK;
888 }
889 
890 /*
891  * Add N copies of the current sample to the buffer. Send the buffer to
892  * the session feed when a maximum amount of data was collected.
893  */
add_samples(struct sr_input * in,uint64_t samples,size_t count)894 static int add_samples(struct sr_input *in, uint64_t samples, size_t count)
895 {
896 	struct context *inc;
897 	uint8_t sample_buffer[sizeof(uint64_t)];
898 	size_t idx;
899 	size_t copy_count;
900 	uint8_t *p;
901 	int rc;
902 
903 	inc = in->priv;
904 	for (idx = 0; idx < inc->unitsize; idx++) {
905 		sample_buffer[idx] = samples & 0xff;
906 		samples >>= 8;
907 	}
908 	while (count) {
909 		copy_count = inc->samples_per_chunk - inc->samples_in_buffer;
910 		if (copy_count > count)
911 			copy_count = count;
912 		count -= copy_count;
913 
914 		p = inc->feed_buffer + inc->samples_in_buffer * inc->unitsize;
915 		while (copy_count-- > 0) {
916 			memcpy(p, sample_buffer, inc->unitsize);
917 			p += inc->unitsize;
918 			inc->samples_in_buffer++;
919 		}
920 
921 		if (inc->samples_in_buffer == inc->samples_per_chunk) {
922 			rc = send_buffer(in);
923 			if (rc)
924 				return rc;
925 		}
926 	}
927 
928 	return SR_OK;
929 }
930 
931 /* Pass on previously received samples to the session. */
process_queued_samples(struct sr_input * in)932 static int process_queued_samples(struct sr_input *in)
933 {
934 	struct context *inc;
935 	struct sample_data_entry *entry;
936 	uint64_t sample_bits;
937 	int rc;
938 
939 	inc = in->priv;
940 	while (inc->sample_lines_fed < inc->sample_lines_total) {
941 		entry = &inc->sample_data_queue[inc->sample_lines_fed++];
942 		sample_bits = entry->bits;
943 		sample_bits ^= inc->wires_inverted;
944 		sample_bits &= inc->wires_enabled;
945 		rc = add_samples(in, sample_bits, entry->repeat);
946 		if (rc)
947 			return rc;
948 	}
949 
950 	return SR_OK;
951 }
952 
953 /*
954  * Create required resources between having read the input file and
955  * sending sample data to the session. Send initial packets before
956  * sample data follows.
957  */
prepare_session_feed(struct sr_input * in)958 static int prepare_session_feed(struct sr_input *in)
959 {
960 	struct context *inc;
961 	int rc;
962 
963 	inc = in->priv;
964 	if (inc->ch_feed_prep)
965 		return SR_OK;
966 
967 	/* Got channel names? At least fallbacks? */
968 	if (!inc->wire_names[0] || !inc->wire_names[0][0])
969 		return SR_ERR_DATA;
970 	/* Samples seen? Seen them all? */
971 	if (!inc->channel_count)
972 		return SR_ERR_DATA;
973 	if (!inc->sample_lines_total)
974 		return SR_ERR_DATA;
975 	if (inc->in_sample_data)
976 		return SR_ERR_DATA;
977 	if (!inc->sample_data_queue)
978 		return SR_ERR_DATA;
979 	inc->sample_lines_fed = 0;
980 
981 	/*
982 	 * Normalize some variants of input data.
983 	 * - Let's create a mask for the maximum possible
984 	 *   bit positions, it will be useful to avoid garbage
985 	 *   in other code paths, too.
986 	 * - Input files _might_ specify which channels were
987 	 *   enabled during acquisition. _Or_ not specify the
988 	 *   enabled channels, but provide 'U' values in some
989 	 *   columns. When neither was seen, assume that all
990 	 *   channels are enabled.
991 	 * - If there are any signal groups, put all signals into
992 	 *   an anonymous group that are not part of another group.
993 	 */
994 	inc->wires_all_mask = UINT64_C(1);
995 	inc->wires_all_mask <<= inc->channel_count;
996 	inc->wires_all_mask--;
997 	sr_dbg("all wires mask: 0x%" PRIx64 ".", inc->wires_all_mask);
998 	if (!inc->wires_enabled) {
999 		inc->wires_enabled = ~inc->wires_undefined;
1000 		inc->wires_enabled &= ~inc->wires_all_mask;
1001 		sr_dbg("enabled from undefined: 0x%" PRIx64 ".",
1002 			inc->wires_enabled);
1003 	}
1004 	if (!inc->wires_enabled) {
1005 		inc->wires_enabled = inc->wires_all_mask;
1006 		sr_dbg("enabled from total mask: 0x%" PRIx64 ".",
1007 			inc->wires_enabled);
1008 	}
1009 	sr_dbg("enabled mask: 0x%" PRIx64 ".",
1010 		inc->wires_enabled);
1011 	rc = process_ungrouped_signals(inc);
1012 	if (rc)
1013 		return rc;
1014 
1015 	/*
1016 	 * "Start" the session: Create channels, send the DF
1017 	 * header to the session. Optionally send the sample
1018 	 * rate before sample data will be sent.
1019 	 */
1020 	rc = create_channels_groups(in);
1021 	if (rc)
1022 		return rc;
1023 	rc = create_feed_buffer(in);
1024 	if (rc)
1025 		return rc;
1026 
1027 	inc->ch_feed_prep = TRUE;
1028 
1029 	return SR_OK;
1030 }
1031 
format_match(GHashTable * metadata,unsigned int * confidence)1032 static int format_match(GHashTable *metadata, unsigned int *confidence)
1033 {
1034 	GString *buf, *tmpbuf;
1035 	int rc;
1036 	gchar *version, *build;
1037 
1038 	/* Get a copy of the start of the file's content. */
1039 	buf = g_hash_table_lookup(metadata, GINT_TO_POINTER(SR_INPUT_META_HEADER));
1040 	if (!buf || !buf->str)
1041 		return SR_ERR_ARG;
1042 	tmpbuf = g_string_new_len(buf->str, buf->len);
1043 	if (!tmpbuf || !tmpbuf->str)
1044 		return SR_ERR_MALLOC;
1045 
1046 	/* See if we can spot a typical first LPF line. */
1047 	rc = check_vers_line(tmpbuf->str, 1, &version, &build);
1048 	if (rc == SR_OK && version && build) {
1049 		sr_dbg("Looks like a LogicProbe project, version %s, build %s.",
1050 			version, build);
1051 		*confidence = 1;
1052 	}
1053 	g_string_free(tmpbuf, TRUE);
1054 
1055 	return rc;
1056 }
1057 
init(struct sr_input * in,GHashTable * options)1058 static int init(struct sr_input *in, GHashTable *options)
1059 {
1060 	struct context *inc;
1061 
1062 	(void)options;
1063 
1064 	in->sdi = g_malloc0(sizeof(*in->sdi));
1065 	inc = g_malloc0(sizeof(*inc));
1066 	in->priv = inc;
1067 
1068 	return SR_OK;
1069 }
1070 
receive(struct sr_input * in,GString * buf)1071 static int receive(struct sr_input *in, GString *buf)
1072 {
1073 	struct context *inc;
1074 	int rc;
1075 
1076 	/* Accumulate another chunk of input data. */
1077 	g_string_append_len(in->buf, buf->str, buf->len);
1078 
1079 	/*
1080 	 * Wait for the full header's availability, then process it in a
1081 	 * single call, and set the "ready" flag. Make sure sample data
1082 	 * and the header get processed in disjoint calls to receive(),
1083 	 * the backend requires those separate phases.
1084 	 */
1085 	inc = in->priv;
1086 	if (!inc->got_header) {
1087 		if (!have_header(in->buf))
1088 			return SR_OK;
1089 		rc = parse_header(in);
1090 		if (rc)
1091 			return rc;
1092 		rc = prepare_session_feed(in);
1093 		if (rc)
1094 			return rc;
1095 		in->sdi_ready = TRUE;
1096 		return SR_OK;
1097 	}
1098 
1099 	/* Process sample data, after the header got processed. */
1100 	rc = process_queued_samples(in);
1101 
1102 	return rc;
1103 }
1104 
end(struct sr_input * in)1105 static int end(struct sr_input *in)
1106 {
1107 	struct context *inc;
1108 	int rc;
1109 
1110 	/* Nothing to do here if we never started feeding the session. */
1111 	if (!in->sdi_ready)
1112 		return SR_OK;
1113 
1114 	/*
1115 	 * Process sample data that may not have been forwarded before.
1116 	 * Flush any potentially queued samples.
1117 	 */
1118 	rc = process_queued_samples(in);
1119 	if (rc)
1120 		return rc;
1121 	rc = send_buffer(in);
1122 	if (rc)
1123 		return rc;
1124 
1125 	/* End the session feed if one was started. */
1126 	inc = in->priv;
1127 	if (inc->header_sent) {
1128 		rc = std_session_send_df_end(in->sdi);
1129 		inc->header_sent = FALSE;
1130 	}
1131 
1132 	return rc;
1133 }
1134 
cleanup(struct sr_input * in)1135 static void cleanup(struct sr_input *in)
1136 {
1137 	struct context *inc;
1138 	size_t idx;
1139 
1140 	if (!in)
1141 		return;
1142 
1143 	inc = in->priv;
1144 	if (!inc)
1145 		return;
1146 
1147 	/*
1148 	 * Release potentially allocated resources. Void all references
1149 	 * and scalars, so that re-runs start out fresh again.
1150 	 */
1151 	g_free(inc->sw_version);
1152 	if (inc->cont_buff)
1153 		g_string_free(inc->cont_buff, TRUE);
1154 	g_free(inc->sample_data_queue);
1155 	for (idx = 0; idx < inc->channel_count; idx++)
1156 		g_free(inc->wire_names[idx]);
1157 	for (idx = 0; idx < inc->channel_count; idx++)
1158 		g_free(inc->signal_names[idx]);
1159 	g_slist_free_full(inc->signal_groups, sg_free);
1160 	g_slist_free_full(inc->channels, g_free);
1161 	g_free(inc->feed_buffer);
1162 	memset(inc, 0, sizeof(*inc));
1163 }
1164 
reset(struct sr_input * in)1165 static int reset(struct sr_input *in)
1166 {
1167 	struct context *inc;
1168 	GSList *channels;
1169 
1170 	inc = in->priv;
1171 
1172 	/*
1173 	 * The input module's .reset() routine clears the 'inc' context,
1174 	 * but 'in' is kept which contains channel groups which reference
1175 	 * channels. Since we cannot re-create the channels (applications
1176 	 * don't expect us to, see bug #1215), make sure to keep the
1177 	 * channels across the reset operation.
1178 	 */
1179 	channels = inc->channels;
1180 	inc->channels = NULL;
1181 	cleanup(in);
1182 	inc->channels = channels;
1183 
1184 	return SR_OK;
1185 }
1186 
1187 static struct sr_option options[] = {
1188 	ALL_ZERO,
1189 };
1190 
get_options(void)1191 static const struct sr_option *get_options(void)
1192 {
1193 	return options;
1194 }
1195 
1196 SR_PRIV struct sr_input_module input_logicport = {
1197 	.id = "logicport",
1198 	.name = "LogicPort File",
1199 	.desc = "Intronix LA1034 LogicPort project",
1200 	.exts = (const char *[]){ "lpf", NULL },
1201 	.metadata = { SR_INPUT_META_HEADER | SR_INPUT_META_REQUIRED },
1202 	.options = get_options,
1203 	.format_match = format_match,
1204 	.init = init,
1205 	.receive = receive,
1206 	.end = end,
1207 	.cleanup = cleanup,
1208 	.reset = reset,
1209 };
1210