FOREACH(flag ${SYSTEMD_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
ENDFOREACH(flag)
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -pthread")
ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${SYSTEMD_LDFLAGS})
struct usb_interface_descriptor intf;
struct usb_endpoint_descriptor_no_audio bulk_in;
struct usb_endpoint_descriptor_no_audio bulk_out;
+ struct usb_endpoint_descriptor_no_audio int_in;
+ struct usb_endpoint_descriptor_no_audio int_out;
} __attribute__ ((__packed__)) fs_descs, hs_descs;
} __attribute__ ((__packed__)) descriptors = {
.header = {
.magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC),
.length = htole32(sizeof(descriptors)),
- .fs_count = htole32(3),
- .hs_count = htole32(3),
+ .fs_count = htole32(5),
+ .hs_count = htole32(5),
},
.fs_descs = {
.intf = {
.bLength = sizeof(descriptors.fs_descs.intf),
.bDescriptorType = USB_DT_INTERFACE,
- .bNumEndpoints = 2,
+ .bNumEndpoints = 4,
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.iInterface = 1,
},
.bEndpointAddress = 2 | USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
},
+ .int_in = {
+ .bLength = sizeof(descriptors.fs_descs.int_in),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 3 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bInterval = 10,
+ },
+ .int_out = {
+ .bLength = sizeof(descriptors.fs_descs.int_out),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 4 | USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bInterval = 10,
+ },
},
.hs_descs = {
.intf = {
.bLength = sizeof(descriptors.hs_descs.intf),
.bDescriptorType = USB_DT_INTERFACE,
- .bNumEndpoints = 2,
+ .bNumEndpoints = 4,
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.iInterface = 1,
},
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = htole16(512),
},
+ .int_in = {
+ .bLength = sizeof(descriptors.hs_descs.int_in),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 3 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = htole16(512),
+ .bInterval = 10,
+ },
+ .int_out = {
+ .bLength = sizeof(descriptors.hs_descs.int_out),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 4 | USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = htole16(512),
+ .bInterval = 10,
+ },
},
};
#define FFS_PATH "/tmp/usb-host-test-ffs"
-#define EP_IN_IDX 1
-#define EP_OUT_IDX 2
+enum {
+ EP0_IDX = 0,
+ EP_IN_BULK_IDX,
+ EP_OUT_BULK_IDX,
+ EP_IN_INT_IDX,
+ EP_OUT_INT_IDX,
+ NUM_ENDPOINTS,
+};
#define MAX(a, b) ((a) > (b) ? (a) : (b))
putchar('\n'); \
} while (0)
-char buf[512];
+#define BUFSIZE 512
+char int_buf[BUFSIZE];
+char bulk_buf[BUFSIZE];
/* Close all ep files */
void cleanup_ffs(int *ep)
{
int i;
- for (i = 0; i < 3; ++i)
+ for (i = 0; i < NUM_ENDPOINTS; ++i)
close(ep[i]);
}
return 0;
}
+struct tdata {
+ int ep_in;
+ int ep_out;
+ char *buf;
+};
+
+void *loop_thread(void *data)
+{
+ struct tdata *d = data;
+ int ret;
+
+ while (1) {
+ ret = read(d->ep_out, d->buf, BUFSIZE);
+ if (ret < 0) {
+ report_error("read error on fd %d: %m\n", d->ep_out);
+ if (errno != ECONNRESET && errno != ESHUTDOWN)
+ exit(ret);
+
+ return NULL;
+ }
+
+ fprintf(stderr, "received %d bytes\n", ret);
+
+ ret = write(d->ep_in, d->buf, ret);
+ if (ret < 0) {
+ report_error("write error on fd %d: %m\n", d->ep_in);
+ if (errno != ECONNRESET && errno != ESHUTDOWN)
+ exit(ret);
+
+ return NULL;
+ }
+
+ fprintf(stderr, "sent %d bytes\n", ret);
+ }
+
+ return NULL;
+}
+
/* main chat function */
void do_chat(int *ep)
{
int connected = 0;
int ret;
+ pthread_t int_thread, bulk_thread;
+ struct tdata int_data, bulk_data;
+
+ int_data.ep_in = ep[EP_IN_INT_IDX];
+ int_data.ep_out = ep[EP_OUT_INT_IDX];
+ int_data.buf = int_buf;
+ bulk_data.ep_in = ep[EP_IN_BULK_IDX];
+ bulk_data.ep_out = ep[EP_OUT_BULK_IDX];
+ bulk_data.buf = bulk_buf;
while (1) {
while (!connected) {
if (ret < 0)
return;
}
- while (connected) {
- ret = read(ep[EP_OUT_IDX], buf, sizeof(buf));
- if (ret < 0) {
- if (ret == -ECONNRESET) {
- printf("Connection lost.");
- break;
- }
- return;
- }
-
- ret = write(ep[EP_IN_IDX], buf, ret);
- if (ret < 0) {
- if (ret == -ECONNRESET) {
- printf("Connection lost.");
- break;
- }
- return;
- }
+ ret = pthread_create(&bulk_thread, NULL, loop_thread, &bulk_data);
+ if (ret < 0)
+ return;
+
+ ret = pthread_create(&int_thread, NULL, loop_thread, &int_data);
+ if (ret < 0) {
+ pthread_cancel(bulk_thread);
+ return;
}
+ pthread_join(bulk_thread, NULL);
+ pthread_join(int_thread, NULL);
+
+ connected = 0;
}
}
int main(int argc, char **argv)
{
- int ep[3];
+ int ep[NUM_ENDPOINTS];
int i = 0;
- if (sd_listen_fds(0) < 3) {
+ if (sd_listen_fds(0) < NUM_ENDPOINTS) {
fprintf(stderr, "Expected endpoints not retrieved\n");
return -1;
}
- for (i = 0; i < 3; ++i)
+ for (i = 0; i < NUM_ENDPOINTS; ++i)
ep[i] = SD_LISTEN_FDS_START + i;
do_chat(ep);