usb-host-test: Add interrupt endpoint support 67/164167/4
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Fri, 15 Dec 2017 16:44:26 +0000 (17:44 +0100)
committerKrzysztof Opasiak <k.opasiak@samsung.com>
Fri, 15 Dec 2017 18:30:46 +0000 (18:30 +0000)
Add 2 additional interrupt endpoints to our ffs daemon
to provide also interrupt loop functionality.

Change-Id: I40757984eaf6b5f985e94d8fbca803a2523b1b3b
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
src/usb-host-ffs-test-daemon/CMakeLists.txt
src/usb-host-ffs-test-daemon/descs_gen.c
src/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c

index fb3fed9..e182bb5 100755 (executable)
@@ -11,7 +11,7 @@ pkg_check_modules(SYSTEMD REQUIRED libsystemd)
 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})
index 8cf471c..4abfca1 100644 (file)
@@ -51,19 +51,21 @@ static const struct {
                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,
                },
@@ -79,12 +81,26 @@ static const struct {
                        .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,
                },
@@ -102,6 +118,22 @@ static const struct {
                        .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,
+               },
        },
 };
 
index af17f97..63c434e 100644 (file)
 
 #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]);
 }
 
@@ -94,11 +102,58 @@ int handle_ep0(int ep0, int *connected)
        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) {
@@ -106,41 +161,35 @@ void do_chat(int *ep)
                        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);