discovery/tcp: Ignore already discovered devices
[libjaylink.git] / libjaylink / device.c
bloba3bddf64098103cb61047a4840a675fca1af3671
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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <stdbool.h>
27 #include <string.h>
28 #ifdef _WIN32
29 #include <winsock2.h>
30 #else
31 #include <sys/socket.h>
32 #include <arpa/inet.h>
33 #endif
34 #ifdef HAVE_LIBUSB
35 #include <libusb.h>
36 #endif
38 #include "libjaylink.h"
39 #include "libjaylink-internal.h"
41 /**
42 * @file
44 * Device enumeration and handling.
47 /** @cond PRIVATE */
48 #define CMD_GET_VERSION 0x01
49 #define CMD_GET_HW_STATUS 0x07
50 #define CMD_REGISTER 0x09
51 #define CMD_GET_HW_INFO 0xc1
52 #define CMD_GET_COUNTERS 0xc2
53 #define CMD_GET_FREE_MEMORY 0xd4
54 #define CMD_GET_CAPS 0xe8
55 #define CMD_GET_EXT_CAPS 0xed
56 #define CMD_GET_HW_VERSION 0xf0
57 #define CMD_READ_CONFIG 0xf2
58 #define CMD_WRITE_CONFIG 0xf3
60 #define REG_CMD_REGISTER 0x64
61 #define REG_CMD_UNREGISTER 0x65
63 /** Size of the registration header in bytes. */
64 #define REG_HEADER_SIZE 8
65 /** Minimum registration information size in bytes. */
66 #define REG_MIN_SIZE 0x4c
67 /** Maximum registration information size in bytes. */
68 #define REG_MAX_SIZE 0x200
69 /** Size of a connection entry in bytes. */
70 #define REG_CONN_INFO_SIZE 16
71 /** @endcond */
73 /** @private */
74 JAYLINK_PRIV struct jaylink_device *device_allocate(
75 struct jaylink_context *ctx)
77 struct jaylink_device *dev;
78 struct list *list;
80 dev = malloc(sizeof(struct jaylink_device));
82 if (!dev)
83 return NULL;
85 list = list_prepend(ctx->devs, dev);
87 if (!list) {
88 free(dev);
89 return NULL;
92 ctx->devs = list;
94 dev->ctx = ctx;
95 dev->ref_count = 1;
97 return dev;
100 static struct jaylink_device **allocate_device_list(size_t length)
102 struct jaylink_device **list;
104 list = malloc(sizeof(struct jaylink_device *) * (length + 1));
106 if (!list)
107 return NULL;
109 list[length] = NULL;
111 return list;
115 * Get available devices.
117 * @param[in,out] ctx libjaylink context.
118 * @param[out] devs Newly allocated array which contains instances of available
119 * devices on success, and undefined on failure. The array is
120 * NULL-terminated and must be free'd by the caller with
121 * jaylink_free_devices().
122 * @param[out] count Number of available devices on success, and undefined on
123 * failure. Can be NULL.
125 * @retval JAYLINK_OK Success.
126 * @retval JAYLINK_ERR_ARG Invalid arguments.
127 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
128 * @retval JAYLINK_ERR Other error conditions.
130 * @see jaylink_discovery_scan()
132 * @since 0.1.0
134 JAYLINK_API int jaylink_get_devices(struct jaylink_context *ctx,
135 struct jaylink_device ***devs, size_t *count)
137 size_t num;
138 struct list *item;
139 struct jaylink_device **tmp;
140 struct jaylink_device *dev;
141 size_t i;
143 if (!ctx || !devs)
144 return JAYLINK_ERR_ARG;
146 num = list_length(ctx->discovered_devs);
147 tmp = allocate_device_list(num);
149 if (!tmp) {
150 log_err(ctx, "Failed to allocate device list.");
151 return JAYLINK_ERR_MALLOC;
154 item = ctx->discovered_devs;
156 for (i = 0; i < num; i++) {
157 dev = (struct jaylink_device *)item->data;
158 tmp[i] = jaylink_ref_device(dev);
159 item = item->next;
162 if (count)
163 *count = num;
165 *devs = tmp;
167 return JAYLINK_OK;
171 * Free devices.
173 * @param[in,out] devs Array of device instances. Must be NULL-terminated.
174 * @param[in] unref Determines whether the device instances should be
175 * unreferenced.
177 * @see jaylink_get_devices()
179 * @since 0.1.0
181 JAYLINK_API void jaylink_free_devices(struct jaylink_device **devs, bool unref)
183 size_t i;
185 if (!devs)
186 return;
188 if (unref) {
189 for (i = 0; devs[i]; i++)
190 jaylink_unref_device(devs[i]);
193 free(devs);
197 * Get the host interface of a device.
199 * @param[in] dev Device instance.
200 * @param[out] iface Host interface of the device on success, and undefined on
201 * failure.
203 * @retval JAYLINK_OK Success.
204 * @retval JAYLINK_ERR_ARG Invalid arguments.
206 * @since 0.1.0
208 JAYLINK_API int jaylink_device_get_host_interface(
209 const struct jaylink_device *dev,
210 enum jaylink_host_interface *iface)
212 if (!dev || !iface)
213 return JAYLINK_ERR_ARG;
215 *iface = dev->iface;
217 return JAYLINK_OK;
221 * Get the serial number of a device.
223 * @note This serial number is for enumeration purpose only and might differ
224 * from the real serial number of the device.
226 * @param[in] dev Device instance.
227 * @param[out] serial_number Serial number of the device on success, and
228 * undefined on failure.
230 * @retval JAYLINK_OK Success.
231 * @retval JAYLINK_ERR_ARG Invalid arguments.
232 * @retval JAYLINK_ERR_NOT_AVAILABLE Serial number is not available.
234 * @since 0.1.0
236 JAYLINK_API int jaylink_device_get_serial_number(
237 const struct jaylink_device *dev, uint32_t *serial_number)
239 if (!dev || !serial_number)
240 return JAYLINK_ERR_ARG;
242 if (!dev->valid_serial_number)
243 return JAYLINK_ERR_NOT_AVAILABLE;
245 *serial_number = dev->serial_number;
247 return JAYLINK_OK;
251 * Get the USB address of a device.
253 * @note Identification of a device with the USB address is deprecated and the
254 * serial number should be used instead.
256 * @param[in] dev Device instance.
257 * @param[out] address USB address of the device on success, and undefined on
258 * failure.
260 * @retval JAYLINK_OK Success.
261 * @retval JAYLINK_ERR_ARG Invalid arguments.
262 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
263 * #JAYLINK_HIF_USB only.
265 * @see jaylink_device_get_serial_number()
267 * @since 0.1.0
269 JAYLINK_API int jaylink_device_get_usb_address(
270 const struct jaylink_device *dev,
271 enum jaylink_usb_address *address)
273 if (!dev || !address)
274 return JAYLINK_ERR_ARG;
276 if (dev->iface != JAYLINK_HIF_USB)
277 return JAYLINK_ERR_NOT_SUPPORTED;
279 #ifdef HAVE_LIBUSB
280 *address = dev->usb_address;
282 return JAYLINK_OK;
283 #else
284 return JAYLINK_ERR_NOT_SUPPORTED;
285 #endif
289 * Get the IPv4 address string of a device.
291 * @param[in] dev Device instance.
292 * @param[out] address IPv4 address string in quad-dotted decimal format of the
293 * device on success and undefined on failure.
295 * @retval JAYLINK_OK Success.
296 * @retval JAYLINK_ERR_ARG Invalid arguments.
297 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
298 * #JAYLINK_HIF_TCP only.
300 * @since 0.2.0
302 JAYLINK_API int jaylink_device_get_ipv4_address(
303 const struct jaylink_device *dev, char *address)
305 if (!dev || !address)
306 return JAYLINK_ERR_ARG;
308 if (dev->iface != JAYLINK_HIF_TCP)
309 return JAYLINK_ERR_NOT_SUPPORTED;
311 memcpy(address, dev->ipv4_address, sizeof(dev->ipv4_address));
313 return JAYLINK_OK;
317 * Get the MAC address of a device.
319 * @param[in] dev Device instance.
320 * @param[out] address MAC address of the device on success and undefined on
321 * failure. The length of the MAC address is
322 * #JAYLINK_MAC_ADDRESS_LENGTH bytes.
324 * @retval JAYLINK_OK Success.
325 * @retval JAYLINK_ERR_ARG Invalid arguments.
326 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
327 * #JAYLINK_HIF_TCP only.
328 * @retval JAYLINK_ERR_NOT_AVAILABLE MAC address is not available.
330 * @since 0.2.0
332 JAYLINK_API int jaylink_device_get_mac_address(
333 const struct jaylink_device *dev, uint8_t *address)
335 if (!dev || !address)
336 return JAYLINK_ERR_ARG;
338 if (dev->iface != JAYLINK_HIF_TCP)
339 return JAYLINK_ERR_NOT_SUPPORTED;
341 if (!dev->has_mac_address)
342 return JAYLINK_ERR_NOT_AVAILABLE;
344 memcpy(address, dev->mac_address, sizeof(dev->mac_address));
346 return JAYLINK_OK;
350 * Get the hardware version of a device.
352 * @note The hardware type can not be obtained by this function, use
353 * jaylink_get_hardware_version() instead.
355 * @param[in] dev Device instance.
356 * @param[out] version Hardware version of the device on success and undefined
357 * on failure.
359 * @retval JAYLINK_OK Success.
360 * @retval JAYLINK_ERR_ARG Invalid arguments.
361 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
362 * #JAYLINK_HIF_TCP only.
363 * @retval JAYLINK_ERR_NOT_AVAILABLE Hardware version is not available.
365 * @since 0.2.0
367 JAYLINK_API int jaylink_device_get_hardware_version(
368 const struct jaylink_device *dev,
369 struct jaylink_hardware_version *version)
371 if (!dev || !version)
372 return JAYLINK_ERR_ARG;
374 if (dev->iface != JAYLINK_HIF_TCP)
375 return JAYLINK_ERR_NOT_SUPPORTED;
377 if (!dev->has_hw_version)
378 return JAYLINK_ERR_NOT_AVAILABLE;
380 *version = dev->hw_version;
382 return JAYLINK_OK;
386 * Get the product name of a device.
388 * @param[in] dev Device instance.
389 * @param[out] name Product name of the device on success and undefined on
390 * failure. The maximum length of the product name is
391 * #JAYLINK_PRODUCT_NAME_MAX_LENGTH bytes.
393 * @retval JAYLINK_OK Success.
394 * @retval JAYLINK_ERR_ARG Invalid arguments.
395 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
396 * #JAYLINK_HIF_TCP only.
397 * @retval JAYLINK_ERR_NOT_AVAILABLE Product name is not available.
399 * @since 0.2.0
401 JAYLINK_API int jaylink_device_get_product_name(
402 const struct jaylink_device *dev, char *name)
404 if (!dev || !name)
405 return JAYLINK_ERR_ARG;
407 if (dev->iface != JAYLINK_HIF_TCP)
408 return JAYLINK_ERR_NOT_SUPPORTED;
410 if (!dev->has_product_name)
411 return JAYLINK_ERR_NOT_AVAILABLE;
413 memcpy(name, dev->product_name, sizeof(dev->product_name));
415 return JAYLINK_OK;
419 * Get the nickname of a device.
421 * @param[in] dev Device instance.
422 * @param[out] nickname Nickname of the device on success and undefined on
423 * failure. The maximum length of the nickname is
424 * #JAYLINK_NICKNAME_MAX_LENGTH bytes.
426 * @retval JAYLINK_OK Success.
427 * @retval JAYLINK_ERR_ARG Invalid arguments.
428 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
429 * #JAYLINK_HIF_TCP only.
430 * @retval JAYLINK_ERR_NOT_AVAILABLE Nickname is not available.
432 * @since 0.2.0
434 JAYLINK_API int jaylink_device_get_nickname(const struct jaylink_device *dev,
435 char *nickname)
437 if (!dev || !nickname)
438 return JAYLINK_ERR_ARG;
440 if (dev->iface != JAYLINK_HIF_TCP)
441 return JAYLINK_ERR_NOT_SUPPORTED;
443 if (!dev->has_nickname)
444 return JAYLINK_ERR_NOT_AVAILABLE;
446 memcpy(nickname, dev->nickname, sizeof(dev->nickname));
448 return JAYLINK_OK;
452 * Increment the reference count of a device.
454 * @param[in,out] dev Device instance.
456 * @return The given device instance on success, or NULL on invalid argument.
458 * @since 0.1.0
460 JAYLINK_API struct jaylink_device *jaylink_ref_device(
461 struct jaylink_device *dev)
463 if (!dev)
464 return NULL;
466 dev->ref_count++;
468 return dev;
472 * Decrement the reference count of a device.
474 * @param[in,out] dev Device instance.
476 * @since 0.1.0
478 JAYLINK_API void jaylink_unref_device(struct jaylink_device *dev)
480 struct jaylink_context *ctx;
482 if (!dev)
483 return;
485 dev->ref_count--;
487 if (!dev->ref_count) {
488 ctx = dev->ctx;
489 ctx->devs = list_remove(dev->ctx->devs, dev);
491 if (dev->iface == JAYLINK_HIF_USB) {
492 #ifdef HAVE_LIBUSB
493 log_dbg(ctx, "Device destroyed (bus:address = "
494 "%03u:%03u).",
495 libusb_get_bus_number(dev->usb_dev),
496 libusb_get_device_address(dev->usb_dev));
498 libusb_unref_device(dev->usb_dev);
499 #endif
500 } else if (dev->iface == JAYLINK_HIF_TCP) {
501 log_dbg(ctx, "Device destroyed (IPv4 address = %s).",
502 dev->ipv4_address);
503 } else {
504 log_err(ctx, "BUG: Invalid host interface: %u.",
505 dev->iface);
508 free(dev);
512 static struct jaylink_device_handle *allocate_device_handle(
513 struct jaylink_device *dev)
515 struct jaylink_device_handle *devh;
517 devh = malloc(sizeof(struct jaylink_device_handle));
519 if (!devh)
520 return NULL;
522 devh->dev = jaylink_ref_device(dev);
524 return devh;
527 static void free_device_handle(struct jaylink_device_handle *devh)
529 jaylink_unref_device(devh->dev);
530 free(devh);
534 * Open a device.
536 * @param[in,out] dev Device instance.
537 * @param[out] devh Newly allocated handle for the opened device on success,
538 * and undefined on failure.
540 * @retval JAYLINK_OK Success.
541 * @retval JAYLINK_ERR_ARG Invalid arguments.
542 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
543 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
544 * @retval JAYLINK_ERR_IO Input/output error.
545 * @retval JAYLINK_ERR Other error conditions.
547 * @since 0.1.0
549 JAYLINK_API int jaylink_open(struct jaylink_device *dev,
550 struct jaylink_device_handle **devh)
552 int ret;
553 struct jaylink_device_handle *handle;
555 if (!dev || !devh)
556 return JAYLINK_ERR_ARG;
558 handle = allocate_device_handle(dev);
560 if (!handle) {
561 log_err(dev->ctx, "Device handle malloc failed.");
562 return JAYLINK_ERR_MALLOC;
565 ret = transport_open(handle);
567 if (ret != JAYLINK_OK) {
568 free_device_handle(handle);
569 return ret;
572 *devh = handle;
574 return JAYLINK_OK;
578 * Close a device.
580 * @param[in,out] devh Device instance.
582 * @retval JAYLINK_OK Success.
583 * @retval JAYLINK_ERR_ARG Invalid arguments.
584 * @retval JAYLINK_ERR Other error conditions.
586 * @since 0.1.0
588 JAYLINK_API int jaylink_close(struct jaylink_device_handle *devh)
590 int ret;
592 if (!devh)
593 return JAYLINK_ERR_ARG;
595 ret = transport_close(devh);
596 free_device_handle(devh);
598 return ret;
602 * Get the device instance from a device handle.
604 * @note The reference count of the device instance is not increased.
606 * @param[in] devh Device handle.
608 * @return The device instance on success, or NULL on invalid argument.
610 * @since 0.1.0
612 JAYLINK_API struct jaylink_device *jaylink_get_device(
613 struct jaylink_device_handle *devh)
615 if (!devh)
616 return NULL;
618 return devh->dev;
622 * Retrieve the firmware version of a device.
624 * @param[in,out] devh Device handle.
625 * @param[out] version Newly allocated string which contains the firmware
626 * version on success, and undefined if @p length is zero
627 * or on failure. The string is null-terminated and must be
628 * free'd by the caller.
629 * @param[out] length Length of the firmware version string including trailing
630 * null-terminator on success, and undefined on failure.
631 * Zero if no firmware version string is available.
633 * @retval JAYLINK_OK Success.
634 * @retval JAYLINK_ERR_ARG Invalid arguments.
635 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
636 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
637 * @retval JAYLINK_ERR_IO Input/output error.
638 * @retval JAYLINK_ERR Other error conditions.
640 * @since 0.1.0
642 JAYLINK_API int jaylink_get_firmware_version(
643 struct jaylink_device_handle *devh, char **version,
644 size_t *length)
646 int ret;
647 struct jaylink_context *ctx;
648 uint8_t buf[2];
649 uint16_t dummy;
650 char *tmp;
652 if (!devh || !version || !length)
653 return JAYLINK_ERR_ARG;
655 ctx = devh->dev->ctx;
656 ret = transport_start_write_read(devh, 1, 2, true);
658 if (ret != JAYLINK_OK) {
659 log_err(ctx, "transport_start_write_read() failed: %s.",
660 jaylink_strerror(ret));
661 return ret;
664 buf[0] = CMD_GET_VERSION;
666 ret = transport_write(devh, buf, 1);
668 if (ret != JAYLINK_OK) {
669 log_err(ctx, "transport_write() failed: %s.",
670 jaylink_strerror(ret));
671 return ret;
674 ret = transport_read(devh, buf, 2);
676 if (ret != JAYLINK_OK) {
677 log_err(ctx, "transport_read() failed: %s.",
678 jaylink_strerror(ret));
679 return ret;
682 dummy = buffer_get_u16(buf, 0);
683 *length = dummy;
685 if (!dummy)
686 return JAYLINK_OK;
688 ret = transport_start_read(devh, dummy);
690 if (ret != JAYLINK_OK) {
691 log_err(ctx, "transport_start_read() failed: %s.",
692 jaylink_strerror(ret));
693 return ret;
696 tmp = malloc(dummy);
698 if (!tmp) {
699 log_err(ctx, "Firmware version string malloc failed.");
700 return JAYLINK_ERR_MALLOC;
703 ret = transport_read(devh, (uint8_t *)tmp, dummy);
705 if (ret != JAYLINK_OK) {
706 log_err(ctx, "transport_read() failed: %s.",
707 jaylink_strerror(ret));
708 free(tmp);
709 return ret;
712 /* Last byte is reserved for null-terminator. */
713 tmp[dummy - 1] = 0;
714 *version = tmp;
716 return JAYLINK_OK;
720 * Retrieve the hardware information of a device.
722 * @note This function must only be used if the device has the
723 * #JAYLINK_DEV_CAP_GET_HW_INFO capability.
725 * @param[in,out] devh Device handle.
726 * @param[in] mask A bit field where each set bit represents hardware
727 * information to request. See #jaylink_hardware_info for a
728 * description of the hardware information and their bit
729 * positions.
730 * @param[out] info Array to store the hardware information on success. Its
731 * content is undefined on failure. The array must be large
732 * enough to contain at least as many elements as bits set in
733 * @a mask.
735 * @retval JAYLINK_OK Success.
736 * @retval JAYLINK_ERR_ARG Invalid arguments.
737 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
738 * @retval JAYLINK_ERR_IO Input/output error.
739 * @retval JAYLINK_ERR Other error conditions.
741 * @since 0.1.0
743 JAYLINK_API int jaylink_get_hardware_info(struct jaylink_device_handle *devh,
744 uint32_t mask, uint32_t *info)
746 int ret;
747 struct jaylink_context *ctx;
748 uint8_t buf[5];
749 unsigned int i;
750 unsigned int num;
751 unsigned int length;
753 if (!devh || !mask || !info)
754 return JAYLINK_ERR_ARG;
756 ctx = devh->dev->ctx;
757 num = 0;
759 for (i = 0; i < 32; i++) {
760 if (mask & (1 << i))
761 num++;
764 length = num * sizeof(uint32_t);
766 ret = transport_start_write_read(devh, 5, length, true);
768 if (ret != JAYLINK_OK) {
769 log_err(ctx, "transport_start_write_read() failed: %s.",
770 jaylink_strerror(ret));
771 return ret;
774 buf[0] = CMD_GET_HW_INFO;
775 buffer_set_u32(buf, mask, 1);
777 ret = transport_write(devh, buf, 5);
779 if (ret != JAYLINK_OK) {
780 log_err(ctx, "transport_write() failed: %s.",
781 jaylink_strerror(ret));
782 return ret;
785 ret = transport_read(devh, (uint8_t *)info, length);
787 if (ret != JAYLINK_OK) {
788 log_err(ctx, "transport_read() failed: %s.",
789 jaylink_strerror(ret));
790 return ret;
793 for (i = 0; i < num; i++)
794 info[i] = buffer_get_u32((uint8_t *)info,
795 i * sizeof(uint32_t));
797 return JAYLINK_OK;
801 * Retrieve the counter values of a device.
803 * @note This function must only be used if the device has the
804 * #JAYLINK_DEV_CAP_GET_COUNTERS capability.
806 * @param[in,out] devh Device handle.
807 * @param[in] mask A bit field where each set bit represents a counter value to
808 * request. See #jaylink_counter for a description of the
809 * counters and their bit positions.
810 * @param[out] values Array to store the counter values on success. Its content
811 * is undefined on failure. The array must be large enough
812 * to contain at least as many elements as bits set in @p
813 * mask.
815 * @retval JAYLINK_OK Success.
816 * @retval JAYLINK_ERR_ARG Invalid arguments.
817 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
818 * @retval JAYLINK_ERR_IO Input/output error.
819 * @retval JAYLINK_ERR Other error conditions.
821 * @since 0.2.0
823 JAYLINK_API int jaylink_get_counters(struct jaylink_device_handle *devh,
824 uint32_t mask, uint32_t *values)
826 int ret;
827 struct jaylink_context *ctx;
828 uint8_t buf[5];
829 unsigned int i;
830 unsigned int num;
831 unsigned int length;
833 if (!devh || !mask || !values)
834 return JAYLINK_ERR_ARG;
836 ctx = devh->dev->ctx;
837 num = 0;
839 for (i = 0; i < 32; i++) {
840 if (mask & (1 << i))
841 num++;
844 length = num * sizeof(uint32_t);
845 ret = transport_start_write_read(devh, 5, length, true);
847 if (ret != JAYLINK_OK) {
848 log_err(ctx, "transport_start_write_read() failed: %s.",
849 jaylink_strerror(ret));
850 return ret;
853 buf[0] = CMD_GET_COUNTERS;
854 buffer_set_u32(buf, mask, 1);
856 ret = transport_write(devh, buf, 5);
858 if (ret != JAYLINK_OK) {
859 log_err(ctx, "transport_write() failed: %s.",
860 jaylink_strerror(ret));
861 return ret;
864 ret = transport_read(devh, (uint8_t *)values, length);
866 if (ret != JAYLINK_OK) {
867 log_err(ctx, "transport_read() failed: %s.",
868 jaylink_strerror(ret));
869 return ret;
872 for (i = 0; i < num; i++)
873 values[i] = buffer_get_u32((uint8_t *)values,
874 i * sizeof(uint32_t));
876 return JAYLINK_OK;
880 * Retrieve the hardware version of a device.
882 * @note This function must only be used if the device has the
883 * #JAYLINK_DEV_CAP_GET_HW_VERSION capability.
885 * @warning This function may return a value for @p version where
886 * #jaylink_hardware_version::type is not covered by
887 * #jaylink_hardware_type.
889 * @param[in,out] devh Device handle.
890 * @param[out] version Hardware version on success, and undefined on failure.
892 * @retval JAYLINK_OK Success.
893 * @retval JAYLINK_ERR_ARG Invalid arguments.
894 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
895 * @retval JAYLINK_ERR_IO Input/output error.
896 * @retval JAYLINK_ERR Other error conditions.
898 * @since 0.1.0
900 JAYLINK_API int jaylink_get_hardware_version(
901 struct jaylink_device_handle *devh,
902 struct jaylink_hardware_version *version)
904 int ret;
905 struct jaylink_context *ctx;
906 uint8_t buf[4];
907 uint32_t tmp;
909 if (!devh || !version)
910 return JAYLINK_ERR_ARG;
912 ctx = devh->dev->ctx;
913 ret = transport_start_write_read(devh, 1, 4, true);
915 if (ret != JAYLINK_OK) {
916 log_err(ctx, "transport_start_write_read() failed: %s.",
917 jaylink_strerror(ret));
918 return ret;
921 buf[0] = CMD_GET_HW_VERSION;
923 ret = transport_write(devh, buf, 1);
925 if (ret != JAYLINK_OK) {
926 log_err(ctx, "transport_write() failed: %s.",
927 jaylink_strerror(ret));
928 return ret;
931 ret = transport_read(devh, buf, 4);
933 if (ret != JAYLINK_OK) {
934 log_err(ctx, "transport_read() failed: %s.",
935 jaylink_strerror(ret));
936 return ret;
939 tmp = buffer_get_u32(buf, 0);
941 version->type = (tmp / 1000000) % 100;
942 version->major = (tmp / 10000) % 100;
943 version->minor = (tmp / 100) % 100;
944 version->revision = tmp % 100;
946 return JAYLINK_OK;
950 * Retrieve the hardware status of a device.
952 * @param[in,out] devh Device handle.
953 * @param[out] status Hardware status on success, and undefined on failure.
955 * @retval JAYLINK_OK Success.
956 * @retval JAYLINK_ERR_ARG Invalid arguments.
957 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
958 * @retval JAYLINK_ERR_IO Input/output error.
959 * @retval JAYLINK_ERR Other error conditions.
961 * @since 0.1.0
963 JAYLINK_API int jaylink_get_hardware_status(struct jaylink_device_handle *devh,
964 struct jaylink_hardware_status *status)
966 int ret;
967 struct jaylink_context *ctx;
968 uint8_t buf[8];
970 if (!devh || !status)
971 return JAYLINK_ERR_ARG;
973 ctx = devh->dev->ctx;
974 ret = transport_start_write_read(devh, 1, 8, true);
976 if (ret != JAYLINK_OK) {
977 log_err(ctx, "transport_start_write_read() failed: %s.",
978 jaylink_strerror(ret));
979 return ret;
982 buf[0] = CMD_GET_HW_STATUS;
984 ret = transport_write(devh, buf, 1);
986 if (ret != JAYLINK_OK) {
987 log_err(ctx, "transport_write() failed: %s.",
988 jaylink_strerror(ret));
989 return ret;
992 ret = transport_read(devh, buf, 8);
994 if (ret != JAYLINK_OK) {
995 log_err(ctx, "transport_read() failed: %s.",
996 jaylink_strerror(ret));
997 return ret;
1000 status->target_voltage = buffer_get_u16(buf, 0);
1001 status->tck = buf[2];
1002 status->tdi = buf[3];
1003 status->tdo = buf[4];
1004 status->tms = buf[5];
1005 status->tres = buf[6];
1006 status->trst = buf[7];
1008 return JAYLINK_OK;
1012 * Retrieve the capabilities of a device.
1014 * The capabilities are stored in a 32-bit bit array consisting of
1015 * #JAYLINK_DEV_CAPS_SIZE bytes where each individual bit represents a
1016 * capability. The first bit of this array is the least significant bit of the
1017 * first byte and the following bits are sequentially numbered in order of
1018 * increasing bit significance and byte index. A set bit indicates a supported
1019 * capability. See #jaylink_device_capability for a description of the
1020 * capabilities and their bit positions.
1022 * @param[in,out] devh Device handle.
1023 * @param[out] caps Buffer to store capabilities on success. Its content is
1024 * undefined on failure. The buffer must be large enough to
1025 * contain at least #JAYLINK_DEV_CAPS_SIZE bytes.
1027 * @retval JAYLINK_OK Success.
1028 * @retval JAYLINK_ERR_ARG Invalid arguments.
1029 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1030 * @retval JAYLINK_ERR_IO Input/output error.
1031 * @retval JAYLINK_ERR Other error conditions.
1033 * @see jaylink_get_extended_caps()
1034 * @see jaylink_has_cap()
1036 * @since 0.1.0
1038 JAYLINK_API int jaylink_get_caps(struct jaylink_device_handle *devh,
1039 uint8_t *caps)
1041 int ret;
1042 struct jaylink_context *ctx;
1043 uint8_t buf[1];
1045 if (!devh || !caps)
1046 return JAYLINK_ERR_ARG;
1048 ctx = devh->dev->ctx;
1049 ret = transport_start_write_read(devh, 1, JAYLINK_DEV_CAPS_SIZE, true);
1051 if (ret != JAYLINK_OK) {
1052 log_err(ctx, "transport_start_write_read() failed: %s.",
1053 jaylink_strerror(ret));
1054 return ret;
1057 buf[0] = CMD_GET_CAPS;
1059 ret = transport_write(devh, buf, 1);
1061 if (ret != JAYLINK_OK) {
1062 log_err(ctx, "transport_write() failed: %s.",
1063 jaylink_strerror(ret));
1064 return ret;
1067 ret = transport_read(devh, caps, JAYLINK_DEV_CAPS_SIZE);
1069 if (ret != JAYLINK_OK) {
1070 log_err(ctx, "transport_read() failed: %s.",
1071 jaylink_strerror(ret));
1072 return ret;
1075 return JAYLINK_OK;
1079 * Retrieve the extended capabilities of a device.
1081 * The extended capabilities are stored in a 256-bit bit array consisting of
1082 * #JAYLINK_DEV_EXT_CAPS_SIZE bytes. See jaylink_get_caps() for a further
1083 * description of how the capabilities are represented in this bit array. For a
1084 * description of the capabilities and their bit positions, see
1085 * #jaylink_device_capability.
1087 * @note This function must only be used if the device has the
1088 * #JAYLINK_DEV_CAP_GET_EXT_CAPS capability.
1090 * @param[in,out] devh Device handle.
1091 * @param[out] caps Buffer to store capabilities on success. Its content is
1092 * undefined on failure. The buffer must be large enough to
1093 * contain at least #JAYLINK_DEV_EXT_CAPS_SIZE bytes.
1095 * @retval JAYLINK_OK Success.
1096 * @retval JAYLINK_ERR_ARG Invalid arguments.
1097 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1098 * @retval JAYLINK_ERR_IO Input/output error.
1099 * @retval JAYLINK_ERR Other error conditions.
1101 * @see jaylink_get_caps()
1103 * @since 0.1.0
1105 JAYLINK_API int jaylink_get_extended_caps(struct jaylink_device_handle *devh,
1106 uint8_t *caps)
1108 int ret;
1109 struct jaylink_context *ctx;
1110 uint8_t buf[1];
1112 if (!devh || !caps)
1113 return JAYLINK_ERR_ARG;
1115 ctx = devh->dev->ctx;
1116 ret = transport_start_write_read(devh, 1, JAYLINK_DEV_EXT_CAPS_SIZE,
1117 true);
1119 if (ret != JAYLINK_OK) {
1120 log_err(ctx, "transport_start_write_read() failed: %s.",
1121 jaylink_strerror(ret));
1122 return ret;
1125 buf[0] = CMD_GET_EXT_CAPS;
1127 ret = transport_write(devh, buf, 1);
1129 if (ret != JAYLINK_OK) {
1130 log_err(ctx, "transport_write() failed: %s.",
1131 jaylink_strerror(ret));
1132 return ret;
1135 ret = transport_read(devh, caps, JAYLINK_DEV_EXT_CAPS_SIZE);
1137 if (ret != JAYLINK_OK) {
1138 log_err(ctx, "transport_read() failed: %s.",
1139 jaylink_strerror(ret));
1140 return ret;
1143 return JAYLINK_OK;
1147 * Retrieve the size of free memory of a device.
1149 * @note This function must only be used if the device has the
1150 * #JAYLINK_DEV_CAP_GET_FREE_MEMORY capability.
1152 * @param[in,out] devh Device handle.
1153 * @param[out] size Size of free memory in bytes on success, and undefined on
1154 * failure.
1156 * @retval JAYLINK_OK Success.
1157 * @retval JAYLINK_ERR_ARG Invalid arguments.
1158 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1159 * @retval JAYLINK_ERR_IO Input/output error.
1160 * @retval JAYLINK_ERR Other error conditions.
1162 * @since 0.1.0
1164 JAYLINK_API int jaylink_get_free_memory(struct jaylink_device_handle *devh,
1165 uint32_t *size)
1167 int ret;
1168 struct jaylink_context *ctx;
1169 uint8_t buf[4];
1171 if (!devh || !size)
1172 return JAYLINK_ERR_ARG;
1174 ctx = devh->dev->ctx;
1175 ret = transport_start_write_read(devh, 1, 4, true);
1177 if (ret != JAYLINK_OK) {
1178 log_err(ctx, "transport_start_write_read() failed: %s.",
1179 jaylink_strerror(ret));
1180 return ret;
1183 buf[0] = CMD_GET_FREE_MEMORY;
1185 ret = transport_write(devh, buf, 1);
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, 4);
1195 if (ret != JAYLINK_OK) {
1196 log_err(ctx, "transport_read() failed: %s.",
1197 jaylink_strerror(ret));
1198 return ret;
1201 *size = buffer_get_u32(buf, 0);
1203 return JAYLINK_OK;
1207 * Read the raw configuration data of a device.
1209 * @note This function must only be used if the device has the
1210 * #JAYLINK_DEV_CAP_READ_CONFIG capability.
1212 * @param[in,out] devh Device handle.
1213 * @param[out] config Buffer to store configuration data on success. Its
1214 * content is undefined on failure. The buffer must be large
1215 * enough to contain at least
1216 * #JAYLINK_DEV_CONFIG_SIZE bytes.
1218 * @retval JAYLINK_OK Success.
1219 * @retval JAYLINK_ERR_ARG Invalid arguments.
1220 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1221 * @retval JAYLINK_ERR_IO Input/output error.
1222 * @retval JAYLINK_ERR Other error conditions.
1224 * @since 0.1.0
1226 JAYLINK_API int jaylink_read_raw_config(struct jaylink_device_handle *devh,
1227 uint8_t *config)
1229 int ret;
1230 struct jaylink_context *ctx;
1231 uint8_t buf[1];
1233 if (!devh || !config)
1234 return JAYLINK_ERR_ARG;
1236 ctx = devh->dev->ctx;
1237 ret = transport_start_write_read(devh, 1, JAYLINK_DEV_CONFIG_SIZE,
1238 true);
1240 if (ret != JAYLINK_OK) {
1241 log_err(ctx, "transport_start_write_read() failed: %s.",
1242 jaylink_strerror(ret));
1243 return ret;
1246 buf[0] = CMD_READ_CONFIG;
1248 ret = transport_write(devh, buf, 1);
1250 if (ret != JAYLINK_OK) {
1251 log_err(ctx, "transport_write() failed: %s.",
1252 jaylink_strerror(ret));
1253 return ret;
1256 ret = transport_read(devh, config, JAYLINK_DEV_CONFIG_SIZE);
1258 if (ret != JAYLINK_OK) {
1259 log_err(ctx, "transport_read() failed: %s.",
1260 jaylink_strerror(ret));
1261 return ret;
1264 return JAYLINK_OK;
1268 * Write the raw configuration data of a device.
1270 * @note This function must only be used if the device has the
1271 * #JAYLINK_DEV_CAP_WRITE_CONFIG capability.
1273 * @param[in,out] devh Device handle.
1274 * @param[in] config Buffer to write configuration data from. The size of the
1275 * configuration data is expected to be
1276 * #JAYLINK_DEV_CONFIG_SIZE bytes.
1278 * @retval JAYLINK_OK Success.
1279 * @retval JAYLINK_ERR_ARG Invalid arguments.
1280 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1281 * @retval JAYLINK_ERR_IO Input/output error.
1282 * @retval JAYLINK_ERR Other error conditions.
1284 * @since 0.1.0
1286 JAYLINK_API int jaylink_write_raw_config(struct jaylink_device_handle *devh,
1287 const uint8_t *config)
1289 int ret;
1290 struct jaylink_context *ctx;
1291 uint8_t buf[1];
1293 if (!devh || !config)
1294 return JAYLINK_ERR_ARG;
1296 ctx = devh->dev->ctx;
1297 ret = transport_start_write(devh, 1 + JAYLINK_DEV_CONFIG_SIZE, true);
1299 if (ret != JAYLINK_OK) {
1300 log_err(ctx, "transport_start_write() failed: %s.",
1301 jaylink_strerror(ret));
1302 return ret;
1305 buf[0] = CMD_WRITE_CONFIG;
1307 ret = transport_write(devh, buf, 1);
1309 if (ret != JAYLINK_OK) {
1310 log_err(ctx, "transport_write() failed: %s.",
1311 jaylink_strerror(ret));
1312 return ret;
1315 ret = transport_write(devh, config, JAYLINK_DEV_CONFIG_SIZE);
1317 if (ret != JAYLINK_OK) {
1318 log_err(ctx, "transport_write() failed: %s.",
1319 jaylink_strerror(ret));
1320 return ret;
1323 return JAYLINK_OK;
1326 static void parse_conn_table(struct jaylink_connection *conns,
1327 const uint8_t *buffer, uint16_t num, uint16_t entry_size)
1329 unsigned int i;
1330 size_t offset;
1331 struct in_addr in;
1333 offset = 0;
1335 for (i = 0; i < num; i++) {
1336 conns[i].pid = buffer_get_u32(buffer, offset);
1338 in.s_addr = buffer_get_u32(buffer, offset + 4);
1340 * Use inet_ntoa() instead of inet_ntop() because the latter
1341 * requires at least Windows Vista.
1343 strcpy(conns[i].hid, inet_ntoa(in));
1345 conns[i].iid = buffer[offset + 8];
1346 conns[i].cid = buffer[offset + 9];
1347 conns[i].handle = buffer_get_u16(buffer, offset + 10);
1348 conns[i].timestamp = buffer_get_u32(buffer, offset + 12);
1349 offset = offset + entry_size;
1353 static bool _inet_pton(const char *str, struct in_addr *in)
1355 #ifdef _WIN32
1356 int ret;
1357 struct sockaddr_in sock_in;
1358 int length;
1360 length = sizeof(sock_in);
1363 * Use WSAStringToAddress() instead of inet_pton() because the latter
1364 * requires at least Windows Vista.
1366 ret = WSAStringToAddress((LPTSTR)str, AF_INET, NULL,
1367 (LPSOCKADDR)&sock_in, &length);
1369 if (ret != 0)
1370 return false;
1372 *in = sock_in.sin_addr;
1373 #else
1374 if (inet_pton(AF_INET, str, in) != 1)
1375 return false;
1376 #endif
1378 return true;
1382 * Register a connection on a device.
1384 * A connection can be registered by using 0 as handle. Additional information
1385 * about the connection can be attached whereby the timestamp is a read-only
1386 * value and therefore ignored for registration. On success, a new handle
1387 * greater than 0 is obtained from the device.
1389 * However, if an obtained handle does not appear in the list of device
1390 * connections, the connection was not registered because the maximum number of
1391 * connections on the device is reached.
1393 * @note This function must only be used if the device has the
1394 * #JAYLINK_DEV_CAP_REGISTER capability.
1396 * Example code:
1397 * @code{.c}
1398 * static bool register_connection(struct jaylink_device_handle *devh,
1399 * struct jaylink_connection *conn)
1401 * int ret;
1402 * struct jaylink_connection conns[JAYLINK_MAX_CONNECTIONS];
1403 * bool found_handle;
1404 * size_t count;
1405 * size_t i;
1407 * conn->handle = 0;
1408 * conn->pid = 0;
1409 * strcpy(conn->hid, "0.0.0.0");
1410 * conn->iid = 0;
1411 * conn->cid = 0;
1413 * ret = jaylink_register(devh, conn, conns, &count);
1415 * if (ret != JAYLINK_OK) {
1416 * printf("jaylink_register() failed: %s.\n",
1417 * jaylink_strerror(ret));
1418 * return false;
1421 * found_handle = false;
1423 * for (i = 0; i < count; i++) {
1424 * if (conns[i].handle == conn->handle) {
1425 * found_handle = true;
1426 * break;
1430 * if (!found_handle) {
1431 * printf("Maximum number of connections reached.\n");
1432 * return false;
1435 * printf("Connection successfully registered.\n");
1437 * return true;
1439 * @endcode
1441 * @param[in,out] devh Device handle.
1442 * @param[in,out] connection Connection to register on the device.
1443 * @param[out] connections Array to store device connections on success.
1444 * Its content is undefined on failure. The array must
1445 * be large enough to contain at least
1446 * #JAYLINK_MAX_CONNECTIONS elements.
1447 * @param[out] count Number of device connections on success, and undefined on
1448 * failure.
1450 * @retval JAYLINK_OK Success.
1451 * @retval JAYLINK_ERR_ARG Invalid arguments.
1452 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1453 * @retval JAYLINK_ERR_PROTO Protocol violation.
1454 * @retval JAYLINK_ERR_IO Input/output error.
1455 * @retval JAYLINK_ERR Other error conditions.
1457 * @see jaylink_unregister()
1459 * @since 0.1.0
1461 JAYLINK_API int jaylink_register(struct jaylink_device_handle *devh,
1462 struct jaylink_connection *connection,
1463 struct jaylink_connection *connections, size_t *count)
1465 int ret;
1466 struct jaylink_context *ctx;
1467 uint8_t buf[REG_MAX_SIZE];
1468 uint16_t handle;
1469 uint16_t num;
1470 uint16_t entry_size;
1471 uint32_t size;
1472 uint32_t table_size;
1473 uint16_t info_size;
1474 struct in_addr in;
1476 if (!devh || !connection || !connections || !count)
1477 return JAYLINK_ERR_ARG;
1479 ctx = devh->dev->ctx;
1481 buf[0] = CMD_REGISTER;
1482 buf[1] = REG_CMD_REGISTER;
1483 buffer_set_u32(buf, connection->pid, 2);
1485 if (!_inet_pton(connection->hid, &in))
1486 return JAYLINK_ERR_ARG;
1488 buffer_set_u32(buf, in.s_addr, 6);
1490 buf[10] = connection->iid;
1491 buf[11] = connection->cid;
1492 buffer_set_u16(buf, connection->handle, 12);
1494 ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true);
1496 if (ret != JAYLINK_OK) {
1497 log_err(ctx, "transport_start_write_read() failed: %s.",
1498 jaylink_strerror(ret));
1499 return ret;
1502 ret = transport_write(devh, buf, 14);
1504 if (ret != JAYLINK_OK) {
1505 log_err(ctx, "transport_write() failed: %s.",
1506 jaylink_strerror(ret));
1507 return ret;
1510 ret = transport_read(devh, buf, REG_MIN_SIZE);
1512 if (ret != JAYLINK_OK) {
1513 log_err(ctx, "transport_read() failed: %s.",
1514 jaylink_strerror(ret));
1515 return ret;
1518 handle = buffer_get_u16(buf, 0);
1519 num = buffer_get_u16(buf, 2);
1520 entry_size = buffer_get_u16(buf, 4);
1521 info_size = buffer_get_u16(buf, 6);
1523 if (num > JAYLINK_MAX_CONNECTIONS) {
1524 log_err(ctx, "Maximum number of device connections exceeded: "
1525 "%u.", num);
1526 return JAYLINK_ERR_PROTO;
1529 if (entry_size != REG_CONN_INFO_SIZE) {
1530 log_err(ctx, "Invalid connection entry size: %u bytes.",
1531 entry_size);
1532 return JAYLINK_ERR_PROTO;
1535 table_size = num * entry_size;
1536 size = REG_HEADER_SIZE + table_size + info_size;
1538 if (size > REG_MAX_SIZE) {
1539 log_err(ctx, "Maximum registration information size exceeded: "
1540 "%u bytes.", size);
1541 return JAYLINK_ERR_PROTO;
1544 if (size > REG_MIN_SIZE) {
1545 ret = transport_start_read(devh, size - REG_MIN_SIZE);
1547 if (ret != JAYLINK_OK) {
1548 log_err(ctx, "transport_start_read() failed: %s.",
1549 jaylink_strerror(ret));
1550 return JAYLINK_ERR;
1553 ret = transport_read(devh, buf + REG_MIN_SIZE,
1554 size - REG_MIN_SIZE);
1556 if (ret != JAYLINK_OK) {
1557 log_err(ctx, "transport_read() failed: %s.",
1558 jaylink_strerror(ret));
1559 return JAYLINK_ERR;
1563 if (!handle) {
1564 log_err(ctx, "Obtained invalid connection handle.");
1565 return JAYLINK_ERR_PROTO;
1568 connection->handle = handle;
1569 parse_conn_table(connections, buf + REG_HEADER_SIZE, num, entry_size);
1571 *count = num;
1573 return JAYLINK_OK;
1577 * Unregister a connection from a device.
1579 * @note This function must only be used if the device has the
1580 * #JAYLINK_DEV_CAP_REGISTER capability.
1582 * @param[in,out] devh Device handle.
1583 * @param[in,out] connection Connection to unregister from the device.
1584 * @param[out] connections Array to store device connections on success.
1585 * Its content is undefined on failure. The array must
1586 * be large enough to contain at least
1587 * #JAYLINK_MAX_CONNECTIONS elements.
1588 * @param[out] count Number of device connections on success, and undefined on
1589 * failure.
1591 * @retval JAYLINK_OK Success.
1592 * @retval JAYLINK_ERR_ARG Invalid arguments.
1593 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1594 * @retval JAYLINK_ERR_PROTO Protocol violation.
1595 * @retval JAYLINK_ERR_IO Input/output error.
1596 * @retval JAYLINK_ERR Other error conditions.
1598 * @see jaylink_register()
1600 * @since 0.1.0
1602 JAYLINK_API int jaylink_unregister(struct jaylink_device_handle *devh,
1603 const struct jaylink_connection *connection,
1604 struct jaylink_connection *connections, size_t *count)
1606 int ret;
1607 struct jaylink_context *ctx;
1608 uint8_t buf[REG_MAX_SIZE];
1609 uint16_t num;
1610 uint16_t entry_size;
1611 uint32_t size;
1612 uint32_t table_size;
1613 uint16_t info_size;
1614 struct in_addr in;
1616 if (!devh || !connection || !connections || !count)
1617 return JAYLINK_ERR_ARG;
1619 ctx = devh->dev->ctx;
1621 buf[0] = CMD_REGISTER;
1622 buf[1] = REG_CMD_UNREGISTER;
1623 buffer_set_u32(buf, connection->pid, 2);
1625 if (!_inet_pton(connection->hid, &in))
1626 return JAYLINK_ERR_ARG;
1628 buffer_set_u32(buf, in.s_addr, 6);
1630 buf[10] = connection->iid;
1631 buf[11] = connection->cid;
1632 buffer_set_u16(buf, connection->handle, 12);
1634 ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true);
1636 if (ret != JAYLINK_OK) {
1637 log_err(ctx, "transport_start_write_read() failed: %s.",
1638 jaylink_strerror(ret));
1639 return ret;
1642 ret = transport_write(devh, buf, 14);
1644 if (ret != JAYLINK_OK) {
1645 log_err(ctx, "transport_write() failed: %s.",
1646 jaylink_strerror(ret));
1647 return ret;
1650 ret = transport_read(devh, buf, REG_MIN_SIZE);
1652 if (ret != JAYLINK_OK) {
1653 log_err(ctx, "transport_read() failed: %s.",
1654 jaylink_strerror(ret));
1655 return ret;
1658 num = buffer_get_u16(buf, 2);
1659 entry_size = buffer_get_u16(buf, 4);
1660 info_size = buffer_get_u16(buf, 6);
1662 if (num > JAYLINK_MAX_CONNECTIONS) {
1663 log_err(ctx, "Maximum number of device connections exceeded: "
1664 "%u.", num);
1665 return JAYLINK_ERR_PROTO;
1668 if (entry_size != REG_CONN_INFO_SIZE) {
1669 log_err(ctx, "Invalid connection entry size: %u bytes.",
1670 entry_size);
1671 return JAYLINK_ERR_PROTO;
1674 table_size = num * entry_size;
1675 size = REG_HEADER_SIZE + table_size + info_size;
1677 if (size > REG_MAX_SIZE) {
1678 log_err(ctx, "Maximum registration information size exceeded: "
1679 "%u bytes.", size);
1680 return JAYLINK_ERR_PROTO;
1683 if (size > REG_MIN_SIZE) {
1684 ret = transport_start_read(devh, size - REG_MIN_SIZE);
1686 if (ret != JAYLINK_OK) {
1687 log_err(ctx, "transport_start_read() failed: %s.",
1688 jaylink_strerror(ret));
1689 return JAYLINK_ERR;
1692 ret = transport_read(devh, buf + REG_MIN_SIZE,
1693 size - REG_MIN_SIZE);
1695 if (ret != JAYLINK_OK) {
1696 log_err(ctx, "transport_read() failed: %s.",
1697 jaylink_strerror(ret));
1698 return JAYLINK_ERR;
1702 parse_conn_table(connections, buf + REG_HEADER_SIZE, num, entry_size);
1704 *count = num;
1706 return JAYLINK_OK;