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/>.
26 #include "libjaylink.h"
27 #include "libjaylink-internal.h"
32 * Device enumeration and handling.
36 #define CMD_GET_VERSION 0x01
37 #define CMD_GET_HW_STATUS 0x07
38 #define CMD_REGISTER 0x09
39 #define CMD_GET_HW_INFO 0xc1
40 #define CMD_GET_FREE_MEMORY 0xd4
41 #define CMD_GET_CAPS 0xe8
42 #define CMD_GET_EXT_CAPS 0xed
43 #define CMD_GET_HW_VERSION 0xf0
44 #define CMD_READ_CONFIG 0xf2
45 #define CMD_WRITE_CONFIG 0xf3
47 #define REG_CMD_REGISTER 0x64
48 #define REG_CMD_UNREGISTER 0x65
50 /** Size of the registration header in bytes. */
51 #define REG_HEADER_SIZE 8
52 /** Minimum registration information size in bytes. */
53 #define REG_MIN_SIZE 0x4c
54 /** Maximum registration information size in bytes. */
55 #define REG_MAX_SIZE 0x200
56 /** Size of a connection entry in bytes. */
57 #define REG_CONN_INFO_SIZE 16
61 JAYLINK_PRIV
struct jaylink_device
*device_allocate(struct jaylink_context
*ctx
)
63 struct jaylink_device
*dev
;
66 dev
= malloc(sizeof(struct jaylink_device
));
71 list
= list_prepend(ctx
->devs
, dev
);
88 static struct jaylink_device_handle
*allocate_device_handle(
89 struct jaylink_device
*dev
)
91 struct jaylink_device_handle
*devh
;
93 devh
= malloc(sizeof(struct jaylink_device_handle
));
98 devh
->dev
= jaylink_ref_device(dev
);
104 static void free_device_handle(struct jaylink_device_handle
*devh
)
106 jaylink_unref_device(devh
->dev
);
111 static struct jaylink_device
**allocate_device_list(size_t length
)
113 struct jaylink_device
**list
;
115 list
= malloc(sizeof(struct jaylink_device
*) * (length
+ 1));
126 * Get available devices.
128 * @param[in,out] ctx libjaylink context.
129 * @param[out] devices Newly allocated array which contains instances of
130 * available devices on success, and undefined on failure.
131 * The array is NULL-terminated and must be free'd by the
132 * caller with jaylink_free_devices().
133 * @param[out] count Number of available devices on success, and undefined on
134 * failure. Can be NULL.
136 * @retval JAYLINK_OK Success.
137 * @retval JAYLINK_ERR_ARG Invalid arguments.
138 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
139 * @retval JAYLINK_ERR Other error conditions.
141 * @see jaylink_discovery_scan()
143 JAYLINK_API
int jaylink_get_devices(struct jaylink_context
*ctx
,
144 struct jaylink_device
***devices
, size_t *count
)
148 struct jaylink_device
**devs
;
149 struct jaylink_device
*dev
;
152 if (!ctx
|| !devices
)
153 return JAYLINK_ERR_ARG
;
155 num
= list_length(ctx
->discovered_devs
);
156 devs
= allocate_device_list(num
);
159 log_err(ctx
, "Failed to allocate device list.");
160 return JAYLINK_ERR_MALLOC
;
163 item
= ctx
->discovered_devs
;
165 for (i
= 0; i
< num
; i
++) {
166 dev
= (struct jaylink_device
*)item
->data
;
167 devs
[i
] = jaylink_ref_device(dev
);
182 * @param[in,out] devices Array of device instances. Must be NULL-terminated.
183 * @param[in] unref Determines whether the device instances should be
186 * @see jaylink_get_devices()
188 JAYLINK_API
void jaylink_free_devices(struct jaylink_device
**devices
,
200 jaylink_unref_device(devices
[i
]);
209 * Get the host interface of a device.
211 * @param[in] dev Device instance.
212 * @param[out] interface Host interface of the device on success, and undefined
215 * @retval JAYLINK_OK Success.
216 * @retval JAYLINK_ERR_ARG Invalid arguments.
218 JAYLINK_API
int jaylink_device_get_host_interface(
219 const struct jaylink_device
*dev
,
220 enum jaylink_host_interface
*interface
)
222 if (!dev
|| !interface
)
223 return JAYLINK_ERR_ARG
;
225 *interface
= dev
->interface
;
231 * Get the serial number of a device.
233 * @note This serial number is for enumeration purpose only and might differ
234 * from the real serial number of the device.
236 * @param[in] dev Device instance.
237 * @param[out] serial_number Serial number of the device on success, and
238 * undefined on failure.
240 * @retval JAYLINK_OK Success.
241 * @retval JAYLINK_ERR_ARG Invalid arguments.
242 * @retval JAYLINK_ERR_NOT_AVAILABLE Serial number is not available.
244 JAYLINK_API
int jaylink_device_get_serial_number(
245 const struct jaylink_device
*dev
, uint32_t *serial_number
)
247 if (!dev
|| !serial_number
)
248 return JAYLINK_ERR_ARG
;
250 if (!dev
->valid_serial_number
)
251 return JAYLINK_ERR_NOT_AVAILABLE
;
253 *serial_number
= dev
->serial_number
;
259 * Get the USB address of a device.
261 * @note Identification of a device with the USB address is deprecated and the
262 * serial number should be used instead.
264 * @param[in] dev Device instance.
265 * @param[out] address USB address of the device on success, and undefined on
268 * @retval JAYLINK_OK Success.
269 * @retval JAYLINK_ERR_ARG Invalid arguments.
270 * @retval JAYLINK_ERR_NOT_SUPPORTED Operation not supported.
272 * @see jaylink_device_get_serial_number() to get the serial number of a device.
274 JAYLINK_API
int jaylink_device_get_usb_address(const struct jaylink_device
*dev
,
275 enum jaylink_usb_address
*address
)
277 if (!dev
|| !address
)
278 return JAYLINK_ERR_ARG
;
280 if (dev
->interface
!= JAYLINK_HIF_USB
)
281 return JAYLINK_ERR_NOT_SUPPORTED
;
283 *address
= dev
->usb_address
;
289 * Increment the reference count of a device.
291 * @param[in,out] dev Device instance.
293 * @return The given device instance on success, or NULL for invalid device
296 JAYLINK_API
struct jaylink_device
*jaylink_ref_device(
297 struct jaylink_device
*dev
)
308 * Decrement the reference count of a device.
310 * @param[in,out] dev Device instance.
312 JAYLINK_API
void jaylink_unref_device(struct jaylink_device
*dev
)
314 struct jaylink_context
*ctx
;
321 if (dev
->refcnt
== 0) {
324 log_dbg(ctx
, "Device destroyed (bus:address = %03u:%03u).",
325 libusb_get_bus_number(dev
->usb_dev
),
326 libusb_get_device_address(dev
->usb_dev
));
328 ctx
->devs
= list_remove(dev
->ctx
->devs
, dev
);
331 libusb_unref_device(dev
->usb_dev
);
340 * @param[in,out] dev Device instance.
341 * @param[out] devh Newly allocated handle for the opened device on success,
342 * and undefined on failure.
344 * @retval JAYLINK_OK Success.
345 * @retval JAYLINK_ERR_ARG Invalid arguments.
346 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
347 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
348 * @retval JAYLINK_ERR Other error conditions.
350 JAYLINK_API
int jaylink_open(struct jaylink_device
*dev
,
351 struct jaylink_device_handle
**devh
)
354 struct jaylink_device_handle
*handle
;
357 return JAYLINK_ERR_ARG
;
359 handle
= allocate_device_handle(dev
);
362 log_err(dev
->ctx
, "Device handle malloc failed.");
363 return JAYLINK_ERR_MALLOC
;
366 ret
= transport_open(handle
);
369 free_device_handle(handle
);
381 * @param[in,out] devh Device instance.
383 JAYLINK_API
void jaylink_close(struct jaylink_device_handle
*devh
)
388 transport_close(devh
);
389 free_device_handle(devh
);
393 * Get the device instance from a device handle.
395 * @note The reference count of the device instance is not increased.
397 * @param[in] devh Device handle.
399 * @return The device instance on success, or NULL on invalid argument.
401 JAYLINK_API
struct jaylink_device
*jaylink_get_device(
402 struct jaylink_device_handle
*devh
)
411 * Retrieve the firmware version of a device.
413 * @param[in,out] devh Device handle.
414 * @param[out] version Newly allocated string which contains the firmware
415 * version on success, and undefined if @p length is zero
416 * or on failure. The string is null-terminated and must be
417 * free'd by the caller.
418 * @param[out] length Length of the firmware version string including trailing
419 * null-terminator on success, and undefined on failure.
420 * Zero if no firmware version string is available.
422 * @retval JAYLINK_OK Success.
423 * @retval JAYLINK_ERR_ARG Invalid arguments.
424 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
425 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
426 * @retval JAYLINK_ERR Other error conditions.
428 JAYLINK_API
int jaylink_get_firmware_version(struct jaylink_device_handle
*devh
,
429 char **version
, size_t *length
)
432 struct jaylink_context
*ctx
;
437 if (!devh
|| !version
|| !length
)
438 return JAYLINK_ERR_ARG
;
440 ctx
= devh
->dev
->ctx
;
441 ret
= transport_start_write_read(devh
, 1, 2, true);
443 if (ret
!= JAYLINK_OK
) {
444 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
448 buf
[0] = CMD_GET_VERSION
;
450 ret
= transport_write(devh
, buf
, 1);
452 if (ret
!= JAYLINK_OK
) {
453 log_err(ctx
, "transport_write() failed: %i.", ret
);
457 ret
= transport_read(devh
, buf
, 2);
459 if (ret
!= JAYLINK_OK
) {
460 log_err(ctx
, "transport_read() failed: %i.", ret
);
464 dummy
= buffer_get_u16(buf
, 0);
470 ret
= transport_start_read(devh
, dummy
);
472 if (ret
!= JAYLINK_OK
) {
473 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
480 log_err(ctx
, "Firmware version string malloc failed.");
481 return JAYLINK_ERR_MALLOC
;
484 ret
= transport_read(devh
, (uint8_t *)tmp
, dummy
);
486 if (ret
!= JAYLINK_OK
) {
487 log_err(ctx
, "transport_read() failed: %i.", ret
);
492 /* Last byte is reserved for null-terminator. */
500 * Retrieve the hardware information of a device.
502 * @note This function must only be used if the device has the
503 * #JAYLINK_DEV_CAP_GET_HW_INFO capability.
505 * @param[in,out] devh Device handle.
506 * @param[in] mask A bit field where each set bit represents hardware
507 * information to request. See #jaylink_hardware_info for a
508 * description of the hardware information and their bit
510 * @param[out] info Array to store the hardware information on success. Its
511 * content is undefined on failure. The array must be large
512 * enough to contain at least as many elements as bits set in
515 * @retval JAYLINK_OK Success.
516 * @retval JAYLINK_ERR_ARG Invalid arguments.
517 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
518 * @retval JAYLINK_ERR Other error conditions.
520 JAYLINK_API
int jaylink_get_hardware_info(struct jaylink_device_handle
*devh
,
521 uint32_t mask
, uint32_t *info
)
524 struct jaylink_context
*ctx
;
530 if (!devh
|| !mask
|| !info
)
531 return JAYLINK_ERR_ARG
;
533 ctx
= devh
->dev
->ctx
;
536 for (i
= 0; i
< 32; i
++) {
541 length
= num
* sizeof(uint32_t);
543 ret
= transport_start_write_read(devh
, 5, length
, true);
545 if (ret
!= JAYLINK_OK
) {
546 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
550 buf
[0] = CMD_GET_HW_INFO
;
551 buffer_set_u32(buf
, mask
, 1);
553 ret
= transport_write(devh
, buf
, 5);
555 if (ret
!= JAYLINK_OK
) {
556 log_err(ctx
, "transport_write() failed: %i.", ret
);
560 ret
= transport_read(devh
, (uint8_t *)info
, length
);
562 if (ret
!= JAYLINK_OK
) {
563 log_err(ctx
, "transport_read() failed: %i.", ret
);
567 for (i
= 0; i
< num
; i
++)
568 info
[i
] = buffer_get_u32((uint8_t *)info
, i
* sizeof(uint32_t));
574 * Retrieve the hardware version of a device.
576 * @note This function must only be used if the device has the
577 * #JAYLINK_DEV_CAP_GET_HW_VERSION capability.
579 * @param[in,out] devh Device handle.
580 * @param[out] version Hardware version on success, and undefined on failure.
582 * @retval JAYLINK_OK Success.
583 * @retval JAYLINK_ERR_ARG Invalid arguments.
584 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
585 * @retval JAYLINK_ERR Other error conditions.
587 * @see jaylink_get_caps() to retrieve device capabilities.
589 JAYLINK_API
int jaylink_get_hardware_version(struct jaylink_device_handle
*devh
,
590 struct jaylink_hardware_version
*version
)
593 struct jaylink_context
*ctx
;
597 if (!devh
|| !version
)
598 return JAYLINK_ERR_ARG
;
600 ctx
= devh
->dev
->ctx
;
601 ret
= transport_start_write_read(devh
, 1, 4, true);
603 if (ret
!= JAYLINK_OK
) {
604 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
608 buf
[0] = CMD_GET_HW_VERSION
;
610 ret
= transport_write(devh
, buf
, 1);
612 if (ret
!= JAYLINK_OK
) {
613 log_err(ctx
, "transport_write() failed: %i.", ret
);
617 ret
= transport_read(devh
, buf
, 4);
619 if (ret
!= JAYLINK_OK
) {
620 log_err(ctx
, "transport_read() failed: %i.", ret
);
624 tmp
= buffer_get_u32(buf
, 0);
626 version
->type
= (tmp
/ 1000000) % 100;
627 version
->major
= (tmp
/ 10000) % 100;
628 version
->minor
= (tmp
/ 100) % 100;
629 version
->revision
= tmp
% 100;
635 * Retrieve the hardware status of a device.
637 * @param[in,out] devh Device handle.
638 * @param[out] status Hardware status on success, and undefined on failure.
640 * @retval JAYLINK_OK Success.
641 * @retval JAYLINK_ERR_ARG Invalid arguments.
642 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
643 * @retval JAYLINK_ERR Other error conditions.
645 JAYLINK_API
int jaylink_get_hardware_status(struct jaylink_device_handle
*devh
,
646 struct jaylink_hardware_status
*status
)
649 struct jaylink_context
*ctx
;
652 if (!devh
|| !status
)
653 return JAYLINK_ERR_ARG
;
655 ctx
= devh
->dev
->ctx
;
656 ret
= transport_start_write_read(devh
, 1, 8, true);
658 if (ret
!= JAYLINK_OK
) {
659 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
663 buf
[0] = CMD_GET_HW_STATUS
;
665 ret
= transport_write(devh
, buf
, 1);
667 if (ret
!= JAYLINK_OK
) {
668 log_err(ctx
, "transport_write() failed: %i.", ret
);
672 ret
= transport_read(devh
, buf
, 8);
674 if (ret
!= JAYLINK_OK
) {
675 log_err(ctx
, "transport_read() failed: %i.", ret
);
679 status
->target_voltage
= buffer_get_u16(buf
, 0);
680 status
->tck
= buf
[2];
681 status
->tdi
= buf
[3];
682 status
->tdo
= buf
[4];
683 status
->tms
= buf
[5];
684 status
->tres
= buf
[6];
685 status
->trst
= buf
[7];
691 * Retrieve the capabilities of a device.
693 * The capabilities are stored in a 32-bit bit array consisting of
694 * #JAYLINK_DEV_CAPS_SIZE bytes where each individual bit represents a
695 * capability. The first bit of this array is the least significant bit of the
696 * first byte and the following bits are sequentially numbered in order of
697 * increasing bit significance and byte index. A set bit indicates a supported
698 * capability. See #jaylink_device_capability for a description of the
699 * capabilities and their bit positions.
701 * @param[in,out] devh Device handle.
702 * @param[out] caps Buffer to store capabilities on success. Its content is
703 * undefined on failure. The size of the buffer must be large
704 * enough to contain at least #JAYLINK_DEV_CAPS_SIZE bytes.
706 * @retval JAYLINK_OK Success.
707 * @retval JAYLINK_ERR_ARG Invalid arguments.
708 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
709 * @retval JAYLINK_ERR Other error conditions.
711 * @see jaylink_get_extended_caps() to retrieve extended device capabilities.
713 JAYLINK_API
int jaylink_get_caps(struct jaylink_device_handle
*devh
,
717 struct jaylink_context
*ctx
;
721 return JAYLINK_ERR_ARG
;
723 ctx
= devh
->dev
->ctx
;
724 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_CAPS_SIZE
, true);
726 if (ret
!= JAYLINK_OK
) {
727 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
731 buf
[0] = CMD_GET_CAPS
;
733 ret
= transport_write(devh
, buf
, 1);
735 if (ret
!= JAYLINK_OK
) {
736 log_err(ctx
, "transport_write() failed: %i.", ret
);
740 ret
= transport_read(devh
, caps
, JAYLINK_DEV_CAPS_SIZE
);
742 if (ret
!= JAYLINK_OK
) {
743 log_err(ctx
, "transport_read() failed: %i.", ret
);
751 * Retrieve the extended capabilities of a device.
753 * The extended capabilities are stored in a 256-bit bit array consisting of
754 * #JAYLINK_DEV_EXT_CAPS_SIZE bytes. See jaylink_get_caps() for a further
755 * description of how the capabilities are represented in this bit array. For a
756 * description of the capabilities and their bit positions, see
757 * #jaylink_device_capability.
759 * @note This function must only be used if the device has the
760 * #JAYLINK_DEV_CAP_GET_EXT_CAPS capability.
762 * @param[in,out] devh Device handle.
763 * @param[out] caps Buffer to store capabilities on success. Its content is
764 * undefined on failure. The size of the buffer must be large
765 * enough to contain at least #JAYLINK_DEV_EXT_CAPS_SIZE bytes.
767 * @retval JAYLINK_OK Success.
768 * @retval JAYLINK_ERR_ARG Invalid arguments.
769 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
770 * @retval JAYLINK_ERR Other error conditions.
772 * @see jaylink_get_caps() to retrieve device capabilities.
774 JAYLINK_API
int jaylink_get_extended_caps(struct jaylink_device_handle
*devh
,
778 struct jaylink_context
*ctx
;
782 return JAYLINK_ERR_ARG
;
784 ctx
= devh
->dev
->ctx
;
785 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_EXT_CAPS_SIZE
,
788 if (ret
!= JAYLINK_OK
) {
789 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
793 buf
[0] = CMD_GET_EXT_CAPS
;
795 ret
= transport_write(devh
, buf
, 1);
797 if (ret
!= JAYLINK_OK
) {
798 log_err(ctx
, "transport_write() failed: %i.", ret
);
802 ret
= transport_read(devh
, caps
, JAYLINK_DEV_EXT_CAPS_SIZE
);
804 if (ret
!= JAYLINK_OK
) {
805 log_err(ctx
, "transport_read() failed: %i.", ret
);
813 * Retrieve the size of free memory of a device.
815 * @note This function must only be used if the device has the
816 * #JAYLINK_DEV_CAP_GET_FREE_MEMORY capability.
818 * @param[in,out] devh Device handle.
819 * @param[out] size Size of free memory in bytes on success, and undefined on
822 * @retval JAYLINK_OK Success.
823 * @retval JAYLINK_ERR_ARG Invalid arguments.
824 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
825 * @retval JAYLINK_ERR Other error conditions.
827 * @see jaylink_get_caps() to retrieve device capabilities.
829 JAYLINK_API
int jaylink_get_free_memory(struct jaylink_device_handle
*devh
,
833 struct jaylink_context
*ctx
;
837 return JAYLINK_ERR_ARG
;
839 ctx
= devh
->dev
->ctx
;
840 ret
= transport_start_write_read(devh
, 1, 4, true);
842 if (ret
!= JAYLINK_OK
) {
843 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
847 buf
[0] = CMD_GET_FREE_MEMORY
;
849 ret
= transport_write(devh
, buf
, 1);
851 if (ret
!= JAYLINK_OK
) {
852 log_err(ctx
, "transport_write() failed: %i.", ret
);
856 ret
= transport_read(devh
, buf
, 4);
858 if (ret
!= JAYLINK_OK
) {
859 log_err(ctx
, "transport_read() failed: %i.", ret
);
863 *size
= buffer_get_u32(buf
, 0);
869 * Read the raw configuration data of a device.
871 * @note This function must only be used if the device has the
872 * #JAYLINK_DEV_CAP_READ_CONFIG capability.
874 * @param[in,out] devh Device handle.
875 * @param[out] config Buffer to store configuration data on success. Its
876 * content is undefined on failure. The size of the buffer
877 * must be large enough to contain at least
878 * #JAYLINK_DEV_CONFIG_SIZE bytes.
880 * @retval JAYLINK_OK Success.
881 * @retval JAYLINK_ERR_ARG Invalid arguments.
882 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
883 * @retval JAYLINK_ERR Other error conditions.
885 JAYLINK_API
int jaylink_read_raw_config(struct jaylink_device_handle
*devh
,
889 struct jaylink_context
*ctx
;
892 if (!devh
|| !config
)
893 return JAYLINK_ERR_ARG
;
895 ctx
= devh
->dev
->ctx
;
896 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_CONFIG_SIZE
,
899 if (ret
!= JAYLINK_OK
) {
900 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
904 buf
[0] = CMD_READ_CONFIG
;
906 ret
= transport_write(devh
, buf
, 1);
908 if (ret
!= JAYLINK_OK
) {
909 log_err(ctx
, "transport_write() failed: %i.", ret
);
913 ret
= transport_read(devh
, config
, JAYLINK_DEV_CONFIG_SIZE
);
915 if (ret
!= JAYLINK_OK
) {
916 log_err(ctx
, "transport_read() failed: %i.", ret
);
924 * Write the raw configuration data of a device.
926 * @note This function must only be used if the device has the
927 * #JAYLINK_DEV_CAP_WRITE_CONFIG capability.
929 * @param[in,out] devh Device handle.
930 * @param[in] config Buffer to write configuration data from. The size of the
931 * configuration data is expected to be
932 * #JAYLINK_DEV_CONFIG_SIZE bytes.
934 * @retval JAYLINK_OK Success.
935 * @retval JAYLINK_ERR_ARG Invalid arguments.
936 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
937 * @retval JAYLINK_ERR Other error conditions.
939 JAYLINK_API
int jaylink_write_raw_config(struct jaylink_device_handle
*devh
,
940 const uint8_t *config
)
943 struct jaylink_context
*ctx
;
946 if (!devh
|| !config
)
947 return JAYLINK_ERR_ARG
;
949 ctx
= devh
->dev
->ctx
;
950 ret
= transport_start_write(devh
, 1 + JAYLINK_DEV_CONFIG_SIZE
, true);
952 if (ret
!= JAYLINK_OK
) {
953 log_err(ctx
, "transport_start_write() failed: %i.", ret
);
957 buf
[0] = CMD_WRITE_CONFIG
;
959 ret
= transport_write(devh
, buf
, 1);
961 if (ret
!= JAYLINK_OK
) {
962 log_err(ctx
, "transport_write() failed: %i.", ret
);
966 ret
= transport_write(devh
, config
, JAYLINK_DEV_CONFIG_SIZE
);
968 if (ret
!= JAYLINK_OK
) {
969 log_err(ctx
, "transport_write() failed: %i.", ret
);
976 static void parse_conntable(struct jaylink_connection
*conns
,
977 const uint8_t *buffer
, uint16_t num
, uint16_t entry_size
)
984 for (i
= 0; i
< num
; i
++) {
985 conns
[i
].pid
= buffer_get_u32(buffer
, offset
);
986 conns
[i
].hid
= buffer_get_u32(buffer
, offset
+ 4);
987 conns
[i
].iid
= buffer
[offset
+ 8];
988 conns
[i
].cid
= buffer
[offset
+ 9];
989 conns
[i
].handle
= buffer_get_u16(buffer
, offset
+ 10);
990 conns
[i
].timestamp
= buffer_get_u32(buffer
, offset
+ 12);
991 offset
= offset
+ entry_size
;
996 * Register a connection on a device.
998 * A connection can be registered by using 0 as handle. Additional information
999 * about the connection can be attached whereby the timestamp is a read-only
1000 * value and therefore ignored for registration. On success, a new handle
1001 * greater than 0 is obtained from the device.
1003 * However, if an obtained handle does not appear in the list of device
1004 * connections, the connection was not registered because the maximum number of
1005 * connections on the device is reached.
1007 * @note This function must only be used if the device has the
1008 * #JAYLINK_DEV_CAP_REGISTER capability.
1010 * @param[in,out] devh Device handle.
1011 * @param[in,out] connection Connection to register on the device.
1012 * @param[out] connections Array to store device connections on success.
1013 * Its content is undefined on failure. The array must
1014 * be large enough to contain at least
1015 * #JAYLINK_MAX_CONNECTIONS elements.
1016 * @param[out] count Number of device connections on success, and undefined on
1018 * @param[out] info Buffer to store additional information on success, or NULL.
1019 * The content of the buffer is undefined on failure.
1020 * @param[out] info_size Size of the additional information in bytes on success,
1021 * and undefined on failure. Can be NULL.
1023 * @retval JAYLINK_OK Success.
1024 * @retval JAYLINK_ERR_ARG Invalid arguments.
1025 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1026 * @retval JAYLINK_ERR_PROTO Protocol violation.
1027 * @retval JAYLINK_ERR Other error conditions.
1029 * @see jaylink_unregister() to unregister a connection from a device.
1031 JAYLINK_API
int jaylink_register(struct jaylink_device_handle
*devh
,
1032 struct jaylink_connection
*connection
,
1033 struct jaylink_connection
*connections
, size_t *count
,
1034 uint8_t *info
, uint16_t *info_size
)
1037 struct jaylink_context
*ctx
;
1038 uint8_t buf
[REG_MAX_SIZE
];
1041 uint16_t entry_size
;
1043 uint32_t table_size
;
1044 uint16_t addinfo_size
;
1046 if (!devh
|| !connection
|| !connections
|| !count
)
1047 return JAYLINK_ERR_ARG
;
1049 ctx
= devh
->dev
->ctx
;
1050 ret
= transport_start_write_read(devh
, 14, REG_MIN_SIZE
, true);
1052 if (ret
!= JAYLINK_OK
) {
1053 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
1057 buf
[0] = CMD_REGISTER
;
1058 buf
[1] = REG_CMD_REGISTER
;
1059 buffer_set_u32(buf
, connection
->pid
, 2);
1060 buffer_set_u32(buf
, connection
->hid
, 6);
1061 buf
[10] = connection
->iid
;
1062 buf
[11] = connection
->cid
;
1063 buffer_set_u16(buf
, connection
->handle
, 12);
1065 ret
= transport_write(devh
, buf
, 14);
1067 if (ret
!= JAYLINK_OK
) {
1068 log_err(ctx
, "transport_write() failed: %i.", ret
);
1072 ret
= transport_read(devh
, buf
, REG_MIN_SIZE
);
1074 if (ret
!= JAYLINK_OK
) {
1075 log_err(ctx
, "transport_read() failed: %i.", ret
);
1079 handle
= buffer_get_u16(buf
, 0);
1080 num
= buffer_get_u16(buf
, 2);
1081 entry_size
= buffer_get_u16(buf
, 4);
1082 addinfo_size
= buffer_get_u16(buf
, 6);
1084 if (num
> JAYLINK_MAX_CONNECTIONS
) {
1085 log_err(ctx
, "Maximum number of device connections exceeded: "
1087 return JAYLINK_ERR_PROTO
;
1090 if (entry_size
!= REG_CONN_INFO_SIZE
) {
1091 log_err(ctx
, "Invalid connection entry size: %u bytes.",
1093 return JAYLINK_ERR_PROTO
;
1096 table_size
= num
* entry_size
;
1097 size
= REG_HEADER_SIZE
+ table_size
+ addinfo_size
;
1099 if (size
> REG_MAX_SIZE
) {
1100 log_err(ctx
, "Maximum registration information size exceeded: "
1102 return JAYLINK_ERR_PROTO
;
1105 if (size
> REG_MIN_SIZE
) {
1106 ret
= transport_start_read(devh
, size
- REG_MIN_SIZE
);
1108 if (ret
!= JAYLINK_OK
) {
1109 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
1113 ret
= transport_read(devh
, buf
+ REG_MIN_SIZE
,
1114 size
- REG_MIN_SIZE
);
1116 if (ret
!= JAYLINK_OK
) {
1117 log_err(ctx
, "transport_read() failed: %i.", ret
);
1123 log_err(ctx
, "Obtained invalid connection handle.");
1124 return JAYLINK_ERR_PROTO
;
1127 connection
->handle
= handle
;
1128 parse_conntable(connections
, buf
+ REG_HEADER_SIZE
, num
, entry_size
);
1131 memcpy(info
, buf
+ REG_HEADER_SIZE
+ table_size
, addinfo_size
);
1134 *info_size
= addinfo_size
;
1142 * Unregister a connection from a device.
1144 * @note This function must only be used if the device has the
1145 * #JAYLINK_DEV_CAP_REGISTER capability.
1147 * @param[in,out] devh Device handle.
1148 * @param[in,out] connection Connection to unregister from the device.
1149 * @param[out] connections Array to store device connections on success.
1150 * Its content is undefined on failure. The array must
1151 * be large enough to contain at least
1152 * #JAYLINK_MAX_CONNECTIONS elements.
1153 * @param[out] count Number of device connections on success, and undefined on
1155 * @param[out] info Buffer to store additional information on success, or NULL.
1156 * The content of the buffer is undefined on failure.
1157 * @param[out] info_size Size of the additional information in bytes on success,
1158 * and undefined on failure. Can be NULL.
1160 * @retval JAYLINK_OK Success.
1161 * @retval JAYLINK_ERR_ARG Invalid arguments.
1162 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1163 * @retval JAYLINK_ERR_PROTO Protocol violation.
1164 * @retval JAYLINK_ERR Other error conditions.
1166 JAYLINK_API
int jaylink_unregister(struct jaylink_device_handle
*devh
,
1167 const struct jaylink_connection
*connection
,
1168 struct jaylink_connection
*connections
, size_t *count
,
1169 uint8_t *info
, uint16_t *info_size
)
1172 struct jaylink_context
*ctx
;
1173 uint8_t buf
[REG_MAX_SIZE
];
1175 uint16_t entry_size
;
1177 uint32_t table_size
;
1178 uint16_t addinfo_size
;
1180 if (!devh
|| !connection
|| !connections
|| !count
)
1181 return JAYLINK_ERR_ARG
;
1183 ctx
= devh
->dev
->ctx
;
1184 ret
= transport_start_write_read(devh
, 14, REG_MIN_SIZE
, true);
1186 if (ret
!= JAYLINK_OK
) {
1187 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
1191 buf
[0] = CMD_REGISTER
;
1192 buf
[1] = REG_CMD_UNREGISTER
;
1193 buffer_set_u32(buf
, connection
->pid
, 2);
1194 buffer_set_u32(buf
, connection
->hid
, 6);
1195 buf
[10] = connection
->iid
;
1196 buf
[11] = connection
->cid
;
1197 buffer_set_u16(buf
, connection
->handle
, 12);
1199 ret
= transport_write(devh
, buf
, 14);
1201 if (ret
!= JAYLINK_OK
) {
1202 log_err(ctx
, "transport_write() failed: %i.", ret
);
1206 ret
= transport_read(devh
, buf
, REG_MIN_SIZE
);
1208 if (ret
!= JAYLINK_OK
) {
1209 log_err(ctx
, "transport_read() failed: %i.", ret
);
1213 num
= buffer_get_u16(buf
, 2);
1214 entry_size
= buffer_get_u16(buf
, 4);
1215 addinfo_size
= buffer_get_u16(buf
, 6);
1217 if (num
> JAYLINK_MAX_CONNECTIONS
) {
1218 log_err(ctx
, "Maximum number of device connections exceeded: "
1220 return JAYLINK_ERR_PROTO
;
1223 if (entry_size
!= REG_CONN_INFO_SIZE
) {
1224 log_err(ctx
, "Invalid connection entry size: %u bytes.",
1226 return JAYLINK_ERR_PROTO
;
1229 table_size
= num
* entry_size
;
1230 size
= REG_HEADER_SIZE
+ table_size
+ addinfo_size
;
1232 if (size
> REG_MAX_SIZE
) {
1233 log_err(ctx
, "Maximum registration information size exceeded: "
1235 return JAYLINK_ERR_PROTO
;
1238 if (size
> REG_MIN_SIZE
) {
1239 ret
= transport_start_read(devh
, size
- REG_MIN_SIZE
);
1241 if (ret
!= JAYLINK_OK
) {
1242 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
1246 ret
= transport_read(devh
, buf
+ REG_MIN_SIZE
,
1247 size
- REG_MIN_SIZE
);
1249 if (ret
!= JAYLINK_OK
) {
1250 log_err(ctx
, "transport_read() failed: %i.", ret
);
1255 parse_conntable(connections
, buf
+ REG_HEADER_SIZE
, num
, entry_size
);
1258 memcpy(info
, buf
+ REG_HEADER_SIZE
+ table_size
, addinfo_size
);
1261 *info_size
= addinfo_size
;