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 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/>.
25 #include "libjaylink.h"
26 #include "libjaylink-internal.h"
31 * Device enumeration and handling.
35 #define CMD_GET_VERSION 0x01
36 #define CMD_GET_HW_STATUS 0x07
37 #define CMD_REGISTER 0x09
38 #define CMD_GET_HW_INFO 0xc1
39 #define CMD_GET_FREE_MEMORY 0xd4
40 #define CMD_GET_CAPS 0xe8
41 #define CMD_GET_EXT_CAPS 0xed
42 #define CMD_GET_HW_VERSION 0xf0
43 #define CMD_READ_CONFIG 0xf2
44 #define CMD_WRITE_CONFIG 0xf3
46 #define REG_CMD_REGISTER 0x64
47 #define REG_CMD_UNREGISTER 0x65
49 /** Size of the registration header in bytes. */
50 #define REG_HEADER_SIZE 8
51 /** Minimum registration information size in bytes. */
52 #define REG_MIN_SIZE 0x4c
53 /** Maximum registration information size in bytes. */
54 #define REG_MAX_SIZE 0x200
55 /** Size of a connection entry in bytes. */
56 #define REG_CONN_INFO_SIZE 16
60 JAYLINK_PRIV
struct jaylink_device
*device_allocate(struct jaylink_context
*ctx
)
62 struct jaylink_device
*dev
;
65 dev
= malloc(sizeof(struct jaylink_device
));
70 list
= list_prepend(ctx
->devs
, dev
);
87 static struct jaylink_device_handle
*allocate_device_handle(
88 struct jaylink_device
*dev
)
90 struct jaylink_device_handle
*devh
;
92 devh
= malloc(sizeof(struct jaylink_device_handle
));
97 devh
->dev
= jaylink_ref_device(dev
);
103 static void free_device_handle(struct jaylink_device_handle
*devh
)
105 jaylink_unref_device(devh
->dev
);
110 * Get a list of available devices.
112 * @param[in,out] ctx libjaylink context.
113 * @param[out] devices Newly allocated array which contains instances of
114 * available devices on success, and undefined on failure.
115 * The array is NULL-terminated and must be free'd by the
116 * caller with jaylink_free_device_list().
118 * @return The length of the array excluding the trailing NULL-terminator, or a
119 * negative error code on failure.
121 JAYLINK_API ssize_t
jaylink_get_device_list(struct jaylink_context
*ctx
,
122 struct jaylink_device
***devices
)
124 if (!ctx
|| !devices
)
125 return JAYLINK_ERR_ARG
;
127 return discovery_get_device_list(ctx
, devices
);
131 * Free a device list.
133 * @param[in,out] devices Array of device instances. Must be NULL-terminated.
134 * @param[in] unref_devices Determines whether the device instances should be
137 JAYLINK_API
void jaylink_free_device_list(struct jaylink_device
**devices
,
149 jaylink_unref_device(devices
[i
]);
158 * Get the serial number of a device.
160 * @note This serial number is for enumeration purpose only and might differ
161 * from the real serial number of the device.
163 * @param[in] dev Device instance.
164 * @param[out] serial_number Serial number of the device on success, and
165 * undefined on failure.
167 * @retval JAYLINK_OK Success.
168 * @retval JAYLINK_ERR_ARG Invalid arguments.
169 * @retval JAYLINK_ERR_NOT_AVAILABLE Serial number is not available.
171 JAYLINK_API
int jaylink_device_get_serial_number(
172 const struct jaylink_device
*dev
, uint32_t *serial_number
)
174 if (!dev
|| !serial_number
)
175 return JAYLINK_ERR_ARG
;
177 if (!dev
->valid_serial_number
)
178 return JAYLINK_ERR_NOT_AVAILABLE
;
180 *serial_number
= dev
->serial_number
;
186 * Get the USB address of a device.
188 * @note Identification of a device with the USB address is deprecated and the
189 * serial number should be used instead.
191 * @param[in] dev Device instance.
193 * @return The USB address of the device on success, or #JAYLINK_ERR_ARG for
194 * invalid device instance. See #jaylink_usb_address for valid USB
197 * @see jaylink_device_get_serial_number() to get the serial number of a device.
199 JAYLINK_API
int jaylink_device_get_usb_address(const struct jaylink_device
*dev
)
202 return JAYLINK_ERR_ARG
;
204 return dev
->usb_address
;
208 * Increment the reference count of a device.
210 * @param[in,out] dev Device instance.
212 * @return The given device instance on success, or NULL for invalid device
215 JAYLINK_API
struct jaylink_device
*jaylink_ref_device(
216 struct jaylink_device
*dev
)
227 * Decrement the reference count of a device.
229 * @param[in,out] dev Device instance.
231 JAYLINK_API
void jaylink_unref_device(struct jaylink_device
*dev
)
238 if (dev
->refcnt
== 0) {
239 dev
->ctx
->devs
= list_remove(dev
->ctx
->devs
, dev
);
242 libusb_unref_device(dev
->usb_dev
);
251 * @param[in,out] dev Device instance.
252 * @param[out] devh Newly allocated handle for the opened device on success,
253 * and undefined on failure.
255 * @retval JAYLINK_OK Success.
256 * @retval JAYLINK_ERR_ARG Invalid arguments.
257 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
258 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
259 * @retval JAYLINK_ERR Other error conditions.
261 JAYLINK_API
int jaylink_open(struct jaylink_device
*dev
,
262 struct jaylink_device_handle
**devh
)
265 struct jaylink_device_handle
*handle
;
268 return JAYLINK_ERR_ARG
;
270 handle
= allocate_device_handle(dev
);
273 log_err(dev
->ctx
, "Device handle malloc failed.");
274 return JAYLINK_ERR_MALLOC
;
277 ret
= transport_open(handle
);
280 free_device_handle(handle
);
292 * @param[in,out] devh Device instance.
294 JAYLINK_API
void jaylink_close(struct jaylink_device_handle
*devh
)
299 transport_close(devh
);
300 free_device_handle(devh
);
304 * Retrieve the firmware version of a device.
306 * @param[in,out] devh Device handle.
307 * @param[out] version Newly allocated string which contains the firmware
308 * version on success, and undefined if @p length is zero
309 * or on failure. The string is null-terminated and must be
310 * free'd by the caller.
311 * @param[out] length Length of the firmware version string including trailing
312 * null-terminator on success, and undefined on failure.
313 * Zero if no firmware version string is available.
315 * @retval JAYLINK_OK Success.
316 * @retval JAYLINK_ERR_ARG Invalid arguments.
317 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
318 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
319 * @retval JAYLINK_ERR Other error conditions.
321 JAYLINK_API
int jaylink_get_firmware_version(struct jaylink_device_handle
*devh
,
322 char **version
, size_t *length
)
325 struct jaylink_context
*ctx
;
330 if (!devh
|| !version
|| !length
)
331 return JAYLINK_ERR_ARG
;
333 ctx
= devh
->dev
->ctx
;
334 ret
= transport_start_write_read(devh
, 1, 2, 1);
336 if (ret
!= JAYLINK_OK
) {
337 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
341 buf
[0] = CMD_GET_VERSION
;
343 ret
= transport_write(devh
, buf
, 1);
345 if (ret
!= JAYLINK_OK
) {
346 log_err(ctx
, "transport_write() failed: %i.", ret
);
350 ret
= transport_read(devh
, buf
, 2);
352 if (ret
!= JAYLINK_OK
) {
353 log_err(ctx
, "transport_read() failed: %i.", ret
);
357 dummy
= buffer_get_u16(buf
, 0);
363 ret
= transport_start_read(devh
, dummy
);
365 if (ret
!= JAYLINK_OK
) {
366 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
373 log_err(ctx
, "Firmware version string malloc failed.");
374 return JAYLINK_ERR_MALLOC
;
377 ret
= transport_read(devh
, (uint8_t *)tmp
, dummy
);
379 if (ret
!= JAYLINK_OK
) {
380 log_err(ctx
, "transport_read() failed: %i.", ret
);
385 /* Last byte is reserved for null-terminator. */
393 * Retrieve the hardware information of a device.
395 * @note This function must only be used if the device has the
396 * #JAYLINK_DEV_CAP_GET_HW_INFO capability.
398 * @param[in,out] devh Device handle.
399 * @param[in] mask A bit field where each set bit represents hardware
400 * information to request. See #jaylink_hardware_info for a
401 * description of the hardware information and their bit
403 * @param[out] info Array to store the hardware information on success. Its
404 * content is undefined on failure. The array must be large
405 * enough to contain at least as many elements as bits set in
408 * @retval JAYLINK_OK Success.
409 * @retval JAYLINK_ERR_ARG Invalid arguments.
410 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
411 * @retval JAYLINK_ERR Other error conditions.
413 JAYLINK_API
int jaylink_get_hardware_info(struct jaylink_device_handle
*devh
,
414 uint32_t mask
, uint32_t *info
)
417 struct jaylink_context
*ctx
;
423 if (!devh
|| !mask
|| !info
)
424 return JAYLINK_ERR_ARG
;
426 ctx
= devh
->dev
->ctx
;
429 for (i
= 0; i
< 32; i
++) {
434 length
= num
* sizeof(uint32_t);
436 ret
= transport_start_write_read(devh
, 5, length
, 1);
438 if (ret
!= JAYLINK_OK
) {
439 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
443 buf
[0] = CMD_GET_HW_INFO
;
444 buffer_set_u32(buf
, mask
, 1);
446 ret
= transport_write(devh
, buf
, 5);
448 if (ret
!= JAYLINK_OK
) {
449 log_err(ctx
, "transport_write() failed: %i.", ret
);
453 ret
= transport_read(devh
, (uint8_t *)info
, length
);
455 if (ret
!= JAYLINK_OK
) {
456 log_err(ctx
, "transport_read() failed: %i.", ret
);
460 for (i
= 0; i
< num
; i
++)
461 info
[i
] = buffer_get_u32((uint8_t *)info
, i
* sizeof(uint32_t));
467 * Retrieve the hardware version of a device.
469 * @note This function must only be used if the device has the
470 * #JAYLINK_DEV_CAP_GET_HW_VERSION capability.
472 * @param[in,out] devh Device handle.
473 * @param[out] version Hardware version on success, and undefined on failure.
475 * @retval JAYLINK_OK Success.
476 * @retval JAYLINK_ERR_ARG Invalid arguments.
477 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
478 * @retval JAYLINK_ERR Other error conditions.
480 * @see jaylink_get_caps() to retrieve device capabilities.
482 JAYLINK_API
int jaylink_get_hardware_version(struct jaylink_device_handle
*devh
,
483 struct jaylink_hardware_version
*version
)
486 struct jaylink_context
*ctx
;
490 if (!devh
|| !version
)
491 return JAYLINK_ERR_ARG
;
493 ctx
= devh
->dev
->ctx
;
494 ret
= transport_start_write_read(devh
, 1, 4, 1);
496 if (ret
!= JAYLINK_OK
) {
497 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
501 buf
[0] = CMD_GET_HW_VERSION
;
503 ret
= transport_write(devh
, buf
, 1);
505 if (ret
!= JAYLINK_OK
) {
506 log_err(ctx
, "transport_write() failed: %i.", ret
);
510 ret
= transport_read(devh
, buf
, 4);
512 if (ret
!= JAYLINK_OK
) {
513 log_err(ctx
, "transport_read() failed: %i.", ret
);
517 tmp
= buffer_get_u32(buf
, 0);
519 version
->type
= (tmp
/ 1000000) % 100;
520 version
->major
= (tmp
/ 10000) % 100;
521 version
->minor
= (tmp
/ 100) % 100;
522 version
->revision
= tmp
% 100;
528 * Retrieve the hardware status of a device.
530 * @param[in,out] devh Device handle.
531 * @param[out] status Hardware status on success, and undefined on failure.
533 * @retval JAYLINK_OK Success.
534 * @retval JAYLINK_ERR_ARG Invalid arguments.
535 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
536 * @retval JAYLINK_ERR Other error conditions.
538 JAYLINK_API
int jaylink_get_hardware_status(struct jaylink_device_handle
*devh
,
539 struct jaylink_hardware_status
*status
)
542 struct jaylink_context
*ctx
;
545 if (!devh
|| !status
)
546 return JAYLINK_ERR_ARG
;
548 ctx
= devh
->dev
->ctx
;
549 ret
= transport_start_write_read(devh
, 1, 8, 1);
551 if (ret
!= JAYLINK_OK
) {
552 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
556 buf
[0] = CMD_GET_HW_STATUS
;
558 ret
= transport_write(devh
, buf
, 1);
560 if (ret
!= JAYLINK_OK
) {
561 log_err(ctx
, "transport_write() failed: %i.", ret
);
565 ret
= transport_read(devh
, buf
, 8);
567 if (ret
!= JAYLINK_OK
) {
568 log_err(ctx
, "transport_read() failed: %i.", ret
);
572 status
->target_voltage
= buffer_get_u16(buf
, 0);
573 status
->tck
= buf
[2];
574 status
->tdi
= buf
[3];
575 status
->tdo
= buf
[4];
576 status
->tms
= buf
[5];
577 status
->tres
= buf
[6];
578 status
->trst
= buf
[7];
584 * Retrieve the capabilities of a device.
586 * The capabilities are stored in a 32-bit bit array consisting of
587 * #JAYLINK_DEV_CAPS_SIZE bytes where each individual bit represents a
588 * capability. The first bit of this array is the least significant bit of the
589 * first byte and the following bits are sequentially numbered in order of
590 * increasing bit significance and byte index. A set bit indicates a supported
591 * capability. See #jaylink_device_capability for a description of the
592 * capabilities and their bit positions.
594 * @param[in,out] devh Device handle.
595 * @param[out] caps Buffer to store capabilities on success. Its content is
596 * undefined on failure. The size of the buffer must be large
597 * enough to contain at least #JAYLINK_DEV_CAPS_SIZE bytes.
599 * @retval JAYLINK_OK Success.
600 * @retval JAYLINK_ERR_ARG Invalid arguments.
601 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
602 * @retval JAYLINK_ERR Other error conditions.
604 * @see jaylink_get_extended_caps() to retrieve extended device capabilities.
606 JAYLINK_API
int jaylink_get_caps(struct jaylink_device_handle
*devh
,
610 struct jaylink_context
*ctx
;
614 return JAYLINK_ERR_ARG
;
616 ctx
= devh
->dev
->ctx
;
617 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_CAPS_SIZE
, 1);
619 if (ret
!= JAYLINK_OK
) {
620 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
624 buf
[0] = CMD_GET_CAPS
;
626 ret
= transport_write(devh
, buf
, 1);
628 if (ret
!= JAYLINK_OK
) {
629 log_err(ctx
, "transport_write() failed: %i.", ret
);
633 ret
= transport_read(devh
, caps
, JAYLINK_DEV_CAPS_SIZE
);
635 if (ret
!= JAYLINK_OK
) {
636 log_err(ctx
, "transport_read() failed: %i.", ret
);
644 * Retrieve the extended capabilities of a device.
646 * The extended capabilities are stored in a 256-bit bit array consisting of
647 * #JAYLINK_DEV_EXT_CAPS_SIZE bytes. See jaylink_get_caps() for a further
648 * description of how the capabilities are represented in this bit array. For a
649 * description of the capabilities and their bit positions, see
650 * #jaylink_device_capability.
652 * @note This function must only be used if the device has the
653 * #JAYLINK_DEV_CAP_GET_EXT_CAPS capability.
655 * @param[in,out] devh Device handle.
656 * @param[out] caps Buffer to store capabilities on success. Its content is
657 * undefined on failure. The size of the buffer must be large
658 * enough to contain at least #JAYLINK_DEV_EXT_CAPS_SIZE bytes.
660 * @retval JAYLINK_OK Success.
661 * @retval JAYLINK_ERR_ARG Invalid arguments.
662 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
663 * @retval JAYLINK_ERR Other error conditions.
665 * @see jaylink_get_caps() to retrieve device capabilities.
667 JAYLINK_API
int jaylink_get_extended_caps(struct jaylink_device_handle
*devh
,
671 struct jaylink_context
*ctx
;
675 return JAYLINK_ERR_ARG
;
677 ctx
= devh
->dev
->ctx
;
678 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_EXT_CAPS_SIZE
, 1);
680 if (ret
!= JAYLINK_OK
) {
681 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
685 buf
[0] = CMD_GET_EXT_CAPS
;
687 ret
= transport_write(devh
, buf
, 1);
689 if (ret
!= JAYLINK_OK
) {
690 log_err(ctx
, "transport_write() failed: %i.", ret
);
694 ret
= transport_read(devh
, caps
, JAYLINK_DEV_EXT_CAPS_SIZE
);
696 if (ret
!= JAYLINK_OK
) {
697 log_err(ctx
, "transport_read() failed: %i.", ret
);
705 * Retrieve the size of free memory of a device.
707 * @note This function must only be used if the device has the
708 * #JAYLINK_DEV_CAP_GET_FREE_MEMORY capability.
710 * @param[in,out] devh Device handle.
711 * @param[out] size Size of free memory in bytes on success, and undefined on
714 * @retval JAYLINK_OK Success.
715 * @retval JAYLINK_ERR_ARG Invalid arguments.
716 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
717 * @retval JAYLINK_ERR Other error conditions.
719 * @see jaylink_get_caps() to retrieve device capabilities.
721 JAYLINK_API
int jaylink_get_free_memory(struct jaylink_device_handle
*devh
,
725 struct jaylink_context
*ctx
;
729 return JAYLINK_ERR_ARG
;
731 ctx
= devh
->dev
->ctx
;
732 ret
= transport_start_write_read(devh
, 1, 4, 1);
734 if (ret
!= JAYLINK_OK
) {
735 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
739 buf
[0] = CMD_GET_FREE_MEMORY
;
741 ret
= transport_write(devh
, buf
, 1);
743 if (ret
!= JAYLINK_OK
) {
744 log_err(ctx
, "transport_write() failed: %i.", ret
);
748 ret
= transport_read(devh
, buf
, 4);
750 if (ret
!= JAYLINK_OK
) {
751 log_err(ctx
, "transport_read() failed: %i.", ret
);
755 *size
= buffer_get_u32(buf
, 0);
761 * Read the raw configuration data of a device.
763 * @note This function must only be used if the device has the
764 * #JAYLINK_DEV_CAP_READ_CONFIG capability.
766 * @param[in,out] devh Device handle.
767 * @param[out] config Buffer to store configuration data on success. Its
768 * content is undefined on failure. The size of the buffer
769 * must be large enough to contain at least
770 * #JAYLINK_DEV_CONFIG_SIZE bytes.
772 * @retval JAYLINK_OK Success.
773 * @retval JAYLINK_ERR_ARG Invalid arguments.
774 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
775 * @retval JAYLINK_ERR Other error conditions.
777 JAYLINK_API
int jaylink_read_raw_config(struct jaylink_device_handle
*devh
,
781 struct jaylink_context
*ctx
;
784 if (!devh
|| !config
)
785 return JAYLINK_ERR_ARG
;
787 ctx
= devh
->dev
->ctx
;
788 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_CONFIG_SIZE
, 1);
790 if (ret
!= JAYLINK_OK
) {
791 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
795 buf
[0] = CMD_READ_CONFIG
;
797 ret
= transport_write(devh
, buf
, 1);
799 if (ret
!= JAYLINK_OK
) {
800 log_err(ctx
, "transport_write() failed: %i.", ret
);
804 ret
= transport_read(devh
, config
, JAYLINK_DEV_CONFIG_SIZE
);
806 if (ret
!= JAYLINK_OK
) {
807 log_err(ctx
, "transport_read() failed: %i.", ret
);
815 * Write the raw configuration data of a device.
817 * @note This function must only be used if the device has the
818 * #JAYLINK_DEV_CAP_WRITE_CONFIG capability.
820 * @param[in,out] devh Device handle.
821 * @param[in] config Buffer to write configuration data from. The size of the
822 * configuration data is expected to be
823 * #JAYLINK_DEV_CONFIG_SIZE bytes.
825 * @retval JAYLINK_OK Success.
826 * @retval JAYLINK_ERR_ARG Invalid arguments.
827 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
828 * @retval JAYLINK_ERR Other error conditions.
830 JAYLINK_API
int jaylink_write_raw_config(struct jaylink_device_handle
*devh
,
831 const uint8_t *config
)
834 struct jaylink_context
*ctx
;
837 if (!devh
|| !config
)
838 return JAYLINK_ERR_ARG
;
840 ctx
= devh
->dev
->ctx
;
841 ret
= transport_start_write(devh
, 1 + JAYLINK_DEV_CONFIG_SIZE
, 1);
843 if (ret
!= JAYLINK_OK
) {
844 log_err(ctx
, "transport_start_write() failed: %i.", ret
);
848 buf
[0] = CMD_WRITE_CONFIG
;
850 ret
= transport_write(devh
, buf
, 1);
852 if (ret
!= JAYLINK_OK
) {
853 log_err(ctx
, "transport_write() failed: %i.", ret
);
857 ret
= transport_write(devh
, config
, JAYLINK_DEV_CONFIG_SIZE
);
859 if (ret
!= JAYLINK_OK
) {
860 log_err(ctx
, "transport_write() failed: %i.", ret
);
867 static void parse_conntable(struct jaylink_connection
*conns
,
868 const uint8_t *buffer
, uint16_t num
, uint16_t entry_size
)
875 for (i
= 0; i
< num
; i
++) {
876 conns
[i
].pid
= buffer_get_u32(buffer
, offset
);
877 conns
[i
].hid
= buffer_get_u32(buffer
, offset
+ 4);
878 conns
[i
].iid
= buffer
[offset
+ 8];
879 conns
[i
].cid
= buffer
[offset
+ 9];
880 conns
[i
].handle
= buffer_get_u16(buffer
, offset
+ 10);
881 conns
[i
].timestamp
= buffer_get_u32(buffer
, offset
+ 12);
882 offset
= offset
+ entry_size
;
887 * Register a connection on a device.
889 * A connection can be registered by using 0 as handle. Additional information
890 * about the connection can be attached whereby the timestamp is a read-only
891 * value and therefore ignored for registration. On success, a new handle
892 * greater than 0 is obtained from the device.
894 * However, if an obtained handle does not appear in the list of device
895 * connections, the connection was not registered because the maximum number of
896 * connections on the device is reached.
898 * @note This function must only be used if the device has the
899 * #JAYLINK_DEV_CAP_REGISTER capability.
901 * @param[in,out] devh Device handle.
902 * @param[in,out] connection Connection to register on the device.
903 * @param[out] connections Array to store device connections on success.
904 * Its content is undefined on failure. The array must
905 * be large enough to contain at least
906 * #JAYLINK_MAX_CONNECTIONS elements.
907 * @param[out] info Buffer to store additional information on success, or NULL.
908 * The content of the buffer is undefined on failure.
909 * @param[out] info_size Size of the additional information in bytes on success,
910 * and undefined on failure. Can be NULL.
912 * @return The number of device connections on success, a negative error code on
915 * @see jaylink_unregister() to unregister a connection from a device.
917 JAYLINK_API
int jaylink_register(struct jaylink_device_handle
*devh
,
918 struct jaylink_connection
*connection
,
919 struct jaylink_connection
*connections
, uint8_t *info
,
923 struct jaylink_context
*ctx
;
924 uint8_t buf
[REG_MAX_SIZE
];
930 uint16_t addinfo_size
;
932 if (!devh
|| !connection
|| !connections
)
933 return JAYLINK_ERR_ARG
;
935 ctx
= devh
->dev
->ctx
;
936 ret
= transport_start_write_read(devh
, 14, REG_MIN_SIZE
, 1);
938 if (ret
!= JAYLINK_OK
) {
939 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
943 buf
[0] = CMD_REGISTER
;
944 buf
[1] = REG_CMD_REGISTER
;
945 buffer_set_u32(buf
, connection
->pid
, 2);
946 buffer_set_u32(buf
, connection
->hid
, 6);
947 buf
[10] = connection
->iid
;
948 buf
[11] = connection
->cid
;
949 buffer_set_u16(buf
, connection
->handle
, 12);
951 ret
= transport_write(devh
, buf
, 14);
953 if (ret
!= JAYLINK_OK
) {
954 log_err(ctx
, "transport_write() failed: %i.", ret
);
958 ret
= transport_read(devh
, buf
, REG_MIN_SIZE
);
960 if (ret
!= JAYLINK_OK
) {
961 log_err(ctx
, "transport_read() failed: %i.", ret
);
965 handle
= buffer_get_u16(buf
, 0);
966 num
= buffer_get_u16(buf
, 2);
967 entry_size
= buffer_get_u16(buf
, 4);
968 addinfo_size
= buffer_get_u16(buf
, 6);
970 if (num
> JAYLINK_MAX_CONNECTIONS
) {
971 log_err(ctx
, "Maximum number of device connections exceeded: "
973 return JAYLINK_ERR_PROTO
;
976 if (entry_size
!= REG_CONN_INFO_SIZE
) {
977 log_err(ctx
, "Invalid connection entry size: %u bytes.",
979 return JAYLINK_ERR_PROTO
;
982 table_size
= num
* entry_size
;
983 size
= REG_HEADER_SIZE
+ table_size
+ addinfo_size
;
985 if (size
> REG_MAX_SIZE
) {
986 log_err(ctx
, "Maximum registration information size exceeded: "
988 return JAYLINK_ERR_PROTO
;
991 if (size
> REG_MIN_SIZE
) {
992 ret
= transport_start_read(devh
, size
- REG_MIN_SIZE
);
994 if (ret
!= JAYLINK_OK
) {
995 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
999 ret
= transport_read(devh
, buf
+ REG_MIN_SIZE
,
1000 size
- REG_MIN_SIZE
);
1002 if (ret
!= JAYLINK_OK
) {
1003 log_err(ctx
, "transport_read() failed: %i.", ret
);
1009 log_err(ctx
, "Obtained invalid connection handle.");
1010 return JAYLINK_ERR_PROTO
;
1013 connection
->handle
= handle
;
1014 parse_conntable(connections
, buf
+ REG_HEADER_SIZE
, num
, entry_size
);
1017 memcpy(info
, buf
+ REG_HEADER_SIZE
+ table_size
, addinfo_size
);
1020 *info_size
= addinfo_size
;
1026 * Unregister a connection from a device.
1028 * @note This function must only be used if the device has the
1029 * #JAYLINK_DEV_CAP_REGISTER capability.
1031 * @param[in,out] devh Device handle.
1032 * @param[in,out] connection Connection to unregister from the device.
1033 * @param[out] connections Array to store device connections on success.
1034 * Its content is undefined on failure. The array must
1035 * be large enough to contain at least
1036 * #JAYLINK_MAX_CONNECTIONS elements.
1037 * @param[out] info Buffer to store additional information on success, or NULL.
1038 * The content of the buffer is undefined on failure.
1039 * @param[out] info_size Size of the additional information in bytes on success,
1040 * and undefined on failure. Can be NULL.
1042 * @return The number of device connections on success, a negative error code on
1045 JAYLINK_API
int jaylink_unregister(struct jaylink_device_handle
*devh
,
1046 const struct jaylink_connection
*connection
,
1047 struct jaylink_connection
*connections
, uint8_t *info
,
1048 uint16_t *info_size
)
1051 struct jaylink_context
*ctx
;
1052 uint8_t buf
[REG_MAX_SIZE
];
1054 uint16_t entry_size
;
1056 uint32_t table_size
;
1057 uint16_t addinfo_size
;
1059 if (!devh
|| !connection
|| !connections
)
1060 return JAYLINK_ERR_ARG
;
1062 ctx
= devh
->dev
->ctx
;
1063 ret
= transport_start_write_read(devh
, 14, REG_MIN_SIZE
, 1);
1065 if (ret
!= JAYLINK_OK
) {
1066 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
1070 buf
[0] = CMD_REGISTER
;
1071 buf
[1] = REG_CMD_UNREGISTER
;
1072 buffer_set_u32(buf
, connection
->pid
, 2);
1073 buffer_set_u32(buf
, connection
->hid
, 6);
1074 buf
[10] = connection
->iid
;
1075 buf
[11] = connection
->cid
;
1076 buffer_set_u16(buf
, connection
->handle
, 12);
1078 ret
= transport_write(devh
, buf
, 14);
1080 if (ret
!= JAYLINK_OK
) {
1081 log_err(ctx
, "transport_write() failed: %i.", ret
);
1085 ret
= transport_read(devh
, buf
, REG_MIN_SIZE
);
1087 if (ret
!= JAYLINK_OK
) {
1088 log_err(ctx
, "transport_read() failed: %i.", ret
);
1092 num
= buffer_get_u16(buf
, 2);
1093 entry_size
= buffer_get_u16(buf
, 4);
1094 addinfo_size
= buffer_get_u16(buf
, 6);
1096 if (num
> JAYLINK_MAX_CONNECTIONS
) {
1097 log_err(ctx
, "Maximum number of device connections exceeded: "
1099 return JAYLINK_ERR_PROTO
;
1102 if (entry_size
!= REG_CONN_INFO_SIZE
) {
1103 log_err(ctx
, "Invalid connection entry size: %u bytes.",
1105 return JAYLINK_ERR_PROTO
;
1108 table_size
= num
* entry_size
;
1109 size
= REG_HEADER_SIZE
+ table_size
+ addinfo_size
;
1111 if (size
> REG_MAX_SIZE
) {
1112 log_err(ctx
, "Maximum registration information size exceeded: "
1114 return JAYLINK_ERR_PROTO
;
1117 if (size
> REG_MIN_SIZE
) {
1118 ret
= transport_start_read(devh
, size
- REG_MIN_SIZE
);
1120 if (ret
!= JAYLINK_OK
) {
1121 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
1125 ret
= transport_read(devh
, buf
+ REG_MIN_SIZE
,
1126 size
- REG_MIN_SIZE
);
1128 if (ret
!= JAYLINK_OK
) {
1129 log_err(ctx
, "transport_read() failed: %i.", ret
);
1134 parse_conntable(connections
, buf
+ REG_HEADER_SIZE
, num
, entry_size
);
1137 memcpy(info
, buf
+ REG_HEADER_SIZE
+ table_size
, addinfo_size
);
1140 *info_size
= addinfo_size
;