31 #include <sys/socket.h> 32 #include <arpa/inet.h> 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 64 #define REG_HEADER_SIZE 8 66 #define REG_MIN_SIZE 0x4c 68 #define REG_MAX_SIZE 0x200 70 #define REG_CONN_INFO_SIZE 16 73 #define MAX_USB_PATH_DEPTH 7 152 log_err(ctx,
"Failed to allocate device list.");
158 for (
size_t i = 0; i < num; i++) {
189 for (
size_t i = 0; devs[i]; i++)
239 if (!dev || !serial_number)
273 if (!dev || !address)
280 *address = dev->usb_address;
310 uint8_t **ports,
size_t *
length)
312 if (!dev || !bus || !ports || !length)
322 *ports = malloc(MAX_USB_PATH_DEPTH *
sizeof(uint8_t));
328 ret = libusb_get_port_numbers(dev->usb_dev, *ports,
331 if (ret == LIBUSB_ERROR_OVERFLOW) {
332 log_err(ctx,
"Failed to get port numbers: %s.",
333 libusb_error_name(ret));
338 *bus = libusb_get_bus_number(dev->usb_dev);
363 if (!dev || !address)
393 if (!dev || !address)
429 if (!dev || !version)
495 if (!dev || !nickname)
551 log_dbg(ctx,
"Device destroyed (bus:address = " 553 libusb_get_bus_number(dev->usb_dev),
554 libusb_get_device_address(dev->usb_dev));
556 libusb_unref_device(dev->usb_dev);
559 log_dbg(ctx,
"Device destroyed (IPv4 address = %s).",
562 log_err(ctx,
"BUG: Invalid host interface: %u.",
619 log_err(dev->
ctx,
"Device handle malloc failed.");
710 if (!devh || !version || !length)
717 log_err(ctx,
"transport_start_write_read() failed: %s.",
727 log_err(ctx,
"transport_write() failed: %s.",
735 log_err(ctx,
"transport_read() failed: %s.",
749 log_err(ctx,
"transport_start_read() failed: %s.",
757 log_err(ctx,
"Firmware version string malloc failed.");
764 log_err(ctx,
"transport_read() failed: %s.",
810 if (!devh || !mask || !info)
816 for (
unsigned int i = 0; i < 32; i++) {
821 length = num *
sizeof(uint32_t);
826 log_err(ctx,
"transport_start_write_read() failed: %s.",
831 buf[0] = CMD_GET_HW_INFO;
837 log_err(ctx,
"transport_write() failed: %s.",
845 log_err(ctx,
"transport_read() failed: %s.",
850 for (
unsigned int i = 0; i < num; i++)
852 i *
sizeof(uint32_t));
881 uint32_t
mask, uint32_t *values)
889 if (!devh || !mask || !values)
895 for (
unsigned int i = 0; i < 32; i++) {
900 length = num *
sizeof(uint32_t);
904 log_err(ctx,
"transport_start_write_read() failed: %s.",
909 buf[0] = CMD_GET_COUNTERS;
915 log_err(ctx,
"transport_write() failed: %s.",
923 log_err(ctx,
"transport_read() failed: %s.",
928 for (
unsigned int i = 0; i < num; i++)
930 i *
sizeof(uint32_t));
965 if (!devh || !version)
972 log_err(ctx,
"transport_start_write_read() failed: %s.",
977 buf[0] = CMD_GET_HW_VERSION;
982 log_err(ctx,
"transport_write() failed: %s.",
990 log_err(ctx,
"transport_read() failed: %s.",
997 version->
type = (tmp / 1000000) % 100;
998 version->
major = (tmp / 10000) % 100;
999 version->
minor = (tmp / 100) % 100;
1026 if (!devh || !status)
1033 log_err(ctx,
"transport_start_write_read() failed: %s.",
1038 buf[0] = CMD_GET_HW_STATUS;
1043 log_err(ctx,
"transport_write() failed: %s.",
1051 log_err(ctx,
"transport_read() failed: %s.",
1057 status->
tck = buf[2];
1058 status->
tdi = buf[3];
1059 status->
tdo = buf[4];
1060 status->
tms = buf[5];
1061 status->
tres = buf[6];
1062 status->
trst = buf[7];
1108 log_err(ctx,
"transport_start_write_read() failed: %s.",
1113 buf[0] = CMD_GET_CAPS;
1118 log_err(ctx,
"transport_write() failed: %s.",
1126 log_err(ctx,
"transport_read() failed: %s.",
1176 log_err(ctx,
"transport_start_write_read() failed: %s.",
1181 buf[0] = CMD_GET_EXT_CAPS;
1186 log_err(ctx,
"transport_write() failed: %s.",
1194 log_err(ctx,
"transport_read() failed: %s.",
1234 log_err(ctx,
"transport_start_write_read() failed: %s.",
1239 buf[0] = CMD_GET_FREE_MEMORY;
1244 log_err(ctx,
"transport_write() failed: %s.",
1252 log_err(ctx,
"transport_read() failed: %s.",
1289 if (!devh || !config)
1297 log_err(ctx,
"transport_start_write_read() failed: %s.",
1302 buf[0] = CMD_READ_CONFIG;
1307 log_err(ctx,
"transport_write() failed: %s.",
1315 log_err(ctx,
"transport_read() failed: %s.",
1349 if (!devh || !config)
1356 log_err(ctx,
"transport_start_write() failed: %s.",
1361 buf[0] = CMD_WRITE_CONFIG;
1366 log_err(ctx,
"transport_write() failed: %s.",
1374 log_err(ctx,
"transport_write() failed: %s.",
1383 const uint8_t *
buffer, uint16_t num, uint16_t entry_size)
1390 for (
unsigned int i = 0; i < num; i++) {
1398 strcpy(conns[i].hid, inet_ntoa(in));
1400 conns[i].
iid = buffer[offset + 8];
1401 conns[i].
cid = buffer[offset + 9];
1404 offset = offset + entry_size;
1412 struct sockaddr_in sock_in;
1415 length =
sizeof(sock_in);
1421 ret = WSAStringToAddress((LPTSTR)str, AF_INET,
NULL,
1422 (LPSOCKADDR)&sock_in, &length);
1427 *in = sock_in.sin_addr;
1429 if (inet_pton(AF_INET, str, in) != 1)
1521 uint8_t buf[REG_MAX_SIZE];
1524 uint16_t entry_size;
1526 uint32_t table_size;
1530 if (!devh || !connection || !connections || !count)
1535 buf[0] = CMD_REGISTER;
1536 buf[1] = REG_CMD_REGISTER;
1544 buf[10] = connection->
iid;
1545 buf[11] = connection->
cid;
1551 log_err(ctx,
"transport_start_write_read() failed: %s.",
1559 log_err(ctx,
"transport_write() failed: %s.",
1567 log_err(ctx,
"transport_read() failed: %s.",
1578 log_err(ctx,
"Maximum number of device connections exceeded: " 1583 if (entry_size != REG_CONN_INFO_SIZE) {
1584 log_err(ctx,
"Invalid connection entry size: %u bytes.",
1589 table_size = num * entry_size;
1590 size = REG_HEADER_SIZE + table_size + info_size;
1592 if (size > REG_MAX_SIZE) {
1593 log_err(ctx,
"Maximum registration information size exceeded: " 1598 if (size > REG_MIN_SIZE) {
1602 log_err(ctx,
"transport_start_read() failed: %s.",
1608 size - REG_MIN_SIZE);
1611 log_err(ctx,
"transport_read() failed: %s.",
1618 log_err(ctx,
"Obtained invalid connection handle.");
1622 connection->
handle = handle;
1662 uint8_t buf[REG_MAX_SIZE];
1664 uint16_t entry_size;
1666 uint32_t table_size;
1670 if (!devh || !connection || !connections || !count)
1675 buf[0] = CMD_REGISTER;
1676 buf[1] = REG_CMD_UNREGISTER;
1684 buf[10] = connection->
iid;
1685 buf[11] = connection->
cid;
1691 log_err(ctx,
"transport_start_write_read() failed: %s.",
1699 log_err(ctx,
"transport_write() failed: %s.",
1707 log_err(ctx,
"transport_read() failed: %s.",
1717 log_err(ctx,
"Maximum number of device connections exceeded: " 1722 if (entry_size != REG_CONN_INFO_SIZE) {
1723 log_err(ctx,
"Invalid connection entry size: %u bytes.",
1728 table_size = num * entry_size;
1729 size = REG_HEADER_SIZE + table_size + info_size;
1731 if (size > REG_MAX_SIZE) {
1732 log_err(ctx,
"Maximum registration information size exceeded: " 1737 if (size > REG_MIN_SIZE) {
1741 log_err(ctx,
"transport_start_read() failed: %s.",
1747 size - REG_MIN_SIZE);
1750 log_err(ctx,
"transport_read() failed: %s.",
jaylink_host_interface
Host interfaces.
jaylink_usb_address
USB addresses.
JAYLINK_PRIV int transport_read(struct jaylink_device_handle *devh, uint8_t *buffer, size_t length)
Read data from a device.
bool has_mac_address
Indicates whether the MAC address is available.
JAYLINK_PRIV struct jaylink_device * device_allocate(struct jaylink_context *ctx)
char ipv4_address[INET_ADDRSTRLEN]
IPv4 address.
JAYLINK_PRIV size_t list_length(struct list *list)
JAYLINK_API int jaylink_get_free_memory(struct jaylink_device_handle *devh, uint32_t *size)
Retrieve the size of free memory of a device.
JAYLINK_API int jaylink_register(struct jaylink_device_handle *devh, struct jaylink_connection *connection, struct jaylink_connection *connections, size_t *count)
Register a connection on a device.
struct list * discovered_devs
List of recently discovered devices.
char product_name[JAYLINK_PRODUCT_NAME_MAX_LENGTH]
Product name.
JAYLINK_PRIV void log_err(const struct jaylink_context *ctx, const char *format,...)
JAYLINK_API int jaylink_device_get_usb_address(const struct jaylink_device *dev, enum jaylink_usb_address *address)
Get the USB address of a device.
static libusb_device ** devs
The usb device list.
bool has_serial_number
Indicates whether the serial number is available.
uint8_t minor
Minor version.
Universal Serial Bus (USB).
JAYLINK_PRIV uint32_t buffer_get_u32(const uint8_t *buffer, size_t offset)
Read a 32-bit unsigned integer value from a buffer.
JAYLINK_API int jaylink_get_caps(struct jaylink_device_handle *devh, uint8_t *caps)
Retrieve the capabilities of a device.
JAYLINK_PRIV void buffer_set_u16(uint8_t *buffer, uint16_t value, size_t offset)
Write a 16-bit unsigned integer value to a buffer.
JAYLINK_API int jaylink_get_hardware_version(struct jaylink_device_handle *devh, struct jaylink_hardware_version *version)
Retrieve the hardware version of a device.
Opaque structure representing a device.
static uint8_t caps[JAYLINK_DEV_EXT_CAPS_SIZE]
JAYLINK_API int jaylink_device_get_mac_address(const struct jaylink_device *dev, uint8_t *address)
Get the MAC address of a device.
static struct ublast_lowlevel_priv info
struct list * devs
List of allocated device instances.
JAYLINK_API int jaylink_device_get_hardware_version(const struct jaylink_device *dev, struct jaylink_hardware_version *version)
Get the hardware version of a device.
JAYLINK_API struct jaylink_device * jaylink_ref_device(struct jaylink_device *dev)
Increment the reference count of a device.
JAYLINK_API int jaylink_device_get_usb_bus_ports(const struct jaylink_device *dev, uint8_t *bus, uint8_t **ports, size_t *length)
Get the USB bus and port numbers of a device.
JAYLINK_API int jaylink_get_firmware_version(struct jaylink_device_handle *devh, char **version, size_t *length)
Retrieve the firmware version of a device.
uint8_t major
Major version.
JAYLINK_PRIV int transport_open(struct jaylink_device_handle *devh)
Open a device.
JAYLINK_API int jaylink_write_raw_config(struct jaylink_device_handle *devh, const uint8_t *config)
Write the raw configuration data of a device.
JAYLINK_API int jaylink_get_hardware_status(struct jaylink_device_handle *devh, struct jaylink_hardware_status *status)
Retrieve the hardware status of a device.
Opaque structure representing a libjaylink context.
#define JAYLINK_PRIV
Macro to mark private libjaylink symbol.
uint16_t target_voltage
Target reference voltage in mV.
uint32_t timestamp
Timestamp of the last registration in milliseconds.
Internal libjaylink header file.
static struct device_config config
size_t ref_count
Number of references held on this device instance.
JAYLINK_PRIV void log_dbg(const struct jaylink_context *ctx, const char *format,...)
bool has_nickname
Indicates whether the nickname is available.
static struct jaylink_device ** allocate_device_list(size_t length)
struct jaylink_context * ctx
libjaylink context.
char nickname[JAYLINK_NICKNAME_MAX_LENGTH]
Nickname.
char hid[INET_ADDRSTRLEN]
Host ID (HID).
struct jaylink_hardware_version hw_version
Hardware version.
Transmission Control Protocol (TCP).
JAYLINK_API int jaylink_device_get_ipv4_address(const struct jaylink_device *dev, char *address)
Get the IPv4 address string of a device.
static void parse_conn_table(struct jaylink_connection *conns, const uint8_t *buffer, uint16_t num, uint16_t entry_size)
JAYLINK_API int jaylink_device_get_product_name(const struct jaylink_device *dev, char *name)
Get the product name of a device.
static enum jaylink_target_interface iface
#define JAYLINK_MAX_CONNECTIONS
Maximum number of connections that can be registered on a device.
JAYLINK_API int jaylink_unregister(struct jaylink_device_handle *devh, const struct jaylink_connection *connection, struct jaylink_connection *connections, size_t *count)
Unregister a connection from a device.
enum jaylink_host_interface iface
Host interface.
size_t size
Size of the control block search area.
JAYLINK_PRIV int transport_start_read(struct jaylink_device_handle *devh, size_t length)
Start a read operation for a device.
#define JAYLINK_DEV_CAPS_SIZE
Number of bytes required to store device capabilities.
uint8_t revision
Revision number.
uint8_t mac_address[JAYLINK_MAC_ADDRESS_LENGTH]
Media Access Control (MAC) address.
Opaque structure representing a handle of a device.
JAYLINK_API int jaylink_device_get_nickname(const struct jaylink_device *dev, char *nickname)
Get the nickname of a device.
JAYLINK_PRIV int transport_close(struct jaylink_device_handle *devh)
Close a device.
JAYLINK_PRIV int transport_start_write(struct jaylink_device_handle *devh, size_t length, bool has_command)
Start a write operation for a device.
static void free_device_handle(struct jaylink_device_handle *devh)
Public libjaylink header file to be used by applications.
JAYLINK_API int jaylink_device_get_host_interface(const struct jaylink_device *dev, enum jaylink_host_interface *iface)
Get the host interface of a device.
JAYLINK_API const char * jaylink_strerror(int error_code)
Return a human-readable description of a libjaylink error code.
static struct jaylink_device_handle * allocate_device_handle(struct jaylink_device *dev)
JAYLINK_API int jaylink_close(struct jaylink_device_handle *devh)
Close a device.
static struct jaylink_device_handle * devh
#define JAYLINK_API
Macro to mark public libjaylink API symbol.
JAYLINK_API void jaylink_unref_device(struct jaylink_device *dev)
Decrement the reference count of a device.
JAYLINK_PRIV struct list * list_remove(struct list *list, const void *data)
JAYLINK_API struct jaylink_device * jaylink_get_device(struct jaylink_device_handle *devh)
Get the device instance from a device handle.
#define JAYLINK_DEV_EXT_CAPS_SIZE
Number of bytes required to store extended device capabilities.
JAYLINK_API int jaylink_get_hardware_info(struct jaylink_device_handle *devh, uint32_t mask, uint32_t *info)
Retrieve the hardware information of a device.
enum jaylink_hardware_type type
Hardware type.
JAYLINK_API int jaylink_get_counters(struct jaylink_device_handle *devh, uint32_t mask, uint32_t *values)
Retrieve the counter values of a device.
JAYLINK_API int jaylink_device_get_serial_number(const struct jaylink_device *dev, uint32_t *serial_number)
Get the serial number of a device.
struct jaylink_device * dev
Device instance.
#define JAYLINK_DEV_CONFIG_SIZE
Size of the device configuration data in bytes.
JAYLINK_PRIV int transport_start_write_read(struct jaylink_device_handle *devh, size_t write_length, size_t read_length, bool has_command)
Start a write and read operation for a device.
static bool _inet_pton(const char *str, struct in_addr *in)
JAYLINK_API int jaylink_get_extended_caps(struct jaylink_device_handle *devh, uint8_t *caps)
Retrieve the extended capabilities of a device.
JAYLINK_API void jaylink_free_devices(struct jaylink_device **devs, bool unref)
Free devices.
static uint32_t serial_number
uint32_t serial_number
Serial number of the device.
JAYLINK_PRIV int transport_write(struct jaylink_device_handle *devh, const uint8_t *buffer, size_t length)
Write data to a device.
bool has_hw_version
Indicates whether the hardware version is available.
JAYLINK_PRIV uint16_t buffer_get_u16(const uint8_t *buffer, size_t offset)
Read a 16-bit unsigned integer value from a buffer.
JAYLINK_API int jaylink_read_raw_config(struct jaylink_device_handle *devh, uint8_t *config)
Read the raw configuration data of a device.
uint32_t pid
Process ID (PID).
JAYLINK_PRIV struct list * list_prepend(struct list *list, void *data)
bool has_product_name
Indicates whether the product name is available.
JAYLINK_API int jaylink_open(struct jaylink_device *dev, struct jaylink_device_handle **devh)
Open a device.
JAYLINK_API int jaylink_get_devices(struct jaylink_context *ctx, struct jaylink_device ***devs, size_t *count)
Get available devices.
JAYLINK_PRIV void buffer_set_u32(uint8_t *buffer, uint32_t value, size_t offset)
Write a 32-bit unsigned integer value to a buffer.