Use error description in log messages
[libjaylink.git] / libjaylink / device.c
blobb3c5f00c6c55bf60918b6cf1b3197e5377f47d7f
1 /*
2 * This file is part of the libjaylink project.
4 * Copyright (C) 2014-2016 Marc Schink <jaylink-dev@marcschink.de>
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.
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.
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/>.
20 #include <stdlib.h>
21 #include <stdint.h>
22 #include <stdbool.h>
23 #include <string.h>
24 #ifdef _WIN32
25 #include <winsock2.h>
26 #else
27 #include <sys/socket.h>
28 #include <arpa/inet.h>
29 #endif
30 #include <libusb.h>
32 #include "libjaylink.h"
33 #include "libjaylink-internal.h"
35 /**
36 * @file
38 * Device enumeration and handling.
41 /** @cond PRIVATE */
42 #define CMD_GET_VERSION 0x01
43 #define CMD_GET_HW_STATUS 0x07
44 #define CMD_REGISTER 0x09
45 #define CMD_GET_HW_INFO 0xc1
46 #define CMD_GET_FREE_MEMORY 0xd4
47 #define CMD_GET_CAPS 0xe8
48 #define CMD_GET_EXT_CAPS 0xed
49 #define CMD_GET_HW_VERSION 0xf0
50 #define CMD_READ_CONFIG 0xf2
51 #define CMD_WRITE_CONFIG 0xf3
53 #define REG_CMD_REGISTER 0x64
54 #define REG_CMD_UNREGISTER 0x65
56 /** Size of the registration header in bytes. */
57 #define REG_HEADER_SIZE 8
58 /** Minimum registration information size in bytes. */
59 #define REG_MIN_SIZE 0x4c
60 /** Maximum registration information size in bytes. */
61 #define REG_MAX_SIZE 0x200
62 /** Size of a connection entry in bytes. */
63 #define REG_CONN_INFO_SIZE 16
64 /** @endcond */
66 /** @private */
67 JAYLINK_PRIV struct jaylink_device *device_allocate(
68 struct jaylink_context *ctx)
70 struct jaylink_device *dev;
71 struct list *list;
73 dev = malloc(sizeof(struct jaylink_device));
75 if (!dev)
76 return NULL;
78 list = list_prepend(ctx->devs, dev);
80 if (!list) {
81 free(dev);
82 return NULL;
85 ctx->devs = list;
87 dev->ctx = ctx;
88 dev->ref_count = 1;
89 dev->usb_dev = NULL;
91 return dev;
94 static struct jaylink_device **allocate_device_list(size_t length)
96 struct jaylink_device **list;
98 list = malloc(sizeof(struct jaylink_device *) * (length + 1));
100 if (!list)
101 return NULL;
103 list[length] = NULL;
105 return list;
109 * Get available devices.
111 * @param[in,out] ctx libjaylink context.
112 * @param[out] devices Newly allocated array which contains instances of
113 * available devices on success, and undefined on failure.
114 * The array is NULL-terminated and must be free'd by the
115 * caller with jaylink_free_devices().
116 * @param[out] count Number of available devices on success, and undefined on
117 * failure. Can be NULL.
119 * @retval JAYLINK_OK Success.
120 * @retval JAYLINK_ERR_ARG Invalid arguments.
121 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
122 * @retval JAYLINK_ERR Other error conditions.
124 * @see jaylink_discovery_scan()
126 * @since 0.1.0
128 JAYLINK_API int jaylink_get_devices(struct jaylink_context *ctx,
129 struct jaylink_device ***devices, size_t *count)
131 size_t num;
132 struct list *item;
133 struct jaylink_device **devs;
134 struct jaylink_device *dev;
135 size_t i;
137 if (!ctx || !devices)
138 return JAYLINK_ERR_ARG;
140 num = list_length(ctx->discovered_devs);
141 devs = allocate_device_list(num);
143 if (!devs) {
144 log_err(ctx, "Failed to allocate device list.");
145 return JAYLINK_ERR_MALLOC;
148 item = ctx->discovered_devs;
150 for (i = 0; i < num; i++) {
151 dev = (struct jaylink_device *)item->data;
152 devs[i] = jaylink_ref_device(dev);
153 item = item->next;
156 if (count)
157 *count = num;
159 *devices = devs;
161 return JAYLINK_OK;
165 * Free devices.
167 * @param[in,out] devices Array of device instances. Must be NULL-terminated.
168 * @param[in] unref Determines whether the device instances should be
169 * unreferenced.
171 * @see jaylink_get_devices()
173 * @since 0.1.0
175 JAYLINK_API void jaylink_free_devices(struct jaylink_device **devices,
176 bool unref)
178 size_t i;
180 if (!devices)
181 return;
183 if (unref) {
184 for (i = 0; devices[i]; i++)
185 jaylink_unref_device(devices[i]);
188 free(devices);
192 * Get the host interface of a device.
194 * @param[in] dev Device instance.
195 * @param[out] iface Host interface of the device on success, and undefined on
196 * failure.
198 * @retval JAYLINK_OK Success.
199 * @retval JAYLINK_ERR_ARG Invalid arguments.
201 * @since 0.1.0
203 JAYLINK_API int jaylink_device_get_host_interface(
204 const struct jaylink_device *dev,
205 enum jaylink_host_interface *iface)
207 if (!dev || !iface)
208 return JAYLINK_ERR_ARG;
210 *iface = dev->interface;
212 return JAYLINK_OK;
216 * Get the serial number of a device.
218 * @note This serial number is for enumeration purpose only and might differ
219 * from the real serial number of the device.
221 * @param[in] dev Device instance.
222 * @param[out] serial_number Serial number of the device on success, and
223 * undefined on failure.
225 * @retval JAYLINK_OK Success.
226 * @retval JAYLINK_ERR_ARG Invalid arguments.
227 * @retval JAYLINK_ERR_NOT_AVAILABLE Serial number is not available.
229 * @since 0.1.0
231 JAYLINK_API int jaylink_device_get_serial_number(
232 const struct jaylink_device *dev, uint32_t *serial_number)
234 if (!dev || !serial_number)
235 return JAYLINK_ERR_ARG;
237 if (!dev->valid_serial_number)
238 return JAYLINK_ERR_NOT_AVAILABLE;
240 *serial_number = dev->serial_number;
242 return JAYLINK_OK;
246 * Get the USB address of a device.
248 * @note Identification of a device with the USB address is deprecated and the
249 * serial number should be used instead.
251 * @param[in] dev Device instance.
252 * @param[out] address USB address of the device on success, and undefined on
253 * failure.
255 * @retval JAYLINK_OK Success.
256 * @retval JAYLINK_ERR_ARG Invalid arguments.
257 * @retval JAYLINK_ERR_NOT_SUPPORTED Operation not supported.
259 * @see jaylink_device_get_serial_number()
261 * @since 0.1.0
263 JAYLINK_API int jaylink_device_get_usb_address(
264 const struct jaylink_device *dev,
265 enum jaylink_usb_address *address)
267 if (!dev || !address)
268 return JAYLINK_ERR_ARG;
270 if (dev->interface != JAYLINK_HIF_USB)
271 return JAYLINK_ERR_NOT_SUPPORTED;
273 *address = dev->usb_address;
275 return JAYLINK_OK;
279 * Increment the reference count of a device.
281 * @param[in,out] dev Device instance.
283 * @return The given device instance on success, or NULL on invalid argument.
285 * @since 0.1.0
287 JAYLINK_API struct jaylink_device *jaylink_ref_device(
288 struct jaylink_device *dev)
290 if (!dev)
291 return NULL;
293 dev->ref_count++;
295 return dev;
299 * Decrement the reference count of a device.
301 * @param[in,out] dev Device instance.
303 * @since 0.1.0
305 JAYLINK_API void jaylink_unref_device(struct jaylink_device *dev)
307 struct jaylink_context *ctx;
309 if (!dev)
310 return;
312 dev->ref_count--;
314 if (!dev->ref_count) {
315 ctx = dev->ctx;
317 log_dbg(ctx, "Device destroyed (bus:address = %03u:%03u).",
318 libusb_get_bus_number(dev->usb_dev),
319 libusb_get_device_address(dev->usb_dev));
321 ctx->devs = list_remove(dev->ctx->devs, dev);
323 if (dev->usb_dev)
324 libusb_unref_device(dev->usb_dev);
326 free(dev);
330 static struct jaylink_device_handle *allocate_device_handle(
331 struct jaylink_device *dev)
333 struct jaylink_device_handle *devh;
335 devh = malloc(sizeof(struct jaylink_device_handle));
337 if (!devh)
338 return NULL;
340 devh->dev = jaylink_ref_device(dev);
342 return devh;
345 static void free_device_handle(struct jaylink_device_handle *devh)
347 jaylink_unref_device(devh->dev);
348 free(devh);
352 * Open a device.
354 * @param[in,out] dev Device instance.
355 * @param[out] devh Newly allocated handle for the opened device on success,
356 * and undefined on failure.
358 * @retval JAYLINK_OK Success.
359 * @retval JAYLINK_ERR_ARG Invalid arguments.
360 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
361 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
362 * @retval JAYLINK_ERR Other error conditions.
364 * @since 0.1.0
366 JAYLINK_API int jaylink_open(struct jaylink_device *dev,
367 struct jaylink_device_handle **devh)
369 int ret;
370 struct jaylink_device_handle *handle;
372 if (!dev || !devh)
373 return JAYLINK_ERR_ARG;
375 handle = allocate_device_handle(dev);
377 if (!handle) {
378 log_err(dev->ctx, "Device handle malloc failed.");
379 return JAYLINK_ERR_MALLOC;
382 ret = transport_open(handle);
384 if (ret != JAYLINK_OK) {
385 free_device_handle(handle);
386 return ret;
389 *devh = handle;
391 return JAYLINK_OK;
395 * Close a device.
397 * @param[in,out] devh Device instance.
399 * @retval JAYLINK_OK Success.
400 * @retval JAYLINK_ERR_ARG Invalid arguments.
401 * @retval JAYLINK_ERR Other error conditions.
403 * @since 0.1.0
405 JAYLINK_API int jaylink_close(struct jaylink_device_handle *devh)
407 int ret;
409 if (!devh)
410 return JAYLINK_ERR_ARG;
412 ret = transport_close(devh);
413 free_device_handle(devh);
415 return ret;
419 * Get the device instance from a device handle.
421 * @note The reference count of the device instance is not increased.
423 * @param[in] devh Device handle.
425 * @return The device instance on success, or NULL on invalid argument.
427 * @since 0.1.0
429 JAYLINK_API struct jaylink_device *jaylink_get_device(
430 struct jaylink_device_handle *devh)
432 if (!devh)
433 return NULL;
435 return devh->dev;
439 * Retrieve the firmware version of a device.
441 * @param[in,out] devh Device handle.
442 * @param[out] version Newly allocated string which contains the firmware
443 * version on success, and undefined if @p length is zero
444 * or on failure. The string is null-terminated and must be
445 * free'd by the caller.
446 * @param[out] length Length of the firmware version string including trailing
447 * null-terminator on success, and undefined on failure.
448 * Zero if no firmware version string is available.
450 * @retval JAYLINK_OK Success.
451 * @retval JAYLINK_ERR_ARG Invalid arguments.
452 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
453 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
454 * @retval JAYLINK_ERR Other error conditions.
456 * @since 0.1.0
458 JAYLINK_API int jaylink_get_firmware_version(
459 struct jaylink_device_handle *devh, char **version,
460 size_t *length)
462 int ret;
463 struct jaylink_context *ctx;
464 uint8_t buf[2];
465 uint16_t dummy;
466 char *tmp;
468 if (!devh || !version || !length)
469 return JAYLINK_ERR_ARG;
471 ctx = devh->dev->ctx;
472 ret = transport_start_write_read(devh, 1, 2, true);
474 if (ret != JAYLINK_OK) {
475 log_err(ctx, "transport_start_write_read() failed: %s.",
476 jaylink_strerror(ret));
477 return ret;
480 buf[0] = CMD_GET_VERSION;
482 ret = transport_write(devh, buf, 1);
484 if (ret != JAYLINK_OK) {
485 log_err(ctx, "transport_write() failed: %s.",
486 jaylink_strerror(ret));
487 return ret;
490 ret = transport_read(devh, buf, 2);
492 if (ret != JAYLINK_OK) {
493 log_err(ctx, "transport_read() failed: %s.",
494 jaylink_strerror(ret));
495 return ret;
498 dummy = buffer_get_u16(buf, 0);
499 *length = dummy;
501 if (!dummy)
502 return JAYLINK_OK;
504 ret = transport_start_read(devh, dummy);
506 if (ret != JAYLINK_OK) {
507 log_err(ctx, "transport_start_read() failed: %s.",
508 jaylink_strerror(ret));
509 return ret;
512 tmp = malloc(dummy);
514 if (!tmp) {
515 log_err(ctx, "Firmware version string malloc failed.");
516 return JAYLINK_ERR_MALLOC;
519 ret = transport_read(devh, (uint8_t *)tmp, dummy);
521 if (ret != JAYLINK_OK) {
522 log_err(ctx, "transport_read() failed: %s.",
523 jaylink_strerror(ret));
524 free(tmp);
525 return ret;
528 /* Last byte is reserved for null-terminator. */
529 tmp[dummy - 1] = 0;
530 *version = tmp;
532 return JAYLINK_OK;
536 * Retrieve the hardware information of a device.
538 * @note This function must only be used if the device has the
539 * #JAYLINK_DEV_CAP_GET_HW_INFO capability.
541 * @param[in,out] devh Device handle.
542 * @param[in] mask A bit field where each set bit represents hardware
543 * information to request. See #jaylink_hardware_info for a
544 * description of the hardware information and their bit
545 * positions.
546 * @param[out] info Array to store the hardware information on success. Its
547 * content is undefined on failure. The array must be large
548 * enough to contain at least as many elements as bits set in
549 * @a mask.
551 * @retval JAYLINK_OK Success.
552 * @retval JAYLINK_ERR_ARG Invalid arguments.
553 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
554 * @retval JAYLINK_ERR Other error conditions.
556 * @since 0.1.0
558 JAYLINK_API int jaylink_get_hardware_info(struct jaylink_device_handle *devh,
559 uint32_t mask, uint32_t *info)
561 int ret;
562 struct jaylink_context *ctx;
563 uint8_t buf[5];
564 unsigned int i;
565 unsigned int num;
566 unsigned int length;
568 if (!devh || !mask || !info)
569 return JAYLINK_ERR_ARG;
571 ctx = devh->dev->ctx;
572 num = 0;
574 for (i = 0; i < 32; i++) {
575 if (mask & (1 << i))
576 num++;
579 length = num * sizeof(uint32_t);
581 ret = transport_start_write_read(devh, 5, length, true);
583 if (ret != JAYLINK_OK) {
584 log_err(ctx, "transport_start_write_read() failed: %s.",
585 jaylink_strerror(ret));
586 return ret;
589 buf[0] = CMD_GET_HW_INFO;
590 buffer_set_u32(buf, mask, 1);
592 ret = transport_write(devh, buf, 5);
594 if (ret != JAYLINK_OK) {
595 log_err(ctx, "transport_write() failed: %s.",
596 jaylink_strerror(ret));
597 return ret;
600 ret = transport_read(devh, (uint8_t *)info, length);
602 if (ret != JAYLINK_OK) {
603 log_err(ctx, "transport_read() failed: %s.",
604 jaylink_strerror(ret));
605 return ret;
608 for (i = 0; i < num; i++)
609 info[i] = buffer_get_u32((uint8_t *)info,
610 i * sizeof(uint32_t));
612 return JAYLINK_OK;
616 * Retrieve the hardware version of a device.
618 * @note This function must only be used if the device has the
619 * #JAYLINK_DEV_CAP_GET_HW_VERSION capability.
621 * @warning This function may return a value for @p version where
622 * #jaylink_hardware_version::type is not covered by
623 * #jaylink_hardware_type.
625 * @param[in,out] devh Device handle.
626 * @param[out] version Hardware version on success, and undefined on failure.
628 * @retval JAYLINK_OK Success.
629 * @retval JAYLINK_ERR_ARG Invalid arguments.
630 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
631 * @retval JAYLINK_ERR Other error conditions.
633 * @since 0.1.0
635 JAYLINK_API int jaylink_get_hardware_version(
636 struct jaylink_device_handle *devh,
637 struct jaylink_hardware_version *version)
639 int ret;
640 struct jaylink_context *ctx;
641 uint8_t buf[4];
642 uint32_t tmp;
644 if (!devh || !version)
645 return JAYLINK_ERR_ARG;
647 ctx = devh->dev->ctx;
648 ret = transport_start_write_read(devh, 1, 4, true);
650 if (ret != JAYLINK_OK) {
651 log_err(ctx, "transport_start_write_read() failed: %s.",
652 jaylink_strerror(ret));
653 return ret;
656 buf[0] = CMD_GET_HW_VERSION;
658 ret = transport_write(devh, buf, 1);
660 if (ret != JAYLINK_OK) {
661 log_err(ctx, "transport_write() failed: %s.",
662 jaylink_strerror(ret));
663 return ret;
666 ret = transport_read(devh, buf, 4);
668 if (ret != JAYLINK_OK) {
669 log_err(ctx, "transport_read() failed: %s.",
670 jaylink_strerror(ret));
671 return ret;
674 tmp = buffer_get_u32(buf, 0);
676 version->type = (tmp / 1000000) % 100;
677 version->major = (tmp / 10000) % 100;
678 version->minor = (tmp / 100) % 100;
679 version->revision = tmp % 100;
681 return JAYLINK_OK;
685 * Retrieve the hardware status of a device.
687 * @param[in,out] devh Device handle.
688 * @param[out] status Hardware status on success, and undefined on failure.
690 * @retval JAYLINK_OK Success.
691 * @retval JAYLINK_ERR_ARG Invalid arguments.
692 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
693 * @retval JAYLINK_ERR Other error conditions.
695 * @since 0.1.0
697 JAYLINK_API int jaylink_get_hardware_status(struct jaylink_device_handle *devh,
698 struct jaylink_hardware_status *status)
700 int ret;
701 struct jaylink_context *ctx;
702 uint8_t buf[8];
704 if (!devh || !status)
705 return JAYLINK_ERR_ARG;
707 ctx = devh->dev->ctx;
708 ret = transport_start_write_read(devh, 1, 8, true);
710 if (ret != JAYLINK_OK) {
711 log_err(ctx, "transport_start_write_read() failed: %s.",
712 jaylink_strerror(ret));
713 return ret;
716 buf[0] = CMD_GET_HW_STATUS;
718 ret = transport_write(devh, buf, 1);
720 if (ret != JAYLINK_OK) {
721 log_err(ctx, "transport_write() failed: %s.",
722 jaylink_strerror(ret));
723 return ret;
726 ret = transport_read(devh, buf, 8);
728 if (ret != JAYLINK_OK) {
729 log_err(ctx, "transport_read() failed: %s.",
730 jaylink_strerror(ret));
731 return ret;
734 status->target_voltage = buffer_get_u16(buf, 0);
735 status->tck = buf[2];
736 status->tdi = buf[3];
737 status->tdo = buf[4];
738 status->tms = buf[5];
739 status->tres = buf[6];
740 status->trst = buf[7];
742 return JAYLINK_OK;
746 * Retrieve the capabilities of a device.
748 * The capabilities are stored in a 32-bit bit array consisting of
749 * #JAYLINK_DEV_CAPS_SIZE bytes where each individual bit represents a
750 * capability. The first bit of this array is the least significant bit of the
751 * first byte and the following bits are sequentially numbered in order of
752 * increasing bit significance and byte index. A set bit indicates a supported
753 * capability. See #jaylink_device_capability for a description of the
754 * capabilities and their bit positions.
756 * @param[in,out] devh Device handle.
757 * @param[out] caps Buffer to store capabilities on success. Its content is
758 * undefined on failure. The buffer must be large enough to
759 * contain at least #JAYLINK_DEV_CAPS_SIZE bytes.
761 * @retval JAYLINK_OK Success.
762 * @retval JAYLINK_ERR_ARG Invalid arguments.
763 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
764 * @retval JAYLINK_ERR Other error conditions.
766 * @see jaylink_get_extended_caps()
767 * @see jaylink_has_cap()
769 * @since 0.1.0
771 JAYLINK_API int jaylink_get_caps(struct jaylink_device_handle *devh,
772 uint8_t *caps)
774 int ret;
775 struct jaylink_context *ctx;
776 uint8_t buf[1];
778 if (!devh || !caps)
779 return JAYLINK_ERR_ARG;
781 ctx = devh->dev->ctx;
782 ret = transport_start_write_read(devh, 1, JAYLINK_DEV_CAPS_SIZE, true);
784 if (ret != JAYLINK_OK) {
785 log_err(ctx, "transport_start_write_read() failed: %s.",
786 jaylink_strerror(ret));
787 return ret;
790 buf[0] = CMD_GET_CAPS;
792 ret = transport_write(devh, buf, 1);
794 if (ret != JAYLINK_OK) {
795 log_err(ctx, "transport_write() failed: %s.",
796 jaylink_strerror(ret));
797 return ret;
800 ret = transport_read(devh, caps, JAYLINK_DEV_CAPS_SIZE);
802 if (ret != JAYLINK_OK) {
803 log_err(ctx, "transport_read() failed: %s.",
804 jaylink_strerror(ret));
805 return ret;
808 return JAYLINK_OK;
812 * Retrieve the extended capabilities of a device.
814 * The extended capabilities are stored in a 256-bit bit array consisting of
815 * #JAYLINK_DEV_EXT_CAPS_SIZE bytes. See jaylink_get_caps() for a further
816 * description of how the capabilities are represented in this bit array. For a
817 * description of the capabilities and their bit positions, see
818 * #jaylink_device_capability.
820 * @note This function must only be used if the device has the
821 * #JAYLINK_DEV_CAP_GET_EXT_CAPS capability.
823 * @param[in,out] devh Device handle.
824 * @param[out] caps Buffer to store capabilities on success. Its content is
825 * undefined on failure. The buffer must be large enough to
826 * contain at least #JAYLINK_DEV_EXT_CAPS_SIZE bytes.
828 * @retval JAYLINK_OK Success.
829 * @retval JAYLINK_ERR_ARG Invalid arguments.
830 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
831 * @retval JAYLINK_ERR Other error conditions.
833 * @see jaylink_get_caps()
835 * @since 0.1.0
837 JAYLINK_API int jaylink_get_extended_caps(struct jaylink_device_handle *devh,
838 uint8_t *caps)
840 int ret;
841 struct jaylink_context *ctx;
842 uint8_t buf[1];
844 if (!devh || !caps)
845 return JAYLINK_ERR_ARG;
847 ctx = devh->dev->ctx;
848 ret = transport_start_write_read(devh, 1, JAYLINK_DEV_EXT_CAPS_SIZE,
849 true);
851 if (ret != JAYLINK_OK) {
852 log_err(ctx, "transport_start_write_read() failed: %s.",
853 jaylink_strerror(ret));
854 return ret;
857 buf[0] = CMD_GET_EXT_CAPS;
859 ret = transport_write(devh, buf, 1);
861 if (ret != JAYLINK_OK) {
862 log_err(ctx, "transport_write() failed: %s.",
863 jaylink_strerror(ret));
864 return ret;
867 ret = transport_read(devh, caps, JAYLINK_DEV_EXT_CAPS_SIZE);
869 if (ret != JAYLINK_OK) {
870 log_err(ctx, "transport_read() failed: %s.",
871 jaylink_strerror(ret));
872 return ret;
875 return JAYLINK_OK;
879 * Retrieve the size of free memory of a device.
881 * @note This function must only be used if the device has the
882 * #JAYLINK_DEV_CAP_GET_FREE_MEMORY capability.
884 * @param[in,out] devh Device handle.
885 * @param[out] size Size of free memory in bytes on success, and undefined on
886 * failure.
888 * @retval JAYLINK_OK Success.
889 * @retval JAYLINK_ERR_ARG Invalid arguments.
890 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
891 * @retval JAYLINK_ERR Other error conditions.
893 * @since 0.1.0
895 JAYLINK_API int jaylink_get_free_memory(struct jaylink_device_handle *devh,
896 uint32_t *size)
898 int ret;
899 struct jaylink_context *ctx;
900 uint8_t buf[4];
902 if (!devh || !size)
903 return JAYLINK_ERR_ARG;
905 ctx = devh->dev->ctx;
906 ret = transport_start_write_read(devh, 1, 4, true);
908 if (ret != JAYLINK_OK) {
909 log_err(ctx, "transport_start_write_read() failed: %s.",
910 jaylink_strerror(ret));
911 return ret;
914 buf[0] = CMD_GET_FREE_MEMORY;
916 ret = transport_write(devh, buf, 1);
918 if (ret != JAYLINK_OK) {
919 log_err(ctx, "transport_write() failed: %s.",
920 jaylink_strerror(ret));
921 return ret;
924 ret = transport_read(devh, buf, 4);
926 if (ret != JAYLINK_OK) {
927 log_err(ctx, "transport_read() failed: %s.",
928 jaylink_strerror(ret));
929 return ret;
932 *size = buffer_get_u32(buf, 0);
934 return JAYLINK_OK;
938 * Read the raw configuration data of a device.
940 * @note This function must only be used if the device has the
941 * #JAYLINK_DEV_CAP_READ_CONFIG capability.
943 * @param[in,out] devh Device handle.
944 * @param[out] config Buffer to store configuration data on success. Its
945 * content is undefined on failure. The buffer must be large
946 * enough to contain at least
947 * #JAYLINK_DEV_CONFIG_SIZE bytes.
949 * @retval JAYLINK_OK Success.
950 * @retval JAYLINK_ERR_ARG Invalid arguments.
951 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
952 * @retval JAYLINK_ERR Other error conditions.
954 * @since 0.1.0
956 JAYLINK_API int jaylink_read_raw_config(struct jaylink_device_handle *devh,
957 uint8_t *config)
959 int ret;
960 struct jaylink_context *ctx;
961 uint8_t buf[1];
963 if (!devh || !config)
964 return JAYLINK_ERR_ARG;
966 ctx = devh->dev->ctx;
967 ret = transport_start_write_read(devh, 1, JAYLINK_DEV_CONFIG_SIZE,
968 true);
970 if (ret != JAYLINK_OK) {
971 log_err(ctx, "transport_start_write_read() failed: %s.",
972 jaylink_strerror(ret));
973 return ret;
976 buf[0] = CMD_READ_CONFIG;
978 ret = transport_write(devh, buf, 1);
980 if (ret != JAYLINK_OK) {
981 log_err(ctx, "transport_write() failed: %s.",
982 jaylink_strerror(ret));
983 return ret;
986 ret = transport_read(devh, config, JAYLINK_DEV_CONFIG_SIZE);
988 if (ret != JAYLINK_OK) {
989 log_err(ctx, "transport_read() failed: %s.",
990 jaylink_strerror(ret));
991 return ret;
994 return JAYLINK_OK;
998 * Write the raw configuration data of a device.
1000 * @note This function must only be used if the device has the
1001 * #JAYLINK_DEV_CAP_WRITE_CONFIG capability.
1003 * @param[in,out] devh Device handle.
1004 * @param[in] config Buffer to write configuration data from. The size of the
1005 * configuration data is expected to be
1006 * #JAYLINK_DEV_CONFIG_SIZE bytes.
1008 * @retval JAYLINK_OK Success.
1009 * @retval JAYLINK_ERR_ARG Invalid arguments.
1010 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1011 * @retval JAYLINK_ERR Other error conditions.
1013 * @since 0.1.0
1015 JAYLINK_API int jaylink_write_raw_config(struct jaylink_device_handle *devh,
1016 const uint8_t *config)
1018 int ret;
1019 struct jaylink_context *ctx;
1020 uint8_t buf[1];
1022 if (!devh || !config)
1023 return JAYLINK_ERR_ARG;
1025 ctx = devh->dev->ctx;
1026 ret = transport_start_write(devh, 1 + JAYLINK_DEV_CONFIG_SIZE, true);
1028 if (ret != JAYLINK_OK) {
1029 log_err(ctx, "transport_start_write() failed: %s.",
1030 jaylink_strerror(ret));
1031 return ret;
1034 buf[0] = CMD_WRITE_CONFIG;
1036 ret = transport_write(devh, buf, 1);
1038 if (ret != JAYLINK_OK) {
1039 log_err(ctx, "transport_write() failed: %s.",
1040 jaylink_strerror(ret));
1041 return ret;
1044 ret = transport_write(devh, config, JAYLINK_DEV_CONFIG_SIZE);
1046 if (ret != JAYLINK_OK) {
1047 log_err(ctx, "transport_write() failed: %s.",
1048 jaylink_strerror(ret));
1049 return ret;
1052 return JAYLINK_OK;
1055 static void parse_conntable(struct jaylink_connection *conns,
1056 const uint8_t *buffer, uint16_t num, uint16_t entry_size)
1058 unsigned int i;
1059 size_t offset;
1060 struct in_addr in;
1062 offset = 0;
1064 for (i = 0; i < num; i++) {
1065 conns[i].pid = buffer_get_u32(buffer, offset);
1067 in.s_addr = buffer_get_u32(buffer, offset + 4);
1069 * Use inet_ntoa() instead of inet_ntop() because the latter
1070 * requires at least Windows Vista.
1072 strcpy(conns[i].hid, inet_ntoa(in));
1074 conns[i].iid = buffer[offset + 8];
1075 conns[i].cid = buffer[offset + 9];
1076 conns[i].handle = buffer_get_u16(buffer, offset + 10);
1077 conns[i].timestamp = buffer_get_u32(buffer, offset + 12);
1078 offset = offset + entry_size;
1082 static bool _inet_pton(const char *str, struct in_addr *in)
1084 #ifdef _WIN32
1085 int ret;
1086 struct sockaddr_in sock_in;
1087 int length;
1089 length = sizeof(sock_in);
1092 * Use WSAStringToAddress() instead of inet_pton() because the latter
1093 * requires at least Windows Vista.
1095 ret = WSAStringToAddress((LPTSTR)str, AF_INET, NULL,
1096 (LPSOCKADDR)&sock_in, &length);
1098 if (ret != 0)
1099 return false;
1101 *in = sock_in.sin_addr;
1102 #else
1103 if (inet_pton(AF_INET, str, in) != 1)
1104 return false;
1105 #endif
1107 return true;
1111 * Register a connection on a device.
1113 * A connection can be registered by using 0 as handle. Additional information
1114 * about the connection can be attached whereby the timestamp is a read-only
1115 * value and therefore ignored for registration. On success, a new handle
1116 * greater than 0 is obtained from the device.
1118 * However, if an obtained handle does not appear in the list of device
1119 * connections, the connection was not registered because the maximum number of
1120 * connections on the device is reached.
1122 * @note This function must only be used if the device has the
1123 * #JAYLINK_DEV_CAP_REGISTER capability.
1125 * @param[in,out] devh Device handle.
1126 * @param[in,out] connection Connection to register on the device.
1127 * @param[out] connections Array to store device connections on success.
1128 * Its content is undefined on failure. The array must
1129 * be large enough to contain at least
1130 * #JAYLINK_MAX_CONNECTIONS elements.
1131 * @param[out] count Number of device connections on success, and undefined on
1132 * failure.
1134 * @retval JAYLINK_OK Success.
1135 * @retval JAYLINK_ERR_ARG Invalid arguments.
1136 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1137 * @retval JAYLINK_ERR_PROTO Protocol violation.
1138 * @retval JAYLINK_ERR Other error conditions.
1140 * @see jaylink_unregister()
1142 * @since 0.1.0
1144 JAYLINK_API int jaylink_register(struct jaylink_device_handle *devh,
1145 struct jaylink_connection *connection,
1146 struct jaylink_connection *connections, size_t *count)
1148 int ret;
1149 struct jaylink_context *ctx;
1150 uint8_t buf[REG_MAX_SIZE];
1151 uint16_t handle;
1152 uint16_t num;
1153 uint16_t entry_size;
1154 uint32_t size;
1155 uint32_t table_size;
1156 uint16_t addinfo_size;
1157 struct in_addr in;
1159 if (!devh || !connection || !connections || !count)
1160 return JAYLINK_ERR_ARG;
1162 ctx = devh->dev->ctx;
1164 buf[0] = CMD_REGISTER;
1165 buf[1] = REG_CMD_REGISTER;
1166 buffer_set_u32(buf, connection->pid, 2);
1168 if (!_inet_pton(connection->hid, &in))
1169 return JAYLINK_ERR_ARG;
1171 buffer_set_u32(buf, in.s_addr, 6);
1173 buf[10] = connection->iid;
1174 buf[11] = connection->cid;
1175 buffer_set_u16(buf, connection->handle, 12);
1177 ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true);
1179 if (ret != JAYLINK_OK) {
1180 log_err(ctx, "transport_start_write_read() failed: %s.",
1181 jaylink_strerror(ret));
1182 return ret;
1185 ret = transport_write(devh, buf, 14);
1187 if (ret != JAYLINK_OK) {
1188 log_err(ctx, "transport_write() failed: %s.",
1189 jaylink_strerror(ret));
1190 return ret;
1193 ret = transport_read(devh, buf, REG_MIN_SIZE);
1195 if (ret != JAYLINK_OK) {
1196 log_err(ctx, "transport_read() failed: %s.",
1197 jaylink_strerror(ret));
1198 return ret;
1201 handle = buffer_get_u16(buf, 0);
1202 num = buffer_get_u16(buf, 2);
1203 entry_size = buffer_get_u16(buf, 4);
1204 addinfo_size = buffer_get_u16(buf, 6);
1206 if (num > JAYLINK_MAX_CONNECTIONS) {
1207 log_err(ctx, "Maximum number of device connections exceeded: "
1208 "%u.", num);
1209 return JAYLINK_ERR_PROTO;
1212 if (entry_size != REG_CONN_INFO_SIZE) {
1213 log_err(ctx, "Invalid connection entry size: %u bytes.",
1214 entry_size);
1215 return JAYLINK_ERR_PROTO;
1218 table_size = num * entry_size;
1219 size = REG_HEADER_SIZE + table_size + addinfo_size;
1221 if (size > REG_MAX_SIZE) {
1222 log_err(ctx, "Maximum registration information size exceeded: "
1223 "%u bytes.", size);
1224 return JAYLINK_ERR_PROTO;
1227 if (size > REG_MIN_SIZE) {
1228 ret = transport_start_read(devh, size - REG_MIN_SIZE);
1230 if (ret != JAYLINK_OK) {
1231 log_err(ctx, "transport_start_read() failed: %s.",
1232 jaylink_strerror(ret));
1233 return JAYLINK_ERR;
1236 ret = transport_read(devh, buf + REG_MIN_SIZE,
1237 size - REG_MIN_SIZE);
1239 if (ret != JAYLINK_OK) {
1240 log_err(ctx, "transport_read() failed: %s.",
1241 jaylink_strerror(ret));
1242 return JAYLINK_ERR;
1246 if (!handle) {
1247 log_err(ctx, "Obtained invalid connection handle.");
1248 return JAYLINK_ERR_PROTO;
1251 connection->handle = handle;
1252 parse_conntable(connections, buf + REG_HEADER_SIZE, num, entry_size);
1254 *count = num;
1256 return JAYLINK_OK;
1260 * Unregister a connection from a device.
1262 * @note This function must only be used if the device has the
1263 * #JAYLINK_DEV_CAP_REGISTER capability.
1265 * @param[in,out] devh Device handle.
1266 * @param[in,out] connection Connection to unregister from the device.
1267 * @param[out] connections Array to store device connections on success.
1268 * Its content is undefined on failure. The array must
1269 * be large enough to contain at least
1270 * #JAYLINK_MAX_CONNECTIONS elements.
1271 * @param[out] count Number of device connections on success, and undefined on
1272 * failure.
1274 * @retval JAYLINK_OK Success.
1275 * @retval JAYLINK_ERR_ARG Invalid arguments.
1276 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1277 * @retval JAYLINK_ERR_PROTO Protocol violation.
1278 * @retval JAYLINK_ERR Other error conditions.
1280 * @see jaylink_register()
1282 * @since 0.1.0
1284 JAYLINK_API int jaylink_unregister(struct jaylink_device_handle *devh,
1285 const struct jaylink_connection *connection,
1286 struct jaylink_connection *connections, size_t *count)
1288 int ret;
1289 struct jaylink_context *ctx;
1290 uint8_t buf[REG_MAX_SIZE];
1291 uint16_t num;
1292 uint16_t entry_size;
1293 uint32_t size;
1294 uint32_t table_size;
1295 uint16_t addinfo_size;
1296 struct in_addr in;
1298 if (!devh || !connection || !connections || !count)
1299 return JAYLINK_ERR_ARG;
1301 ctx = devh->dev->ctx;
1303 buf[0] = CMD_REGISTER;
1304 buf[1] = REG_CMD_UNREGISTER;
1305 buffer_set_u32(buf, connection->pid, 2);
1307 if (!_inet_pton(connection->hid, &in))
1308 return JAYLINK_ERR_ARG;
1310 buffer_set_u32(buf, in.s_addr, 6);
1312 buf[10] = connection->iid;
1313 buf[11] = connection->cid;
1314 buffer_set_u16(buf, connection->handle, 12);
1316 ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true);
1318 if (ret != JAYLINK_OK) {
1319 log_err(ctx, "transport_start_write_read() failed: %s.",
1320 jaylink_strerror(ret));
1321 return ret;
1324 ret = transport_write(devh, buf, 14);
1326 if (ret != JAYLINK_OK) {
1327 log_err(ctx, "transport_write() failed: %s.",
1328 jaylink_strerror(ret));
1329 return ret;
1332 ret = transport_read(devh, buf, REG_MIN_SIZE);
1334 if (ret != JAYLINK_OK) {
1335 log_err(ctx, "transport_read() failed: %s.",
1336 jaylink_strerror(ret));
1337 return ret;
1340 num = buffer_get_u16(buf, 2);
1341 entry_size = buffer_get_u16(buf, 4);
1342 addinfo_size = buffer_get_u16(buf, 6);
1344 if (num > JAYLINK_MAX_CONNECTIONS) {
1345 log_err(ctx, "Maximum number of device connections exceeded: "
1346 "%u.", num);
1347 return JAYLINK_ERR_PROTO;
1350 if (entry_size != REG_CONN_INFO_SIZE) {
1351 log_err(ctx, "Invalid connection entry size: %u bytes.",
1352 entry_size);
1353 return JAYLINK_ERR_PROTO;
1356 table_size = num * entry_size;
1357 size = REG_HEADER_SIZE + table_size + addinfo_size;
1359 if (size > REG_MAX_SIZE) {
1360 log_err(ctx, "Maximum registration information size exceeded: "
1361 "%u bytes.", size);
1362 return JAYLINK_ERR_PROTO;
1365 if (size > REG_MIN_SIZE) {
1366 ret = transport_start_read(devh, size - REG_MIN_SIZE);
1368 if (ret != JAYLINK_OK) {
1369 log_err(ctx, "transport_start_read() failed: %s.",
1370 jaylink_strerror(ret));
1371 return JAYLINK_ERR;
1374 ret = transport_read(devh, buf + REG_MIN_SIZE,
1375 size - REG_MIN_SIZE);
1377 if (ret != JAYLINK_OK) {
1378 log_err(ctx, "transport_read() failed: %s.",
1379 jaylink_strerror(ret));
1380 return JAYLINK_ERR;
1384 parse_conntable(connections, buf + REG_HEADER_SIZE, num, entry_size);
1386 *count = num;
1388 return JAYLINK_OK;