2 * This file is part of the libjaylink project.
4 * Copyright (C) 2014-2015 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 3 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/>.
24 #include "libjaylink.h"
25 #include "libjaylink-internal.h"
30 * Device enumeration and handling.
34 #define CMD_GET_VERSION 0x01
35 #define CMD_GET_HW_STATUS 0x07
36 #define CMD_REGISTER 0x09
37 #define CMD_GET_FREE_MEMORY 0xd4
38 #define CMD_GET_CAPS 0xe8
39 #define CMD_GET_EXT_CAPS 0xed
40 #define CMD_GET_HW_VERSION 0xf0
41 #define CMD_READ_CONFIG 0xf2
42 #define CMD_WRITE_CONFIG 0xf3
44 #define REG_CMD_REGISTER 0x64
45 #define REG_CMD_UNREGISTER 0x65
47 /** Size of the registration header in bytes. */
48 #define REG_HEADER_SIZE 8
49 /** Minimum registration information size in bytes. */
50 #define REG_MIN_SIZE 0x4c
51 /** Maximum registration information size in bytes. */
52 #define REG_MAX_SIZE 0x200
53 /** Size of a connection entry in bytes. */
54 #define REG_CONN_INFO_SIZE 16
58 JAYLINK_PRIV
struct jaylink_device
*device_allocate(struct jaylink_context
*ctx
)
60 struct jaylink_device
*dev
;
63 dev
= malloc(sizeof(struct jaylink_device
));
68 list
= list_prepend(ctx
->devs
, dev
);
85 static struct jaylink_device_handle
*allocate_device_handle(
86 struct jaylink_device
*dev
)
88 struct jaylink_device_handle
*devh
;
90 devh
= malloc(sizeof(struct jaylink_device_handle
));
95 devh
->dev
= jaylink_ref_device(dev
);
101 static void free_device_handle(struct jaylink_device_handle
*devh
)
103 jaylink_unref_device(devh
->dev
);
108 * Get a list of available devices.
110 * @param[in,out] ctx libjaylink context.
111 * @param[out] devices Newly allocated array which contains instances of
112 * available devices on success, and undefined on failure.
113 * The array is NULL-terminated and must be free'd by the
114 * caller with jaylink_free_device_list().
116 * @return The length of the array excluding the trailing NULL-terminator, or a
117 * negative error code on failure.
119 JAYLINK_API ssize_t
jaylink_get_device_list(struct jaylink_context
*ctx
,
120 struct jaylink_device
***devices
)
122 if (!ctx
|| !devices
)
123 return JAYLINK_ERR_ARG
;
125 return discovery_get_device_list(ctx
, devices
);
129 * Free a device list.
131 * @param[in,out] devices Array of device instances. Must be NULL-terminated.
132 * @param[in] unref_devices Determines whether the device instances should be
135 JAYLINK_API
void jaylink_free_device_list(struct jaylink_device
**devices
,
147 jaylink_unref_device(devices
[i
]);
156 * Get the serial number of a device.
158 * @note This serial number is for enumeration purpose only and might differ
159 * from the real serial number of the device.
161 * @param[in] dev Device instance.
162 * @param[out] serial_number Serial number of the device on success, and
163 * undefined on failure.
165 * @retval JAYLINK_OK Success.
166 * @retval JAYLINK_ERR_ARG Invalid arguments.
168 JAYLINK_API
int jaylink_device_get_serial_number(
169 const struct jaylink_device
*dev
, uint32_t *serial_number
)
171 if (!dev
|| !serial_number
)
172 return JAYLINK_ERR_ARG
;
174 *serial_number
= dev
->serial_number
;
180 * Get the USB address of a device.
182 * @note Identification of a device with the USB address is deprecated and the
183 * serial number should be used instead.
185 * @param[in] dev Device instance.
187 * @return The USB address of the device on success, or #JAYLINK_ERR_ARG for
188 * invalid device instance. See #jaylink_usb_address for valid USB
191 * @see jaylink_device_get_serial_number() to get the serial number of a device.
193 JAYLINK_API
int jaylink_device_get_usb_address(const struct jaylink_device
*dev
)
196 return JAYLINK_ERR_ARG
;
198 return dev
->usb_address
;
202 * Increment the reference count of a device.
204 * @param[in,out] dev Device instance.
206 * @return The given device instance on success, or NULL for invalid device
209 JAYLINK_API
struct jaylink_device
*jaylink_ref_device(
210 struct jaylink_device
*dev
)
221 * Decrement the reference count of a device.
223 * @param[in,out] dev Device instance.
225 JAYLINK_API
void jaylink_unref_device(struct jaylink_device
*dev
)
232 if (dev
->refcnt
== 0) {
233 dev
->ctx
->devs
= list_remove(dev
->ctx
->devs
, dev
);
236 libusb_unref_device(dev
->usb_dev
);
245 * @param[in,out] dev Device instance.
246 * @param[out] devh Newly allocated handle for the opened device on success,
247 * and undefined on failure.
249 * @retval JAYLINK_OK Success.
250 * @retval JAYLINK_ERR_ARG Invalid arguments.
251 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
252 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
253 * @retval JAYLINK_ERR Other error conditions.
255 JAYLINK_API
int jaylink_open(struct jaylink_device
*dev
,
256 struct jaylink_device_handle
**devh
)
259 struct jaylink_device_handle
*handle
;
262 return JAYLINK_ERR_ARG
;
264 handle
= allocate_device_handle(dev
);
267 log_err(dev
->ctx
, "Device handle malloc failed.");
268 return JAYLINK_ERR_MALLOC
;
271 ret
= transport_open(handle
);
274 free_device_handle(handle
);
286 * @param[in,out] devh Device instance.
288 JAYLINK_API
void jaylink_close(struct jaylink_device_handle
*devh
)
293 transport_close(devh
);
294 free_device_handle(devh
);
298 * Retrieve the firmware version of a device.
300 * @param[in,out] devh Device handle.
301 * @param[out] version Newly allocated string which contains the firmware
302 * version, and undefined if the device returns no
303 * firmware version or on failure. The string is
304 * null-terminated and must be free'd by the caller.
306 * @return The length of the newly allocated firmware version string including
307 * trailing null-terminator, 0 if the device returns no firmware
308 * version, or a negative error code on failure.
310 JAYLINK_API
int jaylink_get_firmware_version(struct jaylink_device_handle
*devh
,
314 struct jaylink_context
*ctx
;
319 if (!devh
|| !version
)
320 return JAYLINK_ERR_ARG
;
322 ctx
= devh
->dev
->ctx
;
323 ret
= transport_start_write_read(devh
, 1, 2, 1);
325 if (ret
!= JAYLINK_OK
) {
326 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
330 buf
[0] = CMD_GET_VERSION
;
332 ret
= transport_write(devh
, buf
, 1);
334 if (ret
!= JAYLINK_OK
) {
335 log_err(ctx
, "transport_write() failed: %i.", ret
);
339 ret
= transport_read(devh
, buf
, 2);
341 if (ret
!= JAYLINK_OK
) {
342 log_err(ctx
, "transport_read() failed: %i.", ret
);
346 length
= buffer_get_u16(buf
, 0);
351 ret
= transport_start_read(devh
, length
);
353 if (ret
!= JAYLINK_OK
) {
354 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
358 tmp
= malloc(length
);
361 log_err(ctx
, "Firmware version string malloc failed.");
362 return JAYLINK_ERR_MALLOC
;
365 ret
= transport_read(devh
, (uint8_t *)tmp
, length
);
367 if (ret
!= JAYLINK_OK
) {
368 log_err(ctx
, "transport_read() failed: %i.", ret
);
373 /* Last byte is reserved for null-terminator. */
381 * Retrieve the hardware version of a device.
383 * @note This function must only be used if the device has the
384 * #JAYLINK_DEV_CAP_GET_HW_VERSION capability.
386 * @param[in,out] devh Device handle.
387 * @param[out] version Hardware version on success, and undefined on failure.
389 * @retval JAYLINK_OK Success.
390 * @retval JAYLINK_ERR_ARG Invalid arguments.
391 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
392 * @retval JAYLINK_ERR Other error conditions.
394 * @see jaylink_get_caps() to retrieve device capabilities.
396 JAYLINK_API
int jaylink_get_hardware_version(struct jaylink_device_handle
*devh
,
397 struct jaylink_hardware_version
*version
)
400 struct jaylink_context
*ctx
;
404 if (!devh
|| !version
)
405 return JAYLINK_ERR_ARG
;
407 ctx
= devh
->dev
->ctx
;
408 ret
= transport_start_write_read(devh
, 1, 4, 1);
410 if (ret
!= JAYLINK_OK
) {
411 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
415 buf
[0] = CMD_GET_HW_VERSION
;
417 ret
= transport_write(devh
, buf
, 1);
419 if (ret
!= JAYLINK_OK
) {
420 log_err(ctx
, "transport_write() failed: %i.", ret
);
424 ret
= transport_read(devh
, buf
, 4);
426 if (ret
!= JAYLINK_OK
) {
427 log_err(ctx
, "transport_read() failed: %i.", ret
);
431 tmp
= buffer_get_u32(buf
, 0);
433 version
->type
= (tmp
/ 1000000) % 100;
434 version
->major
= (tmp
/ 10000) % 100;
435 version
->minor
= (tmp
/ 100) % 100;
436 version
->revision
= tmp
% 100;
442 * Retrieve the hardware status of a device.
444 * @param[in,out] devh Device handle.
445 * @param[out] status Hardware status on success, and undefined on failure.
447 * @retval JAYLINK_OK Success.
448 * @retval JAYLINK_ERR_ARG Invalid arguments.
449 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
450 * @retval JAYLINK_ERR Other error conditions.
452 JAYLINK_API
int jaylink_get_hardware_status(struct jaylink_device_handle
*devh
,
453 struct jaylink_hardware_status
*status
)
456 struct jaylink_context
*ctx
;
459 if (!devh
|| !status
)
460 return JAYLINK_ERR_ARG
;
462 ctx
= devh
->dev
->ctx
;
463 ret
= transport_start_write_read(devh
, 1, 8, 1);
465 if (ret
!= JAYLINK_OK
) {
466 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
470 buf
[0] = CMD_GET_HW_STATUS
;
472 ret
= transport_write(devh
, buf
, 1);
474 if (ret
!= JAYLINK_OK
) {
475 log_err(ctx
, "transport_write() failed: %i.", ret
);
479 ret
= transport_read(devh
, buf
, 8);
481 if (ret
!= JAYLINK_OK
) {
482 log_err(ctx
, "transport_read() failed: %i.", ret
);
486 status
->target_voltage
= buffer_get_u16(buf
, 0);
487 status
->tck
= buf
[2];
488 status
->tdi
= buf
[3];
489 status
->tdo
= buf
[4];
490 status
->tms
= buf
[5];
491 status
->tres
= buf
[6];
492 status
->trst
= buf
[7];
498 * Retrieve the capabilities of a device.
500 * The capabilities are stored in a 32-bit bit array consisting of
501 * #JAYLINK_DEV_CAPS_SIZE bytes where each individual bit represents a
502 * capability. The first bit of this array is the least significant bit of the
503 * first byte and the following bits are sequentially numbered in order of
504 * increasing bit significance and byte index. A set bit indicates a supported
505 * capability. See #jaylink_device_capability for a description of the
506 * capabilities and their bit positions.
508 * @param[in,out] devh Device handle.
509 * @param[out] caps Buffer to store capabilities on success. Its content is
510 * undefined on failure. The size of the buffer must be large
511 * enough to contain at least #JAYLINK_DEV_CAPS_SIZE bytes.
513 * @retval JAYLINK_OK Success.
514 * @retval JAYLINK_ERR_ARG Invalid arguments.
515 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
516 * @retval JAYLINK_ERR Other error conditions.
518 * @see jaylink_get_extended_caps() to retrieve extended device capabilities.
520 JAYLINK_API
int jaylink_get_caps(struct jaylink_device_handle
*devh
,
524 struct jaylink_context
*ctx
;
528 return JAYLINK_ERR_ARG
;
530 ctx
= devh
->dev
->ctx
;
531 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_CAPS_SIZE
, 1);
533 if (ret
!= JAYLINK_OK
) {
534 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
538 buf
[0] = CMD_GET_CAPS
;
540 ret
= transport_write(devh
, buf
, 1);
542 if (ret
!= JAYLINK_OK
) {
543 log_err(ctx
, "transport_write() failed: %i.", ret
);
547 ret
= transport_read(devh
, caps
, JAYLINK_DEV_CAPS_SIZE
);
549 if (ret
!= JAYLINK_OK
) {
550 log_err(ctx
, "transport_read() failed: %i.", ret
);
558 * Retrieve the extended capabilities of a device.
560 * The extended capabilities are stored in a 256-bit bit array consisting of
561 * #JAYLINK_DEV_EXT_CAPS_SIZE bytes. See jaylink_get_caps() for a further
562 * description of how the capabilities are represented in this bit array. For a
563 * description of the capabilities and their bit positions, see
564 * #jaylink_device_capability.
566 * @note This function must only be used if the device has the
567 * #JAYLINK_DEV_CAP_GET_EXT_CAPS capability.
569 * @param[in,out] devh Device handle.
570 * @param[out] caps Buffer to store capabilities on success. Its content is
571 * undefined on failure. The size of the buffer must be large
572 * enough to contain at least #JAYLINK_DEV_EXT_CAPS_SIZE bytes.
574 * @retval JAYLINK_OK Success.
575 * @retval JAYLINK_ERR_ARG Invalid arguments.
576 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
577 * @retval JAYLINK_ERR Other error conditions.
579 * @see jaylink_get_caps() to retrieve device capabilities.
581 JAYLINK_API
int jaylink_get_extended_caps(struct jaylink_device_handle
*devh
,
585 struct jaylink_context
*ctx
;
589 return JAYLINK_ERR_ARG
;
591 ctx
= devh
->dev
->ctx
;
592 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_EXT_CAPS_SIZE
, 1);
594 if (ret
!= JAYLINK_OK
) {
595 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
599 buf
[0] = CMD_GET_EXT_CAPS
;
601 ret
= transport_write(devh
, buf
, 1);
603 if (ret
!= JAYLINK_OK
) {
604 log_err(ctx
, "transport_write() failed: %i.", ret
);
608 ret
= transport_read(devh
, caps
, JAYLINK_DEV_EXT_CAPS_SIZE
);
610 if (ret
!= JAYLINK_OK
) {
611 log_err(ctx
, "transport_read() failed: %i.", ret
);
619 * Retrieve the size of free memory of a device.
621 * @note This function must only be used if the device has the
622 * #JAYLINK_DEV_CAP_GET_FREE_MEMORY capability.
624 * @param[in,out] devh Device handle.
625 * @param[out] size Size of free memory in bytes on success, and undefined on
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 * @see jaylink_get_caps() to retrieve device capabilities.
635 JAYLINK_API
int jaylink_get_free_memory(struct jaylink_device_handle
*devh
,
639 struct jaylink_context
*ctx
;
643 return JAYLINK_ERR_ARG
;
645 ctx
= devh
->dev
->ctx
;
646 ret
= transport_start_write_read(devh
, 1, 4, 1);
648 if (ret
!= JAYLINK_OK
) {
649 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
653 buf
[0] = CMD_GET_FREE_MEMORY
;
655 ret
= transport_write(devh
, buf
, 1);
657 if (ret
!= JAYLINK_OK
) {
658 log_err(ctx
, "transport_write() failed: %i.", ret
);
662 ret
= transport_read(devh
, buf
, 4);
664 if (ret
!= JAYLINK_OK
) {
665 log_err(ctx
, "transport_read() failed: %i.", ret
);
669 *size
= buffer_get_u32(buf
, 0);
675 * Read the raw configuration data of a device.
677 * @note This function must only be used if the device has the
678 * #JAYLINK_DEV_CAP_READ_CONFIG capability.
680 * @param[in,out] devh Device handle.
681 * @param[out] config Buffer to store configuration data on success. Its
682 * content is undefined on failure. The size of the buffer
683 * must be large enough to contain at least
684 * #JAYLINK_DEV_CONFIG_SIZE bytes.
686 * @retval JAYLINK_OK Success.
687 * @retval JAYLINK_ERR_ARG Invalid arguments.
688 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
689 * @retval JAYLINK_ERR Other error conditions.
691 JAYLINK_API
int jaylink_read_raw_config(struct jaylink_device_handle
*devh
,
695 struct jaylink_context
*ctx
;
698 if (!devh
|| !config
)
699 return JAYLINK_ERR_ARG
;
701 ctx
= devh
->dev
->ctx
;
702 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_CONFIG_SIZE
, 1);
704 if (ret
!= JAYLINK_OK
) {
705 log_err(ctx
, "transport_start_write_read() failed: %i.",
710 buf
[0] = CMD_READ_CONFIG
;
712 ret
= transport_write(devh
, buf
, 1);
714 if (ret
!= JAYLINK_OK
) {
715 log_err(ctx
, "transport_write() failed: %i.", ret
);
719 ret
= transport_read(devh
, config
, JAYLINK_DEV_CONFIG_SIZE
);
721 if (ret
!= JAYLINK_OK
) {
722 log_err(ctx
, "transport_read() failed: %i.", ret
);
730 * Write the raw configuration data of a device.
732 * @note This function must only be used if the device has the
733 * #JAYLINK_DEV_CAP_WRITE_CONFIG capability.
735 * @param[in,out] devh Device handle.
736 * @param[in] config Buffer to write configuration data from. The size of the
737 * configuration data is expected to be
738 * #JAYLINK_DEV_CONFIG_SIZE bytes.
740 * @retval JAYLINK_OK Success.
741 * @retval JAYLINK_ERR_ARG Invalid arguments.
742 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
743 * @retval JAYLINK_ERR Other error conditions.
745 JAYLINK_API
int jaylink_write_raw_config(struct jaylink_device_handle
*devh
,
746 const uint8_t *config
)
749 struct jaylink_context
*ctx
;
752 if (!devh
|| !config
)
753 return JAYLINK_ERR_ARG
;
755 ctx
= devh
->dev
->ctx
;
756 ret
= transport_start_write(devh
, 1 + JAYLINK_DEV_CONFIG_SIZE
, 1);
758 if (ret
!= JAYLINK_OK
) {
759 log_err(ctx
, "transport_start_write_read() failed: %i.",
764 buf
[0] = CMD_WRITE_CONFIG
;
766 ret
= transport_write(devh
, buf
, 1);
768 if (ret
!= JAYLINK_OK
) {
769 log_err(ctx
, "transport_write() failed: %i.", ret
);
773 ret
= transport_write(devh
, config
, JAYLINK_DEV_CONFIG_SIZE
);
775 if (ret
!= JAYLINK_OK
) {
776 log_err(ctx
, "transport_read() failed: %i.", ret
);
783 static void parse_conntable(struct jaylink_connection
*conns
,
784 const uint8_t *buffer
, uint16_t num
, uint16_t entry_size
)
791 for (i
= 0; i
< num
; i
++) {
792 conns
[i
].pid
= buffer_get_u32(buffer
, offset
);
793 conns
[i
].hid
= buffer_get_u32(buffer
, offset
+ 4);
794 conns
[i
].iid
= buffer
[offset
+ 8];
795 conns
[i
].cid
= buffer
[offset
+ 9];
796 conns
[i
].handle
= buffer_get_u16(buffer
, offset
+ 10);
797 conns
[i
].timestamp
= buffer_get_u32(buffer
, offset
+ 12);
798 offset
= offset
+ entry_size
;
803 * Register a connection on a device.
805 * A connection can be registered by using 0 as handle. Additional information
806 * about the connection can be attached whereby the timestamp is a read-only
807 * value and therefore ignored for registration. On success, a new handle
808 * greater than 0 is obtained from the device.
810 * However, if an obtained handle does not appear in the list of device
811 * connections, the connection was not registered because the maximum number of
812 * connections on the device is reached.
814 * @note This function must only be used if the device has the
815 * #JAYLINK_DEV_CAP_REGISTER capability.
817 * @param[in,out] devh Device handle.
818 * @param[in,out] connection Connection to register on the device.
819 * @param[out] connections Array to store device connections on success.
820 * Its content is undefined on failure. The array must
821 * be large enough to contain at least
822 * #JAYLINK_MAX_CONNECTIONS elements.
823 * @param[out] info Buffer to store additional information on success, or NULL.
824 * The content of the buffer is undefined on failure.
825 * @param[out] info_size Size of the additional information in bytes on success,
826 * and undefined on failure. Can be NULL.
828 * @return The number of device connections on success, a negative error code on
831 * @see jaylink_unregister() to unregister a connection from a device.
833 JAYLINK_API
int jaylink_register(struct jaylink_device_handle
*devh
,
834 struct jaylink_connection
*connection
,
835 struct jaylink_connection
*connections
, uint8_t *info
,
839 struct jaylink_context
*ctx
;
840 uint8_t buf
[REG_MAX_SIZE
];
846 uint16_t addinfo_size
;
848 if (!devh
|| !connection
|| !connections
)
849 return JAYLINK_ERR_ARG
;
851 ctx
= devh
->dev
->ctx
;
852 ret
= transport_start_write_read(devh
, 14, REG_MIN_SIZE
, 1);
854 if (ret
!= JAYLINK_OK
) {
855 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
859 buf
[0] = CMD_REGISTER
;
860 buf
[1] = REG_CMD_REGISTER
;
861 buffer_set_u32(buf
, connection
->pid
, 2);
862 buffer_set_u32(buf
, connection
->hid
, 6);
863 buf
[10] = connection
->iid
;
864 buf
[11] = connection
->cid
;
865 buffer_set_u16(buf
, connection
->handle
, 12);
867 ret
= transport_write(devh
, buf
, 14);
869 if (ret
!= JAYLINK_OK
) {
870 log_err(ctx
, "transport_write() failed: %i.", ret
);
874 ret
= transport_read(devh
, buf
, REG_MIN_SIZE
);
876 if (ret
!= JAYLINK_OK
) {
877 log_err(ctx
, "transport_read() failed: %i.", ret
);
881 handle
= buffer_get_u16(buf
, 0);
882 num
= buffer_get_u16(buf
, 2);
883 entry_size
= buffer_get_u16(buf
, 4);
884 addinfo_size
= buffer_get_u16(buf
, 6);
886 if (num
> JAYLINK_MAX_CONNECTIONS
) {
887 log_err(ctx
, "Maximum number of device connections exceeded: "
892 if (entry_size
!= REG_CONN_INFO_SIZE
) {
893 log_err(ctx
, "Invalid connection entry size: %u bytes.",
898 table_size
= num
* entry_size
;
899 size
= REG_HEADER_SIZE
+ table_size
+ addinfo_size
;
901 if (size
> REG_MAX_SIZE
) {
902 log_err(ctx
, "Maximum registration information size exceeded: "
907 if (size
> REG_MIN_SIZE
) {
908 ret
= transport_start_read(devh
, size
- REG_MIN_SIZE
);
910 if (ret
!= JAYLINK_OK
) {
911 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
915 ret
= transport_read(devh
, buf
+ REG_MIN_SIZE
,
916 size
- REG_MIN_SIZE
);
918 if (ret
!= JAYLINK_OK
) {
919 log_err(ctx
, "transport_read() failed: %i.", ret
);
925 log_err(ctx
, "Obtained invalid connection handle.");
929 connection
->handle
= handle
;
930 parse_conntable(connections
, buf
+ REG_HEADER_SIZE
, num
, entry_size
);
933 memcpy(info
, buf
+ REG_HEADER_SIZE
+ table_size
, addinfo_size
);
936 *info_size
= addinfo_size
;
942 * Unregister a connection from a device.
944 * @note This function must only be used if the device has the
945 * #JAYLINK_DEV_CAP_REGISTER capability.
947 * @param[in,out] devh Device handle.
948 * @param[in,out] connection Connection to unregister from the device.
949 * @param[out] connections Array to store device connections on success.
950 * Its content is undefined on failure. The array must
951 * be large enough to contain at least
952 * #JAYLINK_MAX_CONNECTIONS elements.
953 * @param[out] info Buffer to store additional information on success, or NULL.
954 * The content of the buffer is undefined on failure.
955 * @param[out] info_size Size of the additional information in bytes on success,
956 * and undefined on failure. Can be NULL.
958 * @return The number of device connections on success, a negative error code on
961 JAYLINK_API
int jaylink_unregister(struct jaylink_device_handle
*devh
,
962 const struct jaylink_connection
*connection
,
963 struct jaylink_connection
*connections
, uint8_t *info
,
967 struct jaylink_context
*ctx
;
968 uint8_t buf
[REG_MAX_SIZE
];
973 uint16_t addinfo_size
;
975 if (!devh
|| !connection
|| !connections
)
976 return JAYLINK_ERR_ARG
;
978 ctx
= devh
->dev
->ctx
;
979 ret
= transport_start_write_read(devh
, 14, REG_MIN_SIZE
, 1);
981 if (ret
!= JAYLINK_OK
) {
982 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
986 buf
[0] = CMD_REGISTER
;
987 buf
[1] = REG_CMD_UNREGISTER
;
988 buffer_set_u32(buf
, connection
->pid
, 2);
989 buffer_set_u32(buf
, connection
->hid
, 6);
990 buf
[10] = connection
->iid
;
991 buf
[11] = connection
->cid
;
992 buffer_set_u16(buf
, connection
->handle
, 12);
994 ret
= transport_write(devh
, buf
, 14);
996 if (ret
!= JAYLINK_OK
) {
997 log_err(ctx
, "transport_write() failed: %i.", ret
);
1001 ret
= transport_read(devh
, buf
, REG_MIN_SIZE
);
1003 if (ret
!= JAYLINK_OK
) {
1004 log_err(ctx
, "transport_read() failed: %i.", ret
);
1008 num
= buffer_get_u16(buf
, 2);
1009 entry_size
= buffer_get_u16(buf
, 4);
1010 addinfo_size
= buffer_get_u16(buf
, 6);
1012 if (num
> JAYLINK_MAX_CONNECTIONS
) {
1013 log_err(ctx
, "Maximum number of device connections exceeded: "
1018 if (entry_size
!= REG_CONN_INFO_SIZE
) {
1019 log_err(ctx
, "Invalid connection entry size: %u bytes.",
1024 table_size
= num
* entry_size
;
1025 size
= REG_HEADER_SIZE
+ table_size
+ addinfo_size
;
1027 if (size
> REG_MAX_SIZE
) {
1028 log_err(ctx
, "Maximum registration information size exceeded: "
1033 if (size
> REG_MIN_SIZE
) {
1034 ret
= transport_start_read(devh
, size
- REG_MIN_SIZE
);
1036 if (ret
!= JAYLINK_OK
) {
1037 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
1041 ret
= transport_read(devh
, buf
+ REG_MIN_SIZE
,
1042 size
- REG_MIN_SIZE
);
1044 if (ret
!= JAYLINK_OK
) {
1045 log_err(ctx
, "transport_read() failed: %i.", ret
);
1050 parse_conntable(connections
, buf
+ REG_HEADER_SIZE
, num
, entry_size
);
1053 memcpy(info
, buf
+ REG_HEADER_SIZE
+ table_size
, addinfo_size
);
1056 *info_size
= addinfo_size
;