backend.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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. #include <glib.h>
  21. #include "config.h" /* Needed for HAVE_LIBUSB_1_0 and others. */
  22. #include "libsigrok.h"
  23. #include "libsigrok-internal.h"
  24. /** @cond PRIVATE */
  25. #define LOG_PREFIX "backend"
  26. /** @endcond */
  27. extern struct sr_session *session;
  28. /**
  29. * @mainpage libsigrok API
  30. *
  31. * @section sec_intro Introduction
  32. *
  33. * The <a href="http://sigrok.org">sigrok</a> project aims at creating a
  34. * portable, cross-platform, Free/Libre/Open-Source signal analysis software
  35. * suite that supports various device types (such as logic analyzers,
  36. * oscilloscopes, multimeters, and more).
  37. *
  38. * <a href="http://sigrok.org/wiki/Libsigrok">libsigrok</a> is a shared
  39. * library written in C which provides the basic API for talking to
  40. * <a href="http://sigrok.org/wiki/Supported_hardware">supported hardware</a>
  41. * and reading/writing the acquired data into various
  42. * <a href="http://sigrok.org/wiki/Input_output_formats">input/output
  43. * file formats</a>.
  44. *
  45. * @section sec_api API reference
  46. *
  47. * See the "Modules" page for an introduction to various libsigrok
  48. * related topics and the detailed API documentation of the respective
  49. * functions.
  50. *
  51. * You can also browse the API documentation by file, or review all
  52. * data structures.
  53. *
  54. * @section sec_mailinglists Mailing lists
  55. *
  56. * There are two mailing lists for sigrok/libsigrok: <a href="https://lists.sourceforge.net/lists/listinfo/sigrok-devel">sigrok-devel</a> and <a href="https://lists.sourceforge.net/lists/listinfo/sigrok-commits">sigrok-commits</a>.
  57. *
  58. * @section sec_irc IRC
  59. *
  60. * You can find the sigrok developers in the
  61. * <a href="irc://chat.freenode.net/sigrok">\#sigrok</a>
  62. * IRC channel on Freenode.
  63. *
  64. * @section sec_website Website
  65. *
  66. * <a href="http://sigrok.org/wiki/Libsigrok">sigrok.org/wiki/Libsigrok</a>
  67. */
  68. /**
  69. * @file
  70. *
  71. * Initializing and shutting down libsigrok.
  72. */
  73. /**
  74. * @defgroup grp_init Initialization
  75. *
  76. * Initializing and shutting down libsigrok.
  77. *
  78. * Before using any of the libsigrok functionality, sr_init() must
  79. * be called to initialize the library, which will return a struct sr_context
  80. * when the initialization was successful.
  81. *
  82. * When libsigrok functionality is no longer needed, sr_exit() should be
  83. * called, which will (among other things) free the struct sr_context.
  84. *
  85. * Example for a minimal program using libsigrok:
  86. *
  87. * @code{.c}
  88. * #include <stdio.h>
  89. * #include <libsigrok/libsigrok.h>
  90. *
  91. * int main(int argc, char **argv)
  92. * {
  93. * int ret;
  94. * struct sr_context *sr_ctx;
  95. *
  96. * if ((ret = sr_init(&sr_ctx)) != SR_OK) {
  97. * printf("Error initializing libsigrok (%s): %s.\n",
  98. * sr_strerror_name(ret), sr_strerror(ret));
  99. * return 1;
  100. * }
  101. *
  102. * // Use libsigrok functions here...
  103. *
  104. * if ((ret = sr_exit(sr_ctx)) != SR_OK) {
  105. * printf("Error shutting down libsigrok (%s): %s.\n",
  106. * sr_strerror_name(ret), sr_strerror(ret));
  107. * return 1;
  108. * }
  109. *
  110. * return 0;
  111. * }
  112. * @endcode
  113. *
  114. * @{
  115. */
  116. /**
  117. * Sanity-check all libsigrok drivers.
  118. *
  119. * @retval SR_OK All drivers are OK
  120. * @retval SR_ERR One or more drivers have issues.
  121. */
  122. static int sanity_check_all_drivers(void)
  123. {
  124. int i, errors, ret = SR_OK;
  125. struct sr_dev_driver **drivers;
  126. const char *d;
  127. sr_spew("Sanity-checking all drivers.");
  128. drivers = sr_driver_list();
  129. for (i = 0; drivers[i]; i++) {
  130. errors = 0;
  131. d = (drivers[i]->name) ? drivers[i]->name : "NULL";
  132. if (!drivers[i]->name) {
  133. sr_err("No name in driver %d ('%s').", i, d);
  134. errors++;
  135. }
  136. if (!drivers[i]->longname) {
  137. sr_err("No longname in driver %d ('%s').", i, d);
  138. errors++;
  139. }
  140. if (drivers[i]->api_version < 1) {
  141. sr_err("API version in driver %d ('%s') < 1.", i, d);
  142. errors++;
  143. }
  144. if (!drivers[i]->init) {
  145. sr_err("No init in driver %d ('%s').", i, d);
  146. errors++;
  147. }
  148. if (!drivers[i]->cleanup) {
  149. sr_err("No cleanup in driver %d ('%s').", i, d);
  150. errors++;
  151. }
  152. if (!drivers[i]->scan) {
  153. sr_err("No scan in driver %d ('%s').", i, d);
  154. errors++;
  155. }
  156. if (!drivers[i]->dev_list) {
  157. sr_err("No dev_list in driver %d ('%s').", i, d);
  158. errors++;
  159. }
  160. /* Note: config_get() is optional. */
  161. if (!drivers[i]->config_set) {
  162. sr_err("No config_set in driver %d ('%s').", i, d);
  163. errors++;
  164. }
  165. if (!drivers[i]->config_list) {
  166. sr_err("No config_list in driver %d ('%s').", i, d);
  167. errors++;
  168. }
  169. if (!drivers[i]->dev_open) {
  170. sr_err("No dev_open in driver %d ('%s').", i, d);
  171. errors++;
  172. }
  173. if (!drivers[i]->dev_close) {
  174. sr_err("No dev_close in driver %d ('%s').", i, d);
  175. errors++;
  176. }
  177. if (!drivers[i]->dev_acquisition_start) {
  178. sr_err("No dev_acquisition_start in driver %d ('%s').",
  179. i, d);
  180. errors++;
  181. }
  182. if (!drivers[i]->dev_acquisition_stop) {
  183. sr_err("No dev_acquisition_stop in driver %d ('%s').",
  184. i, d);
  185. errors++;
  186. }
  187. /* Note: 'priv' is allowed to be NULL. */
  188. if (errors == 0)
  189. continue;
  190. ret = SR_ERR;
  191. }
  192. return ret;
  193. }
  194. /**
  195. * Sanity-check all libsigrok input modules.
  196. *
  197. * @retval SR_OK All modules are OK
  198. * @retval SR_ERR One or more modules have issues.
  199. */
  200. static int sanity_check_all_input_modules(void)
  201. {
  202. int i, errors, ret = SR_OK;
  203. struct sr_input_format **inputs;
  204. const char *d;
  205. sr_spew("Sanity-checking all input modules.");
  206. inputs = sr_input_list();
  207. for (i = 0; inputs[i]; i++) {
  208. errors = 0;
  209. d = (inputs[i]->id) ? inputs[i]->id : "NULL";
  210. if (!inputs[i]->id) {
  211. sr_err("No ID in module %d ('%s').", i, d);
  212. errors++;
  213. }
  214. if (!inputs[i]->description) {
  215. sr_err("No description in module %d ('%s').", i, d);
  216. errors++;
  217. }
  218. if (!inputs[i]->format_match) {
  219. sr_err("No format_match in module %d ('%s').", i, d);
  220. errors++;
  221. }
  222. if (!inputs[i]->init) {
  223. sr_err("No init in module %d ('%s').", i, d);
  224. errors++;
  225. }
  226. if (!inputs[i]->loadfile) {
  227. sr_err("No loadfile in module %d ('%s').", i, d);
  228. errors++;
  229. }
  230. if (errors == 0)
  231. continue;
  232. ret = SR_ERR;
  233. }
  234. return ret;
  235. }
  236. /**
  237. * Sanity-check all libsigrok output modules.
  238. *
  239. * @retval SR_OK All modules are OK
  240. * @retval SR_ERR One or more modules have issues.
  241. */
  242. static int sanity_check_all_output_modules(void)
  243. {
  244. int i, errors, ret = SR_OK;
  245. struct sr_output_format **outputs;
  246. const char *d;
  247. sr_spew("Sanity-checking all output modules.");
  248. outputs = sr_output_list();
  249. for (i = 0; outputs[i]; i++) {
  250. errors = 0;
  251. d = (outputs[i]->id) ? outputs[i]->id : "NULL";
  252. if (!outputs[i]->id) {
  253. sr_err("No ID in module %d ('%s').", i, d);
  254. errors++;
  255. }
  256. if (!outputs[i]->description) {
  257. sr_err("No description in module '%s'.", d);
  258. errors++;
  259. }
  260. if (!outputs[i]->receive) {
  261. sr_err("No receive in module '%s'.", d);
  262. errors++;
  263. }
  264. if (errors == 0)
  265. continue;
  266. ret = SR_ERR;
  267. }
  268. return ret;
  269. }
  270. /**
  271. * Initialize libsigrok.
  272. *
  273. * This function must be called before any other libsigrok function.
  274. *
  275. * @param ctx Pointer to a libsigrok context struct pointer. Must not be NULL.
  276. * This will be a pointer to a newly allocated libsigrok context
  277. * object upon success, and is undefined upon errors.
  278. *
  279. * @return SR_OK upon success, a (negative) error code otherwise. Upon errors
  280. * the 'ctx' pointer is undefined and should not be used. Upon success,
  281. * the context will be free'd by sr_exit() as part of the libsigrok
  282. * shutdown.
  283. *
  284. * @since 0.2.0
  285. */
  286. SR_API int sr_init(struct sr_context **ctx)
  287. {
  288. int ret = SR_ERR;
  289. struct sr_context *context;
  290. if (!ctx) {
  291. sr_err("%s(): libsigrok context was NULL.", __func__);
  292. return SR_ERR;
  293. }
  294. if (sanity_check_all_drivers() < 0) {
  295. sr_err("Internal driver error(s), aborting.");
  296. return ret;
  297. }
  298. if (sanity_check_all_input_modules() < 0) {
  299. sr_err("Internal input module error(s), aborting.");
  300. return ret;
  301. }
  302. if (sanity_check_all_output_modules() < 0) {
  303. sr_err("Internal output module error(s), aborting.");
  304. return ret;
  305. }
  306. /* + 1 to handle when struct sr_context has no members. */
  307. context = g_try_malloc0(sizeof(struct sr_context) + 1);
  308. if (!context) {
  309. ret = SR_ERR_MALLOC;
  310. goto done;
  311. }
  312. #ifdef HAVE_LIBUSB_1_0
  313. ret = libusb_init(&context->libusb_ctx);
  314. if (LIBUSB_SUCCESS != ret) {
  315. sr_err("libusb_init() returned %s.", libusb_error_name(ret));
  316. ret = SR_ERR;
  317. goto done;
  318. }
  319. #endif
  320. *ctx = context;
  321. context = NULL;
  322. session = NULL;
  323. ret = SR_OK;
  324. done:
  325. if (context)
  326. g_free(context);
  327. return ret;
  328. }
  329. /**
  330. * Shutdown libsigrok.
  331. *
  332. * @param ctx Pointer to a libsigrok context struct. Must not be NULL.
  333. *
  334. * @retval SR_OK Success
  335. * @retval other Error code SR_ERR, ...
  336. *
  337. * @since 0.2.0
  338. */
  339. SR_API int sr_exit(struct sr_context *ctx)
  340. {
  341. if (!ctx) {
  342. sr_err("%s(): libsigrok context was NULL.", __func__);
  343. return SR_ERR;
  344. }
  345. sr_hw_cleanup_all();
  346. #ifdef HAVE_LIBUSB_1_0
  347. libusb_exit(ctx->libusb_ctx);
  348. #endif
  349. g_free(ctx);
  350. return SR_OK;
  351. }
  352. /** @} */