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