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/>.
27 #include <sys/socket.h>
28 #include <arpa/inet.h>
32 #include "libjaylink.h"
33 #include "libjaylink-internal.h"
38 * Device enumeration and handling.
42 #define CMD_GET_VERSION 0x01
43 #define CMD_GET_HW_STATUS 0x07
44 #define CMD_REGISTER 0x09
45 #define CMD_GET_HW_INFO 0xc1
46 #define CMD_GET_COUNTERS 0xc2
47 #define CMD_GET_FREE_MEMORY 0xd4
48 #define CMD_GET_CAPS 0xe8
49 #define CMD_GET_EXT_CAPS 0xed
50 #define CMD_GET_HW_VERSION 0xf0
51 #define CMD_READ_CONFIG 0xf2
52 #define CMD_WRITE_CONFIG 0xf3
54 #define REG_CMD_REGISTER 0x64
55 #define REG_CMD_UNREGISTER 0x65
57 /** Size of the registration header in bytes. */
58 #define REG_HEADER_SIZE 8
59 /** Minimum registration information size in bytes. */
60 #define REG_MIN_SIZE 0x4c
61 /** Maximum registration information size in bytes. */
62 #define REG_MAX_SIZE 0x200
63 /** Size of a connection entry in bytes. */
64 #define REG_CONN_INFO_SIZE 16
68 JAYLINK_PRIV
struct jaylink_device
*device_allocate(
69 struct jaylink_context
*ctx
)
71 struct jaylink_device
*dev
;
74 dev
= malloc(sizeof(struct jaylink_device
));
79 list
= list_prepend(ctx
->devs
, dev
);
94 static struct jaylink_device
**allocate_device_list(size_t length
)
96 struct jaylink_device
**list
;
98 list
= malloc(sizeof(struct jaylink_device
*) * (length
+ 1));
109 * Get available devices.
111 * @param[in,out] ctx libjaylink context.
112 * @param[out] devs Newly allocated array which contains instances of available
113 * devices on success, and undefined on failure. The array is
114 * NULL-terminated and must be free'd by the caller with
115 * jaylink_free_devices().
116 * @param[out] count Number of available devices on success, and undefined on
117 * failure. Can be NULL.
119 * @retval JAYLINK_OK Success.
120 * @retval JAYLINK_ERR_ARG Invalid arguments.
121 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
122 * @retval JAYLINK_ERR Other error conditions.
124 * @see jaylink_discovery_scan()
128 JAYLINK_API
int jaylink_get_devices(struct jaylink_context
*ctx
,
129 struct jaylink_device
***devs
, size_t *count
)
133 struct jaylink_device
**tmp
;
134 struct jaylink_device
*dev
;
138 return JAYLINK_ERR_ARG
;
140 num
= list_length(ctx
->discovered_devs
);
141 tmp
= allocate_device_list(num
);
144 log_err(ctx
, "Failed to allocate device list.");
145 return JAYLINK_ERR_MALLOC
;
148 item
= ctx
->discovered_devs
;
150 for (i
= 0; i
< num
; i
++) {
151 dev
= (struct jaylink_device
*)item
->data
;
152 tmp
[i
] = jaylink_ref_device(dev
);
167 * @param[in,out] devs Array of device instances. Must be NULL-terminated.
168 * @param[in] unref Determines whether the device instances should be
171 * @see jaylink_get_devices()
175 JAYLINK_API
void jaylink_free_devices(struct jaylink_device
**devs
, bool unref
)
183 for (i
= 0; devs
[i
]; i
++)
184 jaylink_unref_device(devs
[i
]);
191 * Get the host interface of a device.
193 * @param[in] dev Device instance.
194 * @param[out] iface Host interface of the device on success, and undefined on
197 * @retval JAYLINK_OK Success.
198 * @retval JAYLINK_ERR_ARG Invalid arguments.
202 JAYLINK_API
int jaylink_device_get_host_interface(
203 const struct jaylink_device
*dev
,
204 enum jaylink_host_interface
*iface
)
207 return JAYLINK_ERR_ARG
;
209 *iface
= dev
->interface
;
215 * Get the serial number of a device.
217 * @note This serial number is for enumeration purpose only and might differ
218 * from the real serial number of the device.
220 * @param[in] dev Device instance.
221 * @param[out] serial_number Serial number of the device on success, and
222 * undefined on failure.
224 * @retval JAYLINK_OK Success.
225 * @retval JAYLINK_ERR_ARG Invalid arguments.
226 * @retval JAYLINK_ERR_NOT_AVAILABLE Serial number is not available.
230 JAYLINK_API
int jaylink_device_get_serial_number(
231 const struct jaylink_device
*dev
, uint32_t *serial_number
)
233 if (!dev
|| !serial_number
)
234 return JAYLINK_ERR_ARG
;
236 if (!dev
->valid_serial_number
)
237 return JAYLINK_ERR_NOT_AVAILABLE
;
239 *serial_number
= dev
->serial_number
;
245 * Get the USB address of a device.
247 * @note Identification of a device with the USB address is deprecated and the
248 * serial number should be used instead.
250 * @param[in] dev Device instance.
251 * @param[out] address USB address of the device on success, and undefined on
254 * @retval JAYLINK_OK Success.
255 * @retval JAYLINK_ERR_ARG Invalid arguments.
256 * @retval JAYLINK_ERR_NOT_SUPPORTED Operation not supported.
258 * @see jaylink_device_get_serial_number()
262 JAYLINK_API
int jaylink_device_get_usb_address(
263 const struct jaylink_device
*dev
,
264 enum jaylink_usb_address
*address
)
266 if (!dev
|| !address
)
267 return JAYLINK_ERR_ARG
;
269 if (dev
->interface
!= JAYLINK_HIF_USB
)
270 return JAYLINK_ERR_NOT_SUPPORTED
;
272 *address
= dev
->usb_address
;
278 * Get the IPv4 address string of a device.
280 * @param[in] dev Device instance.
281 * @param[out] address IPv4 address string in quad-dotted decimal format of the
282 * device on success and undefined on failure.
284 * @retval JAYLINK_OK Success.
285 * @retval JAYLINK_ERR_ARG Invalid arguments.
286 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
287 * #JAYLINK_HIF_TCP only.
291 JAYLINK_API
int jaylink_device_get_ipv4_address(
292 const struct jaylink_device
*dev
, char *address
)
294 if (!dev
|| !address
)
295 return JAYLINK_ERR_ARG
;
297 if (dev
->interface
!= JAYLINK_HIF_TCP
)
298 return JAYLINK_ERR_NOT_SUPPORTED
;
300 memcpy(address
, dev
->ipv4_address
, sizeof(dev
->ipv4_address
));
306 * Get the MAC address of a device.
308 * @param[in] dev Device instance.
309 * @param[out] address MAC address of the device on success and undefined on
310 * failure. The length of the MAC address is
311 * #JAYLINK_MAC_ADDRESS_LENGTH bytes.
313 * @retval JAYLINK_OK Success.
314 * @retval JAYLINK_ERR_ARG Invalid arguments.
315 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
316 * #JAYLINK_HIF_TCP only.
317 * @retval JAYLINK_ERR_NOT_AVAILABLE MAC address is not available.
321 JAYLINK_API
int jaylink_device_get_mac_address(
322 const struct jaylink_device
*dev
, uint8_t *address
)
324 if (!dev
|| !address
)
325 return JAYLINK_ERR_ARG
;
327 if (dev
->interface
!= JAYLINK_HIF_TCP
)
328 return JAYLINK_ERR_NOT_SUPPORTED
;
330 if (!dev
->has_mac_address
)
331 return JAYLINK_ERR_NOT_AVAILABLE
;
333 memcpy(address
, dev
->mac_address
, sizeof(dev
->mac_address
));
339 * Get the hardware version of a device.
341 * @note The hardware type can not be obtained by this function, use
342 * jaylink_get_hardware_version() instead.
344 * @param[in] dev Device instance.
345 * @param[out] version Hardware version of the device on success and undefined
348 * @retval JAYLINK_OK Success.
349 * @retval JAYLINK_ERR_ARG Invalid arguments.
350 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
351 * #JAYLINK_HIF_TCP only.
352 * @retval JAYLINK_ERR_NOT_AVAILABLE Hardware version is not available.
356 JAYLINK_API
int jaylink_device_get_hardware_version(
357 const struct jaylink_device
*dev
,
358 struct jaylink_hardware_version
*version
)
360 if (!dev
|| !version
)
361 return JAYLINK_ERR_ARG
;
363 if (dev
->interface
!= JAYLINK_HIF_TCP
)
364 return JAYLINK_ERR_NOT_SUPPORTED
;
366 if (!dev
->has_hw_version
)
367 return JAYLINK_ERR_NOT_AVAILABLE
;
369 *version
= dev
->hw_version
;
375 * Get the product name of a device.
377 * @param[in] dev Device instance.
378 * @param[out] name Product name of the device on success and undefined on
379 * failure. The maximum length of the product name is
380 * #JAYLINK_PRODUCT_NAME_MAX_LENGTH bytes.
382 * @retval JAYLINK_OK Success.
383 * @retval JAYLINK_ERR_ARG Invalid arguments.
384 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
385 * #JAYLINK_HIF_TCP only.
386 * @retval JAYLINK_ERR_NOT_AVAILABLE Product name is not available.
390 JAYLINK_API
int jaylink_device_get_product_name(
391 const struct jaylink_device
*dev
, char *name
)
394 return JAYLINK_ERR_ARG
;
396 if (dev
->interface
!= JAYLINK_HIF_TCP
)
397 return JAYLINK_ERR_NOT_SUPPORTED
;
399 if (!dev
->has_product_name
)
400 return JAYLINK_ERR_NOT_AVAILABLE
;
402 memcpy(name
, dev
->product_name
, sizeof(dev
->product_name
));
408 * Get the nickname of a device.
410 * @param[in] dev Device instance.
411 * @param[out] nickname Nickname of the device on success and undefined on
412 * failure. The maximum length of the nickname is
413 * #JAYLINK_NICKNAME_MAX_LENGTH bytes.
415 * @retval JAYLINK_OK Success.
416 * @retval JAYLINK_ERR_ARG Invalid arguments.
417 * @retval JAYLINK_ERR_NOT_SUPPORTED Supported for devices with host interface
418 * #JAYLINK_HIF_TCP only.
419 * @retval JAYLINK_ERR_NOT_AVAILABLE Nickname is not available.
423 JAYLINK_API
int jaylink_device_get_nickname(const struct jaylink_device
*dev
,
426 if (!dev
|| !nickname
)
427 return JAYLINK_ERR_ARG
;
429 if (dev
->interface
!= JAYLINK_HIF_TCP
)
430 return JAYLINK_ERR_NOT_SUPPORTED
;
432 if (!dev
->has_nickname
)
433 return JAYLINK_ERR_NOT_AVAILABLE
;
435 memcpy(nickname
, dev
->nickname
, sizeof(dev
->nickname
));
441 * Increment the reference count of a device.
443 * @param[in,out] dev Device instance.
445 * @return The given device instance on success, or NULL on invalid argument.
449 JAYLINK_API
struct jaylink_device
*jaylink_ref_device(
450 struct jaylink_device
*dev
)
461 * Decrement the reference count of a device.
463 * @param[in,out] dev Device instance.
467 JAYLINK_API
void jaylink_unref_device(struct jaylink_device
*dev
)
469 struct jaylink_context
*ctx
;
476 if (!dev
->ref_count
) {
478 ctx
->devs
= list_remove(dev
->ctx
->devs
, dev
);
480 if (dev
->interface
== JAYLINK_HIF_USB
) {
481 log_dbg(ctx
, "Device destroyed (bus:address = "
483 libusb_get_bus_number(dev
->usb_dev
),
484 libusb_get_device_address(dev
->usb_dev
));
486 libusb_unref_device(dev
->usb_dev
);
487 } else if (dev
->interface
== JAYLINK_HIF_TCP
) {
488 log_dbg(ctx
, "Device destroyed (IPv4 address = %s).",
491 log_err(ctx
, "BUG: Invalid host interface: %u.",
499 static struct jaylink_device_handle
*allocate_device_handle(
500 struct jaylink_device
*dev
)
502 struct jaylink_device_handle
*devh
;
504 devh
= malloc(sizeof(struct jaylink_device_handle
));
509 devh
->dev
= jaylink_ref_device(dev
);
514 static void free_device_handle(struct jaylink_device_handle
*devh
)
516 jaylink_unref_device(devh
->dev
);
523 * @param[in,out] dev Device instance.
524 * @param[out] devh Newly allocated handle for the opened device on success,
525 * and undefined on failure.
527 * @retval JAYLINK_OK Success.
528 * @retval JAYLINK_ERR_ARG Invalid arguments.
529 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
530 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
531 * @retval JAYLINK_ERR_NOT_SUPPORTED Operation not supported.
532 * @retval JAYLINK_ERR_IO Input/output error.
533 * @retval JAYLINK_ERR Other error conditions.
537 JAYLINK_API
int jaylink_open(struct jaylink_device
*dev
,
538 struct jaylink_device_handle
**devh
)
541 struct jaylink_device_handle
*handle
;
544 return JAYLINK_ERR_ARG
;
546 if (dev
->interface
!= JAYLINK_HIF_USB
)
547 return JAYLINK_ERR_NOT_SUPPORTED
;
549 handle
= allocate_device_handle(dev
);
552 log_err(dev
->ctx
, "Device handle malloc failed.");
553 return JAYLINK_ERR_MALLOC
;
556 ret
= transport_open(handle
);
558 if (ret
!= JAYLINK_OK
) {
559 free_device_handle(handle
);
571 * @param[in,out] devh Device instance.
573 * @retval JAYLINK_OK Success.
574 * @retval JAYLINK_ERR_ARG Invalid arguments.
575 * @retval JAYLINK_ERR Other error conditions.
579 JAYLINK_API
int jaylink_close(struct jaylink_device_handle
*devh
)
584 return JAYLINK_ERR_ARG
;
586 ret
= transport_close(devh
);
587 free_device_handle(devh
);
593 * Get the device instance from a device handle.
595 * @note The reference count of the device instance is not increased.
597 * @param[in] devh Device handle.
599 * @return The device instance on success, or NULL on invalid argument.
603 JAYLINK_API
struct jaylink_device
*jaylink_get_device(
604 struct jaylink_device_handle
*devh
)
613 * Retrieve the firmware version of a device.
615 * @param[in,out] devh Device handle.
616 * @param[out] version Newly allocated string which contains the firmware
617 * version on success, and undefined if @p length is zero
618 * or on failure. The string is null-terminated and must be
619 * free'd by the caller.
620 * @param[out] length Length of the firmware version string including trailing
621 * null-terminator on success, and undefined on failure.
622 * Zero if no firmware version string is available.
624 * @retval JAYLINK_OK Success.
625 * @retval JAYLINK_ERR_ARG Invalid arguments.
626 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
627 * @retval JAYLINK_ERR_MALLOC Memory allocation error.
628 * @retval JAYLINK_ERR_IO Input/output error.
629 * @retval JAYLINK_ERR Other error conditions.
633 JAYLINK_API
int jaylink_get_firmware_version(
634 struct jaylink_device_handle
*devh
, char **version
,
638 struct jaylink_context
*ctx
;
643 if (!devh
|| !version
|| !length
)
644 return JAYLINK_ERR_ARG
;
646 ctx
= devh
->dev
->ctx
;
647 ret
= transport_start_write_read(devh
, 1, 2, true);
649 if (ret
!= JAYLINK_OK
) {
650 log_err(ctx
, "transport_start_write_read() failed: %s.",
651 jaylink_strerror(ret
));
655 buf
[0] = CMD_GET_VERSION
;
657 ret
= transport_write(devh
, buf
, 1);
659 if (ret
!= JAYLINK_OK
) {
660 log_err(ctx
, "transport_write() failed: %s.",
661 jaylink_strerror(ret
));
665 ret
= transport_read(devh
, buf
, 2);
667 if (ret
!= JAYLINK_OK
) {
668 log_err(ctx
, "transport_read() failed: %s.",
669 jaylink_strerror(ret
));
673 dummy
= buffer_get_u16(buf
, 0);
679 ret
= transport_start_read(devh
, dummy
);
681 if (ret
!= JAYLINK_OK
) {
682 log_err(ctx
, "transport_start_read() failed: %s.",
683 jaylink_strerror(ret
));
690 log_err(ctx
, "Firmware version string malloc failed.");
691 return JAYLINK_ERR_MALLOC
;
694 ret
= transport_read(devh
, (uint8_t *)tmp
, dummy
);
696 if (ret
!= JAYLINK_OK
) {
697 log_err(ctx
, "transport_read() failed: %s.",
698 jaylink_strerror(ret
));
703 /* Last byte is reserved for null-terminator. */
711 * Retrieve the hardware information of a device.
713 * @note This function must only be used if the device has the
714 * #JAYLINK_DEV_CAP_GET_HW_INFO capability.
716 * @param[in,out] devh Device handle.
717 * @param[in] mask A bit field where each set bit represents hardware
718 * information to request. See #jaylink_hardware_info for a
719 * description of the hardware information and their bit
721 * @param[out] info Array to store the hardware information on success. Its
722 * content is undefined on failure. The array must be large
723 * enough to contain at least as many elements as bits set in
726 * @retval JAYLINK_OK Success.
727 * @retval JAYLINK_ERR_ARG Invalid arguments.
728 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
729 * @retval JAYLINK_ERR_IO Input/output error.
730 * @retval JAYLINK_ERR Other error conditions.
734 JAYLINK_API
int jaylink_get_hardware_info(struct jaylink_device_handle
*devh
,
735 uint32_t mask
, uint32_t *info
)
738 struct jaylink_context
*ctx
;
744 if (!devh
|| !mask
|| !info
)
745 return JAYLINK_ERR_ARG
;
747 ctx
= devh
->dev
->ctx
;
750 for (i
= 0; i
< 32; i
++) {
755 length
= num
* sizeof(uint32_t);
757 ret
= transport_start_write_read(devh
, 5, length
, true);
759 if (ret
!= JAYLINK_OK
) {
760 log_err(ctx
, "transport_start_write_read() failed: %s.",
761 jaylink_strerror(ret
));
765 buf
[0] = CMD_GET_HW_INFO
;
766 buffer_set_u32(buf
, mask
, 1);
768 ret
= transport_write(devh
, buf
, 5);
770 if (ret
!= JAYLINK_OK
) {
771 log_err(ctx
, "transport_write() failed: %s.",
772 jaylink_strerror(ret
));
776 ret
= transport_read(devh
, (uint8_t *)info
, length
);
778 if (ret
!= JAYLINK_OK
) {
779 log_err(ctx
, "transport_read() failed: %s.",
780 jaylink_strerror(ret
));
784 for (i
= 0; i
< num
; i
++)
785 info
[i
] = buffer_get_u32((uint8_t *)info
,
786 i
* sizeof(uint32_t));
792 * Retrieve the counter values of a device.
794 * @note This function must only be used if the device has the
795 * #JAYLINK_DEV_CAP_GET_COUNTERS capability.
797 * @param[in,out] devh Device handle.
798 * @param[in] mask A bit field where each set bit represents a counter value to
799 * request. See #jaylink_counter for a description of the
800 * counters and their bit positions.
801 * @param[out] values Array to store the counter values on success. Its content
802 * is undefined on failure. The array must be large enough
803 * to contain at least as many elements as bits set in @p
806 * @retval JAYLINK_OK Success.
807 * @retval JAYLINK_ERR_ARG Invalid arguments.
808 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
809 * @retval JAYLINK_ERR_IO Input/output error.
810 * @retval JAYLINK_ERR Other error conditions.
814 JAYLINK_API
int jaylink_get_counters(struct jaylink_device_handle
*devh
,
815 uint32_t mask
, uint32_t *values
)
818 struct jaylink_context
*ctx
;
824 if (!devh
|| !mask
|| !values
)
825 return JAYLINK_ERR_ARG
;
827 ctx
= devh
->dev
->ctx
;
830 for (i
= 0; i
< 32; i
++) {
835 length
= num
* sizeof(uint32_t);
836 ret
= transport_start_write_read(devh
, 5, length
, true);
838 if (ret
!= JAYLINK_OK
) {
839 log_err(ctx
, "transport_start_write_read() failed: %s.",
840 jaylink_strerror(ret
));
844 buf
[0] = CMD_GET_COUNTERS
;
845 buffer_set_u32(buf
, mask
, 1);
847 ret
= transport_write(devh
, buf
, 5);
849 if (ret
!= JAYLINK_OK
) {
850 log_err(ctx
, "transport_write() failed: %s.",
851 jaylink_strerror(ret
));
855 ret
= transport_read(devh
, (uint8_t *)values
, length
);
857 if (ret
!= JAYLINK_OK
) {
858 log_err(ctx
, "transport_read() failed: %s.",
859 jaylink_strerror(ret
));
863 for (i
= 0; i
< num
; i
++)
864 values
[i
] = buffer_get_u32((uint8_t *)values
,
865 i
* sizeof(uint32_t));
871 * Retrieve the hardware version of a device.
873 * @note This function must only be used if the device has the
874 * #JAYLINK_DEV_CAP_GET_HW_VERSION capability.
876 * @warning This function may return a value for @p version where
877 * #jaylink_hardware_version::type is not covered by
878 * #jaylink_hardware_type.
880 * @param[in,out] devh Device handle.
881 * @param[out] version Hardware version on success, and undefined on failure.
883 * @retval JAYLINK_OK Success.
884 * @retval JAYLINK_ERR_ARG Invalid arguments.
885 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
886 * @retval JAYLINK_ERR_IO Input/output error.
887 * @retval JAYLINK_ERR Other error conditions.
891 JAYLINK_API
int jaylink_get_hardware_version(
892 struct jaylink_device_handle
*devh
,
893 struct jaylink_hardware_version
*version
)
896 struct jaylink_context
*ctx
;
900 if (!devh
|| !version
)
901 return JAYLINK_ERR_ARG
;
903 ctx
= devh
->dev
->ctx
;
904 ret
= transport_start_write_read(devh
, 1, 4, true);
906 if (ret
!= JAYLINK_OK
) {
907 log_err(ctx
, "transport_start_write_read() failed: %s.",
908 jaylink_strerror(ret
));
912 buf
[0] = CMD_GET_HW_VERSION
;
914 ret
= transport_write(devh
, buf
, 1);
916 if (ret
!= JAYLINK_OK
) {
917 log_err(ctx
, "transport_write() failed: %s.",
918 jaylink_strerror(ret
));
922 ret
= transport_read(devh
, buf
, 4);
924 if (ret
!= JAYLINK_OK
) {
925 log_err(ctx
, "transport_read() failed: %s.",
926 jaylink_strerror(ret
));
930 tmp
= buffer_get_u32(buf
, 0);
932 version
->type
= (tmp
/ 1000000) % 100;
933 version
->major
= (tmp
/ 10000) % 100;
934 version
->minor
= (tmp
/ 100) % 100;
935 version
->revision
= tmp
% 100;
941 * Retrieve the hardware status of a device.
943 * @param[in,out] devh Device handle.
944 * @param[out] status Hardware status on success, and undefined on failure.
946 * @retval JAYLINK_OK Success.
947 * @retval JAYLINK_ERR_ARG Invalid arguments.
948 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
949 * @retval JAYLINK_ERR_IO Input/output error.
950 * @retval JAYLINK_ERR Other error conditions.
954 JAYLINK_API
int jaylink_get_hardware_status(struct jaylink_device_handle
*devh
,
955 struct jaylink_hardware_status
*status
)
958 struct jaylink_context
*ctx
;
961 if (!devh
|| !status
)
962 return JAYLINK_ERR_ARG
;
964 ctx
= devh
->dev
->ctx
;
965 ret
= transport_start_write_read(devh
, 1, 8, true);
967 if (ret
!= JAYLINK_OK
) {
968 log_err(ctx
, "transport_start_write_read() failed: %s.",
969 jaylink_strerror(ret
));
973 buf
[0] = CMD_GET_HW_STATUS
;
975 ret
= transport_write(devh
, buf
, 1);
977 if (ret
!= JAYLINK_OK
) {
978 log_err(ctx
, "transport_write() failed: %s.",
979 jaylink_strerror(ret
));
983 ret
= transport_read(devh
, buf
, 8);
985 if (ret
!= JAYLINK_OK
) {
986 log_err(ctx
, "transport_read() failed: %s.",
987 jaylink_strerror(ret
));
991 status
->target_voltage
= buffer_get_u16(buf
, 0);
992 status
->tck
= buf
[2];
993 status
->tdi
= buf
[3];
994 status
->tdo
= buf
[4];
995 status
->tms
= buf
[5];
996 status
->tres
= buf
[6];
997 status
->trst
= buf
[7];
1003 * Retrieve the capabilities of a device.
1005 * The capabilities are stored in a 32-bit bit array consisting of
1006 * #JAYLINK_DEV_CAPS_SIZE bytes where each individual bit represents a
1007 * capability. The first bit of this array is the least significant bit of the
1008 * first byte and the following bits are sequentially numbered in order of
1009 * increasing bit significance and byte index. A set bit indicates a supported
1010 * capability. See #jaylink_device_capability for a description of the
1011 * capabilities and their bit positions.
1013 * @param[in,out] devh Device handle.
1014 * @param[out] caps Buffer to store capabilities on success. Its content is
1015 * undefined on failure. The buffer must be large enough to
1016 * contain at least #JAYLINK_DEV_CAPS_SIZE bytes.
1018 * @retval JAYLINK_OK Success.
1019 * @retval JAYLINK_ERR_ARG Invalid arguments.
1020 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1021 * @retval JAYLINK_ERR_IO Input/output error.
1022 * @retval JAYLINK_ERR Other error conditions.
1024 * @see jaylink_get_extended_caps()
1025 * @see jaylink_has_cap()
1029 JAYLINK_API
int jaylink_get_caps(struct jaylink_device_handle
*devh
,
1033 struct jaylink_context
*ctx
;
1037 return JAYLINK_ERR_ARG
;
1039 ctx
= devh
->dev
->ctx
;
1040 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_CAPS_SIZE
, true);
1042 if (ret
!= JAYLINK_OK
) {
1043 log_err(ctx
, "transport_start_write_read() failed: %s.",
1044 jaylink_strerror(ret
));
1048 buf
[0] = CMD_GET_CAPS
;
1050 ret
= transport_write(devh
, buf
, 1);
1052 if (ret
!= JAYLINK_OK
) {
1053 log_err(ctx
, "transport_write() failed: %s.",
1054 jaylink_strerror(ret
));
1058 ret
= transport_read(devh
, caps
, JAYLINK_DEV_CAPS_SIZE
);
1060 if (ret
!= JAYLINK_OK
) {
1061 log_err(ctx
, "transport_read() failed: %s.",
1062 jaylink_strerror(ret
));
1070 * Retrieve the extended capabilities of a device.
1072 * The extended capabilities are stored in a 256-bit bit array consisting of
1073 * #JAYLINK_DEV_EXT_CAPS_SIZE bytes. See jaylink_get_caps() for a further
1074 * description of how the capabilities are represented in this bit array. For a
1075 * description of the capabilities and their bit positions, see
1076 * #jaylink_device_capability.
1078 * @note This function must only be used if the device has the
1079 * #JAYLINK_DEV_CAP_GET_EXT_CAPS capability.
1081 * @param[in,out] devh Device handle.
1082 * @param[out] caps Buffer to store capabilities on success. Its content is
1083 * undefined on failure. The buffer must be large enough to
1084 * contain at least #JAYLINK_DEV_EXT_CAPS_SIZE bytes.
1086 * @retval JAYLINK_OK Success.
1087 * @retval JAYLINK_ERR_ARG Invalid arguments.
1088 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1089 * @retval JAYLINK_ERR_IO Input/output error.
1090 * @retval JAYLINK_ERR Other error conditions.
1092 * @see jaylink_get_caps()
1096 JAYLINK_API
int jaylink_get_extended_caps(struct jaylink_device_handle
*devh
,
1100 struct jaylink_context
*ctx
;
1104 return JAYLINK_ERR_ARG
;
1106 ctx
= devh
->dev
->ctx
;
1107 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_EXT_CAPS_SIZE
,
1110 if (ret
!= JAYLINK_OK
) {
1111 log_err(ctx
, "transport_start_write_read() failed: %s.",
1112 jaylink_strerror(ret
));
1116 buf
[0] = CMD_GET_EXT_CAPS
;
1118 ret
= transport_write(devh
, buf
, 1);
1120 if (ret
!= JAYLINK_OK
) {
1121 log_err(ctx
, "transport_write() failed: %s.",
1122 jaylink_strerror(ret
));
1126 ret
= transport_read(devh
, caps
, JAYLINK_DEV_EXT_CAPS_SIZE
);
1128 if (ret
!= JAYLINK_OK
) {
1129 log_err(ctx
, "transport_read() failed: %s.",
1130 jaylink_strerror(ret
));
1138 * Retrieve the size of free memory of a device.
1140 * @note This function must only be used if the device has the
1141 * #JAYLINK_DEV_CAP_GET_FREE_MEMORY capability.
1143 * @param[in,out] devh Device handle.
1144 * @param[out] size Size of free memory in bytes on success, and undefined on
1147 * @retval JAYLINK_OK Success.
1148 * @retval JAYLINK_ERR_ARG Invalid arguments.
1149 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1150 * @retval JAYLINK_ERR_IO Input/output error.
1151 * @retval JAYLINK_ERR Other error conditions.
1155 JAYLINK_API
int jaylink_get_free_memory(struct jaylink_device_handle
*devh
,
1159 struct jaylink_context
*ctx
;
1163 return JAYLINK_ERR_ARG
;
1165 ctx
= devh
->dev
->ctx
;
1166 ret
= transport_start_write_read(devh
, 1, 4, true);
1168 if (ret
!= JAYLINK_OK
) {
1169 log_err(ctx
, "transport_start_write_read() failed: %s.",
1170 jaylink_strerror(ret
));
1174 buf
[0] = CMD_GET_FREE_MEMORY
;
1176 ret
= transport_write(devh
, buf
, 1);
1178 if (ret
!= JAYLINK_OK
) {
1179 log_err(ctx
, "transport_write() failed: %s.",
1180 jaylink_strerror(ret
));
1184 ret
= transport_read(devh
, buf
, 4);
1186 if (ret
!= JAYLINK_OK
) {
1187 log_err(ctx
, "transport_read() failed: %s.",
1188 jaylink_strerror(ret
));
1192 *size
= buffer_get_u32(buf
, 0);
1198 * Read the raw configuration data of a device.
1200 * @note This function must only be used if the device has the
1201 * #JAYLINK_DEV_CAP_READ_CONFIG capability.
1203 * @param[in,out] devh Device handle.
1204 * @param[out] config Buffer to store configuration data on success. Its
1205 * content is undefined on failure. The buffer must be large
1206 * enough to contain at least
1207 * #JAYLINK_DEV_CONFIG_SIZE bytes.
1209 * @retval JAYLINK_OK Success.
1210 * @retval JAYLINK_ERR_ARG Invalid arguments.
1211 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1212 * @retval JAYLINK_ERR_IO Input/output error.
1213 * @retval JAYLINK_ERR Other error conditions.
1217 JAYLINK_API
int jaylink_read_raw_config(struct jaylink_device_handle
*devh
,
1221 struct jaylink_context
*ctx
;
1224 if (!devh
|| !config
)
1225 return JAYLINK_ERR_ARG
;
1227 ctx
= devh
->dev
->ctx
;
1228 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_CONFIG_SIZE
,
1231 if (ret
!= JAYLINK_OK
) {
1232 log_err(ctx
, "transport_start_write_read() failed: %s.",
1233 jaylink_strerror(ret
));
1237 buf
[0] = CMD_READ_CONFIG
;
1239 ret
= transport_write(devh
, buf
, 1);
1241 if (ret
!= JAYLINK_OK
) {
1242 log_err(ctx
, "transport_write() failed: %s.",
1243 jaylink_strerror(ret
));
1247 ret
= transport_read(devh
, config
, JAYLINK_DEV_CONFIG_SIZE
);
1249 if (ret
!= JAYLINK_OK
) {
1250 log_err(ctx
, "transport_read() failed: %s.",
1251 jaylink_strerror(ret
));
1259 * Write the raw configuration data of a device.
1261 * @note This function must only be used if the device has the
1262 * #JAYLINK_DEV_CAP_WRITE_CONFIG capability.
1264 * @param[in,out] devh Device handle.
1265 * @param[in] config Buffer to write configuration data from. The size of the
1266 * configuration data is expected to be
1267 * #JAYLINK_DEV_CONFIG_SIZE bytes.
1269 * @retval JAYLINK_OK Success.
1270 * @retval JAYLINK_ERR_ARG Invalid arguments.
1271 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1272 * @retval JAYLINK_ERR_IO Input/output error.
1273 * @retval JAYLINK_ERR Other error conditions.
1277 JAYLINK_API
int jaylink_write_raw_config(struct jaylink_device_handle
*devh
,
1278 const uint8_t *config
)
1281 struct jaylink_context
*ctx
;
1284 if (!devh
|| !config
)
1285 return JAYLINK_ERR_ARG
;
1287 ctx
= devh
->dev
->ctx
;
1288 ret
= transport_start_write(devh
, 1 + JAYLINK_DEV_CONFIG_SIZE
, true);
1290 if (ret
!= JAYLINK_OK
) {
1291 log_err(ctx
, "transport_start_write() failed: %s.",
1292 jaylink_strerror(ret
));
1296 buf
[0] = CMD_WRITE_CONFIG
;
1298 ret
= transport_write(devh
, buf
, 1);
1300 if (ret
!= JAYLINK_OK
) {
1301 log_err(ctx
, "transport_write() failed: %s.",
1302 jaylink_strerror(ret
));
1306 ret
= transport_write(devh
, config
, JAYLINK_DEV_CONFIG_SIZE
);
1308 if (ret
!= JAYLINK_OK
) {
1309 log_err(ctx
, "transport_write() failed: %s.",
1310 jaylink_strerror(ret
));
1317 static void parse_conn_table(struct jaylink_connection
*conns
,
1318 const uint8_t *buffer
, uint16_t num
, uint16_t entry_size
)
1326 for (i
= 0; i
< num
; i
++) {
1327 conns
[i
].pid
= buffer_get_u32(buffer
, offset
);
1329 in
.s_addr
= buffer_get_u32(buffer
, offset
+ 4);
1331 * Use inet_ntoa() instead of inet_ntop() because the latter
1332 * requires at least Windows Vista.
1334 strcpy(conns
[i
].hid
, inet_ntoa(in
));
1336 conns
[i
].iid
= buffer
[offset
+ 8];
1337 conns
[i
].cid
= buffer
[offset
+ 9];
1338 conns
[i
].handle
= buffer_get_u16(buffer
, offset
+ 10);
1339 conns
[i
].timestamp
= buffer_get_u32(buffer
, offset
+ 12);
1340 offset
= offset
+ entry_size
;
1344 static bool _inet_pton(const char *str
, struct in_addr
*in
)
1348 struct sockaddr_in sock_in
;
1351 length
= sizeof(sock_in
);
1354 * Use WSAStringToAddress() instead of inet_pton() because the latter
1355 * requires at least Windows Vista.
1357 ret
= WSAStringToAddress((LPTSTR
)str
, AF_INET
, NULL
,
1358 (LPSOCKADDR
)&sock_in
, &length
);
1363 *in
= sock_in
.sin_addr
;
1365 if (inet_pton(AF_INET
, str
, in
) != 1)
1373 * Register a connection on a device.
1375 * A connection can be registered by using 0 as handle. Additional information
1376 * about the connection can be attached whereby the timestamp is a read-only
1377 * value and therefore ignored for registration. On success, a new handle
1378 * greater than 0 is obtained from the device.
1380 * However, if an obtained handle does not appear in the list of device
1381 * connections, the connection was not registered because the maximum number of
1382 * connections on the device is reached.
1384 * @note This function must only be used if the device has the
1385 * #JAYLINK_DEV_CAP_REGISTER capability.
1389 * static bool register_connection(struct jaylink_device_handle *devh,
1390 * struct jaylink_connection *conn)
1393 * struct jaylink_connection conns[JAYLINK_MAX_CONNECTIONS];
1394 * bool found_handle;
1400 * strcpy(conn->hid, "0.0.0.0");
1404 * ret = jaylink_register(devh, conn, conns, &count);
1406 * if (ret != JAYLINK_OK) {
1407 * printf("jaylink_register() failed: %s.\n",
1408 * jaylink_strerror(ret));
1412 * found_handle = false;
1414 * for (i = 0; i < count; i++) {
1415 * if (conns[i].handle == conn->handle) {
1416 * found_handle = true;
1421 * if (!found_handle) {
1422 * printf("Maximum number of connections reached.\n");
1426 * printf("Connection successfully registered.\n");
1432 * @param[in,out] devh Device handle.
1433 * @param[in,out] connection Connection to register on the device.
1434 * @param[out] connections Array to store device connections on success.
1435 * Its content is undefined on failure. The array must
1436 * be large enough to contain at least
1437 * #JAYLINK_MAX_CONNECTIONS elements.
1438 * @param[out] count Number of device connections on success, and undefined on
1441 * @retval JAYLINK_OK Success.
1442 * @retval JAYLINK_ERR_ARG Invalid arguments.
1443 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1444 * @retval JAYLINK_ERR_PROTO Protocol violation.
1445 * @retval JAYLINK_ERR_IO Input/output error.
1446 * @retval JAYLINK_ERR Other error conditions.
1448 * @see jaylink_unregister()
1452 JAYLINK_API
int jaylink_register(struct jaylink_device_handle
*devh
,
1453 struct jaylink_connection
*connection
,
1454 struct jaylink_connection
*connections
, size_t *count
)
1457 struct jaylink_context
*ctx
;
1458 uint8_t buf
[REG_MAX_SIZE
];
1461 uint16_t entry_size
;
1463 uint32_t table_size
;
1467 if (!devh
|| !connection
|| !connections
|| !count
)
1468 return JAYLINK_ERR_ARG
;
1470 ctx
= devh
->dev
->ctx
;
1472 buf
[0] = CMD_REGISTER
;
1473 buf
[1] = REG_CMD_REGISTER
;
1474 buffer_set_u32(buf
, connection
->pid
, 2);
1476 if (!_inet_pton(connection
->hid
, &in
))
1477 return JAYLINK_ERR_ARG
;
1479 buffer_set_u32(buf
, in
.s_addr
, 6);
1481 buf
[10] = connection
->iid
;
1482 buf
[11] = connection
->cid
;
1483 buffer_set_u16(buf
, connection
->handle
, 12);
1485 ret
= transport_start_write_read(devh
, 14, REG_MIN_SIZE
, true);
1487 if (ret
!= JAYLINK_OK
) {
1488 log_err(ctx
, "transport_start_write_read() failed: %s.",
1489 jaylink_strerror(ret
));
1493 ret
= transport_write(devh
, buf
, 14);
1495 if (ret
!= JAYLINK_OK
) {
1496 log_err(ctx
, "transport_write() failed: %s.",
1497 jaylink_strerror(ret
));
1501 ret
= transport_read(devh
, buf
, REG_MIN_SIZE
);
1503 if (ret
!= JAYLINK_OK
) {
1504 log_err(ctx
, "transport_read() failed: %s.",
1505 jaylink_strerror(ret
));
1509 handle
= buffer_get_u16(buf
, 0);
1510 num
= buffer_get_u16(buf
, 2);
1511 entry_size
= buffer_get_u16(buf
, 4);
1512 info_size
= buffer_get_u16(buf
, 6);
1514 if (num
> JAYLINK_MAX_CONNECTIONS
) {
1515 log_err(ctx
, "Maximum number of device connections exceeded: "
1517 return JAYLINK_ERR_PROTO
;
1520 if (entry_size
!= REG_CONN_INFO_SIZE
) {
1521 log_err(ctx
, "Invalid connection entry size: %u bytes.",
1523 return JAYLINK_ERR_PROTO
;
1526 table_size
= num
* entry_size
;
1527 size
= REG_HEADER_SIZE
+ table_size
+ info_size
;
1529 if (size
> REG_MAX_SIZE
) {
1530 log_err(ctx
, "Maximum registration information size exceeded: "
1532 return JAYLINK_ERR_PROTO
;
1535 if (size
> REG_MIN_SIZE
) {
1536 ret
= transport_start_read(devh
, size
- REG_MIN_SIZE
);
1538 if (ret
!= JAYLINK_OK
) {
1539 log_err(ctx
, "transport_start_read() failed: %s.",
1540 jaylink_strerror(ret
));
1544 ret
= transport_read(devh
, buf
+ REG_MIN_SIZE
,
1545 size
- REG_MIN_SIZE
);
1547 if (ret
!= JAYLINK_OK
) {
1548 log_err(ctx
, "transport_read() failed: %s.",
1549 jaylink_strerror(ret
));
1555 log_err(ctx
, "Obtained invalid connection handle.");
1556 return JAYLINK_ERR_PROTO
;
1559 connection
->handle
= handle
;
1560 parse_conn_table(connections
, buf
+ REG_HEADER_SIZE
, num
, entry_size
);
1568 * Unregister a connection from a device.
1570 * @note This function must only be used if the device has the
1571 * #JAYLINK_DEV_CAP_REGISTER capability.
1573 * @param[in,out] devh Device handle.
1574 * @param[in,out] connection Connection to unregister from the device.
1575 * @param[out] connections Array to store device connections on success.
1576 * Its content is undefined on failure. The array must
1577 * be large enough to contain at least
1578 * #JAYLINK_MAX_CONNECTIONS elements.
1579 * @param[out] count Number of device connections on success, and undefined on
1582 * @retval JAYLINK_OK Success.
1583 * @retval JAYLINK_ERR_ARG Invalid arguments.
1584 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
1585 * @retval JAYLINK_ERR_PROTO Protocol violation.
1586 * @retval JAYLINK_ERR_IO Input/output error.
1587 * @retval JAYLINK_ERR Other error conditions.
1589 * @see jaylink_register()
1593 JAYLINK_API
int jaylink_unregister(struct jaylink_device_handle
*devh
,
1594 const struct jaylink_connection
*connection
,
1595 struct jaylink_connection
*connections
, size_t *count
)
1598 struct jaylink_context
*ctx
;
1599 uint8_t buf
[REG_MAX_SIZE
];
1601 uint16_t entry_size
;
1603 uint32_t table_size
;
1607 if (!devh
|| !connection
|| !connections
|| !count
)
1608 return JAYLINK_ERR_ARG
;
1610 ctx
= devh
->dev
->ctx
;
1612 buf
[0] = CMD_REGISTER
;
1613 buf
[1] = REG_CMD_UNREGISTER
;
1614 buffer_set_u32(buf
, connection
->pid
, 2);
1616 if (!_inet_pton(connection
->hid
, &in
))
1617 return JAYLINK_ERR_ARG
;
1619 buffer_set_u32(buf
, in
.s_addr
, 6);
1621 buf
[10] = connection
->iid
;
1622 buf
[11] = connection
->cid
;
1623 buffer_set_u16(buf
, connection
->handle
, 12);
1625 ret
= transport_start_write_read(devh
, 14, REG_MIN_SIZE
, true);
1627 if (ret
!= JAYLINK_OK
) {
1628 log_err(ctx
, "transport_start_write_read() failed: %s.",
1629 jaylink_strerror(ret
));
1633 ret
= transport_write(devh
, buf
, 14);
1635 if (ret
!= JAYLINK_OK
) {
1636 log_err(ctx
, "transport_write() failed: %s.",
1637 jaylink_strerror(ret
));
1641 ret
= transport_read(devh
, buf
, REG_MIN_SIZE
);
1643 if (ret
!= JAYLINK_OK
) {
1644 log_err(ctx
, "transport_read() failed: %s.",
1645 jaylink_strerror(ret
));
1649 num
= buffer_get_u16(buf
, 2);
1650 entry_size
= buffer_get_u16(buf
, 4);
1651 info_size
= buffer_get_u16(buf
, 6);
1653 if (num
> JAYLINK_MAX_CONNECTIONS
) {
1654 log_err(ctx
, "Maximum number of device connections exceeded: "
1656 return JAYLINK_ERR_PROTO
;
1659 if (entry_size
!= REG_CONN_INFO_SIZE
) {
1660 log_err(ctx
, "Invalid connection entry size: %u bytes.",
1662 return JAYLINK_ERR_PROTO
;
1665 table_size
= num
* entry_size
;
1666 size
= REG_HEADER_SIZE
+ table_size
+ info_size
;
1668 if (size
> REG_MAX_SIZE
) {
1669 log_err(ctx
, "Maximum registration information size exceeded: "
1671 return JAYLINK_ERR_PROTO
;
1674 if (size
> REG_MIN_SIZE
) {
1675 ret
= transport_start_read(devh
, size
- REG_MIN_SIZE
);
1677 if (ret
!= JAYLINK_OK
) {
1678 log_err(ctx
, "transport_start_read() failed: %s.",
1679 jaylink_strerror(ret
));
1683 ret
= transport_read(devh
, buf
+ REG_MIN_SIZE
,
1684 size
- REG_MIN_SIZE
);
1686 if (ret
!= JAYLINK_OK
) {
1687 log_err(ctx
, "transport_read() failed: %s.",
1688 jaylink_strerror(ret
));
1693 parse_conn_table(connections
, buf
+ REG_HEADER_SIZE
, num
, entry_size
);