diff --git a/CMakeLists.txt b/CMakeLists.txt index 0741a16..d20ae15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,6 @@ set(SRCS ${PROJECT_SOURCE_DIR}/src/adb/xdbd_adb_request.c ${PROJECT_SOURCE_DIR}/src/connection/connection.c ${PROJECT_SOURCE_DIR}/src/connection/tcp/xdbd_connection_tcp.c - ${PROJECT_SOURCE_DIR}/src/connection/usb/xdbd_connection_usb.c ${PROJECT_SOURCE_DIR}/src/core/xdbd_buf.c ${PROJECT_SOURCE_DIR}/src/core/xdbd_pool.c ${PROJECT_SOURCE_DIR}/src/core/xdbd_times.c @@ -39,6 +38,13 @@ set(SRCS ${PROJECT_SOURCE_DIR}/src/xdbd.c ) +if(LINUX) +set(SRCS + ${SRCS} + ${PROJECT_SOURCE_DIR}/src/connection/usb/xdbd_connection_usb.c +) +endif() + set( XADB_INCLUDES ${PROJECT_SOURCE_DIR}/include/ diff --git a/src/connection/usb/xdbd_connection_usb.c b/src/connection/usb/xdbd_connection_usb.c index e6414ab..f034772 100644 --- a/src/connection/usb/xdbd_connection_usb.c +++ b/src/connection/usb/xdbd_connection_usb.c @@ -1 +1,194 @@ +#include +#include +#include #include +#include + +#define USB_ADB_PATH "/dev/adb/usb" +#define USB_FFS_ADB_PATH "/dev/usb-ffs/adb/" + +#define USB_FFS_ADB_EP(x) USB_FFS_ADB_PATH#x +#define USB_FFS_ADB_EP0 USB_FFS_ADB_EP(ep0) +#define USB_FFS_ADB_OUT USB_FFS_ADB_EP(ep1) +#define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2) + +#define ADB_DESCRIPTORS_MAGIC 1 +#define ADB_STRINGS_MAGIC 2 +#define ADB_CLASS 0xff +#define ADB_SUBCLASS 0x42 +#define ADB_PROTOCOL 0x1 +#define ADB_INTERFACE "ADB Interface" + +#define MAX_PACKET_SIZE_FS 64 +#define MAX_PACKET_SIZE_HS 512 + +struct adb_functionfs_descs_head { + bfdev_le32 magic; + bfdev_le32 length; + bfdev_le32 fs_count; + bfdev_le32 hs_count; +} __bfdev_packed; + +struct adb_functionfs_strings_head { + bfdev_le32 magic; + bfdev_le32 length; + bfdev_le32 str_count; + bfdev_le32 lang_count; +} __bfdev_packed; + +static const struct { + struct adb_functionfs_descs_head header; + struct { + struct usb_interface_descriptor intf; + struct usb_endpoint_descriptor source, sink; + } __bfdev_packed fs_descs, hs_descs; +} __bfdev_packed adb_descriptors = { + .header = { + .magic = ADB_DESCRIPTORS_MAGIC, + .length = sizeof(adb_descriptors), + .fs_count = 3, + .hs_count = 3, + }, + .fs_descs = { + .intf = { + .bLength = sizeof(adb_descriptors.fs_descs.intf), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 2, + .bInterfaceClass = ADB_CLASS, + .bInterfaceSubClass = ADB_SUBCLASS, + .bInterfaceProtocol = ADB_PROTOCOL, + .iInterface = 1, + }, + .source = { + .bLength = sizeof(adb_descriptors.fs_descs.source), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_FS, + }, + .sink = { + .bLength = sizeof(adb_descriptors.fs_descs.sink), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_FS, + }, + }, + .hs_descs = { + .intf = { + .bLength = sizeof(adb_descriptors.hs_descs.intf), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 2, + .bInterfaceClass = ADB_CLASS, + .bInterfaceSubClass = ADB_SUBCLASS, + .bInterfaceProtocol = ADB_PROTOCOL, + .iInterface = 1, + }, + .source = { + .bLength = sizeof(adb_descriptors.hs_descs.source), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_HS, + }, + .sink = { + .bLength = sizeof(adb_descriptors.hs_descs.sink), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_HS, + }, + }, +}; + +static const struct { + struct adb_functionfs_strings_head header; + struct { + bfdev_le16 code; + const char str[sizeof(ADB_INTERFACE)]; + } __bfdev_packed lang; +} __bfdev_packed adb_strings = { + .header = { + .magic = ADB_STRINGS_MAGIC, + .length = sizeof(adb_strings), + .str_count = 1, + .lang_count = 1, + }, + .lang = { + .code = 0x0409, + .str = ADB_INTERFACE, + }, +}; + +struct adb_connection { + int control; + int bulk_out; + int bulk_in; +}; + +static int +adb_init_send(struct adb_connection *conn) +{ + int retval; + + retval = write(conn->control, &adb_descriptors, sizeof(adb_descriptors)); + if (retval != sizeof(adb_descriptors)) { + bfdev_log_err("adbd: %s write descriptors failed: %m\n", USB_FFS_ADB_EP0); + return retval; + } + + retval = write(conn->control, &adb_strings, sizeof(adb_strings)); + if (retval != sizeof(adb_strings)) { + bfdev_log_err("adbd: %s write strings failed: %m\n", USB_FFS_ADB_EP0); + return retval; + } + + return 0; +} + +static int +adb_init_connection(struct adb_connection *conn) +{ + int retval; + + retval = open(USB_FFS_ADB_EP0, O_RDWR); + if (retval < 0) { + bfdev_log_err("adbd: %s open failed: %m\n", USB_FFS_ADB_EP0); + goto failed; + } + conn->control = retval; + + retval = open(USB_FFS_ADB_OUT, O_RDWR); + if (retval < 0) { + bfdev_log_err("adbd: %s open failed: %m\n", USB_FFS_ADB_OUT); + goto failed; + } + conn->bulk_out = retval; + + retval = open(USB_FFS_ADB_IN, O_RDWR); + if (retval < 0) { + bfdev_log_err("adbd: %s open failed: %m\n", USB_FFS_ADB_IN); + goto failed; + } + conn->bulk_in = retval; + + retval = adb_init_send(conn); + if (retval) { + bfdev_log_err("adbd: init send failed\n"); + goto failed; + } + + return 0; + +failed: + if (conn->control) + close(conn->control); + if (conn->bulk_out) + close(conn->bulk_out); + if (conn->bulk_in) + close(conn->bulk_in); + + return retval; +}