2 * This file is part of the libsigrok project.
4 * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
5 * Copyright (C) 2012 Peter Stuge <peter@stuge.se>
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.
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.
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/>.
26 #include <libsigrok/libsigrok.h>
27 #include "libsigrok-internal.h"
28 #include "minilzo/minilzo.h"
31 #define LOG_PREFIX "backend"
35 * @mainpage libsigrok API
37 * @section sec_intro Introduction
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).
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
51 * @section sec_api API reference
53 * See the "Modules" page for an introduction to various libsigrok
54 * related topics and the detailed API documentation of the respective
57 * You can also browse the API documentation by file, or review all
60 * @section sec_mailinglists Mailing lists
62 * There is one mailing list for sigrok/libsigrok: <a href="https://lists.sourceforge.net/lists/listinfo/sigrok-devel">sigrok-devel</a>.
64 * @section sec_irc IRC
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.
70 * @section sec_website Website
72 * <a href="http://sigrok.org/wiki/Libsigrok">sigrok.org/wiki/Libsigrok</a>
78 * Initializing and shutting down libsigrok.
82 * @defgroup grp_init Initialization
84 * Initializing and shutting down libsigrok.
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
91 * When libsigrok functionality is no longer needed, sr_exit() should be
92 * called, which will (among other things) free the struct sr_context.
94 * Example for a minimal program using libsigrok:
98 * #include <libsigrok/libsigrok.h>
100 * int main(int argc, char **argv)
103 * struct sr_context *sr_ctx;
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));
111 * // Use libsigrok functions here...
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));
126 SR_API GSList
*sr_buildinfo_libs_get(void)
128 GSList
*l
= NULL
, *m
= NULL
;
129 #if defined(HAVE_LIBUSB_1_0) && !defined(__FreeBSD__)
130 const struct libusb_version
*lv
;
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
);
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
);
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
);
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
);
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
);
159 #ifdef HAVE_LIBUSB_1_0
160 m
= g_slist_append(NULL
, g_strdup("libusb-1.0"));
162 m
= g_slist_append(m
, g_strdup_printf("%s", CONF_LIBUSB_1_0_VERSION
));
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)
169 #elif defined(LIBUSBX_API_VERSION)
174 l
= g_slist_append(l
, m
);
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
);
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
);
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
);
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
);
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
);
205 SR_API
char *sr_buildinfo_host_get(void)
207 return g_strdup_printf("%s, %s-endian", CONF_HOST
,
208 #ifdef WORDS_BIGENDIAN
216 SR_API
char *sr_buildinfo_scpi_backends_get(void)
221 s
= g_string_sized_new(200);
223 g_string_append_printf(s
, "TCP, ");
225 g_string_append_printf(s
, "RPC, ");
227 #ifdef HAVE_SERIAL_COMM
228 g_string_append_printf(s
, "serial, ");
230 #ifdef HAVE_LIBREVISA
231 g_string_append_printf(s
, "VISA, ");
234 g_string_append_printf(s
, "GPIB, ");
236 #ifdef HAVE_LIBUSB_1_0
237 g_string_append_printf(s
, "USBTMC, ");
239 s
->str
[s
->len
- 2] = '\0';
241 str
= g_strdup(s
->str
);
242 g_string_free(s
, TRUE
);
247 static void print_versions(void)
250 GSList
*l
, *l_orig
, *m
;
252 const char *lib
, *version
;
254 sr_dbg("libsigrok %s/%s.",
255 sr_package_version_string_get(), sr_lib_version_string_get());
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
) {
263 version
= m
->next
->data
;
264 g_string_append_printf(s
, "%s %s, ", lib
, version
);
265 g_slist_free_full(m
, g_free
);
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
);
273 str
= sr_buildinfo_host_get();
274 sr_dbg("Host: %s.", str
);
277 str
= sr_buildinfo_scpi_backends_get();
278 sr_dbg("SCPI backends: %s.", str
);
282 static void print_resourcepaths(void)
286 sr_dbg("Firmware search paths:");
287 l_orig
= sr_resourcepaths_get(SR_RESOURCE_FIRMWARE
);
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
);
294 * Sanity-check all libsigrok drivers.
296 * @param[in] ctx Pointer to a libsigrok context struct. Must not be NULL.
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.
302 static int sanity_check_all_drivers(const struct sr_context
*ctx
)
304 int i
, errors
, ret
= SR_OK
;
305 struct sr_dev_driver
**drivers
;
311 sr_spew("Sanity-checking all drivers.");
313 drivers
= sr_driver_list(ctx
);
314 for (i
= 0; drivers
[i
]; i
++) {
317 d
= (drivers
[i
]->name
) ? drivers
[i
]->name
: "NULL";
319 if (!drivers
[i
]->name
) {
320 sr_err("No name in driver %d ('%s').", i
, d
);
323 if (!drivers
[i
]->longname
) {
324 sr_err("No longname in driver %d ('%s').", i
, d
);
327 if (drivers
[i
]->api_version
< 1) {
328 sr_err("API version in driver %d ('%s') < 1.", i
, d
);
331 if (!drivers
[i
]->init
) {
332 sr_err("No init in driver %d ('%s').", i
, d
);
335 if (!drivers
[i
]->cleanup
) {
336 sr_err("No cleanup in driver %d ('%s').", i
, d
);
339 if (!drivers
[i
]->scan
) {
340 sr_err("No scan in driver %d ('%s').", i
, d
);
343 if (!drivers
[i
]->dev_list
) {
344 sr_err("No dev_list in driver %d ('%s').", i
, d
);
347 if (!drivers
[i
]->dev_clear
) {
348 sr_err("No dev_clear in driver %d ('%s').", i
, d
);
351 /* Note: config_get() is optional. */
352 if (!drivers
[i
]->config_set
) {
353 sr_err("No config_set in driver %d ('%s').", i
, d
);
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
);
362 if (!drivers
[i
]->dev_open
) {
363 sr_err("No dev_open in driver %d ('%s').", i
, d
);
366 if (!drivers
[i
]->dev_close
) {
367 sr_err("No dev_close in driver %d ('%s').", i
, d
);
370 if (!drivers
[i
]->dev_acquisition_start
) {
371 sr_err("No dev_acquisition_start in driver %d ('%s').",
375 if (!drivers
[i
]->dev_acquisition_stop
) {
376 sr_err("No dev_acquisition_stop in driver %d ('%s').",
381 /* Note: 'priv' is allowed to be NULL. */
393 * Sanity-check all libsigrok input modules.
395 * @retval SR_OK All modules are OK
396 * @retval SR_ERR One or more modules have issues.
398 static int sanity_check_all_input_modules(void)
400 int i
, errors
, ret
= SR_OK
;
401 const struct sr_input_module
**inputs
;
404 sr_spew("Sanity-checking all input modules.");
406 inputs
= sr_input_list();
407 for (i
= 0; inputs
[i
]; i
++) {
410 d
= (inputs
[i
]->id
) ? inputs
[i
]->id
: "NULL";
412 if (!inputs
[i
]->id
) {
413 sr_err("No ID in module %d ('%s').", i
, d
);
416 if (!inputs
[i
]->name
) {
417 sr_err("No name in module %d ('%s').", i
, d
);
420 if (!inputs
[i
]->desc
) {
421 sr_err("No description in module %d ('%s').", i
, d
);
424 if (!inputs
[i
]->init
) {
425 sr_err("No init in module %d ('%s').", i
, d
);
428 if (!inputs
[i
]->receive
) {
429 sr_err("No receive in module %d ('%s').", i
, d
);
432 if (!inputs
[i
]->end
) {
433 sr_err("No end in module %d ('%s').", i
, d
);
447 * Sanity-check all libsigrok output modules.
449 * @retval SR_OK All modules are OK
450 * @retval SR_ERR One or more modules have issues.
452 static int sanity_check_all_output_modules(void)
454 int i
, errors
, ret
= SR_OK
;
455 const struct sr_output_module
**outputs
;
458 sr_spew("Sanity-checking all output modules.");
460 outputs
= sr_output_list();
461 for (i
= 0; outputs
[i
]; i
++) {
464 d
= (outputs
[i
]->id
) ? outputs
[i
]->id
: "NULL";
466 if (!outputs
[i
]->id
) {
467 sr_err("No ID in module %d ('%s').", i
, d
);
470 if (!outputs
[i
]->name
) {
471 sr_err("No name in module %d ('%s').", i
, d
);
474 if (!outputs
[i
]->desc
) {
475 sr_err("No description in module '%s'.", d
);
478 if (!outputs
[i
]->receive
) {
479 sr_err("No receive in module '%s'.", d
);
493 * Sanity-check all libsigrok transform modules.
495 * @retval SR_OK All modules are OK
496 * @retval SR_ERR One or more modules have issues.
498 static int sanity_check_all_transform_modules(void)
500 int i
, errors
, ret
= SR_OK
;
501 const struct sr_transform_module
**transforms
;
504 sr_spew("Sanity-checking all transform modules.");
506 transforms
= sr_transform_list();
507 for (i
= 0; transforms
[i
]; i
++) {
510 d
= (transforms
[i
]->id
) ? transforms
[i
]->id
: "NULL";
512 if (!transforms
[i
]->id
) {
513 sr_err("No ID in module %d ('%s').", i
, d
);
516 if (!transforms
[i
]->name
) {
517 sr_err("No name in module %d ('%s').", i
, d
);
520 if (!transforms
[i
]->desc
) {
521 sr_err("No description in module '%s'.", d
);
524 /* Note: options() is optional. */
525 /* Note: init() is optional. */
526 if (!transforms
[i
]->receive
) {
527 sr_err("No receive in module '%s'.", d
);
530 /* Note: cleanup() is optional. */
542 * Initialize libsigrok.
544 * This function must be called before any other libsigrok function.
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.
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
557 SR_API
int sr_init(struct sr_context
**ctx
)
560 struct sr_context
*context
;
567 print_resourcepaths();
570 sr_err("%s(): libsigrok context was NULL.", __func__
);
574 context
= g_malloc0(sizeof(struct sr_context
));
576 sr_drivers_init(context
);
578 if (sanity_check_all_drivers(context
) < 0) {
579 sr_err("Internal driver error(s), aborting.");
583 if (sanity_check_all_input_modules() < 0) {
584 sr_err("Internal input module error(s), aborting.");
588 if (sanity_check_all_output_modules() < 0) {
589 sr_err("Internal output module error(s), aborting.");
593 if (sanity_check_all_transform_modules() < 0) {
594 sr_err("Internal transform module error(s), aborting.");
599 if ((ret
= WSAStartup(MAKEWORD(2, 2), &wsadata
)) != 0) {
600 sr_err("WSAStartup failed with error code %d.", ret
);
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.");
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
));
622 #ifdef HAVE_LIBHIDAPI
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.
630 if (hid_init() != 0) {
631 sr_err("HIDAPI hid_init() failed.");
636 sr_resource_set_hooks(context
, NULL
, NULL
, NULL
, NULL
);
648 * Shutdown libsigrok.
650 * @param ctx Pointer to a libsigrok context struct. Must not be NULL.
652 * @retval SR_OK Success
653 * @retval other Error code SR_ERR, ...
657 SR_API
int sr_exit(struct sr_context
*ctx
)
660 sr_err("%s(): libsigrok context was NULL.", __func__
);
664 sr_hw_cleanup_all(ctx
);
670 #ifdef HAVE_LIBHIDAPI
673 #ifdef HAVE_LIBUSB_1_0
674 libusb_exit(ctx
->libusb_ctx
);
677 g_free(sr_driver_list(ctx
));