libsigrok  unreleased development snapshot
sigrok hardware access and backend library
backend.c
Go to the documentation of this file.
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
5  * Copyright (C) 2012 Peter Stuge <peter@stuge.se>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 #include <glib.h>
23 #ifdef _WIN32
24 #include <winsock2.h>
25 #endif
26 #include <libsigrok/libsigrok.h>
27 #include "libsigrok-internal.h"
28 #include "minilzo/minilzo.h"
29 
30 /** @cond PRIVATE */
31 #define LOG_PREFIX "backend"
32 /** @endcond */
33 
34 /**
35  * @mainpage libsigrok API
36  *
37  * @section sec_intro Introduction
38  *
39  * The <a href="http://sigrok.org">sigrok</a> project aims at creating a
40  * portable, cross-platform, Free/Libre/Open-Source signal analysis software
41  * suite that supports various device types (such as logic analyzers,
42  * oscilloscopes, multimeters, and more).
43  *
44  * <a href="http://sigrok.org/wiki/Libsigrok">libsigrok</a> is a shared
45  * library written in C which provides the basic API for talking to
46  * <a href="http://sigrok.org/wiki/Supported_hardware">supported hardware</a>
47  * and reading/writing the acquired data into various
48  * <a href="http://sigrok.org/wiki/Input_output_formats">input/output
49  * file formats</a>.
50  *
51  * @section sec_api API reference
52  *
53  * See the "Modules" page for an introduction to various libsigrok
54  * related topics and the detailed API documentation of the respective
55  * functions.
56  *
57  * You can also browse the API documentation by file, or review all
58  * data structures.
59  *
60  * @section sec_mailinglists Mailing lists
61  *
62  * There is one mailing list for sigrok/libsigrok: <a href="https://lists.sourceforge.net/lists/listinfo/sigrok-devel">sigrok-devel</a>.
63  *
64  * @section sec_irc IRC
65  *
66  * You can find the sigrok developers in the
67  * <a href="ircs://irc.libera.chat/#sigrok">\#sigrok</a>
68  * IRC channel on Libera.Chat.
69  *
70  * @section sec_website Website
71  *
72  * <a href="http://sigrok.org/wiki/Libsigrok">sigrok.org/wiki/Libsigrok</a>
73  */
74 
75 /**
76  * @file
77  *
78  * Initializing and shutting down libsigrok.
79  */
80 
81 /**
82  * @defgroup grp_init Initialization
83  *
84  * Initializing and shutting down libsigrok.
85  *
86  * Before using any of the libsigrok functionality (except for
87  * sr_log_loglevel_set()), sr_init() must be called to initialize the
88  * library, which will return a struct sr_context when the initialization
89  * was successful.
90  *
91  * When libsigrok functionality is no longer needed, sr_exit() should be
92  * called, which will (among other things) free the struct sr_context.
93  *
94  * Example for a minimal program using libsigrok:
95  *
96  * @code{.c}
97  * #include <stdio.h>
98  * #include <libsigrok/libsigrok.h>
99  *
100  * int main(int argc, char **argv)
101  * {
102  * int ret;
103  * struct sr_context *sr_ctx;
104  *
105  * if ((ret = sr_init(&sr_ctx)) != SR_OK) {
106  * printf("Error initializing libsigrok (%s): %s.\n",
107  * sr_strerror_name(ret), sr_strerror(ret));
108  * return 1;
109  * }
110  *
111  * // Use libsigrok functions here...
112  *
113  * if ((ret = sr_exit(sr_ctx)) != SR_OK) {
114  * printf("Error shutting down libsigrok (%s): %s.\n",
115  * sr_strerror_name(ret), sr_strerror(ret));
116  * return 1;
117  * }
118  *
119  * return 0;
120  * }
121  * @endcode
122  *
123  * @{
124  */
125 
127 {
128  GSList *l = NULL, *m = NULL;
129 #if defined(HAVE_LIBUSB_1_0) && !defined(__FreeBSD__)
130  const struct libusb_version *lv;
131 #endif
132 
133  m = g_slist_append(NULL, g_strdup("glib"));
134  m = g_slist_append(m, g_strdup_printf("%d.%d.%d (rt: %d.%d.%d/%d:%d)",
135  GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION,
136  glib_major_version, glib_minor_version, glib_micro_version,
137  glib_binary_age, glib_interface_age));
138  l = g_slist_append(l, m);
139 
140  m = g_slist_append(NULL, g_strdup("zlib"));
141  m = g_slist_append(m, g_strdup_printf("%s", CONF_ZLIB_VERSION));
142  l = g_slist_append(l, m);
143 
144  m = g_slist_append(NULL, g_strdup("libzip"));
145  m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBZIP_VERSION));
146  l = g_slist_append(l, m);
147 
148  m = g_slist_append(NULL, g_strdup("minilzo"));
149  m = g_slist_append(m, g_strdup_printf("%s", lzo_version_string()));
150  l = g_slist_append(l, m);
151 
152 #ifdef HAVE_LIBSERIALPORT
153  m = g_slist_append(NULL, g_strdup("libserialport"));
154  m = g_slist_append(m, g_strdup_printf("%s/%s (rt: %s/%s)",
155  SP_PACKAGE_VERSION_STRING, SP_LIB_VERSION_STRING,
156  sp_get_package_version_string(), sp_get_lib_version_string()));
157  l = g_slist_append(l, m);
158 #endif
159 #ifdef HAVE_LIBUSB_1_0
160  m = g_slist_append(NULL, g_strdup("libusb-1.0"));
161 #ifdef __FreeBSD__
162  m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBUSB_1_0_VERSION));
163 #else
164  lv = libusb_get_version();
165  m = g_slist_append(m, g_strdup_printf("%d.%d.%d.%d%s API 0x%08x",
166  lv->major, lv->minor, lv->micro, lv->nano, lv->rc,
167 #if defined(LIBUSB_API_VERSION)
168  LIBUSB_API_VERSION
169 #elif defined(LIBUSBX_API_VERSION)
170  LIBUSBX_API_VERSION
171 #endif
172  ));
173 #endif
174  l = g_slist_append(l, m);
175 #endif
176 #ifdef HAVE_LIBHIDAPI
177  m = g_slist_append(NULL, g_strdup("hidapi"));
178  m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBHIDAPI_VERSION));
179  l = g_slist_append(l, m);
180 #endif
181 #ifdef HAVE_LIBBLUEZ
182  m = g_slist_append(NULL, g_strdup("bluez"));
183  m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBBLUEZ_VERSION));
184  l = g_slist_append(l, m);
185 #endif
186 #ifdef HAVE_LIBFTDI
187  m = g_slist_append(NULL, g_strdup("libftdi"));
188  m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBFTDI_VERSION));
189  l = g_slist_append(l, m);
190 #endif
191 #ifdef HAVE_LIBGPIB
192  m = g_slist_append(NULL, g_strdup("libgpib"));
193  m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBGPIB_VERSION));
194  l = g_slist_append(l, m);
195 #endif
196 #ifdef HAVE_LIBREVISA
197  m = g_slist_append(NULL, g_strdup("librevisa"));
198  m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBREVISA_VERSION));
199  l = g_slist_append(l, m);
200 #endif
201 
202  return l;
203 }
204 
206 {
207  return g_strdup_printf("%s, %s-endian", CONF_HOST,
208 #ifdef WORDS_BIGENDIAN
209  "big"
210 #else
211  "little"
212 #endif
213  );
214 }
215 
217 {
218  GString *s;
219  char *str;
220 
221  s = g_string_sized_new(200);
222 
223  g_string_append_printf(s, "TCP, ");
224 #if HAVE_RPC
225  g_string_append_printf(s, "RPC, ");
226 #endif
227 #ifdef HAVE_SERIAL_COMM
228  g_string_append_printf(s, "serial, ");
229 #endif
230 #ifdef HAVE_LIBREVISA
231  g_string_append_printf(s, "VISA, ");
232 #endif
233 #ifdef HAVE_LIBGPIB
234  g_string_append_printf(s, "GPIB, ");
235 #endif
236 #ifdef HAVE_LIBUSB_1_0
237  g_string_append_printf(s, "USBTMC, ");
238 #endif
239  s->str[s->len - 2] = '\0';
240 
241  str = g_strdup(s->str);
242  g_string_free(s, TRUE);
243 
244  return str;
245 }
246 
247 static void print_versions(void)
248 {
249  GString *s;
250  GSList *l, *l_orig, *m;
251  char *str;
252  const char *lib, *version;
253 
254  sr_dbg("libsigrok %s/%s.",
256 
257  s = g_string_sized_new(200);
258  g_string_append(s, "Libs: ");
259  l_orig = sr_buildinfo_libs_get();
260  for (l = l_orig; l; l = l->next) {
261  m = l->data;
262  lib = m->data;
263  version = m->next->data;
264  g_string_append_printf(s, "%s %s, ", lib, version);
265  g_slist_free_full(m, g_free);
266  }
267  g_slist_free(l_orig);
268  s->str[s->len - 2] = '.';
269  s->str[s->len - 1] = '\0';
270  sr_dbg("%s", s->str);
271  g_string_free(s, TRUE);
272 
273  str = sr_buildinfo_host_get();
274  sr_dbg("Host: %s.", str);
275  g_free(str);
276 
278  sr_dbg("SCPI backends: %s.", str);
279  g_free(str);
280 }
281 
282 static void print_resourcepaths(void)
283 {
284  GSList *l, *l_orig;
285 
286  sr_dbg("Firmware search paths:");
288  for (l = l_orig; l; l = l->next)
289  sr_dbg(" - %s", (const char *)l->data);
290  g_slist_free_full(l_orig, g_free);
291 }
292 
293 /**
294  * Sanity-check all libsigrok drivers.
295  *
296  * @param[in] ctx Pointer to a libsigrok context struct. Must not be NULL.
297  *
298  * @retval SR_OK All drivers are OK
299  * @retval SR_ERR One or more drivers have issues.
300  * @retval SR_ERR_ARG Invalid argument.
301  */
302 static int sanity_check_all_drivers(const struct sr_context *ctx)
303 {
304  int i, errors, ret = SR_OK;
305  struct sr_dev_driver **drivers;
306  const char *d;
307 
308  if (!ctx)
309  return SR_ERR_ARG;
310 
311  sr_spew("Sanity-checking all drivers.");
312 
313  drivers = sr_driver_list(ctx);
314  for (i = 0; drivers[i]; i++) {
315  errors = 0;
316 
317  d = (drivers[i]->name) ? drivers[i]->name : "NULL";
318 
319  if (!drivers[i]->name) {
320  sr_err("No name in driver %d ('%s').", i, d);
321  errors++;
322  }
323  if (!drivers[i]->longname) {
324  sr_err("No longname in driver %d ('%s').", i, d);
325  errors++;
326  }
327  if (drivers[i]->api_version < 1) {
328  sr_err("API version in driver %d ('%s') < 1.", i, d);
329  errors++;
330  }
331  if (!drivers[i]->init) {
332  sr_err("No init in driver %d ('%s').", i, d);
333  errors++;
334  }
335  if (!drivers[i]->cleanup) {
336  sr_err("No cleanup in driver %d ('%s').", i, d);
337  errors++;
338  }
339  if (!drivers[i]->scan) {
340  sr_err("No scan in driver %d ('%s').", i, d);
341  errors++;
342  }
343  if (!drivers[i]->dev_list) {
344  sr_err("No dev_list in driver %d ('%s').", i, d);
345  errors++;
346  }
347  if (!drivers[i]->dev_clear) {
348  sr_err("No dev_clear in driver %d ('%s').", i, d);
349  errors++;
350  }
351  /* Note: config_get() is optional. */
352  if (!drivers[i]->config_set) {
353  sr_err("No config_set in driver %d ('%s').", i, d);
354  errors++;
355  }
356  /* Note: config_channel_set() is optional. */
357  /* Note: config_commit() is optional. */
358  if (!drivers[i]->config_list) {
359  sr_err("No config_list in driver %d ('%s').", i, d);
360  errors++;
361  }
362  if (!drivers[i]->dev_open) {
363  sr_err("No dev_open in driver %d ('%s').", i, d);
364  errors++;
365  }
366  if (!drivers[i]->dev_close) {
367  sr_err("No dev_close in driver %d ('%s').", i, d);
368  errors++;
369  }
370  if (!drivers[i]->dev_acquisition_start) {
371  sr_err("No dev_acquisition_start in driver %d ('%s').",
372  i, d);
373  errors++;
374  }
375  if (!drivers[i]->dev_acquisition_stop) {
376  sr_err("No dev_acquisition_stop in driver %d ('%s').",
377  i, d);
378  errors++;
379  }
380 
381  /* Note: 'priv' is allowed to be NULL. */
382 
383  if (errors == 0)
384  continue;
385 
386  ret = SR_ERR;
387  }
388 
389  return ret;
390 }
391 
392 /**
393  * Sanity-check all libsigrok input modules.
394  *
395  * @retval SR_OK All modules are OK
396  * @retval SR_ERR One or more modules have issues.
397  */
398 static int sanity_check_all_input_modules(void)
399 {
400  int i, errors, ret = SR_OK;
401  const struct sr_input_module **inputs;
402  const char *d;
403 
404  sr_spew("Sanity-checking all input modules.");
405 
406  inputs = sr_input_list();
407  for (i = 0; inputs[i]; i++) {
408  errors = 0;
409 
410  d = (inputs[i]->id) ? inputs[i]->id : "NULL";
411 
412  if (!inputs[i]->id) {
413  sr_err("No ID in module %d ('%s').", i, d);
414  errors++;
415  }
416  if (!inputs[i]->name) {
417  sr_err("No name in module %d ('%s').", i, d);
418  errors++;
419  }
420  if (!inputs[i]->desc) {
421  sr_err("No description in module %d ('%s').", i, d);
422  errors++;
423  }
424  if (!inputs[i]->init) {
425  sr_err("No init in module %d ('%s').", i, d);
426  errors++;
427  }
428  if (!inputs[i]->receive) {
429  sr_err("No receive in module %d ('%s').", i, d);
430  errors++;
431  }
432  if (!inputs[i]->end) {
433  sr_err("No end in module %d ('%s').", i, d);
434  errors++;
435  }
436 
437  if (errors == 0)
438  continue;
439 
440  ret = SR_ERR;
441  }
442 
443  return ret;
444 }
445 
446 /**
447  * Sanity-check all libsigrok output modules.
448  *
449  * @retval SR_OK All modules are OK
450  * @retval SR_ERR One or more modules have issues.
451  */
452 static int sanity_check_all_output_modules(void)
453 {
454  int i, errors, ret = SR_OK;
455  const struct sr_output_module **outputs;
456  const char *d;
457 
458  sr_spew("Sanity-checking all output modules.");
459 
460  outputs = sr_output_list();
461  for (i = 0; outputs[i]; i++) {
462  errors = 0;
463 
464  d = (outputs[i]->id) ? outputs[i]->id : "NULL";
465 
466  if (!outputs[i]->id) {
467  sr_err("No ID in module %d ('%s').", i, d);
468  errors++;
469  }
470  if (!outputs[i]->name) {
471  sr_err("No name in module %d ('%s').", i, d);
472  errors++;
473  }
474  if (!outputs[i]->desc) {
475  sr_err("No description in module '%s'.", d);
476  errors++;
477  }
478  if (!outputs[i]->receive) {
479  sr_err("No receive in module '%s'.", d);
480  errors++;
481  }
482 
483  if (errors == 0)
484  continue;
485 
486  ret = SR_ERR;
487  }
488 
489  return ret;
490 }
491 
492 /**
493  * Sanity-check all libsigrok transform modules.
494  *
495  * @retval SR_OK All modules are OK
496  * @retval SR_ERR One or more modules have issues.
497  */
498 static int sanity_check_all_transform_modules(void)
499 {
500  int i, errors, ret = SR_OK;
501  const struct sr_transform_module **transforms;
502  const char *d;
503 
504  sr_spew("Sanity-checking all transform modules.");
505 
506  transforms = sr_transform_list();
507  for (i = 0; transforms[i]; i++) {
508  errors = 0;
509 
510  d = (transforms[i]->id) ? transforms[i]->id : "NULL";
511 
512  if (!transforms[i]->id) {
513  sr_err("No ID in module %d ('%s').", i, d);
514  errors++;
515  }
516  if (!transforms[i]->name) {
517  sr_err("No name in module %d ('%s').", i, d);
518  errors++;
519  }
520  if (!transforms[i]->desc) {
521  sr_err("No description in module '%s'.", d);
522  errors++;
523  }
524  /* Note: options() is optional. */
525  /* Note: init() is optional. */
526  if (!transforms[i]->receive) {
527  sr_err("No receive in module '%s'.", d);
528  errors++;
529  }
530  /* Note: cleanup() is optional. */
531 
532  if (errors == 0)
533  continue;
534 
535  ret = SR_ERR;
536  }
537 
538  return ret;
539 }
540 
541 /**
542  * Initialize libsigrok.
543  *
544  * This function must be called before any other libsigrok function.
545  *
546  * @param ctx Pointer to a libsigrok context struct pointer. Must not be NULL.
547  * This will be a pointer to a newly allocated libsigrok context
548  * object upon success, and is undefined upon errors.
549  *
550  * @return SR_OK upon success, a (negative) error code otherwise. Upon errors
551  * the 'ctx' pointer is undefined and should not be used. Upon success,
552  * the context will be free'd by sr_exit() as part of the libsigrok
553  * shutdown.
554  *
555  * @since 0.2.0
556  */
557 SR_API int sr_init(struct sr_context **ctx)
558 {
559  int ret = SR_ERR;
560  struct sr_context *context;
561 #ifdef _WIN32
562  WSADATA wsadata;
563 #endif
564 
565  print_versions();
566 
567  print_resourcepaths();
568 
569  if (!ctx) {
570  sr_err("%s(): libsigrok context was NULL.", __func__);
571  return SR_ERR;
572  }
573 
574  context = g_malloc0(sizeof(struct sr_context));
575 
576  sr_drivers_init(context);
577 
578  if (sanity_check_all_drivers(context) < 0) {
579  sr_err("Internal driver error(s), aborting.");
580  goto done;
581  }
582 
583  if (sanity_check_all_input_modules() < 0) {
584  sr_err("Internal input module error(s), aborting.");
585  goto done;
586  }
587 
588  if (sanity_check_all_output_modules() < 0) {
589  sr_err("Internal output module error(s), aborting.");
590  goto done;
591  }
592 
593  if (sanity_check_all_transform_modules() < 0) {
594  sr_err("Internal transform module error(s), aborting.");
595  goto done;
596  }
597 
598 #ifdef _WIN32
599  if ((ret = WSAStartup(MAKEWORD(2, 2), &wsadata)) != 0) {
600  sr_err("WSAStartup failed with error code %d.", ret);
601  ret = SR_ERR;
602  goto done;
603  }
604 #endif
605 
606  if ((ret = lzo_init()) != LZO_E_OK) {
607  sr_err("lzo_init() failed with return code %d.", ret);
608  sr_err("This usually indicates a compiler bug. Recompile without");
609  sr_err("optimizations, and enable '-DLZO_DEBUG' for diagnostics.");
610  ret = SR_ERR;
611  goto done;
612  }
613 
614 #ifdef HAVE_LIBUSB_1_0
615  ret = libusb_init(&context->libusb_ctx);
616  if (LIBUSB_SUCCESS != ret) {
617  sr_err("libusb_init() returned %s.", libusb_error_name(ret));
618  ret = SR_ERR;
619  goto done;
620  }
621 #endif
622 #ifdef HAVE_LIBHIDAPI
623  /*
624  * According to <hidapi.h>, the hid_init() routine just returns
625  * zero or non-zero, and hid_error() appears to relate to calls
626  * for a specific device after hid_open(). Which means that there
627  * is no more detailled information available beyond success/fail
628  * at this point in time.
629  */
630  if (hid_init() != 0) {
631  sr_err("HIDAPI hid_init() failed.");
632  ret = SR_ERR;
633  goto done;
634  }
635 #endif
636  sr_resource_set_hooks(context, NULL, NULL, NULL, NULL);
637 
638  *ctx = context;
639  context = NULL;
640  ret = SR_OK;
641 
642 done:
643  g_free(context);
644  return ret;
645 }
646 
647 /**
648  * Shutdown libsigrok.
649  *
650  * @param ctx Pointer to a libsigrok context struct. Must not be NULL.
651  *
652  * @retval SR_OK Success
653  * @retval other Error code SR_ERR, ...
654  *
655  * @since 0.2.0
656  */
657 SR_API int sr_exit(struct sr_context *ctx)
658 {
659  if (!ctx) {
660  sr_err("%s(): libsigrok context was NULL.", __func__);
661  return SR_ERR;
662  }
663 
664  sr_hw_cleanup_all(ctx);
665 
666 #ifdef _WIN32
667  WSACleanup();
668 #endif
669 
670 #ifdef HAVE_LIBHIDAPI
671  hid_exit();
672 #endif
673 #ifdef HAVE_LIBUSB_1_0
674  libusb_exit(ctx->libusb_ctx);
675 #endif
676 
677  g_free(sr_driver_list(ctx));
678  g_free(ctx);
679 
680  return SR_OK;
681 }
682 
683 /** @} */
#define LZO_E_OK
Definition: lzoconf.h:310
int(* cleanup)(const struct sr_dev_driver *driver)
Called before driver is unloaded.
Definition: libsigrok.h:1266
No error.
Definition: libsigrok.h:67
const char * name
Driver name.
Definition: libsigrok.h:1257
const struct sr_output_module ** sr_output_list(void)
Returns a NULL-terminated list of all available output modules.
Definition: output.c:93
#define lzo_init()
Definition: lzoconf.h:336
GSList * sr_resourcepaths_get(int res_type)
Get a list of paths where we look for resource (e.g.
Definition: resource.c:47
int(* config_set)(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
Set value of a configuration key in driver or a given device instance.
Definition: libsigrok.h:1289
const char * longname
Long name.
Definition: libsigrok.h:1259
GSList *(* dev_list)(const struct sr_dev_driver *driver)
Get list of device instances the driver knows about.
Definition: libsigrok.h:1278
int(* dev_acquisition_stop)(struct sr_dev_inst *sdi)
End data acquisition on the specified device.
Definition: libsigrok.h:1314
#define SR_API
Definition: libsigrok.h:128
int(* dev_close)(struct sr_dev_inst *sdi)
Close device.
Definition: libsigrok.h:1310
const struct sr_transform_module ** sr_transform_list(void)
Returns a NULL-terminated list of all available transform modules.
Definition: transform.c:62
int(* config_list)(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
List all possible values for a configuration key in a device instance.
Definition: libsigrok.h:1302
int sr_resource_set_hooks(struct sr_context *ctx, sr_resource_open_callback open_cb, sr_resource_close_callback close_cb, sr_resource_read_callback read_cb, void *cb_data)
Install resource access hooks.
Definition: resource.c:263
GSList * sr_buildinfo_libs_get(void)
Definition: backend.c:126
int(* dev_open)(struct sr_dev_inst *sdi)
Open device.
Definition: libsigrok.h:1308
int sr_init(struct sr_context **ctx)
Initialize libsigrok.
Definition: backend.c:557
int(* dev_acquisition_start)(const struct sr_dev_inst *sdi)
Begin data acquisition on the specified device.
Definition: libsigrok.h:1312
int(* init)(struct sr_dev_driver *driver, struct sr_context *sr_ctx)
Called when driver is loaded, e.g.
Definition: libsigrok.h:1263
char * sr_buildinfo_host_get(void)
Definition: backend.c:205
Generic/unspecified error.
Definition: libsigrok.h:68
const struct sr_input_module ** sr_input_list(void)
Returns a NULL-terminated list of all available input modules.
Definition: input.c:103
lzo_version_string(void)
Definition: minilzo.c:4247
int(* dev_clear)(const struct sr_dev_driver *driver)
Clear list of devices the driver knows about.
Definition: libsigrok.h:1280
const char * name
Definition: strutil.c:1407
int api_version
API version (currently 1).
Definition: libsigrok.h:1261
Opaque structure representing a libsigrok context.
Function argument error.
Definition: libsigrok.h:70
int sr_exit(struct sr_context *ctx)
Shutdown libsigrok.
Definition: backend.c:657
GSList *(* scan)(struct sr_dev_driver *driver, GSList *options)
Scan for devices.
Definition: libsigrok.h:1273
struct sr_dev_driver ** sr_driver_list(const struct sr_context *ctx)
Return the list of supported hardware drivers.
Definition: hwdriver.c:398
The public libsigrok header file to be used by frontends.
const char * sr_package_version_string_get(void)
Get the libsigrok package version number as a string.
Definition: version.c:96
char * sr_buildinfo_scpi_backends_get(void)
Definition: backend.c:216
const char * sr_lib_version_string_get(void)
Get the libsigrok library version number as a string.
Definition: version.c:145
Device driver data.
Definition: libsigrok.h:1254