]> sigrok.org Git - libsigrok.git/blob - src/std.c
fbcad8a9d65e74ec3318f8c2d7847e2b67bdc14e
[libsigrok.git] / src / std.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /**
21  * @file
22  *
23  * Standard API helper functions.
24  *
25  * @internal
26  */
27
28 #include <config.h>
29 #include <glib.h>
30 #include <libsigrok/libsigrok.h>
31 #include "libsigrok-internal.h"
32 #include "scpi.h"
33
34 #define LOG_PREFIX "std"
35
36 /**
37  * Standard driver init() callback API helper.
38  *
39  * This function can be used to simplify most driver's init() API callback.
40  *
41  * Create a new 'struct drv_context' (drvc), assign sr_ctx to it, and
42  * then assign 'drvc' to the 'struct sr_dev_driver' (di) that is passed.
43  *
44  * @param[in] di The driver instance to use. Must not be NULL.
45  * @param[in] sr_ctx The libsigrok context to assign. May be NULL.
46  *
47  * @retval SR_OK Success.
48  * @retval SR_ERR_ARG Invalid argument.
49  */
50 SR_PRIV int std_init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
51 {
52         struct drv_context *drvc;
53
54         if (!di) {
55                 sr_err("%s: Invalid argument.", __func__);
56                 return SR_ERR_ARG;
57         }
58
59         drvc = g_malloc0(sizeof(struct drv_context));
60         drvc->sr_ctx = sr_ctx;
61         drvc->instances = NULL;
62         di->context = drvc;
63
64         return SR_OK;
65 }
66
67 /**
68  * Standard driver cleanup() callback API helper.
69  *
70  * This function can be used to simplify most driver's cleanup() API callback.
71  *
72  * Free all device instances by calling sr_dev_clear() and then release any
73  * resources allocated by std_init().
74  *
75  * @param[in] di The driver instance to use. Must not be NULL.
76  *
77  * @retval SR_OK Success.
78  * @retval SR_ERR_ARG Invalid argument.
79  * @retval other Other error.
80  */
81 SR_PRIV int std_cleanup(const struct sr_dev_driver *di)
82 {
83         int ret;
84
85         if (!di) {
86                 sr_err("%s: Invalid argument.", __func__);
87                 return SR_ERR_ARG;
88         }
89
90         ret = sr_dev_clear(di);
91         g_free(di->context);
92
93         return ret;
94 }
95
96 /**
97  * Dummmy driver dev_open() callback API helper.
98  *
99  * @param[in] sdi The device instance to use. May be NULL (unused).
100  *
101  * @retval SR_OK Success.
102  */
103 SR_PRIV int std_dummy_dev_open(struct sr_dev_inst *sdi)
104 {
105         (void)sdi;
106
107         return SR_OK;
108 }
109
110 /**
111  * Dummmy driver dev_close() callback API helper.
112  *
113  * @param[in] sdi The device instance to use. May be NULL (unused).
114  *
115  * @retval SR_OK Success.
116  */
117 SR_PRIV int std_dummy_dev_close(struct sr_dev_inst *sdi)
118 {
119         (void)sdi;
120
121         return SR_OK;
122 }
123
124 /**
125  * Dummmy driver dev_acquisition_start() callback API helper.
126  *
127  * @param[in] sdi The device instance to use. May be NULL (unused).
128  *
129  * @retval SR_OK Success.
130  */
131 SR_PRIV int std_dummy_dev_acquisition_start(const struct sr_dev_inst *sdi)
132 {
133         (void)sdi;
134
135         return SR_OK;
136 }
137
138 /**
139  * Dummmy driver dev_acquisition_stop() callback API helper.
140  *
141  * @param[in] sdi The device instance to use. May be NULL (unused).
142  *
143  * @retval SR_OK Success.
144  */
145 SR_PRIV int std_dummy_dev_acquisition_stop(struct sr_dev_inst *sdi)
146 {
147         (void)sdi;
148
149         return SR_OK;
150 }
151
152 /**
153  * Standard API helper for sending an SR_DF_HEADER packet.
154  *
155  * This function can be used to simplify most drivers'
156  * dev_acquisition_start() API callback.
157  *
158  * @param[in] sdi The device instance to use. Must not be NULL.
159  *
160  * @retval SR_OK Success.
161  * @retval SR_ERR_ARG Invalid argument.
162  * @retval other Other error.
163  */
164 SR_PRIV int std_session_send_df_header(const struct sr_dev_inst *sdi)
165 {
166         const char *prefix;
167         int ret;
168         struct sr_datafeed_packet packet;
169         struct sr_datafeed_header header;
170
171         if (!sdi) {
172                 sr_err("%s: Invalid argument.", __func__);
173                 return SR_ERR_ARG;
174         }
175
176         prefix = (sdi->driver) ? sdi->driver->name : "unknown";
177
178         /* Send header packet to the session bus. */
179         sr_dbg("%s: Sending SR_DF_HEADER packet.", prefix);
180         packet.type = SR_DF_HEADER;
181         packet.payload = (uint8_t *)&header;
182         header.feed_version = 1;
183         gettimeofday(&header.starttime, NULL);
184
185         if ((ret = sr_session_send(sdi, &packet)) < 0) {
186                 sr_err("%s: Failed to send SR_DF_HEADER packet: %d.", prefix, ret);
187                 return ret;
188         }
189
190         return SR_OK;
191 }
192
193 /**
194  * Standard API helper for sending an SR_DF_END packet.
195  *
196  * This function can be used to simplify most drivers'
197  * dev_acquisition_stop() API callback.
198  *
199  * @param[in] sdi The device instance to use. Must not be NULL.
200  *
201  * @retval SR_OK Success.
202  * @retval SR_ERR_ARG Invalid argument.
203  * @retval other Other error.
204  */
205 SR_PRIV int std_session_send_df_end(const struct sr_dev_inst *sdi)
206 {
207         const char *prefix;
208         int ret;
209         struct sr_datafeed_packet packet;
210
211         if (!sdi) {
212                 sr_err("%s: Invalid argument.", __func__);
213                 return SR_ERR_ARG;
214         }
215
216         prefix = (sdi->driver) ? sdi->driver->name : "unknown";
217
218         sr_dbg("%s: Sending SR_DF_END packet.", prefix);
219
220         packet.type = SR_DF_END;
221         packet.payload = NULL;
222
223         if ((ret = sr_session_send(sdi, &packet)) < 0) {
224                 sr_err("%s: Failed to send SR_DF_END packet: %d.", prefix, ret);
225                 return ret;
226         }
227
228         return SR_OK;
229 }
230
231 #ifdef HAVE_LIBSERIALPORT
232
233 /**
234  * Standard serial driver dev_open() callback API helper.
235  *
236  * This function can be used to implement the dev_open() driver API
237  * callback in drivers that use a serial port. The port is opened
238  * with the SERIAL_RDWR flag.
239  *
240  * @param[in] sdi The device instance to use. Must not be NULL.
241  *
242  * @retval SR_OK Success.
243  * @retval SR_ERR_ARG Invalid argument.
244  * @retval other Serial port open failed.
245  */
246 SR_PRIV int std_serial_dev_open(struct sr_dev_inst *sdi)
247 {
248         struct sr_serial_dev_inst *serial;
249
250         if (!sdi) {
251                 sr_err("%s: Invalid argument.", __func__);
252                 return SR_ERR_ARG;
253         }
254
255         serial = sdi->conn;
256
257         return serial_open(serial, SERIAL_RDWR);
258 }
259
260 /**
261  * Standard serial driver dev_close() callback API helper.
262  *
263  * This function can be used to implement the dev_close() driver API
264  * callback in drivers that use a serial port.
265  *
266  * @param[in] sdi The device instance to use. Must not be NULL.
267  *
268  * @retval SR_OK Success.
269  * @retval SR_ERR_ARG Invalid argument.
270  * @retval other Serial port close failed.
271  */
272 SR_PRIV int std_serial_dev_close(struct sr_dev_inst *sdi)
273 {
274         struct sr_serial_dev_inst *serial;
275
276         if (!sdi) {
277                 sr_err("%s: Invalid argument.", __func__);
278                 return SR_ERR_ARG;
279         }
280
281         serial = sdi->conn;
282
283         return serial_close(serial);
284 }
285
286 /**
287  * Standard serial driver dev_acquisition_stop() callback API helper.
288  *
289  * This function can be used to simplify most (serial port based) drivers'
290  * dev_acquisition_stop() API callback.
291  *
292  * @param[in] sdi The device instance for which acquisition should stop.
293  *                Must not be NULL.
294  *
295  * @retval SR_OK Success.
296  * @retval SR_ERR_ARG Invalid argument.
297  * @retval other Other error.
298  */
299 SR_PRIV int std_serial_dev_acquisition_stop(struct sr_dev_inst *sdi)
300 {
301         struct sr_serial_dev_inst *serial;
302         const char *prefix;
303         int ret;
304
305         if (!sdi) {
306                 sr_err("%s: Invalid argument.", __func__);
307                 return SR_ERR_ARG;
308         }
309
310         serial = sdi->conn;
311         prefix = sdi->driver->name;
312
313         if ((ret = serial_source_remove(sdi->session, serial)) < 0) {
314                 sr_err("%s: Failed to remove source: %d.", prefix, ret);
315                 return ret;
316         }
317
318         if ((ret = sr_dev_close(sdi)) < 0) {
319                 sr_err("%s: Failed to close device: %d.", prefix, ret);
320                 return ret;
321         }
322
323         return std_session_send_df_end(sdi);
324 }
325
326 #endif
327
328 /**
329  * Standard driver dev_clear() callback API helper.
330  *
331  * Clear driver, this means, close all instances.
332  *
333  * This function can be used to implement the dev_clear() driver API
334  * callback. dev_close() is called before every sr_dev_inst is cleared.
335  *
336  * The only limitation is driver-specific device contexts (sdi->priv / devc).
337  * These are freed, but any dynamic allocation within structs stored
338  * there cannot be freed.
339  *
340  * @param[in] driver The driver which will have its instances released.
341  *                   Must not be NULL.
342  * @param[in] clear_private If not NULL, this points to a function called
343  *            with sdi->priv (devc) as argument. The function can then clear
344  *            any device instance-specific resources kept there.
345  *            It must NOT clear the struct pointed to by sdi->priv (devc),
346  *            since this function will always free it after clear_private()
347  *            has run.
348  *
349  * @retval SR_OK Success.
350  * @retval SR_ERR_ARG Invalid argument.
351  * @retval SR_ERR_BUG Implementation bug.
352  * @retval other Other error.
353  */
354 SR_PRIV int std_dev_clear_with_callback(const struct sr_dev_driver *driver,
355                 std_dev_clear_callback clear_private)
356 {
357         struct drv_context *drvc;
358         struct sr_dev_inst *sdi;
359         GSList *l;
360         int ret;
361
362         if (!driver) {
363                 sr_err("%s: Invalid argument.", __func__);
364                 return SR_ERR_ARG;
365         }
366
367         drvc = driver->context; /* Caller checked for context != NULL. */
368
369         ret = SR_OK;
370         for (l = drvc->instances; l; l = l->next) {
371                 if (!(sdi = l->data)) {
372                         sr_err("%s: Invalid device instance.", __func__);
373                         ret = SR_ERR_BUG;
374                         continue;
375                 }
376                 if (driver->dev_close)
377                         driver->dev_close(sdi);
378
379                 if (sdi->conn) {
380 #ifdef HAVE_LIBSERIALPORT
381                         if (sdi->inst_type == SR_INST_SERIAL)
382                                 sr_serial_dev_inst_free(sdi->conn);
383 #endif
384 #ifdef HAVE_LIBUSB_1_0
385                         if (sdi->inst_type == SR_INST_USB)
386                                 sr_usb_dev_inst_free(sdi->conn);
387 #endif
388                         if (sdi->inst_type == SR_INST_SCPI)
389                                 sr_scpi_free(sdi->conn);
390                         if (sdi->inst_type == SR_INST_MODBUS)
391                                 sr_modbus_free(sdi->conn);
392                 }
393
394                 /* Clear driver-specific stuff, if any. */
395                 if (clear_private)
396                         clear_private(sdi->priv);
397
398                 /* Clear sdi->priv (devc). */
399                 g_free(sdi->priv);
400
401                 sr_dev_inst_free(sdi);
402         }
403
404         g_slist_free(drvc->instances);
405         drvc->instances = NULL;
406
407         return ret;
408 }
409
410 SR_PRIV int std_dev_clear(const struct sr_dev_driver *driver)
411 {
412         return std_dev_clear_with_callback(driver, NULL);
413 }
414
415 /**
416  * Standard driver dev_list() callback API helper.
417  *
418  * This function can be used as the dev_list() callback by most drivers.
419  *
420  * Return the devices contained in the driver context instances list.
421  *
422  * @param[in] di The driver instance to use. Must not be NULL.
423  *
424  * @retval NULL Error, or the list is empty.
425  * @retval other The list of device instances of this driver.
426  */
427 SR_PRIV GSList *std_dev_list(const struct sr_dev_driver *di)
428 {
429         struct drv_context *drvc;
430
431         if (!di) {
432                 sr_err("%s: Invalid argument.", __func__);
433                 return NULL;
434         }
435
436         drvc = di->context;
437
438         return drvc->instances;
439 }
440
441 /**
442  * Standard driver scan() callback API helper.
443  *
444  * This function can be used to perform common tasks required by a driver's
445  * scan() callback. It will initialize the driver for each device on the list
446  * and add the devices on the list to the driver's device instance list.
447  * Usually it should be used as the last step in the scan() callback, right
448  * before returning.
449  *
450  * Note: This function can only be used if std_init() has been called
451  * previously by the driver.
452  *
453  * Example:
454  * @code{c}
455  * static GSList *scan(struct sr_dev_driver *di, GSList *options)
456  * {
457  *     struct GSList *device;
458  *     struct sr_dev_inst *sdi;
459  *
460  *     sdi = g_new0(sr_dev_inst, 1);
461  *     sdi->vendor = ...;
462  *     ...
463  *     devices = g_slist_append(devices, sdi);
464  *     ...
465  *     return std_scan_complete(di, devices);
466  * }
467  * @endcode
468  *
469  * @param[in] di The driver instance to use. Must not be NULL.
470  * @param[in] devices List of newly discovered devices (struct sr_dev_inst).
471  *                    May be NULL.
472  *
473  * @return The @p devices list.
474  */
475 SR_PRIV GSList *std_scan_complete(struct sr_dev_driver *di, GSList *devices)
476 {
477         struct drv_context *drvc;
478         GSList *l;
479
480         if (!di) {
481                 sr_err("Invalid driver instance (di), cannot complete scan.");
482                 return NULL;
483         }
484
485         drvc = di->context;
486
487         for (l = devices; l; l = l->next) {
488                 struct sr_dev_inst *sdi = l->data;
489                 if (!sdi) {
490                         sr_err("Invalid device instance, cannot complete scan.");
491                         return NULL;
492                 }
493                 sdi->driver = di;
494         }
495
496         drvc->instances = g_slist_concat(drvc->instances, g_slist_copy(devices));
497
498         return devices;
499 }
500
501 SR_PRIV int std_opts_config_list(uint32_t key, GVariant **data,
502         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg,
503         const uint32_t scanopts[], size_t scansize, const uint32_t drvopts[],
504         size_t drvsize, const uint32_t devopts[], size_t devsize)
505 {
506         switch (key) {
507         case SR_CONF_SCAN_OPTIONS:
508                 /* Always return scanopts, regardless of sdi or cg. */
509                 if (!scanopts)
510                         return SR_ERR_ARG;
511                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
512                         scanopts, scansize, sizeof(uint32_t));
513                 break;
514         case SR_CONF_DEVICE_OPTIONS:
515                 if (!sdi) {
516                         /* sdi == NULL: return drvopts. */
517                         if (!drvopts)
518                                 return SR_ERR_ARG;
519                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
520                                 drvopts, drvsize, sizeof(uint32_t));
521                 } else if (sdi && !cg) {
522                         /* sdi != NULL, cg == NULL: return devopts. */
523                         if (!devopts)
524                                 return SR_ERR_ARG;
525                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
526                                 devopts, devsize, sizeof(uint32_t));
527                 } else {
528                         /*
529                          * Note: sdi != NULL, cg != NULL is not handled by
530                          * this function since it's very driver-specific.
531                          */
532                         sr_err("%s: %s: sdi/cg != NULL: not handling.",
533                                sdi->driver->name, __func__);
534                         return SR_ERR_ARG;
535                 }
536                 break;
537         default:
538                 return SR_ERR_NA;
539         }
540
541         return SR_OK;
542 }
543
544 SR_PRIV GVariant *std_gvar_tuple_array(const uint64_t a[][2], unsigned int n)
545 {
546         unsigned int i;
547         GVariant *rational[2];
548         GVariantBuilder gvb;
549
550         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
551
552         for (i = 0; i < n; i++) {
553                 rational[0] = g_variant_new_uint64(a[i][0]);
554                 rational[1] = g_variant_new_uint64(a[i][1]);
555
556                 /* FIXME: Valgrind reports a memory leak here. */
557                 g_variant_builder_add_value(&gvb, g_variant_new_tuple(rational, 2));
558         }
559
560         return g_variant_builder_end(&gvb);
561 }
562
563 SR_PRIV GVariant *std_gvar_tuple_rational(const struct sr_rational *r, unsigned int n)
564 {
565         unsigned int i;
566         GVariant *rational[2];
567         GVariantBuilder gvb;
568
569         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
570
571         for (i = 0; i < n; i++) {
572                 rational[0] = g_variant_new_uint64(r[i].p);
573                 rational[1] = g_variant_new_uint64(r[i].q);
574
575                 /* FIXME: Valgrind reports a memory leak here. */
576                 g_variant_builder_add_value(&gvb, g_variant_new_tuple(rational, 2));
577         }
578
579         return g_variant_builder_end(&gvb);
580 }
581
582 static GVariant *samplerate_helper(const uint64_t samplerates[], unsigned int n, const char *str)
583 {
584         GVariant *gvar;
585         GVariantBuilder gvb;
586
587         g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
588         gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
589                         n, sizeof(uint64_t));
590         g_variant_builder_add(&gvb, "{sv}", str, gvar);
591
592         return g_variant_builder_end(&gvb);
593 }
594
595 SR_PRIV GVariant *std_gvar_samplerates(const uint64_t samplerates[], unsigned int n)
596 {
597         return samplerate_helper(samplerates, n, "samplerates");
598 }
599
600 SR_PRIV GVariant *std_gvar_samplerates_steps(const uint64_t samplerates[], unsigned int n)
601 {
602         return samplerate_helper(samplerates, n, "samplerate-steps");
603 }
604
605 SR_PRIV GVariant *std_gvar_min_max_step(double min, double max, double step)
606 {
607         GVariantBuilder gvb;
608
609         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
610
611         g_variant_builder_add_value(&gvb, g_variant_new_double(min));
612         g_variant_builder_add_value(&gvb, g_variant_new_double(max));
613         g_variant_builder_add_value(&gvb, g_variant_new_double(step));
614
615         return g_variant_builder_end(&gvb);
616 }
617
618 SR_PRIV GVariant *std_gvar_min_max_step_array(const double a[3])
619 {
620         unsigned int i;
621         GVariantBuilder gvb;
622
623         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
624
625         for (i = 0; i < 3; i++)
626                 g_variant_builder_add_value(&gvb, g_variant_new_double(a[i]));
627
628         return g_variant_builder_end(&gvb);
629 }
630
631 SR_PRIV GVariant *std_gvar_min_max_step_thresholds(const double min, const double max, const double step)
632 {
633         double d;
634         GVariant *gvar, *range[2];
635         GVariantBuilder gvb;
636
637         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
638
639         for (d = min; d <= max; d += step) {
640                 range[0] = g_variant_new_double(d);
641                 range[1] = g_variant_new_double(d);
642
643                 gvar = g_variant_new_tuple(range, 2);
644                 g_variant_builder_add_value(&gvb, gvar);
645         }
646
647         return g_variant_builder_end(&gvb);
648 }
649
650 SR_PRIV GVariant *std_gvar_tuple_u64(uint64_t low, uint64_t high)
651 {
652         GVariant *range[2];
653
654         range[0] = g_variant_new_uint64(low);
655         range[1] = g_variant_new_uint64(high);
656
657         return g_variant_new_tuple(range, 2);
658 }
659
660 SR_PRIV GVariant *std_gvar_tuple_double(double low, double high)
661 {
662         GVariant *range[2];
663
664         range[0] = g_variant_new_double(low);
665         range[1] = g_variant_new_double(high);
666
667         return g_variant_new_tuple(range, 2);
668 }
669
670 SR_PRIV GVariant *std_gvar_array_i32(const int32_t *a, unsigned int n)
671 {
672         return g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
673                                 a, n, sizeof(int32_t));
674 }
675
676 SR_PRIV GVariant *std_gvar_array_u32(const uint32_t *a, unsigned int n)
677 {
678         return g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
679                                 a, n, sizeof(uint32_t));
680 }
681
682 SR_PRIV GVariant *std_gvar_array_u64(const uint64_t *a, unsigned int n)
683 {
684         return g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
685                                 a, n, sizeof(uint64_t));
686 }
687
688 SR_PRIV GVariant *std_gvar_thresholds(const double a[][2], unsigned int n)
689 {
690         unsigned int i;
691         GVariant *gvar, *range[2];
692         GVariantBuilder gvb;
693
694         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
695
696         for (i = 0; i < n; i++) {
697                 range[0] = g_variant_new_double(a[i][0]);
698                 range[1] = g_variant_new_double(a[i][1]);
699                 gvar = g_variant_new_tuple(range, 2);
700                 g_variant_builder_add_value(&gvb, gvar);
701         }
702
703         return g_variant_builder_end(&gvb);
704 }