]> sigrok.org Git - libsigrok.git/blob - src/hardware/uni-t-ut181a/protocol.c
uni-t-ut181a: silence compiler warning, use of uninitialized variable
[libsigrok.git] / src / hardware / uni-t-ut181a / protocol.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2019-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 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 /*
21  * This implementation uses protocol information which was provided by
22  * the MIT licensed ut181a project. See Protocol.md for more details:
23  *
24  *   https://github.com/antage/ut181a/blob/master/Protocol.md
25  */
26
27 #include <config.h>
28 #include <ctype.h>
29 #include <math.h>
30 #include <string.h>
31
32 #include "protocol.h"
33
34 /*
35  * This driver depends on the user's enabling serial communication in
36  * the multimeter's menu system: SETUP -> Communication -> ON. The BLE
37  * adapter will shutdown within a short period of time when it's not
38  * being communicated to, needs another power cycle to re-connect. The
39  * USB cable does not suffer from such a constraint.
40  *
41  * Developer notes on the UT181A protocol:
42  * - Serial communication over HID or BLE based "cables", UT-D09 or
43  *   UT-D07A, bidirectional communication (UT-D04 won't do).
44  * - UART frame format 8n1 at 9600 bps. Variable length DMM packets.
45  * - DMM packet starts with a magic marker, followed by the length,
46  *   followed by data bytes and terminated by the checksum field.
47  *   The length includes the remainder of the frame. The checksum
48  *   includes the length field as well. The checksum value is the
49  *   16bit sum of all preceeding byte values.
50  * - The meter has many features (live readings, saved measurements,
51  *   recorded measurement series) with many additional attributes:
52  *   relative, min/max/avg, peak, AC+DC, multiple temperature probes,
53  *   COMP mode (PASS/FAIL). The protocol reflects this with highly
54  *   variable responses, with differing response layouts including
55  *   optional field presence.
56  * - Frame field values are communicated in 8/16/32 bit integer as well
57  *   as 32bit float formats in little endian presentation. Measurement
58  *   values are represented by a combination of a float value and flags
59  *   and a precision (digits count) and a text string which encodes the
60  *   measured quantity including its flags and another scale factor
61  *   (prefix reflecting the current range).
62  * - Response frames often provide a set of values at the same time:
63  *   There are multiple displays, like current and min/max/avg values,
64  *   relative values including their reference and the absolute value,
65  *   differences between probes, etc.
66  * - The meter can hold multiple recordings with user assigned names,
67  *   sample interval and duration, including interactive stop of a
68  *   currently active recording. These recordings contain samples that
69  *   were taken at a user specified interval.
70  * - The meter can store a list of measurements, which get saved upon
71  *   user requests, and can span arbitrary modes/functions/layouts per
72  *   saved measurement. In contrast to recordings which keep their type
73  *   of measurement across the set of samples.
74  *
75  * See https://github.com/antage/ut181a/blob/master/Protocol.md for a
76  * detailled description of the meter's protocol. Some additional notes
77  * in slightly reformatted layout for improved maintainability:
78  * - "Range byte"
79  *   0x00       Auto range
80  *   0x01       60 mV   6 V     600 uA  60 mA   600 R   60 Hz   6 nF
81  *   0x02       600 mV  60 V    6000 uA 600 mA  6 K     600 Hz  60 nF
82  *   0x03               600V    (20A is: auto)  60 K    6 KHz   600 nF
83  *   0x04               1000 V                  600 K   60 KHz  6 uF
84  *   0x05                                       6 M     600 KHz 60 uF
85  *   0x06                                       60 M    6 MHz   600 uF
86  *   0x07                                               60 MHz  6 mF
87  *   0x08                                                       60 mF
88  *   ampere: 20A is auto, not user selectable
89  *   continuity: 600 R, not user selectable
90  *   conductivity: 60nS, not user selectable
91  *   temperature: not user selectable
92  *   diode: not user selectable
93  *   frequency: all of the above ranges are available
94  *   duty cycle, period: 60Hz to 60kHz, not user selectable beyond 60kHz
95  * - DMM response packets in COMP mode (limits check, PASS/FAIL):
96  *   - The device supports two limits (upper, lower) and several modes
97  *     ("inner", "outer", "below", "above"). The result is boolean for
98  *     PASS or FAIL.
99  *   - Response packets are NORMAL MEASUREMENTs, with a MAIN value but
100  *     without AUX1/AUX2/BAR. Plus some more fields after the bargraph
101  *     unit field's position which are specific to COMP mode. Auto range
102  *     is off (also in the display).
103  *   - Example data for COMP mode responses:
104  *     INNER +0mV +3.3mV PASS -- 00 00 03  33 33 53 40  00 00 00 00
105  *     INNER +0mV +3.3mV FAIL -- 00 01 03  33 33 53 40  00 00 00 00
106  *     INNER +1mV +3.3mV FAIL -- 00 01 03  33 33 53 40  00 00 80 3f
107  *     OUTER +0mV +3.3mV PASS -- 01 00 03  33 33 53 40  00 00 00 00
108  *     BELOW +30mV PASS       -- 02 00 03  00 00 f0 41
109  *   - Extra fields:
110  *     1 byte mode, can be 0 to 3 for INNER/OUTER/BELOW/ABOVE
111  *     1 byte test result, bool failure, 0 is PASS, 1 is FAIL
112  *     1 byte digits, *not* shifted as in other precision fields
113  *     4 byte (always) high limit
114  *     4 byte (conditional) low limit, not in all modes
115  *
116  * Implementation notes on this driver version:
117  * - DMM channel assignment for measurement types:
118  *   - normal: P1 main, P2 aux1, P3 aux2, P5 bar (as applicable)
119  *   - relative: P1 relative, P2 reference, P3 absolute
120  *   - min-max: P1 current, P2 maximum, P3 average, P4 minimum
121  *   - peak: P2 maximum, P4 minimum
122  *   - save/recording: P5 timestamp (in addition to the above)
123  */
124
125 /*
126  * TODO:
127  * - General question: How many channels to export? An overlay with ever
128  *   changing meanings? Or a multitude where values are sparse?
129  * - Check how the PC side can _set_ the mode and range. Does mode
130  *   selection depend on the physical knob? Would assume it does.
131  *   The multitude of mode codes (some 70) and the lack of an apparent
132  *   formula to them makes this enhancement tedious. Listing too many
133  *   items in the "list" query could reduce usability.
134  * - Add support for "COMP mode" (comparison, PASS/FAIL result).
135  *   - How to express PASS/FAIL in the data feed submission? There is
136  *     SR_UNIT_BOOLEAN but not a good MQ for envelope test results.
137  *   - How to communicate limits to the session feed? COMP replies are
138  *     normal measurements without aux1 and aux2. Is it appropriate to
139  *     re-use DMM channels, or shall we add more of them?
140  * - Communicate timestamps for saved measurements and recordings to the
141  *   session feed.
142  *   - There is SR_MQ_TIME and SR_MQFLAG_RELATIVE, and SR_UNIT_SECOND.
143  *     Absolute time seems appropriate for save, relative (to the start
144  *     of the recording) for recordings.
145  *   - Unfortunately double data types are not fully operational, so we
146  *     use float. Which is limited to 23 bits, thus can only span some
147  *     100 days. But recordings can span longer periods when the sample
148  *     interval is large.
149  *   - Absolute times suffer from the 23bit limit (epoch time_t values
150  *     require 32 bits these days). And they get presented as 1.5Gs,
151  *     there seems to be no "date/time" flag or format.
152  * - Dynamically allocate and re-allocate the record name table. There
153  *   appears to be no limit of 20 recordings. The manual won't tell, but
154  *   it's assumed that a few hundreds or thousands are supported (10K
155  *   samples in total? that's a guess though).
156  * - The PC side could initiate to save a live measurement. The command
157  *   is there, it's just uncertain which SR_CONF_ key to use, DATALOG
158  *   appears to enter/leave a period of recording, not a single shot.
159  * - The PC side could start and stop recordings. But the start command
160  *   requires a name, sample interval, and duration, but SR_CONF_DATALOG
161  *   is just a boolean. Combining SR_CONF_LIMIT_SAMPLES, _DATALOG, et al
162  *   raises the question which order applications will send configure
163  *   requests for them.
164  * - How to communicate the LOWPASS condition? PASS/FAIL results for
165  *   COMP mode? Timestamps (absolute wall clock times)? High voltage,
166  *   lead errors (probe plugs in ampere modes)?
167  */
168
169 /*
170  * Development HACK, to see data frame exchange at -l 2 without the
171  * serial spew of -l 5. Also lets you concentrate on some of the code
172  * paths which currently are most interesting during maintenance. :)
173  */
174 #if UT181A_WITH_SER_ECHO
175 #  define FRAME_DUMP_LEVEL SR_LOG_WARN
176 #  define FRAME_DUMP_CALL sr_warn
177 #else
178 #  define FRAME_DUMP_LEVEL (SR_LOG_SPEW + 1)
179 #  define sr_nop(...) do { /* EMPTY */ } while (0)
180 #  define FRAME_DUMP_CALL sr_nop
181 #endif
182
183 #define FRAME_DUMP_RXDATA 0     /* UART level receive data. */
184 #define FRAME_DUMP_CSUM 0       /* Chunking, frame isolation. */
185 #define FRAME_DUMP_FRAME 0      /* DMM frames, including envelope. */
186 #define FRAME_DUMP_BYTES 0      /* DMM frame's payload data, "DMM packet". */
187 #define FRAME_DUMP_PARSE 1      /* Measurement value extraction. */
188 #define FRAME_DUMP_REMAIN 1     /* Unprocessed response data. */
189
190 /*
191  * TODO Can we collapse several u16 modes in useful ways? Need we keep
192  * them separate for "MQ+flags to mode" lookups, yet mark only some of
193  * them for LIST result sets? Can't filter and need to provide them all
194  * to the user? There are some 70-80 combinations. :-O
195  *
196  * Unfortunately there is no general pattern to these code numbers, or
197  * when there is it's non-obvious. There are _some_ conventions, but also
198  * exceptions, so that programmatic handling fails.
199  *
200  * TODO
201  * - Factor out LOWPASS to a separate mode? At least derive an MQFLAG.
202  */
203 static const struct mqopt_item ut181a_mqopts[] = {
204         {
205                 SR_MQ_VOLTAGE, SR_MQFLAG_AC, {
206                         MODE_V_AC, MODE_V_AC_REL,
207                         MODE_mV_AC, MODE_mV_AC_REL,
208                         MODE_V_AC_PEAK, MODE_mV_AC_PEAK,
209                         MODE_V_AC_LOWPASS, MODE_V_AC_LOWPASS_REL,
210                         0,
211                 },
212         },
213         {
214                 SR_MQ_VOLTAGE, SR_MQFLAG_DC, {
215                         MODE_V_DC, MODE_V_DC_REL,
216                         MODE_mV_DC, MODE_mV_DC_REL,
217                         MODE_V_DC_PEAK, MODE_mV_DC_PEAK,
218                         0,
219                 },
220         },
221         {
222                 SR_MQ_VOLTAGE, SR_MQFLAG_DC | SR_MQFLAG_AC, {
223                         MODE_V_DC_ACDC, MODE_V_DC_ACDC_REL,
224                         MODE_mV_AC_ACDC, MODE_mV_AC_ACDC_REL,
225                         0,
226                 },
227         },
228         {
229                 SR_MQ_GAIN, 0, {
230                         MODE_V_AC_dBV, MODE_V_AC_dBV_REL,
231                         MODE_V_AC_dBm, MODE_V_AC_dBm_REL,
232                         0,
233                 },
234         },
235         {
236                 SR_MQ_CURRENT, SR_MQFLAG_AC, {
237                         MODE_A_AC, MODE_A_AC_REL,
238                         MODE_A_AC_PEAK,
239                         MODE_mA_AC, MODE_mA_AC_REL,
240                         MODE_mA_AC_PEAK,
241                         MODE_uA_AC, MODE_uA_AC_REL,
242                         MODE_uA_AC_PEAK,
243                         0,
244                 },
245         },
246         {
247                 SR_MQ_CURRENT, SR_MQFLAG_DC, {
248                         MODE_A_DC, MODE_A_DC_REL,
249                         MODE_A_DC_PEAK,
250                         MODE_mA_DC, MODE_mA_DC_REL,
251                         MODE_uA_DC, MODE_uA_DC_REL,
252                         MODE_uA_DC_PEAK,
253                         0,
254                 },
255         },
256         {
257                 SR_MQ_CURRENT, SR_MQFLAG_DC | SR_MQFLAG_AC, {
258                         MODE_A_DC_ACDC, MODE_A_DC_ACDC_REL,
259                         MODE_mA_DC_ACDC, MODE_mA_DC_ACDC_REL,
260                         MODE_uA_DC_ACDC, MODE_uA_DC_ACDC_REL,
261                         MODE_mA_DC_ACDC_PEAK,
262                         0,
263                 },
264         },
265         {
266                 SR_MQ_RESISTANCE, 0, {
267                         MODE_RES, MODE_RES_REL, 0,
268                 },
269         },
270         {
271                 SR_MQ_CONDUCTANCE, 0, {
272                         MODE_COND, MODE_COND_REL, 0,
273                 },
274         },
275         {
276                 SR_MQ_CONTINUITY, 0, {
277                         MODE_CONT_SHORT, MODE_CONT_OPEN, 0,
278                 },
279         },
280         {
281                 SR_MQ_VOLTAGE, SR_MQFLAG_DIODE | SR_MQFLAG_DC, {
282                         MODE_DIODE, MODE_DIODE_ALARM, 0,
283                 },
284         },
285         {
286                 SR_MQ_CAPACITANCE, 0, {
287                         MODE_CAP, MODE_CAP_REL, 0,
288                 },
289         },
290         {
291                 SR_MQ_FREQUENCY, 0, {
292                         MODE_FREQ, MODE_FREQ_REL,
293                         MODE_V_AC_Hz, MODE_mV_AC_Hz,
294                         MODE_A_AC_Hz, MODE_mA_AC_Hz, MODE_uA_AC_Hz,
295                         0,
296                 },
297         },
298         {
299                 SR_MQ_DUTY_CYCLE, 0, {
300                         MODE_DUTY, MODE_DUTY_REL, 0,
301                 },
302         },
303         {
304                 SR_MQ_PULSE_WIDTH, 0, {
305                         MODE_PULSEWIDTH, MODE_PULSEWIDTH_REL, 0,
306                 },
307         },
308         {
309                 SR_MQ_TEMPERATURE, 0, {
310                         MODE_TEMP_C_T1_and_T2, MODE_TEMP_C_T1_and_T2_REL,
311                         MODE_TEMP_C_T1_minus_T2, MODE_TEMP_F_T1_and_T2,
312                         MODE_TEMP_C_T2_and_T1, MODE_TEMP_C_T2_and_T1_REL,
313                         MODE_TEMP_C_T2_minus_T1,
314                         MODE_TEMP_F_T1_and_T2_REL, MODE_TEMP_F_T1_minus_T2,
315                         MODE_TEMP_F_T2_and_T1, MODE_TEMP_F_T2_and_T1_REL,
316                         MODE_TEMP_F_T2_minus_T1,
317                         0,
318                 },
319         },
320 };
321
322 SR_PRIV const struct mqopt_item *ut181a_get_mqitem_from_mode(uint16_t mode)
323 {
324         size_t mq_idx, mode_idx;
325         const struct mqopt_item *item;
326
327         for (mq_idx = 0; mq_idx < ARRAY_SIZE(ut181a_mqopts); mq_idx++) {
328                 item = &ut181a_mqopts[mq_idx];
329                 for (mode_idx = 0; mode_idx < ARRAY_SIZE(item->modes); mode_idx++) {
330                         if (!item->modes[mode_idx])
331                                 break;
332                         if (item->modes[mode_idx] != mode)
333                                 continue;
334                         /* Found a matching mode. */
335                         return item;
336                 }
337         }
338         return NULL;
339 }
340
341 SR_PRIV uint16_t ut181a_get_mode_from_mq_flags(enum sr_mq mq, enum sr_mqflag mqflags)
342 {
343         size_t mq_idx;
344         const struct mqopt_item *item;
345
346         for (mq_idx = 0; mq_idx < ARRAY_SIZE(ut181a_mqopts); mq_idx++) {
347                 item = &ut181a_mqopts[mq_idx];
348                 if (mq != item->mq)
349                         continue;
350                 /* TODO Need finer checks? Masked? */
351                 if (mqflags != item->mqflags)
352                         continue;
353                 return item->modes[0];
354         }
355         return 0;
356 }
357
358 SR_PRIV GVariant *ut181a_get_mq_flags_list_item(enum sr_mq mq, enum sr_mqflag mqflag)
359 {
360         GVariant *arr[2], *tuple;
361
362         arr[0] = g_variant_new_uint32(mq);
363         arr[1] = g_variant_new_uint64(mqflag);
364         tuple = g_variant_new_tuple(arr, ARRAY_SIZE(arr));
365
366         return tuple;
367 }
368
369 SR_PRIV GVariant *ut181a_get_mq_flags_list(void)
370 {
371         GVariantBuilder gvb;
372         GVariant *tuple, *list;
373         size_t i;
374         const struct mqopt_item *item;
375
376         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
377         for (i = 0; i < ARRAY_SIZE(ut181a_mqopts); i++) {
378                 item = &ut181a_mqopts[i];
379                 tuple = ut181a_get_mq_flags_list_item(item->mq, item->mqflags);
380                 g_variant_builder_add_value(&gvb, tuple);
381         }
382         list = g_variant_builder_end(&gvb);
383
384         return list;
385 }
386
387 /*
388  * See the Protocol.md document's "Range byte" section. Value 0 is said
389  * to communicate "auto range", while values 1-8 are said to communicate
390  * specific ranges which depend on the meter's current function. Yet
391  * there is another misc flag for auto range.
392  *
393  * From this information, and observed packet content, it is assumed
394  * that the following logic applies:
395  * - Measurements (response packets) carry the "auto" flag, _and_ a
396  *   "range" byte, to provide the information that auto ranging was in
397  *   effect, and which specific range the automatic detection picked.
398  * - "Set range" requests can request a specific range (values 1-8), or
399  *   switch to auto range (value 0).
400  *
401  * This driver implementation returns non-settable string literals for
402  * modes where auto ranging is not user adjustable (high current, diode,
403  * continuity, conductivity, temperature). Setup requests get rejected.
404  * (The local user interface neither responds to RANGE button presses.)
405  */
406 static const char *range_auto = "auto";
407 static const char *ranges_volt_mv[] = {
408         "60mV", "600mV", NULL,
409 };
410 static const char *ranges_volt_v[] = {
411         "6V", "60V", "600V", "1000V", NULL,
412 };
413 static const char *ranges_volt_diode[] = {
414         /* Diode is always auto, not user adjustable. */
415         "3.0V", NULL,
416 };
417 static const char *ranges_amp_ua[] = {
418         "600uA", "6000uA", NULL,
419 };
420 static const char *ranges_amp_ma[] = {
421         "60mA", "600mA", NULL,
422 };
423 static const char *ranges_amp_a[] = {
424         /* The 'A' range is always 20A (in the display, manual says 10A). */
425         "20A", NULL,
426 };
427 static const char *ranges_ohm_res[] = {
428         /* TODO
429          * Prefer "Ohm" (or "R" for sub-kilo ranges) instead? We try to
430          * keep usability in other places (micro), too, by letting users
431          * type regular non-umlaut text, and avoiding encoding issues.
432          */
433         "600Ω", "6kΩ", "60kΩ", "600kΩ", "6MΩ", "60MΩ", NULL,
434 };
435 static const char *ranges_ohm_600[] = {
436         /* Continuity is always 600R, not user adjustable. */
437         "600Ω", NULL,
438 };
439 static const char *ranges_cond[] = {
440         /* Conductivity is always 60nS, not user adjustable. */
441         "60nS", NULL,
442 };
443 static const char *ranges_capa[] = {
444         "6nF", "60nF", "600nF", "6uF", "60uF", "600uF", "6mF", "600mF", NULL,
445 };
446 static const char *ranges_freq_full[] = {
447         "60Hz", "600Hz", "6kHz", "60kHz", "600kHz", "6MHz", "60MHz", NULL,
448 };
449 static const char *ranges_freq_60khz[] = {
450         /* Duty cycle and period only support up to 60kHz. */
451         "60Hz", "600Hz", "6kHz", "60kHz", NULL,
452 };
453 static const char *ranges_temp_c[] = {
454         /* Temperature always is up to 1000 degree C, not user adjustable. */
455         "1000°C", NULL,
456 };
457 static const char *ranges_temp_f[] = {
458         /* Temperature always is up to 1832 F, not user adjustable. */
459         "1832F", NULL,
460 };
461
462 static void ut181a_add_ranges_list(GVariantBuilder *b, const char **l)
463 {
464         const char *range;
465
466         while (l && *l && **l) {
467                 range = *l++;
468                 g_variant_builder_add(b, "s", range);
469         }
470 }
471
472 SR_PRIV GVariant *ut181a_get_ranges_list(void)
473 {
474         GVariantBuilder gvb;
475         GVariant *list;
476
477         /* Also list those ranges which cannot get set? */
478 #define WITH_RANGE_LIST_FIXED 1
479
480         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
481         g_variant_builder_add(&gvb, "s", range_auto);
482         ut181a_add_ranges_list(&gvb, ranges_volt_mv);
483         ut181a_add_ranges_list(&gvb, ranges_volt_v);
484         (void)ranges_volt_diode;
485         ut181a_add_ranges_list(&gvb, ranges_amp_ua);
486         ut181a_add_ranges_list(&gvb, ranges_amp_ma);
487 #if WITH_RANGE_LIST_FIXED
488         ut181a_add_ranges_list(&gvb, ranges_amp_a);
489 #else
490         (void)ranges_amp_a;
491 #endif
492         ut181a_add_ranges_list(&gvb, ranges_ohm_res);
493         (void)ranges_ohm_600;
494         ut181a_add_ranges_list(&gvb, ranges_cond);
495         ut181a_add_ranges_list(&gvb, ranges_capa);
496         ut181a_add_ranges_list(&gvb, ranges_freq_full);
497         (void)ranges_freq_60khz;
498 #if WITH_RANGE_LIST_FIXED
499         ut181a_add_ranges_list(&gvb, ranges_temp_c);
500         ut181a_add_ranges_list(&gvb, ranges_temp_f);
501 #else
502         (void)ranges_temp_c;
503         (void)ranges_temp_f;
504 #endif
505         list = g_variant_builder_end(&gvb);
506
507         return list;
508 }
509
510 SR_PRIV const char *ut181a_get_range_from_packet_bytes(struct dev_context *devc)
511 {
512         uint16_t mode;
513         uint8_t range;
514         gboolean is_auto;
515         const char **ranges;
516
517         if (!devc)
518                 return NULL;
519         mode = devc->info.meas_head.mode;
520         range = devc->info.meas_head.range;
521         is_auto = devc->info.meas_head.is_auto_range;
522
523         /* Handle the simple cases of "auto" and out of (absolute) limits. */
524         if (is_auto)
525                 return range_auto;
526         if (!mode)
527                 return NULL;
528         if (!range)
529                 return range_auto;
530         if (range > MAX_RANGE_INDEX)
531                 return NULL;
532
533         /* Lookup the list of ranges which depend on the meter's current mode. */
534         switch (mode) {
535
536         case MODE_V_AC:
537         case MODE_V_AC_REL:
538         case MODE_V_AC_Hz:
539         case MODE_V_AC_PEAK:
540         case MODE_V_AC_LOWPASS:
541         case MODE_V_AC_LOWPASS_REL:
542         case MODE_V_AC_dBV:
543         case MODE_V_AC_dBV_REL:
544         case MODE_V_AC_dBm:
545         case MODE_V_AC_dBm_REL:
546         case MODE_V_DC:
547         case MODE_V_DC_REL:
548         case MODE_V_DC_ACDC:
549         case MODE_V_DC_ACDC_REL:
550         case MODE_V_DC_PEAK:
551                 ranges = ranges_volt_v;
552                 break;
553         case MODE_mV_AC:
554         case MODE_mV_AC_REL:
555         case MODE_mV_AC_Hz:
556         case MODE_mV_AC_PEAK:
557         case MODE_mV_AC_ACDC:
558         case MODE_mV_AC_ACDC_REL:
559         case MODE_mV_DC:
560         case MODE_mV_DC_REL:
561         case MODE_mV_DC_PEAK:
562                 ranges = ranges_volt_mv;
563                 break;
564         case MODE_RES:
565         case MODE_RES_REL:
566                 ranges = ranges_ohm_res;
567                 break;
568         case MODE_CONT_SHORT:
569         case MODE_CONT_OPEN:
570                 ranges = ranges_ohm_600;
571                 break;
572         case MODE_COND:
573         case MODE_COND_REL:
574                 ranges = ranges_cond;
575                 break;
576         case MODE_CAP:
577         case MODE_CAP_REL:
578                 ranges = ranges_capa;
579                 break;
580         case MODE_FREQ:
581         case MODE_FREQ_REL:
582                 ranges = ranges_freq_full;
583                 break;
584         case MODE_DUTY:
585         case MODE_DUTY_REL:
586         case MODE_PULSEWIDTH:
587         case MODE_PULSEWIDTH_REL:
588                 ranges = ranges_freq_60khz;
589                 break;
590         case MODE_uA_DC:
591         case MODE_uA_DC_REL:
592         case MODE_uA_DC_ACDC:
593         case MODE_uA_DC_ACDC_REL:
594         case MODE_uA_DC_PEAK:
595         case MODE_uA_AC:
596         case MODE_uA_AC_REL:
597         case MODE_uA_AC_Hz:
598         case MODE_uA_AC_PEAK:
599                 ranges = ranges_amp_ua;
600                 break;
601         case MODE_mA_DC:
602         case MODE_mA_DC_REL:
603         case MODE_mA_DC_ACDC:
604         case MODE_mA_DC_ACDC_REL:
605         case MODE_mA_DC_ACDC_PEAK:
606         case MODE_mA_AC:
607         case MODE_mA_AC_REL:
608         case MODE_mA_AC_Hz:
609         case MODE_mA_AC_PEAK:
610                 ranges = ranges_amp_ma;
611                 break;
612
613         /* Some modes are neither flexible nor adjustable. */
614         case MODE_TEMP_C_T1_and_T2:
615         case MODE_TEMP_C_T1_and_T2_REL:
616         case MODE_TEMP_C_T2_and_T1:
617         case MODE_TEMP_C_T2_and_T1_REL:
618         case MODE_TEMP_C_T1_minus_T2:
619         case MODE_TEMP_C_T2_minus_T1:
620                 ranges = ranges_temp_c;
621                 break;
622         case MODE_TEMP_F_T1_and_T2:
623         case MODE_TEMP_F_T1_and_T2_REL:
624         case MODE_TEMP_F_T2_and_T1:
625         case MODE_TEMP_F_T2_and_T1_REL:
626         case MODE_TEMP_F_T1_minus_T2:
627         case MODE_TEMP_F_T2_minus_T1:
628                 ranges = ranges_temp_f;
629                 break;
630         /* Diode, always 3V. */
631         case MODE_DIODE:
632         case MODE_DIODE_ALARM:
633                 ranges = ranges_volt_diode;
634                 break;
635         /* High current (A range). Always 20A. */
636         case MODE_A_DC:
637         case MODE_A_DC_REL:
638         case MODE_A_DC_ACDC:
639         case MODE_A_DC_ACDC_REL:
640         case MODE_A_DC_PEAK:
641         case MODE_A_AC:
642         case MODE_A_AC_REL:
643         case MODE_A_AC_Hz:
644         case MODE_A_AC_PEAK:
645                 ranges = ranges_amp_a;
646                 break;
647
648         /* Unknown mode? Programming error? */
649         default:
650                 return NULL;
651         }
652
653         /* Lookup the range in the list of the mode's ranges. */
654         while (ranges && *ranges && **ranges && --range > 0) {
655                 ranges++;
656         }
657         if (!ranges || !*ranges || !**ranges)
658                 return NULL;
659         return *ranges;
660 }
661
662 SR_PRIV int ut181a_set_range_from_text(const struct sr_dev_inst *sdi, const char *text)
663 {
664         struct dev_context *devc;
665         uint16_t mode;
666         const char **ranges;
667         uint8_t range;
668
669         /* We must have determined the meter's current mode first. */
670         if (!sdi)
671                 return SR_ERR_ARG;
672         if (!text || !*text)
673                 return SR_ERR_ARG;
674         devc = sdi->priv;
675         if (!devc)
676                 return SR_ERR_ARG;
677         mode = devc->info.meas_head.mode;
678         if (!mode)
679                 return SR_ERR_ARG;
680
681         /* Handle the simple case of "auto" caller spec. */
682         if (strcmp(text, range_auto) == 0) {
683                 range = 0;
684                 return ut181a_send_cmd_setmode(sdi->conn, range);
685         }
686
687         /* Lookup the list of ranges which depend on the meter's current mode. */
688         switch (mode) {
689
690         /* Map "user servicable" modes to their respective ranges list. */
691         case MODE_V_AC:
692         case MODE_V_AC_REL:
693         case MODE_V_AC_Hz:
694         case MODE_V_AC_PEAK:
695         case MODE_V_AC_LOWPASS:
696         case MODE_V_AC_LOWPASS_REL:
697         case MODE_V_AC_dBV:
698         case MODE_V_AC_dBV_REL:
699         case MODE_V_AC_dBm:
700         case MODE_V_AC_dBm_REL:
701         case MODE_V_DC:
702         case MODE_V_DC_REL:
703         case MODE_V_DC_ACDC:
704         case MODE_V_DC_ACDC_REL:
705         case MODE_V_DC_PEAK:
706                 ranges = ranges_volt_v;
707                 break;
708         case MODE_mV_AC:
709         case MODE_mV_AC_REL:
710         case MODE_mV_AC_Hz:
711         case MODE_mV_AC_PEAK:
712         case MODE_mV_AC_ACDC:
713         case MODE_mV_AC_ACDC_REL:
714         case MODE_mV_DC:
715         case MODE_mV_DC_REL:
716         case MODE_mV_DC_PEAK:
717                 ranges = ranges_volt_mv;
718                 break;
719         case MODE_RES:
720         case MODE_RES_REL:
721                 ranges = ranges_ohm_res;
722                 break;
723         case MODE_CAP:
724         case MODE_CAP_REL:
725                 ranges = ranges_capa;
726                 break;
727         case MODE_FREQ:
728         case MODE_FREQ_REL:
729                 ranges = ranges_freq_full;
730                 break;
731         case MODE_DUTY:
732         case MODE_DUTY_REL:
733         case MODE_PULSEWIDTH:
734         case MODE_PULSEWIDTH_REL:
735                 ranges = ranges_freq_60khz;
736                 break;
737         case MODE_uA_DC:
738         case MODE_uA_DC_REL:
739         case MODE_uA_DC_ACDC:
740         case MODE_uA_DC_ACDC_REL:
741         case MODE_uA_DC_PEAK:
742         case MODE_uA_AC:
743         case MODE_uA_AC_REL:
744         case MODE_uA_AC_Hz:
745         case MODE_uA_AC_PEAK:
746                 ranges = ranges_amp_ua;
747                 break;
748         case MODE_mA_DC:
749         case MODE_mA_DC_REL:
750         case MODE_mA_DC_ACDC:
751         case MODE_mA_DC_ACDC_REL:
752         case MODE_mA_DC_ACDC_PEAK:
753         case MODE_mA_AC:
754         case MODE_mA_AC_REL:
755         case MODE_mA_AC_Hz:
756         case MODE_mA_AC_PEAK:
757                 ranges = ranges_amp_ma;
758                 break;
759
760         /*
761          * Some modes use fixed ranges. Accept their specs or refuse to
762          * set a specific range? The meter's UI refuses MANUAL mode and
763          * remains in AUTO mode. So do we here.
764          */
765         case MODE_CONT_SHORT:
766         case MODE_CONT_OPEN:
767                 return SR_ERR_NA;
768                 ranges = ranges_ohm_600;
769                 break;
770         case MODE_COND:
771         case MODE_COND_REL:
772                 return SR_ERR_NA;
773                 ranges = ranges_cond;
774                 break;
775         case MODE_TEMP_C_T1_and_T2:
776         case MODE_TEMP_C_T1_and_T2_REL:
777         case MODE_TEMP_C_T2_and_T1:
778         case MODE_TEMP_C_T2_and_T1_REL:
779         case MODE_TEMP_C_T1_minus_T2:
780         case MODE_TEMP_C_T2_minus_T1:
781                 return SR_ERR_NA;
782                 ranges = ranges_temp_c;
783                 break;
784         case MODE_TEMP_F_T1_and_T2:
785         case MODE_TEMP_F_T1_and_T2_REL:
786         case MODE_TEMP_F_T2_and_T1:
787         case MODE_TEMP_F_T2_and_T1_REL:
788         case MODE_TEMP_F_T1_minus_T2:
789         case MODE_TEMP_F_T2_minus_T1:
790                 return SR_ERR_NA;
791                 ranges = ranges_temp_f;
792                 break;
793         /* Diode, always 3V. */
794         case MODE_DIODE:
795         case MODE_DIODE_ALARM:
796                 return SR_ERR_NA;
797                 ranges = ranges_volt_diode;
798                 break;
799         /* High current (A range). Always 20A. */
800         case MODE_A_DC:
801         case MODE_A_DC_REL:
802         case MODE_A_DC_ACDC:
803         case MODE_A_DC_ACDC_REL:
804         case MODE_A_DC_PEAK:
805         case MODE_A_AC:
806         case MODE_A_AC_REL:
807         case MODE_A_AC_Hz:
808         case MODE_A_AC_PEAK:
809                 return SR_ERR_NA;
810                 ranges = ranges_amp_a;
811                 break;
812
813         /* Unknown mode? Programming error? */
814         default:
815                 return SR_ERR_BUG;
816         }
817
818         /* Lookup the range in the list of the mode's ranges. */
819         range = 1;
820         while (ranges && *ranges && **ranges) {
821                 if (strcmp(*ranges, text) != 0) {
822                         range++;
823                         ranges++;
824                         continue;
825                 }
826                 return ut181a_send_cmd_setrange(sdi->conn, range);
827         }
828         return SR_ERR_ARG;
829 }
830
831 /**
832  * Parse a unit text into scale factor, MQ and flags, and unit.
833  *
834  * @param[out] mqs The scale/MQ/unit details to fill in.
835  * @param[in] text The DMM's "unit text" (string label).
836  *
837  * @returns SR_OK upon success, SR_ERR_* upon error.
838  *
839  * UT181A unit text strings encode several details: They start with an
840  * optional prefix (which communicates a scale factor), specify the unit
841  * of the measured value (which hints towards the measured quantity),
842  * and carry optional attributes (which MQ flags can get derived from).
843  *
844  * See unit.rs for the list of known input strings. Though there are
845  * unexpected differences:
846  * - \u{FFFD}C/F instead of 0xb0 for degree (local platform conversion?)
847  * - 'u' seems to be used for micro, good (no 'micro' umlaut involved)
848  * - '~' (tilde, 0x7e) for Ohm
849  *
850  * Prefixes: p n u m '' k M G
851  *
852  * Units:
853  * - F Farad (m u n)
854  * - dBV, dBm (no prefix)
855  * - ~ (tilde, Ohm) (- k M)
856  * - S Siemens (n)
857  * - % percent (no prefix)
858  * - s seconds (m)
859  * - Hz Hertz (- k M)
860  * - xC, xF degree (no prefix)
861  *
862  * Units with Flags:
863  * - Aac+dc ampere AC+DC (- m u)
864  * - AAC ampere AC (- m u)
865  * - ADC ampere DC (- m u)
866  * - Vac+dc volt AC+DC (- m)
867  * - VAC volt AC (- m)
868  * - VDC volt DC (- m)
869  */
870 static int ut181a_get_mq_details_from_text(struct mq_scale_params *mqs, const char *text)
871 {
872         char scale_char;
873         int scale;
874         enum sr_mq mq;
875         enum sr_mqflag mqflags;
876         enum sr_unit unit;
877
878         if (!mqs)
879                 return SR_ERR_ARG;
880         memset(mqs, 0, sizeof(*mqs));
881
882         /* Start from unknown state, no modifiers. */
883         scale = 0;
884         unit = 0;
885         mq = 0;
886         mqflags = 0;
887
888         /* Derive the scale factor from the optional prefix. */
889         scale_char = *text++;
890         if (scale_char == 'p')
891                 scale = -12;
892         else if (scale_char == 'n')
893                 scale = -9;
894         else if (scale_char == 'u')
895                 scale = -6;
896         else if (scale_char == 'm')
897                 scale = -3;
898         else if (scale_char == 'k')
899                 scale = +3;
900         else if (scale_char == 'M')
901                 scale = +6;
902         else if (scale_char == 'G')
903                 scale = +9;
904         else
905                 text--;
906
907         /* Guess the MQ (and flags) from the unit text. */
908         if (g_str_has_prefix(text, "F")) {
909                 text += strlen("F");
910                 unit = SR_UNIT_FARAD;
911                 if (!mq)
912                         mq = SR_MQ_CAPACITANCE;
913         } else if (g_str_has_prefix(text, "dBV")) {
914                 text += strlen("dBV");
915                 unit = SR_UNIT_DECIBEL_VOLT;
916                 if (!mq)
917                         mq = SR_MQ_GAIN;
918         } else if (g_str_has_prefix(text, "dBm")) {
919                 text += strlen("dBm");
920                 unit = SR_UNIT_DECIBEL_MW;
921                 if (!mq)
922                         mq = SR_MQ_GAIN;
923         } else if (g_str_has_prefix(text, "~")) {
924                 text += strlen("~");
925                 unit = SR_UNIT_OHM;
926                 if (!mq)
927                         mq = SR_MQ_RESISTANCE;
928         } else if (g_str_has_prefix(text, "S")) {
929                 text += strlen("S");
930                 unit = SR_UNIT_SIEMENS;
931                 if (!mq)
932                         mq = SR_MQ_CONDUCTANCE;
933         } else if (g_str_has_prefix(text, "%")) {
934                 text += strlen("%");
935                 unit = SR_UNIT_PERCENTAGE;
936                 if (!mq)
937                         mq = SR_MQ_DUTY_CYCLE;
938         } else if (g_str_has_prefix(text, "s")) {
939                 text += strlen("s");
940                 unit = SR_UNIT_SECOND;
941                 if (!mq)
942                         mq = SR_MQ_PULSE_WIDTH;
943         } else if (g_str_has_prefix(text, "Hz")) {
944                 text += strlen("Hz");
945                 unit = SR_UNIT_HERTZ;
946                 if (!mq)
947                         mq = SR_MQ_FREQUENCY;
948         } else if (g_str_has_prefix(text, "\xb0" "C")) {
949                 text += strlen("\xb0" "C");
950                 unit = SR_UNIT_CELSIUS;
951                 if (!mq)
952                         mq = SR_MQ_TEMPERATURE;
953         } else if (g_str_has_prefix(text, "\xb0" "F")) {
954                 text += strlen("\xb0" "F");
955                 unit = SR_UNIT_FAHRENHEIT;
956                 if (!mq)
957                         mq = SR_MQ_TEMPERATURE;
958         } else if (g_str_has_prefix(text, "A")) {
959                 text += strlen("A");
960                 unit = SR_UNIT_AMPERE;
961                 if (!mq)
962                         mq = SR_MQ_CURRENT;
963         } else if (g_str_has_prefix(text, "V")) {
964                 text += strlen("V");
965                 unit = SR_UNIT_VOLT;
966                 if (!mq)
967                         mq = SR_MQ_VOLTAGE;
968         } else if (g_str_has_prefix(text, "timestamp")) {
969                 /*
970                  * The meter never provides this "timestamp" label,
971                  * but the driver re-uses common logic here to have
972                  * the MQ details filled in for save/record stamps.
973                  */
974                 text += strlen("timestamp");
975                 unit = SR_UNIT_SECOND;
976                 if (!mq)
977                         mq = SR_MQ_TIME;
978         }
979
980         /* Amend MQ flags from an optional suffix. */
981         if (g_str_has_prefix(text, "ac+dc")) {
982                 text += strlen("ac+dc");
983                 mqflags |= SR_MQFLAG_AC | SR_MQFLAG_DC;
984         } else if (g_str_has_prefix(text, "AC")) {
985                 text += strlen("AC");
986                 mqflags |= SR_MQFLAG_AC;
987         } else if (g_str_has_prefix(text, "DC")) {
988                 text += strlen("DC");
989                 mqflags |= SR_MQFLAG_DC;
990         }
991
992         /* Put all previously determined details into the container. */
993         mqs->scale = scale;
994         mqs->mq = mq;
995         mqs->mqflags = mqflags;
996         mqs->unit = unit;
997
998         return SR_OK;
999 }
1000
1001 /*
1002  * Break down a packed 32bit timestamp presentation, and create an epoch
1003  * value from it. The UT181A protocol encodes timestamps in a 32bit value:
1004  *
1005  *   [5:0] year - 2000
1006  *   [9:6] month
1007  *   [14:10] mday
1008  *   [19:15] hour
1009  *   [25:20] min
1010  *   [31:26] sec
1011  *
1012  * TODO Find a portable and correct conversion helper. The mktime() API
1013  * is said to involve timezone details, and modify the environment. Is
1014  * strftime("%s") a better approach? Until then mktime() might be good
1015  * enough an approach, assuming that the meter will be set to the user's
1016  * local time.
1017  */
1018 static time_t ut181a_get_epoch_for_timestamp(uint32_t ts)
1019 {
1020         struct tm t;
1021
1022         memset(&t, 0, sizeof(t));
1023         t.tm_year = ((ts >> 0) & 0x3f) + 2000 - 1900;
1024         t.tm_mon = ((ts >> 6) & 0x0f) - 1;
1025         t.tm_mday = ((ts >> 10) & 0x1f);
1026         t.tm_hour = ((ts >> 15) & 0x1f);
1027         t.tm_min = ((ts >> 20) & 0x3f);
1028         t.tm_sec = ((ts >> 26) & 0x3f);
1029         t.tm_isdst = -1;
1030
1031         return mktime(&t);
1032 }
1033
1034 /**
1035  * Calculate UT181A specific checksum for serial data frame.
1036  *
1037  * @param[in] data The payload bytes to calculate the checksum for.
1038  * @param[in] dlen The number of payload bytes.
1039  *
1040  * @returns The checksum value.
1041  *
1042  * On the wire the checksum covers all fields after the magic and before
1043  * the checksum. In other words the checksum covers the length field and
1044  * the payload bytes.
1045  */
1046 static uint16_t ut181a_checksum(const uint8_t *data, size_t dlen)
1047 {
1048         uint16_t cs;
1049
1050         cs = 0;
1051         while (dlen-- > 0)
1052                 cs += *data++;
1053
1054         return cs;
1055 }
1056
1057 /**
1058  * Send payload bytes via serial comm, add frame envelope and transmit.
1059  *
1060  * @param[in] serial Serial port.
1061  * @param[in] data Payload bytes.
1062  * @param[in] dlen Payload length.
1063  *
1064  * @returns >= 0 upon success, negative upon failure (SR_ERR codes)
1065  */
1066 static int ut181a_send_frame(struct sr_serial_dev_inst *serial,
1067         const uint8_t *data, size_t dlen)
1068 {
1069         uint8_t frame_buff[SEND_BUFF_SIZE];
1070         size_t frame_off;
1071         const uint8_t *cs_data;
1072         size_t cs_dlen;
1073         uint16_t cs_value;
1074         int ret;
1075
1076         if (FRAME_DUMP_BYTES && sr_log_loglevel_get() >= FRAME_DUMP_LEVEL) {
1077                 GString *spew;
1078                 spew = sr_hexdump_new(data, dlen);
1079                 FRAME_DUMP_CALL("TX payload, %zu bytes: %s", dlen, spew->str);
1080                 sr_hexdump_free(spew);
1081         }
1082
1083         /*
1084          * The frame buffer must hold the magic and length and payload
1085          * bytes and checksum. Check for the available space.
1086          */
1087         if (dlen > sizeof(frame_buff) - 3 * sizeof(uint16_t)) {
1088                 return SR_ERR_ARG;
1089         }
1090
1091         /*
1092          * Create a frame for the payload bytes. The length field's value
1093          * also includes the checksum field (spans the remainder of the
1094          * frame). The checksum covers everything between the magic and
1095          * the checksum field.
1096          */
1097         frame_off = 0;
1098         WL16(&frame_buff[frame_off], FRAME_MAGIC);
1099         frame_off += sizeof(uint16_t);
1100         WL16(&frame_buff[frame_off], dlen + sizeof(uint16_t));
1101         frame_off += sizeof(uint16_t);
1102         memcpy(&frame_buff[frame_off], data, dlen);
1103         frame_off += dlen;
1104         cs_data = &frame_buff[sizeof(uint16_t)];
1105         cs_dlen = frame_off - sizeof(uint16_t);
1106         cs_value = ut181a_checksum(cs_data, cs_dlen);
1107         WL16(&frame_buff[frame_off], cs_value);
1108         frame_off += sizeof(uint16_t);
1109
1110         if (FRAME_DUMP_FRAME && sr_log_loglevel_get() >= FRAME_DUMP_LEVEL) {
1111                 GString *spew;
1112                 spew = sr_hexdump_new(frame_buff, frame_off);
1113                 FRAME_DUMP_CALL("TX frame, %zu bytes: %s", frame_off, spew->str);
1114                 sr_hexdump_free(spew);
1115         }
1116
1117         ret = serial_write_blocking(serial, frame_buff, frame_off, SEND_TO_MS);
1118         if (ret < 0)
1119                 return ret;
1120
1121         return SR_OK;
1122 }
1123
1124 /* Construct and transmit "set mode" command. */
1125 SR_PRIV int ut181a_send_cmd_setmode(struct sr_serial_dev_inst *serial, uint16_t mode)
1126 {
1127         uint8_t cmd[sizeof(uint8_t) + sizeof(uint16_t)];
1128         size_t cmd_off;
1129
1130         cmd_off = 0;
1131         cmd[cmd_off++] = CMD_CODE_SET_MODE;
1132         WL16(&cmd[cmd_off], mode);
1133         cmd_off += sizeof(uint16_t);
1134
1135         return ut181a_send_frame(serial, cmd, cmd_off);
1136 }
1137
1138 /* Construct and transmit "set range" command. */
1139 SR_PRIV int ut181a_send_cmd_setrange(struct sr_serial_dev_inst *serial, uint8_t range)
1140 {
1141         uint8_t cmd[sizeof(uint8_t) + sizeof(uint8_t)];
1142         size_t cmd_off;
1143
1144         cmd_off = 0;
1145         cmd[cmd_off++] = CMD_CODE_SET_RANGE;
1146         cmd[cmd_off++] = range;
1147
1148         return ut181a_send_frame(serial, cmd, cmd_off);
1149 }
1150
1151 /* Construct and transmit "monitor on/off" command. */
1152 SR_PRIV int ut181a_send_cmd_monitor(struct sr_serial_dev_inst *serial, gboolean on)
1153 {
1154         uint8_t cmd[sizeof(uint8_t) + sizeof(uint8_t)];
1155         size_t cmd_off;
1156
1157         cmd_off = 0;
1158         cmd[cmd_off++] = CMD_CODE_SET_MONITOR;
1159         cmd[cmd_off++] = on ? 1 : 0;
1160
1161         return ut181a_send_frame(serial, cmd, cmd_off);
1162 }
1163
1164 /* Construct and transmit "get saved measurements count" command. */
1165 SR_PRIV int ut181a_send_cmd_get_save_count(struct sr_serial_dev_inst *serial)
1166 {
1167         uint8_t cmd;
1168
1169         cmd = CMD_CODE_GET_SAVED_COUNT;
1170         return ut181a_send_frame(serial, &cmd, sizeof(cmd));
1171 }
1172
1173 /*
1174  * Construct and transmit "get saved measurement value" command.
1175  * Important: Callers use 0-based index, protocol needs 1-based index.
1176  */
1177 SR_PRIV int ut181a_send_cmd_get_saved_value(struct sr_serial_dev_inst *serial, size_t idx)
1178 {
1179         uint8_t cmd[sizeof(uint8_t) + sizeof(uint16_t)];
1180         size_t cmd_off;
1181
1182         cmd_off = 0;
1183         cmd[cmd_off++] = CMD_CODE_GET_SAVED_MEAS;
1184         WL16(&cmd[cmd_off], idx + 1);
1185         cmd_off += sizeof(uint16_t);
1186
1187         return ut181a_send_frame(serial, cmd, sizeof(cmd));
1188 }
1189
1190 /* Construct and transmit "get recordings count" command. */
1191 SR_PRIV int ut181a_send_cmd_get_recs_count(struct sr_serial_dev_inst *serial)
1192 {
1193         uint8_t cmd;
1194
1195         cmd = CMD_CODE_GET_RECS_COUNT;
1196         return ut181a_send_frame(serial, &cmd, sizeof(cmd));
1197 }
1198
1199 /*
1200  * Construct and transmit "get recording information" command.
1201  * Important: Callers use 0-based index, protocol needs 1-based index.
1202  */
1203 SR_PRIV int ut181a_send_cmd_get_rec_info(struct sr_serial_dev_inst *serial, size_t idx)
1204 {
1205         uint8_t cmd[sizeof(uint8_t) + sizeof(uint16_t)];
1206         size_t cmd_off;
1207
1208         cmd_off = 0;
1209         cmd[cmd_off++] = CMD_CODE_GET_REC_INFO;
1210         WL16(&cmd[cmd_off], idx + 1);
1211         cmd_off += sizeof(uint16_t);
1212
1213         return ut181a_send_frame(serial, cmd, sizeof(cmd));
1214 }
1215
1216 /*
1217  * Construct and transmit "get recording samples" command.
1218  * Important: Callers use 0-based index, protocol needs 1-based index.
1219  */
1220 SR_PRIV int ut181a_send_cmd_get_rec_samples(struct sr_serial_dev_inst *serial, size_t idx, size_t off)
1221 {
1222         uint8_t cmd[sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t)];
1223         size_t cmd_off;
1224
1225         cmd_off = 0;
1226         cmd[cmd_off++] = CMD_CODE_GET_REC_SAMPLES;
1227         WL16(&cmd[cmd_off], idx + 1);
1228         cmd_off += sizeof(uint16_t);
1229         WL32(&cmd[cmd_off], off + 1);
1230         cmd_off += sizeof(uint32_t);
1231
1232         return ut181a_send_frame(serial, cmd, sizeof(cmd));
1233 }
1234
1235 /* TODO
1236  * Construct and transmit "record on/off" command. Requires a caption,
1237  * an interval, and a duration to start a recording. Recordings can get
1238  * stopped upon request, or end when the requested duration has passed.
1239  */
1240
1241 /**
1242  * Specify which kind of response to wait for.
1243  *
1244  * @param[in] devc The device context.
1245  * @param[in] want_code Reply code wanted, boolean.
1246  * @param[in] want_data Reply data wanted, boolean.
1247  * @param[in] want_rsp_type Special response type wanted.
1248  * @param[in] want_measure Measurement wanted, boolean.
1249  * @param[in] want_rec_count Records count wanted, boolean.
1250  * @param[in] want_save_count Saved count wanted, boolean.
1251  * @param[in] want_sample_count Samples count wanted, boolean.
1252  */
1253 SR_PRIV int ut181a_configure_waitfor(struct dev_context *devc,
1254         gboolean want_code, enum ut181_cmd_code want_data,
1255         enum ut181_rsp_type want_rsp_type,
1256         gboolean want_measure, gboolean want_rec_count,
1257         gboolean want_save_count, gboolean want_sample_count)
1258 {
1259
1260         if (want_rec_count)
1261                 want_data = CMD_CODE_GET_RECS_COUNT;
1262         if (want_save_count)
1263                 want_data = CMD_CODE_GET_SAVED_COUNT;
1264         if (want_sample_count)
1265                 want_data = CMD_CODE_GET_REC_SAMPLES;
1266
1267         memset(&devc->wait_state, 0, sizeof(devc->wait_state));
1268         devc->wait_state.want_code = want_code;
1269         devc->wait_state.want_data = want_data;
1270         devc->wait_state.want_rsp_type = want_rsp_type;
1271         devc->wait_state.want_measure = want_measure;
1272         memset(&devc->last_data, 0, sizeof(devc->last_data));
1273
1274         return SR_OK;
1275 }
1276
1277 /**
1278  * Wait for a response (or timeout) after a command was sent.
1279  *
1280  * @param[in] sdi The device instance.
1281  * @param[in] timeout_ms The timeout in milliseconds.
1282  *
1283  * @returns SR_OK upon success, SR_ERR_* upon error.
1284  *
1285  * This routine waits for the complete reception of a response (any kind)
1286  * after a command was previously sent by the caller, or terminates when
1287  * the timeout has expired without reception of a response. Callers need
1288  * to check the kind of response (data values, or status, or error codes).
1289  */
1290 SR_PRIV int ut181a_waitfor_response(const struct sr_dev_inst *sdi, int timeout_ms)
1291 {
1292         struct dev_context *devc;
1293         gint64 deadline, delay;
1294         struct wait_state *state;
1295
1296         devc = sdi->priv;
1297         state = &devc->wait_state;
1298         state->response_count = 0;
1299
1300         deadline = g_get_monotonic_time();
1301         deadline += timeout_ms * 1000;
1302         delay = 0;
1303         while (1) {
1304                 gboolean got_wanted;
1305                 if (g_get_monotonic_time() >= deadline)
1306                         return SR_ERR_DATA;
1307                 if (delay)
1308                         g_usleep(delay);
1309                 delay = 100;
1310                 ut181a_handle_events(-1, G_IO_IN, (void *)sdi);
1311                 got_wanted = FALSE;
1312                 if (state->want_code && state->got_code)
1313                         got_wanted = TRUE;
1314                 if (state->want_data && state->got_data)
1315                         got_wanted = TRUE;
1316                 if (state->want_rsp_type && state->got_rsp_type)
1317                         got_wanted = TRUE;
1318                 if (state->want_measure && state->got_measure)
1319                         got_wanted = TRUE;
1320                 if (state->want_data == CMD_CODE_GET_RECS_COUNT && state->got_rec_count)
1321                         got_wanted = TRUE;
1322                 if (state->want_data == CMD_CODE_GET_SAVED_COUNT && state->got_save_count)
1323                         got_wanted = TRUE;
1324                 if (state->want_data == CMD_CODE_GET_REC_INFO && state->got_sample_count)
1325                         got_wanted = TRUE;
1326                 if (got_wanted)
1327                         return SR_OK;
1328         }
1329 }
1330
1331 /**
1332  * Get measurement value and precision details from protocol's raw bytes.
1333  */
1334 static int ut181a_get_value_params(struct value_params *params, float value, uint8_t prec)
1335 {
1336
1337         if (!params)
1338                 return SR_ERR_ARG;
1339
1340         memset(params, 0, sizeof(*params));
1341         params->value = value;
1342         params->digits = (prec >> 4) & 0x0f;
1343         params->ol_neg = (prec & (1 << 1)) ? 1 : 0;
1344         params->ol_pos = (prec & (1 << 0)) ? 1 : 0;
1345
1346         return SR_OK;
1347 }
1348
1349 static void ut181a_cond_stop_acquisition(struct sr_dev_inst *sdi)
1350 {
1351         struct dev_context *devc;
1352
1353         if (!sdi)
1354                 return;
1355         devc = sdi->priv;
1356         if (!devc)
1357                 return;
1358
1359         if (sdi->status == SR_ST_ACTIVE)
1360                 sr_dev_acquisition_stop(sdi);
1361 }
1362
1363 /**
1364  * Send meta packet with samplerate to the session feed.
1365  *
1366  * @param[in] sdi The device instance.
1367  * @param[in] interval The sample interval in seconds.
1368  *
1369  * @returns SR_OK upon success, SR_ERR_* upon error.
1370  *
1371  * The DMM records data at intervals which are multiples of seconds.
1372  * The @ref SR_CONF_SAMPLERATE key cannot express the rate values which
1373  * are below 1Hz. Instead the @ref SR_CONF_SAMPLE_INTERVAL key is sent,
1374  * which applications may or may not support.
1375  */
1376 static int ut181a_feed_send_rate(struct sr_dev_inst *sdi, int interval)
1377 {
1378 #if 1
1379         return sr_session_send_meta(sdi,
1380                 SR_CONF_SAMPLE_INTERVAL, g_variant_new_uint64(interval));
1381 #else
1382         uint64_t rate;
1383
1384         /*
1385          * In theory we know the sample interval, and could provide a
1386          * corresponding sample rate. In practice the interval has a
1387          * resolution of seconds, which translates to rates below 1Hz,
1388          * which we cannot express. So let's keep the routine here for
1389          * awareness, and send a rate of 0.
1390          */
1391         (void)interval;
1392         rate = 0;
1393
1394         return sr_session_send_meta(sdi,
1395                 SR_CONF_SAMPLERATE, g_variant_new_uint64(rate));
1396 #endif
1397 }
1398
1399 /**
1400  * Initialize session feed buffer before submission of values.
1401  */
1402 static int ut181a_feedbuff_initialize(struct feed_buffer *buff)
1403 {
1404
1405         memset(buff, 0, sizeof(*buff));
1406
1407         /*
1408          * NOTE: The 'digits' fields get updated later from sample data.
1409          * As do the MQ and unit fields and the channel list.
1410          */
1411         memset(&buff->packet, 0, sizeof(buff->packet));
1412         sr_analog_init(&buff->analog, &buff->encoding, &buff->meaning, &buff->spec, 0);
1413         buff->analog.meaning->mq = 0;
1414         buff->analog.meaning->mqflags = 0;
1415         buff->analog.meaning->unit = 0;
1416         buff->analog.meaning->channels = NULL;
1417         buff->analog.encoding->unitsize = sizeof(buff->main_value);
1418         buff->analog.encoding->digits = 0;
1419         buff->analog.spec->spec_digits = 0;
1420         buff->analog.num_samples = 1;
1421         buff->analog.data = &buff->main_value;
1422         buff->packet.type = SR_DF_ANALOG;
1423         buff->packet.payload = &buff->analog;
1424
1425         return SR_OK;
1426 }
1427
1428 /**
1429  * Setup feed buffer's MQ, MQ flags, and unit before submission of values.
1430  */
1431 static int ut181a_feedbuff_setup_unit(struct feed_buffer *buff, const char *text)
1432 {
1433         int ret;
1434         struct mq_scale_params scale;
1435
1436         /* Derive MQ, flags, unit, and scale from caller's unit text. */
1437         ret = ut181a_get_mq_details_from_text(&scale, text);
1438         if (ret < 0)
1439                 return ret;
1440         buff->scale = scale.scale;
1441         buff->analog.meaning->mq = scale.mq;
1442         buff->analog.meaning->mqflags = scale.mqflags;
1443         buff->analog.meaning->unit = scale.unit;
1444
1445         return SR_OK;
1446 }
1447
1448 /**
1449  * Setup feed buffer's measurement value details before submission of values.
1450  */
1451 static int ut181a_feedbuff_setup_value(struct feed_buffer *buff,
1452         struct value_params *value)
1453 {
1454
1455         if (!buff || !value)
1456                 return SR_ERR_ARG;
1457
1458         if (buff->scale) {
1459                 value->value *= pow(10, buff->scale);
1460                 value->digits += -buff->scale;
1461         }
1462         if (value->ol_neg)
1463                 value->value = -INFINITY;
1464         if (value->ol_pos)
1465                 value->value = +INFINITY;
1466
1467         buff->main_value = value->value;
1468         buff->analog.encoding->digits = value->digits;
1469         buff->analog.spec->spec_digits = value->digits;
1470
1471         return SR_OK;
1472 }
1473
1474 /**
1475  * Setup feed buffer's channel before submission of values.
1476  */
1477 static int ut181a_feedbuff_setup_channel(struct feed_buffer *buff,
1478         enum ut181a_channel_idx ch, struct sr_dev_inst *sdi)
1479 {
1480
1481         if (!buff || !sdi)
1482                 return SR_ERR_ARG;
1483         if (!buff->analog.meaning)
1484                 return SR_ERR_ARG;
1485
1486         g_slist_free(buff->analog.meaning->channels);
1487         buff->analog.meaning->channels = g_slist_append(NULL,
1488                 g_slist_nth_data(sdi->channels, ch));
1489
1490         return SR_OK;
1491 }
1492
1493 /**
1494  * Send previously configured feed buffer's content to the session.
1495  */
1496 static int ut181a_feedbuff_send_feed(struct feed_buffer *buff,
1497         struct sr_dev_inst *sdi, size_t count)
1498 {
1499         int ret;
1500         struct dev_context *devc;
1501
1502         if (!buff || !sdi)
1503                 return SR_ERR_ARG;
1504
1505         if (sdi->status != SR_ST_ACTIVE)
1506                 return SR_OK;
1507         devc = sdi->priv;
1508         if (!devc || devc->disable_feed)
1509                 return SR_OK;
1510
1511         ret = sr_session_send(sdi, &buff->packet);
1512         if (ret == SR_OK && count && sdi->priv) {
1513                 sr_sw_limits_update_samples_read(&devc->limits, count);
1514                 if (sr_sw_limits_check(&devc->limits))
1515                         ut181a_cond_stop_acquisition(sdi);
1516         }
1517
1518         return ret;
1519 }
1520
1521 /**
1522  * Release previously allocated resources in the feed buffer.
1523  */
1524 static int ut181a_feedbuff_cleanup(struct feed_buffer *buff)
1525 {
1526         if (!buff)
1527                 return SR_ERR_ARG;
1528
1529         if (buff->analog.meaning)
1530                 g_slist_free(buff->analog.meaning->channels);
1531
1532         return SR_OK;
1533 }
1534
1535 static int ut181a_feedbuff_start_frame(struct sr_dev_inst *sdi)
1536 {
1537         struct dev_context *devc;
1538         int ret;
1539
1540         devc = sdi->priv;
1541         if (devc->disable_feed)
1542                 return SR_OK;
1543         if (devc->frame_started)
1544                 return SR_OK;
1545
1546         ret = std_session_send_df_frame_begin(sdi);
1547         if (ret == SR_OK)
1548                 devc->frame_started = TRUE;
1549
1550         return ret;
1551 }
1552
1553 static int ut181a_feedbuff_count_frame(struct sr_dev_inst *sdi)
1554 {
1555         struct dev_context *devc;
1556         int ret;
1557
1558         devc = sdi->priv;
1559         if (devc->disable_feed)
1560                 return SR_OK;
1561         if (!devc->frame_started)
1562                 return SR_OK;
1563
1564         ret = std_session_send_df_frame_end(sdi);
1565         if (ret != SR_OK)
1566                 return ret;
1567         devc->frame_started = FALSE;
1568
1569         sr_sw_limits_update_frames_read(&devc->limits, 1);
1570         if (sr_sw_limits_check(&devc->limits))
1571                 ut181a_cond_stop_acquisition(sdi);
1572
1573         return SR_OK;
1574 }
1575
1576 /* Deserializing helpers which also advance the read pointer. */
1577
1578 static int check_len(size_t *got, size_t want)
1579 {
1580
1581         if (!got)
1582                 return SR_ERR_ARG;
1583         if (want > *got)
1584                 return SR_ERR_DATA;
1585
1586         return SR_OK;
1587 }
1588
1589 static void advance_len(const uint8_t **p, size_t *l, size_t sz)
1590 {
1591
1592         if (p)
1593                 *p += sz;
1594         if (l)
1595                 *l -= sz;
1596 }
1597
1598 static int consume_u8(uint8_t *v, const uint8_t **p, size_t *l)
1599 {
1600         size_t sz;
1601         int ret;
1602
1603         if (v)
1604                 *v = 0;
1605
1606         sz = sizeof(uint8_t);
1607         ret = check_len(l, sz);
1608         if (ret != SR_OK)
1609                 return ret;
1610
1611         if (v)
1612                 *v = R8(*p);
1613         advance_len(p, l, sz);
1614
1615         return SR_OK;
1616 }
1617
1618 static int consume_u16(uint16_t *v, const uint8_t **p, size_t *l)
1619 {
1620         size_t sz;
1621         int ret;
1622
1623         if (v)
1624                 *v = 0;
1625
1626         sz = sizeof(uint16_t);
1627         ret = check_len(l, sz);
1628         if (ret != SR_OK)
1629                 return ret;
1630
1631         if (v)
1632                 *v = RL16(*p);
1633         advance_len(p, l, sz);
1634
1635         return SR_OK;
1636 }
1637
1638 static int consume_u32(uint32_t *v, const uint8_t **p, size_t *l)
1639 {
1640         size_t sz;
1641         int ret;
1642
1643         if (v)
1644                 *v = 0;
1645
1646         sz = sizeof(uint32_t);
1647         ret = check_len(l, sz);
1648         if (ret != SR_OK)
1649                 return ret;
1650
1651         if (v)
1652                 *v = RL32(*p);
1653         advance_len(p, l, sz);
1654
1655         return SR_OK;
1656 }
1657
1658 static int consume_flt(float *v, const uint8_t **p, size_t *l)
1659 {
1660         size_t sz;
1661         int ret;
1662
1663         if (v)
1664                 *v = 0;
1665
1666         sz = sizeof(float);
1667         ret = check_len(l, sz);
1668         if (ret != SR_OK)
1669                 return ret;
1670
1671         if (v)
1672                 *v = RLFL(*p);
1673         advance_len(p, l, sz);
1674
1675         return SR_OK;
1676 }
1677
1678 /*
1679  * Fills the caller's text buffer from input data. Also trims and NUL
1680  * terminates the buffer content so that callers don't have to.
1681  */
1682 static int consume_str(char *buff, size_t sz, const uint8_t **p, size_t *l)
1683 {
1684         int ret;
1685         const char *v;
1686
1687         if (buff)
1688                 *buff = '\0';
1689
1690         ret = check_len(l, sz);
1691         if (ret != SR_OK)
1692                 return ret;
1693
1694         /*
1695          * Quickly grab current position. Immediate bailout if there is
1696          * no caller buffer to fill in. Simpilifies the remaining logic.
1697          */
1698         v = (const char *)*p;
1699         advance_len(p, l, sz);
1700         if (!buff)
1701                 return SR_OK;
1702
1703         /*
1704          * Trim leading space off the input text. Then copy the remaining
1705          * input data to the caller's buffer. This operation is bounded,
1706          * and adds the NUL termination. Then trim trailing space.
1707          *
1708          * The resulting buffer content is known to be NUL terminated.
1709          * It has at most the requested size (modulo the termination).
1710          * The content may be empty, which can be acceptable to callers.
1711          * So these need to check for and handle that condition.
1712          */
1713         memset(buff, 0, sz);
1714         while (sz && isspace(*v)) {
1715                 v++;
1716                 sz--;
1717         }
1718         if (sz)
1719                 snprintf(buff, sz, "%s", v);
1720         buff[sz] = '\0';
1721         sz = strlen(buff);
1722         while (sz && isspace(buff[sz - 1])) {
1723                 buff[--sz] = '\0';
1724         }
1725
1726         return SR_OK;
1727 }
1728
1729 /* Process a DMM packet (a frame in the serial protocol). */
1730 static int process_packet(struct sr_dev_inst *sdi, uint8_t *pkt, size_t len)
1731 {
1732         struct dev_context *devc;
1733         struct wait_state *state;
1734         struct ut181a_info *info;
1735         uint16_t got_magic, got_length, got_cs, want_cs;
1736         const uint8_t *cs_data, *payload;
1737         size_t cs_dlen, pl_dlen;
1738         uint8_t rsp_type;
1739         enum sr_mqflag add_mqflags;
1740         char unit_buff[8], rec_name_buff[11];
1741         const char *unit_text, *rec_name;
1742         struct feed_buffer feedbuff;
1743         struct value_params value;
1744         const struct mqopt_item *mqitem;
1745         int ret;
1746         uint8_t v8; uint16_t v16; uint32_t v32; float vf;
1747
1748         /*
1749          * Cope with different calling contexts. The packet parser can
1750          * get invoked outside of data acquisition, during preparation
1751          * or in shutdown paths.
1752          */
1753         devc = sdi ? sdi->priv : NULL;
1754         state = devc ? &devc->wait_state : NULL;
1755         info = devc ? &devc->info : NULL;
1756         if (FRAME_DUMP_FRAME && sr_log_loglevel_get() >= FRAME_DUMP_LEVEL) {
1757                 GString *spew;
1758                 spew = sr_hexdump_new(pkt, len);
1759                 FRAME_DUMP_CALL("RX frame, %zu bytes: %s", len, spew->str);
1760                 sr_hexdump_free(spew);
1761         }
1762
1763         /*
1764          * Check the frame envelope. Redundancy with common reception
1765          * logic is perfectly fine. Several code paths end up here, we
1766          * need to gracefully deal with incomplete or incorrect data.
1767          *
1768          * This stage uses random access to arbitrary positions in the
1769          * packet which surround the payload. Before the then available
1770          * payload gets consumed in a strict serial manner.
1771          */
1772         if (len < 3 * sizeof(uint16_t)) {
1773                 /* Need at least magic, length, checksum. */
1774                 if (FRAME_DUMP_CSUM) {
1775                         FRAME_DUMP_CALL("Insufficient frame data, need %zu, got %zu.",
1776                                 3 * sizeof(uint16_t), len);
1777                 }
1778                 return SR_ERR_DATA;
1779         }
1780
1781         got_magic = RL16(&pkt[0]);
1782         if (got_magic != FRAME_MAGIC) {
1783                 if (FRAME_DUMP_CSUM) {
1784                         FRAME_DUMP_CALL("Frame magic mismatch, want 0x%04x, got 0x%04x.",
1785                                 (unsigned int)FRAME_MAGIC, (unsigned int)got_magic);
1786                 }
1787                 return SR_ERR_DATA;
1788         }
1789
1790         got_length = RL16(&pkt[sizeof(uint16_t)]);
1791         if (got_length != len - 2 * sizeof(uint16_t)) {
1792                 if (FRAME_DUMP_CSUM) {
1793                         FRAME_DUMP_CALL("Frame length mismatch, want %zu, got %u.",
1794                                 len - 2 * sizeof(uint16_t), got_length);
1795                 }
1796                 return SR_ERR_DATA;
1797         }
1798
1799         payload = &pkt[2 * sizeof(uint16_t)];
1800         pl_dlen = got_length - sizeof(uint16_t);
1801
1802         cs_data = &pkt[sizeof(uint16_t)];
1803         cs_dlen = len - 2 * sizeof(uint16_t);
1804         want_cs = ut181a_checksum(cs_data, cs_dlen);
1805         got_cs = RL16(&pkt[len - sizeof(uint16_t)]);
1806         if (got_cs != want_cs) {
1807                 if (FRAME_DUMP_CSUM) {
1808                         FRAME_DUMP_CALL("Frame checksum mismatch, want 0x%04x, got 0x%04x.",
1809                                 (unsigned int)want_cs, (unsigned int)got_cs);
1810                 }
1811                 return SR_ERR_DATA;
1812         }
1813         if (state)
1814                 state->response_count++;
1815         if (FRAME_DUMP_BYTES && sr_log_loglevel_get() >= FRAME_DUMP_LEVEL) {
1816                 GString *spew;
1817                 spew = sr_hexdump_new(payload, pl_dlen);
1818                 FRAME_DUMP_CALL("RX payload, %zu bytes: %s", pl_dlen, spew->str);
1819                 sr_hexdump_free(spew);
1820         }
1821
1822         /*
1823          * Interpret the frame's payload data. The first byte contains
1824          * a packet type which specifies how to interpret the remainder.
1825          */
1826         ret = consume_u8(&v8, &payload, &pl_dlen);
1827         if (ret != SR_OK) {
1828                 sr_err("Insufficient payload data, need packet type.");
1829                 return ret;
1830         }
1831         rsp_type = v8;
1832         if (info)
1833                 info->rsp_head.rsp_type = rsp_type;
1834
1835         add_mqflags = 0;
1836         switch (rsp_type) {
1837         case RSP_TYPE_REPLY_CODE:
1838                 /*
1839                  * Reply code: One 16bit item with either 'OK' or 'ER'
1840                  * "string literals" to communicate boolean state.
1841                  */
1842                 ret = consume_u16(&v16, &payload, &pl_dlen);
1843                 if (ret != SR_OK)
1844                         return SR_ERR_DATA;
1845                 if (info) {
1846                         info->reply_code.code = v16;
1847                         info->reply_code.ok = v16 == REPLY_CODE_OK;
1848                 }
1849                 if (state && state->want_code) {
1850                         state->got_code = TRUE;
1851                         state->code_ok = v16 == REPLY_CODE_OK;
1852                 }
1853                 break;
1854         case RSP_TYPE_SAVE:
1855                 /*
1856                  * Saved measurement: A 32bit timestamp, followed by a
1857                  * measurement (FALLTHROUGH).
1858                  */
1859                 ret = consume_u32(&v32, &payload, &pl_dlen);
1860                 if (ret != SR_OK)
1861                         return SR_ERR_DATA;
1862                 if (info)
1863                         info->save_time.stamp = v32;
1864                 v32 = ut181a_get_epoch_for_timestamp(v32);
1865                 if (info)
1866                         info->save_time.epoch = v32;
1867
1868 #if UT181A_WITH_TIMESTAMP
1869                 if (devc) {
1870                         ret = ut181a_feedbuff_start_frame(sdi);
1871                         if (ret != SR_OK)
1872                                 return SR_ERR_DATA;
1873                         ret = SR_OK;
1874                         ret |= ut181a_feedbuff_initialize(&feedbuff);
1875                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_TIME, sdi);
1876                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, "timestamp");
1877                         ret |= ut181a_get_value_params(&value, v32, 0x00);
1878                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
1879                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
1880                         ret |= ut181a_feedbuff_cleanup(&feedbuff);
1881                         if (ret != SR_OK)
1882                                 return SR_ERR_DATA;
1883                 }
1884 #endif
1885                 if (info)
1886                         info->save_info.save_idx++;
1887
1888                 /* FALLTHROUGH */
1889         case RSP_TYPE_MEASUREMENT:
1890                 /*
1891                  * A measurement. Starts with a common header, which
1892                  * specifies the layout of the remainder (variants, with
1893                  * optional fields, depending on preceeding fields).
1894                  *
1895                  * Only useful to process when 'info' (and thus 'devc')
1896                  * are available.
1897                  */
1898                 if (!info)
1899                         return SR_ERR_NA;
1900
1901                 /*
1902                  * Get the header fields (misc1, misc2, mode, and range),
1903                  * derive local packet type details and flags from them.
1904                  */
1905                 ret = consume_u8(&v8, &payload, &pl_dlen);
1906                 if (ret != SR_OK)
1907                         return SR_ERR_DATA;
1908                 info->meas_head.misc1 = v8;
1909                 info->meas_head.has_hold = (v8 & 0x80) ? 1 : 0;
1910                 info->meas_head.is_type = (v8 & 0x70) >> 4;
1911                 info->meas_head.is_norm = (info->meas_head.is_type == 0) ? 1 : 0;
1912                 info->meas_head.is_rel = (info->meas_head.is_type == 1) ? 1 : 0;
1913                 info->meas_head.is_minmax = (info->meas_head.is_type == 2) ? 1 : 0;
1914                 info->meas_head.is_peak = (info->meas_head.is_type == 4) ? 1 : 0;
1915                 info->meas_head.has_bar = (v8 & 0x8) ? 1 : 0;
1916                 info->meas_head.has_aux2 = (v8 & 0x4) ? 1 : 0;
1917                 info->meas_head.has_aux1 = (v8 & 0x2) ? 1 : 0;
1918
1919                 ret = consume_u8(&v8, &payload, &pl_dlen);
1920                 if (ret != SR_OK)
1921                         return SR_ERR_DATA;
1922                 info->meas_head.misc2 = v8;
1923                 info->meas_head.is_rec = (v8 & 0x20) ? 1 : 0;
1924                 if (devc)
1925                         devc->is_recording = info->meas_head.is_rec;
1926                 info->meas_head.is_comp = (v8 & 0x10) ? 1 : 0;
1927                 info->meas_head.has_lead_err = (v8 & 0x8) ? 1 : 0;
1928                 info->meas_head.has_high_volt = (v8 & 0x2) ? 1 : 0;
1929                 info->meas_head.is_auto_range = (v8 & 0x1) ? 1 : 0;
1930
1931                 ret = consume_u16(&v16, &payload, &pl_dlen);
1932                 if (ret != SR_OK)
1933                         return SR_ERR_DATA;
1934                 info->meas_head.mode = v16;
1935                 mqitem = ut181a_get_mqitem_from_mode(v16);
1936                 if (!mqitem || !mqitem->mq)
1937                         return SR_ERR_DATA;
1938                 add_mqflags |= mqitem->mqflags;
1939                 if (info->meas_head.has_hold)
1940                         add_mqflags |= SR_MQFLAG_HOLD;
1941                 if (info->meas_head.is_auto_range)
1942                         add_mqflags |= SR_MQFLAG_AUTORANGE;
1943                 if (add_mqflags & SR_MQFLAG_DIODE)
1944                         add_mqflags |= SR_MQFLAG_DC;
1945
1946                 ret = consume_u8(&v8, &payload, &pl_dlen);
1947                 if (ret != SR_OK)
1948                         return SR_ERR_DATA;
1949                 info->meas_head.range = v8;
1950
1951                 if (state && state->want_measure)
1952                         state->got_measure = TRUE;
1953
1954                 ret = ut181a_feedbuff_start_frame(sdi);
1955                 if (ret != SR_OK)
1956                         return SR_ERR_DATA;
1957
1958                 /*
1959                  * The remaining measurement's layout depends on type.
1960                  * - Normal measurement:
1961                  *   - Main value (4/1/8 value/precision/unit).
1962                  *   - Aux1 value (4/1/8 value/precision/unit) when AUX1
1963                  *     flag active.
1964                  *   - Aux2 value (4/1/8 value/precision/unit) when AUX2
1965                  *     flag active.
1966                  *   - Bargraph (4/8 value/unit) when BAR flag active.
1967                  *   - COMP result when COMP flag active.
1968                  *     - Always 1/1/1/4 mode/flags/digits/limit: type
1969                  *       of check, PASS/FAIL verdict, limit values'
1970                  *       precision, upper or only limit.
1971                  *     - Conditional 4 limit: Lower limit for checks
1972                  *       which involve two limit values.
1973                  * - Relative measurement:
1974                  *   - Relative value (4/1/8 value/precision/unit).
1975                  *   - Reference value (4/1/8 value/precision/unit),
1976                  *     when AUX1 active (practically always).
1977                  *   - Absolute value (4/1/8 value/precision/unit),
1978                  *     when AUX2 active (practically always).
1979                  *   - Bargraph (4/8 value/unit) when BAR flag active.
1980                  * - Min/Max measurement:
1981                  *   - All fields always present, no conditions.
1982                  *   - One common unit spec at the end which applies to
1983                  *     all curr/max/avg/min values.
1984                  *   - Current value (4/1 value/precision).
1985                  *   - Maximum value (4/1/4 value/precision/time).
1986                  *   - Average value (4/1/4 value/precision/time).
1987                  *   - Minimum value (4/1/4 value/precision/time).
1988                  *   - Common unit text (8).
1989                  * - Peak measurement:
1990                  *   - All fields always present.
1991                  *   - Maximum value (4/1/8 value/precision/unit).
1992                  *   - Minimum value (4/1/8 value/precision/unit).
1993                  */
1994                 ret = ut181a_feedbuff_initialize(&feedbuff);
1995                 if (info->meas_head.is_norm) {
1996                         /* Main value, unconditional. Get details. */
1997                         ret = consume_flt(&vf, &payload, &pl_dlen);
1998                         if (ret != SR_OK)
1999                                 return SR_ERR_DATA;
2000                         info->meas_data.norm.main_value = vf;
2001                         ret = consume_u8(&v8, &payload, &pl_dlen);
2002                         if (ret != SR_OK)
2003                                 return SR_ERR_DATA;
2004                         info->meas_data.norm.main_prec = v8;
2005                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2006                         unit_text = &unit_buff[0];
2007                         if (ret != SR_OK)
2008                                 return SR_ERR_DATA;
2009                         snprintf(info->meas_data.norm.main_unit,
2010                                 sizeof(info->meas_data.norm.main_unit),
2011                                 "%s", unit_text);
2012                         unit_text = info->meas_data.norm.main_unit;
2013
2014                         /* Submit main value to session feed. */
2015                         ret = SR_OK;
2016                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_MAIN, sdi);
2017                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2018                         feedbuff.analog.meaning->mqflags |= add_mqflags;
2019                         ret |= ut181a_get_value_params(&value, vf, v8);
2020                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2021                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 1);
2022                         if (ret != SR_OK)
2023                                 return SR_ERR_DATA;
2024                 }
2025                 if (info->meas_head.is_norm && info->meas_head.has_aux1) {
2026                         /* Aux1 value, optional. Get details. */
2027                         ret = consume_flt(&vf, &payload, &pl_dlen);
2028                         if (ret != SR_OK)
2029                                 return SR_ERR_DATA;
2030                         info->meas_data.norm.aux1_value = vf;
2031                         ret = consume_u8(&v8, &payload, &pl_dlen);
2032                         if (ret != SR_OK)
2033                                 return SR_ERR_DATA;
2034                         info->meas_data.norm.aux1_prec = v8;
2035                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2036                         unit_text = &unit_buff[0];
2037                         if (ret != SR_OK)
2038                                 return SR_ERR_DATA;
2039                         snprintf(info->meas_data.norm.aux1_unit,
2040                                 sizeof(info->meas_data.norm.aux1_unit),
2041                                 "%s", unit_text);
2042                         unit_text = info->meas_data.norm.aux1_unit;
2043
2044                         /* Submit aux1 value to session feed. */
2045                         ret = SR_OK;
2046                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_AUX1, sdi);
2047                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2048                         ret |= ut181a_get_value_params(&value, vf, v8);
2049                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2050                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2051                         if (ret != SR_OK)
2052                                 return SR_ERR_DATA;
2053                 }
2054                 if (info->meas_head.is_norm && info->meas_head.has_aux2) {
2055                         /* Aux2 value, optional. Get details. */
2056                         ret = consume_flt(&vf, &payload, &pl_dlen);
2057                         if (ret != SR_OK)
2058                                 return SR_ERR_DATA;
2059                         info->meas_data.norm.aux2_value = vf;
2060                         ret = consume_u8(&v8, &payload, &pl_dlen);
2061                         if (ret != SR_OK)
2062                                 return SR_ERR_DATA;
2063                         info->meas_data.norm.aux2_prec = v8;
2064                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2065                         unit_text = &unit_buff[0];
2066                         if (ret != SR_OK)
2067                                 return SR_ERR_DATA;
2068                         snprintf(info->meas_data.norm.aux2_unit,
2069                                 sizeof(info->meas_data.norm.aux2_unit),
2070                                 "%s", unit_text);
2071                         unit_text = info->meas_data.norm.aux2_unit;
2072
2073                         /* Submit aux2 value to session feed. */
2074                         ret = SR_OK;
2075                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_AUX2, sdi);
2076                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2077                         ret |= ut181a_get_value_params(&value, vf, v8);
2078                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2079                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2080                         if (ret != SR_OK)
2081                                 return SR_ERR_DATA;
2082                 }
2083                 if (info->meas_head.is_norm && info->meas_head.has_bar) {
2084                         /* Bargraph value, optional. */
2085                         ret = consume_flt(&vf, &payload, &pl_dlen);
2086                         if (ret != SR_OK)
2087                                 return SR_ERR_DATA;
2088                         info->meas_data.norm.bar_value = vf;
2089                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2090                         unit_text = &unit_buff[0];
2091                         if (ret != SR_OK)
2092                                 return SR_ERR_DATA;
2093                         snprintf(info->meas_data.norm.bar_unit,
2094                                 sizeof(info->meas_data.norm.bar_unit),
2095                                 "%s", unit_text);
2096                         unit_text = info->meas_data.norm.bar_unit;
2097
2098                         /* Submit bargraph value to session feed. */
2099                         ret = 0;
2100                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_BAR, sdi);
2101                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2102                         ret |= ut181a_get_value_params(&value, vf, 0x00);
2103                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2104                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2105                         if (ret != SR_OK)
2106                                 return SR_ERR_DATA;
2107                 }
2108                 if (info->meas_head.is_norm && info->meas_head.is_comp) {
2109                         /* COMP result, optional. Get details. */
2110                         ret = consume_u8(&v8, &payload, &pl_dlen);
2111                         if (ret != SR_OK)
2112                                 return SR_ERR_DATA;
2113                         if (v8 > COMP_MODE_ABOVE)
2114                                 return SR_ERR_DATA;
2115                         info->meas_data.comp.mode = v8;
2116                         ret = consume_u8(&v8, &payload, &pl_dlen);
2117                         if (ret != SR_OK)
2118                                 return SR_ERR_DATA;
2119                         info->meas_data.comp.fail = v8 ? TRUE : FALSE;
2120                         ret = consume_u8(&v8, &payload, &pl_dlen);
2121                         if (ret != SR_OK)
2122                                 return SR_ERR_DATA;
2123                         info->meas_data.comp.digits = v8 & 0x0f;
2124                         ret = consume_flt(&vf, &payload, &pl_dlen);
2125                         if (ret != SR_OK)
2126                                 return SR_ERR_DATA;
2127                         info->meas_data.comp.limit_high = vf;
2128                         if (info->meas_data.comp.mode <= COMP_MODE_OUTER) {
2129                                 ret = consume_flt(&vf, &payload, &pl_dlen);
2130                                 if (ret != SR_OK)
2131                                         return SR_ERR_DATA;
2132                                 info->meas_data.comp.limit_low = vf;
2133                         }
2134
2135                         /* TODO
2136                          * How to present this result to the feed? This
2137                          * implementation extracts and interprets the
2138                          * fields, but does not pass the values to the
2139                          * session. Which MQ to use for PASS/FAIL checks?
2140                          */
2141                         static const char *mode_text[] = {
2142                                 [COMP_MODE_INNER] = "INNER",
2143                                 [COMP_MODE_OUTER] = "OUTER",
2144                                 [COMP_MODE_BELOW] = "BELOW",
2145                                 [COMP_MODE_ABOVE] = "ABOVE",
2146                         };
2147
2148                         if (info->meas_data.comp.mode <= COMP_MODE_OUTER) {
2149                                 sr_dbg("Unprocessed COMP result:"
2150                                         " mode %s, %s, digits %d, low %f, high %f",
2151                                         mode_text[info->meas_data.comp.mode],
2152                                         info->meas_data.comp.fail ? "FAIL" : "PASS",
2153                                         info->meas_data.comp.digits,
2154                                         info->meas_data.comp.limit_low,
2155                                         info->meas_data.comp.limit_high);
2156                         } else {
2157                                 sr_dbg("Unprocessed COMP result:"
2158                                         " mode %s, %s, digits %d, limit %f",
2159                                         mode_text[info->meas_data.comp.mode],
2160                                         info->meas_data.comp.fail ? "FAIL" : "PASS",
2161                                         info->meas_data.comp.digits,
2162                                         info->meas_data.comp.limit_high);
2163                         }
2164                 }
2165                 if (info->meas_head.is_norm) {
2166                         /* Normal measurement code path done. */
2167                         ret = ut181a_feedbuff_cleanup(&feedbuff);
2168                         ret = ut181a_feedbuff_count_frame(sdi);
2169                         if (ret != SR_OK)
2170                                 return SR_ERR_DATA;
2171                         break;
2172                 }
2173
2174                 if (info->meas_head.is_rel) {
2175                         /* Relative value, unconditional. Get details. */
2176                         ret = consume_flt(&vf, &payload, &pl_dlen);
2177                         if (ret != SR_OK)
2178                                 return SR_ERR_DATA;
2179                         info->meas_data.rel.rel_value = vf;
2180                         ret = consume_u8(&v8, &payload, &pl_dlen);
2181                         if (ret != SR_OK)
2182                                 return SR_ERR_DATA;
2183                         info->meas_data.rel.rel_prec = v8;
2184                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2185                         unit_text = &unit_buff[0];
2186                         if (ret != SR_OK)
2187                                 return SR_ERR_DATA;
2188                         snprintf(info->meas_data.rel.rel_unit,
2189                                 sizeof(info->meas_data.rel.rel_unit),
2190                                 "%s", unit_text);
2191                         unit_text = info->meas_data.rel.rel_unit;
2192
2193                         /* Submit relative value to session feed. */
2194                         ret = SR_OK;
2195                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_MAIN, sdi);
2196                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2197                         feedbuff.analog.meaning->mqflags |= add_mqflags;
2198                         feedbuff.analog.meaning->mqflags |= SR_MQFLAG_RELATIVE;
2199                         ret |= ut181a_get_value_params(&value, vf, v8);
2200                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2201                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 1);
2202                         if (ret != SR_OK)
2203                                 return SR_ERR_DATA;
2204                 }
2205                 if (info->meas_head.is_rel && info->meas_head.has_aux1) {
2206                         /* Reference value, "conditional" in theory. */
2207                         ret = consume_flt(&vf, &payload, &pl_dlen);
2208                         if (ret != SR_OK)
2209                                 return SR_ERR_DATA;
2210                         info->meas_data.rel.ref_value = vf;
2211                         ret = consume_u8(&v8, &payload, &pl_dlen);
2212                         if (ret != SR_OK)
2213                                 return SR_ERR_DATA;
2214                         info->meas_data.rel.ref_prec = v8;
2215                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2216                         unit_text = &unit_buff[0];
2217                         if (ret != SR_OK)
2218                                 return SR_ERR_DATA;
2219                         snprintf(info->meas_data.rel.ref_unit,
2220                                 sizeof(info->meas_data.rel.ref_unit),
2221                                 "%s", unit_text);
2222                         unit_text = info->meas_data.rel.ref_unit;
2223
2224                         /* Submit reference value to session feed. */
2225                         ret = SR_OK;
2226                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_AUX1, sdi);
2227                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2228                         feedbuff.analog.meaning->mqflags |= SR_MQFLAG_REFERENCE;
2229                         ret |= ut181a_get_value_params(&value, vf, v8);
2230                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2231                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2232                         if (ret != SR_OK)
2233                                 return SR_ERR_DATA;
2234                 }
2235                 if (info->meas_head.is_rel && info->meas_head.has_aux2) {
2236                         /* Absolute value, "conditional" in theory. */
2237                         ret = consume_flt(&vf, &payload, &pl_dlen);
2238                         if (ret != SR_OK)
2239                                 return SR_ERR_DATA;
2240                         info->meas_data.rel.abs_value = vf;
2241                         ret = consume_u8(&v8, &payload, &pl_dlen);
2242                         if (ret != SR_OK)
2243                                 return SR_ERR_DATA;
2244                         info->meas_data.rel.abs_prec = v8;
2245                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2246                         unit_text = &unit_buff[0];
2247                         if (ret != SR_OK)
2248                                 return SR_ERR_DATA;
2249                         snprintf(info->meas_data.rel.abs_unit,
2250                                 sizeof(info->meas_data.rel.abs_unit),
2251                                 "%s", unit_text);
2252                         unit_text = info->meas_data.rel.abs_unit;
2253
2254                         /* Submit absolute value to session feed. */
2255                         ret = SR_OK;
2256                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_AUX2, sdi);
2257                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2258                         ret |= ut181a_get_value_params(&value, vf, v8);
2259                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2260                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2261                         if (ret != SR_OK)
2262                                 return SR_ERR_DATA;
2263                 }
2264                 if (info->meas_head.is_rel && info->meas_head.has_bar) {
2265                         /* Bargraph value, conditional. */
2266                         ret = consume_flt(&vf, &payload, &pl_dlen);
2267                         if (ret != SR_OK)
2268                                 return SR_ERR_DATA;
2269                         info->meas_data.rel.bar_value = vf;
2270                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2271                         unit_text = &unit_buff[0];
2272                         if (ret != SR_OK)
2273                                 return SR_ERR_DATA;
2274                         snprintf(info->meas_data.rel.bar_unit,
2275                                 sizeof(info->meas_data.rel.bar_unit),
2276                                 "%s", unit_text);
2277                         unit_text = info->meas_data.rel.bar_unit;
2278
2279                         /* Submit bargraph value to session feed. */
2280                         ret = SR_OK;
2281                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_BAR, sdi);
2282                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2283                         ret |= ut181a_get_value_params(&value, vf, 0x00);
2284                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2285                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2286                         if (ret != SR_OK)
2287                                 return SR_ERR_DATA;
2288                 }
2289                 if (info->meas_head.is_rel) {
2290                         /* Relative measurement code path done. */
2291                         ret = ut181a_feedbuff_cleanup(&feedbuff);
2292                         ret = ut181a_feedbuff_count_frame(sdi);
2293                         if (ret != SR_OK)
2294                                 return SR_ERR_DATA;
2295                         break;
2296                 }
2297
2298                 if (info->meas_head.is_minmax) {
2299                         /*
2300                          * Min/max measurement values, none of them are
2301                          * conditional in practice (all are present).
2302                          * This is special in that all of curr, max, avg,
2303                          * and min values share the same unit text which
2304                          * is only at the end of the data fields.
2305                          */
2306                         ret = SR_OK;
2307                         ret |= consume_flt(&info->meas_data.minmax.curr_value, &payload, &pl_dlen);
2308                         ret |= consume_u8(&info->meas_data.minmax.curr_prec, &payload, &pl_dlen);
2309                         ret |= consume_flt(&info->meas_data.minmax.max_value, &payload, &pl_dlen);
2310                         ret |= consume_u8(&info->meas_data.minmax.max_prec, &payload, &pl_dlen);
2311                         ret |= consume_u32(&info->meas_data.minmax.max_stamp, &payload, &pl_dlen);
2312                         ret |= consume_flt(&info->meas_data.minmax.avg_value, &payload, &pl_dlen);
2313                         ret |= consume_u8(&info->meas_data.minmax.avg_prec, &payload, &pl_dlen);
2314                         ret |= consume_u32(&info->meas_data.minmax.avg_stamp, &payload, &pl_dlen);
2315                         ret |= consume_flt(&info->meas_data.minmax.min_value, &payload, &pl_dlen);
2316                         ret |= consume_u8(&info->meas_data.minmax.min_prec, &payload, &pl_dlen);
2317                         ret |= consume_u32(&info->meas_data.minmax.min_stamp, &payload, &pl_dlen);
2318                         ret |= consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2319                         unit_text = &unit_buff[0];
2320                         if (ret != SR_OK)
2321                                 return SR_ERR_DATA;
2322                         snprintf(info->meas_data.minmax.all_unit,
2323                                 sizeof(info->meas_data.minmax.all_unit),
2324                                 "%s", unit_text);
2325                         unit_text = info->meas_data.minmax.all_unit;
2326
2327                         /* Submit the current value. */
2328                         vf = info->meas_data.minmax.curr_value;
2329                         v8 = info->meas_data.minmax.curr_prec;
2330                         ret = SR_OK;
2331                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_MAIN, sdi);
2332                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2333                         feedbuff.analog.meaning->mqflags |= add_mqflags;
2334                         ret |= ut181a_get_value_params(&value, vf, v8);
2335                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2336                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 1);
2337                         if (ret != SR_OK)
2338                                 return SR_ERR_DATA;
2339
2340                         /* Submit the maximum value. */
2341                         vf = info->meas_data.minmax.max_value;
2342                         v8 = info->meas_data.minmax.max_prec;
2343                         ret = SR_OK;
2344                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_AUX1, sdi);
2345                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2346                         feedbuff.analog.meaning->mqflags |= SR_MQFLAG_MAX;
2347                         ret |= ut181a_get_value_params(&value, vf, v8);
2348                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2349                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2350                         if (ret != SR_OK)
2351                                 return SR_ERR_DATA;
2352
2353                         /* Submit the average value. */
2354                         vf = info->meas_data.minmax.avg_value;
2355                         v8 = info->meas_data.minmax.avg_prec;
2356                         ret = SR_OK;
2357                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_AUX2, sdi);
2358                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2359                         feedbuff.analog.meaning->mqflags |= SR_MQFLAG_AVG;
2360                         ret |= ut181a_get_value_params(&value, vf, v8);
2361                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2362                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2363                         if (ret != SR_OK)
2364                                 return SR_ERR_DATA;
2365
2366                         /* Submit the minimum value. */
2367                         vf = info->meas_data.minmax.min_value;
2368                         v8 = info->meas_data.minmax.min_prec;
2369                         ret = SR_OK;
2370                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_AUX3, sdi);
2371                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2372                         feedbuff.analog.meaning->mqflags |= SR_MQFLAG_MIN;
2373                         ret |= ut181a_get_value_params(&value, vf, v8);
2374                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2375                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2376                         if (ret != SR_OK)
2377                                 return SR_ERR_DATA;
2378                 }
2379                 if (info->meas_head.is_minmax) {
2380                         /* Min/max measurement code path done. */
2381                         ret = ut181a_feedbuff_cleanup(&feedbuff);
2382                         ret = ut181a_feedbuff_count_frame(sdi);
2383                         if (ret != SR_OK)
2384                                 return SR_ERR_DATA;
2385                         break;
2386                 }
2387
2388                 if (info->meas_head.is_peak) {
2389                         /* Maximum value, unconditional. Get details. */
2390                         ret = consume_flt(&vf, &payload, &pl_dlen);
2391                         if (ret != SR_OK)
2392                                 return SR_ERR_DATA;
2393                         info->meas_data.peak.max_value = vf;
2394                         ret = consume_u8(&v8, &payload, &pl_dlen);
2395                         if (ret != SR_OK)
2396                                 return SR_ERR_DATA;
2397                         info->meas_data.peak.max_prec = v8;
2398                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2399                         unit_text = &unit_buff[0];
2400                         if (ret != SR_OK)
2401                                 return SR_ERR_DATA;
2402                         snprintf(info->meas_data.peak.max_unit,
2403                                 sizeof(info->meas_data.peak.max_unit),
2404                                 "%s", unit_text);
2405                         unit_text = info->meas_data.peak.max_unit;
2406
2407                         /* Submit max value to session feed. */
2408                         ret = SR_OK;
2409                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_AUX1, sdi);
2410                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2411                         feedbuff.analog.meaning->mqflags |= add_mqflags; /* ??? */
2412                         feedbuff.analog.meaning->mqflags |= SR_MQFLAG_MAX;
2413                         ret |= ut181a_get_value_params(&value, vf, v8);
2414                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2415                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 1);
2416                         if (ret != SR_OK)
2417                                 return SR_ERR_DATA;
2418
2419                         /* Minimum value, unconditional. Get details. */
2420                         ret = consume_flt(&vf, &payload, &pl_dlen);
2421                         if (ret != SR_OK)
2422                                 return SR_ERR_DATA;
2423                         info->meas_data.peak.min_value = vf;
2424                         ret = consume_u8(&v8, &payload, &pl_dlen);
2425                         if (ret != SR_OK)
2426                                 return SR_ERR_DATA;
2427                         info->meas_data.peak.min_prec = v8;
2428                         ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2429                         unit_text = &unit_buff[0];
2430                         if (ret != SR_OK)
2431                                 return SR_ERR_DATA;
2432                         snprintf(info->meas_data.peak.min_unit,
2433                                 sizeof(info->meas_data.peak.min_unit),
2434                                 "%s", unit_text);
2435                         unit_text = info->meas_data.peak.min_unit;
2436
2437                         /* Submit min value to session feed. */
2438                         ret = SR_OK;
2439                         ret |= ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_AUX3, sdi);
2440                         ret |= ut181a_feedbuff_setup_unit(&feedbuff, unit_text);
2441                         feedbuff.analog.meaning->mqflags |= SR_MQFLAG_MIN;
2442                         ret |= ut181a_get_value_params(&value, vf, v8);
2443                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2444                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 0);
2445                         if (ret != SR_OK)
2446                                 return SR_ERR_DATA;
2447                 }
2448                 if (info->meas_head.is_peak) {
2449                         /* Relative measurement code path done. */
2450                         ret = ut181a_feedbuff_cleanup(&feedbuff);
2451                         ret = ut181a_feedbuff_count_frame(sdi);
2452                         if (ret != SR_OK)
2453                                 return SR_ERR_DATA;
2454                         break;
2455                 }
2456
2457                 /* ShouldNeverHappen(TM) */
2458                 sr_dbg("Unhandled measurement type.");
2459                 return SR_ERR_DATA;
2460
2461         case RSP_TYPE_REC_INFO:
2462                 /*
2463                  * Not useful to process without 'devc' or 'info'.
2464                  * The caller provided the recording's index (the
2465                  * protocol won't in the response).
2466                  */
2467                 if (!devc || !info)
2468                         return SR_ERR_ARG;
2469
2470                 /*
2471                  * Record information:
2472                  * - User specified recording's name (11 ASCIIZ chars).
2473                  * - Unit text (8).
2474                  * - Interval, duration, sample count (2/4/4).
2475                  * - Max/avg/min values and precision (4+1/4+1/4+1).
2476                  * - Time when recording started (4).
2477                  *
2478                  * Notice that the recording name needs to get trimmed
2479                  * due to limited text editing capabilities of the DMM
2480                  * UI. The name need not be unique, and typically isn't
2481                  * (again: because of limited editing, potential numbers
2482                  * in names are not auto incremented in the firmware).
2483                  */
2484                 ret = consume_str(&rec_name_buff[0], 11, &payload, &pl_dlen);
2485                 rec_name = &rec_name_buff[0];
2486                 if (ret != SR_OK)
2487                         return SR_ERR_DATA;
2488                 if (!*rec_name)
2489                         return SR_ERR_DATA;
2490                 snprintf(devc->record_names[info->rec_info.rec_idx],
2491                         sizeof(devc->record_names[info->rec_info.rec_idx]),
2492                         "%s", rec_name);
2493                 snprintf(info->rec_info.name, sizeof(info->rec_info.name),
2494                         "%s", rec_name);
2495                 ret = consume_str(&unit_buff[0], 8, &payload, &pl_dlen);
2496                 unit_text = &unit_buff[0];
2497                 if (ret != SR_OK)
2498                         return SR_ERR_DATA;
2499                 snprintf(info->rec_info.unit,
2500                         sizeof(info->rec_info.unit),
2501                         "%s", unit_text);
2502                 unit_text = info->rec_info.unit;
2503                 ret = SR_OK;
2504                 ret |= consume_u16(&info->rec_info.interval, &payload, &pl_dlen);
2505                 ret |= consume_u32(&info->rec_info.duration, &payload, &pl_dlen);
2506                 ret |= consume_u32(&info->rec_info.samples, &payload, &pl_dlen);
2507                 ret |= consume_flt(&info->rec_info.max_value, &payload, &pl_dlen);
2508                 ret |= consume_u8(&info->rec_info.max_prec, &payload, &pl_dlen);
2509                 ret |= consume_flt(&info->rec_info.avg_value, &payload, &pl_dlen);
2510                 ret |= consume_u8(&info->rec_info.avg_prec, &payload, &pl_dlen);
2511                 ret |= consume_flt(&info->rec_info.min_value, &payload, &pl_dlen);
2512                 ret |= consume_u8(&info->rec_info.min_prec, &payload, &pl_dlen);
2513                 ret |= consume_u32(&v32, &payload, &pl_dlen);
2514                 if (ret != SR_OK)
2515                         return SR_ERR_DATA;
2516                 info->rec_info.start_stamp = ut181a_get_epoch_for_timestamp(v32);
2517
2518                 /*
2519                  * Cheat, provide sample count as if it was reply data.
2520                  * Some api.c code paths assume to find this detail there.
2521                  * Keep the last unit text at hand, subsequent reception
2522                  * of record data will reference it.
2523                  */
2524                 if (state && state->want_data == CMD_CODE_GET_REC_INFO) {
2525                         state->got_sample_count = TRUE;
2526                         state->data_value = info->rec_info.samples;
2527                 }
2528                 snprintf(devc->last_data.unit_text,
2529                         sizeof(devc->last_data.unit_text),
2530                         "%s", unit_text);
2531
2532                 /*
2533                  * Optionally automatically forward the sample interval
2534                  * to the session feed, before record data is sent.
2535                  */
2536                 if (devc->info.rec_info.auto_feed) {
2537                         ret = ut181a_feed_send_rate(sdi, info->rec_info.interval);
2538                 }
2539
2540                 break;
2541
2542         case RSP_TYPE_REC_DATA:
2543                 /*
2544                  * We expect record data only during acquisitions from
2545                  * that data source, and depend on being able to feed
2546                  * data to the session.
2547                  */
2548                 if (sdi->status != SR_ST_ACTIVE)
2549                         break;
2550                 if (!devc || devc->disable_feed || !info)
2551                         break;
2552                 ret = ut181a_feedbuff_initialize(&feedbuff);
2553                 ret = ut181a_feedbuff_setup_channel(&feedbuff, UT181A_CH_MAIN, sdi);
2554                 ret = ut181a_feedbuff_setup_unit(&feedbuff, devc->last_data.unit_text);
2555
2556                 /*
2557                  * Record data:
2558                  * - u8 sample count for this data chunk, then the
2559                  *   corresponding number of samples, each is 9 bytes:
2560                  *   - f32 value
2561                  *   - u8 precision
2562                  *   - u32 timestamp
2563                  */
2564                 ret = consume_u8(&info->rec_data.samples_chunk, &payload, &pl_dlen);
2565                 if (ret != SR_OK)
2566                         return SR_ERR_DATA;
2567                 info->rec_data.samples_curr += info->rec_data.samples_chunk;
2568                 while (info->rec_data.samples_chunk--) {
2569                         /*
2570                          * Implementation detail: Consume all received
2571                          * data, yet skip processing when a limit was
2572                          * reached and previously terminated acquisition.
2573                          */
2574                         ret = SR_OK;
2575                         ret |= consume_flt(&vf, &payload, &pl_dlen);
2576                         ret |= consume_u8(&v8, &payload, &pl_dlen);
2577                         ret |= consume_u32(&v32, &payload, &pl_dlen);
2578                         if (ret != SR_OK)
2579                                 return SR_ERR_DATA;
2580
2581                         if (sdi->status != SR_ST_ACTIVE)
2582                                 continue;
2583
2584                         ret = ut181a_feedbuff_start_frame(sdi);
2585                         if (ret != SR_OK)
2586                                 return SR_ERR_DATA;
2587
2588                         ret = SR_OK;
2589                         ret |= ut181a_get_value_params(&value, vf, v8);
2590                         ret |= ut181a_feedbuff_setup_value(&feedbuff, &value);
2591                         ret |= ut181a_feedbuff_send_feed(&feedbuff, sdi, 1);
2592                         if (ret != SR_OK)
2593                                 return SR_ERR_DATA;
2594
2595                         ret = ut181a_feedbuff_count_frame(sdi);
2596                         if (ret != SR_OK)
2597                                 return SR_ERR_DATA;
2598                 }
2599                 ret = ut181a_feedbuff_cleanup(&feedbuff);
2600                 break;
2601
2602         case RSP_TYPE_REPLY_DATA:
2603                 /*
2604                  * Reply data. Generic 16bit value preceeded by 8bit
2605                  * request code.
2606                  */
2607                 ret = SR_OK;
2608                 ret |= consume_u8(&v8, &payload, &pl_dlen);
2609                 ret |= consume_u16(&v16, &payload, &pl_dlen);
2610                 if (ret != SR_OK)
2611                         return SR_ERR_DATA;
2612                 if (info) {
2613                         info->reply_data.code = v8;
2614                         info->reply_data.data = v16;
2615                 }
2616                 if (state && state->want_data && state->want_data == v8) {
2617                         state->got_data = TRUE;
2618                         state->data_value = v16;
2619                         if (v8 == CMD_CODE_GET_RECS_COUNT)
2620                                 state->got_rec_count = TRUE;
2621                         if (v8 == CMD_CODE_GET_SAVED_COUNT)
2622                                 state->got_save_count = TRUE;
2623                         if (v8 == CMD_CODE_GET_REC_INFO)
2624                                 state->got_sample_count = TRUE;
2625                 }
2626                 break;
2627
2628         default:
2629                 if (FRAME_DUMP_PARSE)
2630                         FRAME_DUMP_CALL("Unhandled response type 0x%02x", rsp_type);
2631                 return SR_ERR_NA;
2632         }
2633         if (state && state->want_rsp_type == rsp_type)
2634                 state->got_rsp_type = TRUE;
2635         if (FRAME_DUMP_REMAIN && pl_dlen) {
2636                 GString *txt;
2637                 txt = sr_hexdump_new(payload, pl_dlen);
2638                 FRAME_DUMP_CALL("Unprocessed response data: %s", txt->str);
2639                 sr_hexdump_free(txt);
2640         }
2641
2642         /* Unconditionally check, we may have hit a time limit. */
2643         if (sr_sw_limits_check(&devc->limits)) {
2644                 ut181a_cond_stop_acquisition(sdi);
2645                 return SR_OK;
2646         }
2647
2648         /*
2649          * Only emit next requests for chunked downloads after successful
2650          * reception and consumption of the currently received item(s).
2651          */
2652         if (devc) {
2653                 struct sr_serial_dev_inst *serial;
2654                 serial = sdi->conn;
2655
2656                 switch (rsp_type) {
2657                 case RSP_TYPE_SAVE:
2658                         if (!info)
2659                                 break;
2660                         /* Sample count was incremented during reception above. */
2661                         if (info->save_info.save_idx >= info->save_info.save_count) {
2662                                 ut181a_cond_stop_acquisition(sdi);
2663                                 break;
2664                         }
2665                         ret = ut181a_send_cmd_get_saved_value(serial, info->save_info.save_idx);
2666                         if (ret < 0)
2667                                 ut181a_cond_stop_acquisition(sdi);
2668                         break;
2669                 case RSP_TYPE_REC_DATA:
2670                         if (!info)
2671                                 break;
2672                         /*
2673                          * The sample count was incremented above during
2674                          * reception, because of variable length chunks
2675                          * of sample data.
2676                          */
2677                         if (info->rec_data.samples_curr >= info->rec_data.samples_total) {
2678                                 ut181a_cond_stop_acquisition(sdi);
2679                                 break;
2680                         }
2681                         ret = ut181a_send_cmd_get_rec_samples(serial,
2682                                 info->rec_data.rec_idx, info->rec_data.samples_curr);
2683                         if (ret < 0)
2684                                 ut181a_cond_stop_acquisition(sdi);
2685                         break;
2686                 default:
2687                         /* EMPTY */
2688                         break;
2689                 }
2690         }
2691
2692         return SR_OK;
2693 }
2694
2695 /* Process a previously received RX buffer. May find none or several packets. */
2696 static int process_buffer(struct sr_dev_inst *sdi)
2697 {
2698         struct dev_context *devc;
2699         uint8_t *pkt;
2700         uint16_t v16;
2701         size_t pkt_len, remain, idx;
2702         int ret;
2703
2704         devc = sdi->priv;
2705
2706         /*
2707          * Specifically do not insist on finding the packet boundary at
2708          * the edge of the most recently received data chunk. Serial ports
2709          * might involve hardware buffers (FIFO). We want to sync as fast
2710          * as possible.
2711          *
2712          * Handle the synchronized situation first. Process complete and
2713          * valid packets that reside at the start of the buffer. Continue
2714          * reception when partially valid data was received but does not
2715          * yet span a complete frame. Break out if data was received that
2716          * failed verification. Assume temporary failure and try to sync
2717          * to the input stream again.
2718          *
2719          * This logic is a little more complex than the typical DMM parser
2720          * because of the variable frame length of the UT181A protocol. A
2721          * frame always contains a magic (u16) and a length (u16), then a
2722          * number of bytes according to length. The frame ends there, the
2723          * checksum field is covered by the length value. packet processing
2724          * will verify the checksum.
2725          */
2726         pkt = &devc->recv_buff[0];
2727         do {
2728                 /* Search for (the start of) a valid packet. */
2729                 if (devc->recv_count < 2 * sizeof(uint16_t)) {
2730                         /* Need more RX data for magic and length. */
2731                         return SR_OK;
2732                 }
2733                 v16 = RL16(&pkt[0]);
2734                 if (v16 != FRAME_MAGIC) {
2735                         /* Not the expected magic marker. */
2736                         if (FRAME_DUMP_CSUM) {
2737                                 FRAME_DUMP_CALL("Not a frame marker -> re-sync");
2738                         }
2739                         break;
2740                 }
2741                 v16 = RL16(&pkt[sizeof(uint16_t)]);
2742                 if (v16 < sizeof(uint16_t)) {
2743                         /* Insufficient length value, need at least checksum. */
2744                         if (FRAME_DUMP_CSUM) {
2745                                 FRAME_DUMP_CALL("Too small a length -> re-sync");
2746                         }
2747                         break;
2748                 }
2749                 /* TODO Can we expect a maximum length value? */
2750                 pkt_len = 2 * sizeof(uint16_t) + v16;
2751                 if (pkt_len >= sizeof(devc->recv_buff)) {
2752                         /* Frame will never fit in RX buffer. Invalid RX data? */
2753                         if (FRAME_DUMP_CSUM) {
2754                                 FRAME_DUMP_CALL("Excessive length -> re-sync");
2755                         }
2756                         break;
2757                 }
2758                 if (pkt_len > devc->recv_count) {
2759                         /* Need more RX data to complete the frame. */
2760                         return SR_OK;
2761                 }
2762
2763                 /* Process the packet which completed reception. */
2764                 if (FRAME_DUMP_CSUM && sr_log_loglevel_get() >= FRAME_DUMP_LEVEL) {
2765                         GString *spew;
2766                         spew = sr_hexdump_new(pkt, pkt_len);
2767                         FRAME_DUMP_CALL("Found RX frame, %zu bytes: %s", pkt_len, spew->str);
2768                         sr_hexdump_free(spew);
2769                 }
2770                 ret = process_packet(sdi, pkt, pkt_len);
2771                 if (ret == SR_ERR_DATA) {
2772                         /* Verification failed, might be invalid RX data. */
2773                         if (FRAME_DUMP_CSUM) {
2774                                 FRAME_DUMP_CALL("RX frame processing failed -> re-sync");
2775                         }
2776                         break;
2777                 }
2778                 remain = devc->recv_count - pkt_len;
2779                 if (remain)
2780                         memmove(&pkt[0], &pkt[pkt_len], remain);
2781                 devc->recv_count -= pkt_len;
2782         } while (1);
2783         if (devc->recv_count < 2 * sizeof(uint16_t)) {
2784                 /* Assume incomplete reception. Re-check later. */
2785                 return SR_OK;
2786         }
2787
2788         /*
2789          * Data was received but failed the test for a valid frame. Try to
2790          * synchronize to the next frame marker. Make sure to skip the
2791          * current position which might have been a marker yet the frame
2792          * check failed.
2793          */
2794         if (FRAME_DUMP_CSUM) {
2795                 FRAME_DUMP_CALL("Trying to re-sync on RX frame");
2796         }
2797         for (idx = 1; idx < devc->recv_count; idx++) {
2798                 if (devc->recv_count - idx < sizeof(uint16_t)) {
2799                         /* Nothing found. Drop all but the last byte here. */
2800                         pkt[0] = pkt[idx];
2801                         devc->recv_count = 1;
2802                         if (FRAME_DUMP_CSUM) {
2803                                 FRAME_DUMP_CALL("Dropping %zu bytes, still not in sync", idx);
2804                         }
2805                         return SR_OK;
2806                 }
2807                 v16 = RL16(&pkt[idx]);
2808                 if (v16 != FRAME_MAGIC)
2809                         continue;
2810                 /*
2811                  * Found a frame marker at offset 'idx'. Discard data
2812                  * before the marker. Next receive starts another attempt
2813                  * to interpret the frame, and may search the next marker
2814                  * upon failure.
2815                  */
2816                 if (FRAME_DUMP_CSUM) {
2817                         FRAME_DUMP_CALL("Dropping %zu bytes, next marker found", idx);
2818                 }
2819                 remain = devc->recv_count - idx;
2820                 if (remain)
2821                         memmove(&pkt[0], &pkt[idx], remain);
2822                 devc->recv_count -= idx;
2823                 break;
2824         }
2825
2826         return SR_OK;
2827 }
2828
2829 /* Gets invoked when RX data is available. */
2830 static int ut181a_receive_data(struct sr_dev_inst *sdi)
2831 {
2832         struct dev_context *devc;
2833         struct sr_serial_dev_inst *serial;
2834         size_t len;
2835         uint8_t *data;
2836         ssize_t slen;
2837         GString *spew;
2838
2839         devc = sdi->priv;
2840         serial = sdi->conn;
2841
2842         /*
2843          * Discard receive data when the buffer is exhausted. This shall
2844          * allow to (re-)synchronize to the data stream when we find it
2845          * in an arbitrary state. (Takes a while to exhaust the buffer.
2846          * Data is seriously unusable when we get here.)
2847          */
2848         if (devc->recv_count == sizeof(devc->recv_buff)) {
2849                 if (FRAME_DUMP_RXDATA)
2850                         FRAME_DUMP_CALL("Discarding RX buffer (space exhausted)");
2851                 (void)process_packet(sdi, &devc->recv_buff[0], devc->recv_count);
2852                 devc->recv_count = 0;
2853         }
2854
2855         /*
2856          * Drain more data from the serial port, and check the receive
2857          * buffer for packets. Process what was found to be complete.
2858          */
2859         len = sizeof(devc->recv_buff) - devc->recv_count;
2860         data = &devc->recv_buff[devc->recv_count];
2861         slen = serial_read_nonblocking(serial, data, len);
2862         if (slen < 0) {
2863                 if (FRAME_DUMP_RXDATA)
2864                         FRAME_DUMP_CALL("UART RX failed, rc %zd", slen);
2865                 return 0;
2866         }
2867         len = slen;
2868         if (FRAME_DUMP_RXDATA && sr_log_loglevel_get() >= FRAME_DUMP_LEVEL) {
2869                 spew = sr_hexdump_new(data, len);
2870                 FRAME_DUMP_CALL("UART RX, %zu bytes: %s", len, spew->str);
2871                 sr_hexdump_free(spew);
2872         }
2873         devc->recv_count += len;
2874         process_buffer(sdi);
2875
2876         return 0;
2877 }
2878
2879 SR_PRIV int ut181a_handle_events(int fd, int revents, void *cb_data)
2880 {
2881         struct sr_dev_inst *sdi;
2882         struct sr_serial_dev_inst *serial;
2883         struct dev_context *devc;
2884
2885         (void)fd;
2886
2887         sdi = cb_data;
2888         if (!sdi)
2889                 return TRUE;
2890         serial = sdi->conn;
2891         if (!serial)
2892                 return TRUE;
2893         devc = sdi->priv;
2894
2895         if (revents & G_IO_IN)
2896                 (void)ut181a_receive_data(sdi);
2897
2898         if (sdi->status == SR_ST_STOPPING) {
2899                 if (devc->data_source == DATA_SOURCE_LIVE) {
2900                         sdi->status = SR_ST_INACTIVE;
2901                         (void)ut181a_send_cmd_monitor(serial, FALSE);
2902                         (void)ut181a_waitfor_response(sdi, 100);
2903                 }
2904                 serial_source_remove(sdi->session, serial);
2905                 std_session_send_df_end(sdi);
2906         }
2907
2908         return TRUE;
2909 }