<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-remsim/+/16610">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">remsim_client: Port to async libosmousb select loop<br><br>By using the non-blocking / asynchronous libusb via the newly-<br>introduced libosmousb (integration to libosmocore select loop),<br>we can not only get a cleaner code-base, but we also get a<br>considerable speed-up.<br><br>In my tests with a Quectel E25 and a sysmoUSIM-SJS1 card,<br>I am down from 41.4s to 4.7s for the initial reading of the SIM<br>at start-up.<br><br>Change-Id: Ic18690b3c2cbc5e99de0665c0b68b7555433b3cd<br>Closes: OS#4299<br>Depends: libosmocore.git I656a1a38cbb5b1f3a9145d2869d3b4d0adefcae3<br>---<br>M src/simtrace2-remsim_client.c<br>1 file changed, 140 insertions(+), 34 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-remsim refs/changes/10/16610/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/simtrace2-remsim_client.c b/src/simtrace2-remsim_client.c</span><br><span>index 30a9c5b..fa6b102 100644</span><br><span>--- a/src/simtrace2-remsim_client.c</span><br><span>+++ b/src/simtrace2-remsim_client.c</span><br><span>@@ -143,20 +143,50 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void usb_out_xfer_cb(struct libusb_transfer *xfer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct msgb *msg = xfer->user_data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      switch (xfer->status) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case LIBUSB_TRANSFER_COMPLETED:</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case LIBUSB_TRANSFER_NO_DEVICE:</span><br><span style="color: hsl(120, 100%, 40%);">+               fprintf(stderr, "USB device disappeared\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                exit(23);</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_panic("USB OUT transfer failed, status=%u\n", xfer->status);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       libusb_free_transfer(xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Transmit a given command to the SIMtrace2 device */</span><br><span> int st_transp_tx_msg(struct st_transport *transp, struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        struct libusb_transfer *xfer;</span><br><span>        int rc;</span><br><span> </span><br><span>  printf("SIMtrace <- %s\n", msgb_hexdump(msg));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- int xfer_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ xfer = libusb_alloc_transfer(0);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+    xfer->dev_handle = transp->usb_devh;</span><br><span style="color: hsl(120, 100%, 40%);">+    xfer->flags = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   xfer->type = LIBUSB_TRANSFER_TYPE_BULK;</span><br><span style="color: hsl(120, 100%, 40%);">+    xfer->endpoint = transp->usb_ep.out;</span><br><span style="color: hsl(120, 100%, 40%);">+    xfer->timeout = 1000;</span><br><span style="color: hsl(120, 100%, 40%);">+      xfer->user_data = msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     xfer->length = msgb_length(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+   xfer->buffer = msgb_data(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+     xfer->callback = usb_out_xfer_cb;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.out,</span><br><span style="color: hsl(0, 100%, 40%);">-           msgb_data(msg), msgb_length(msg),</span><br><span style="color: hsl(0, 100%, 40%);">-               &xfer_len, 1000);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* submit the OUT transfer */</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = libusb_submit_transfer(xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(rc == 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_free(msg);</span><br><span>      return rc;</span><br><span> }</span><br><span> </span><br><span>@@ -472,38 +502,106 @@</span><br><span>         return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void run_mainloop(struct cardem_inst *ci)</span><br><span style="color: hsl(120, 100%, 40%);">+static void usb_in_xfer_cb(struct libusb_transfer *xfer)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct st_transport *transp = ci->slot->transp;</span><br><span style="color: hsl(0, 100%, 40%);">-   unsigned int msg_count, byte_count = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t buf[16*265];</span><br><span style="color: hsl(0, 100%, 40%);">-    int xfer_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct cardem_inst *ci = xfer->user_data;</span><br><span>         int rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     printf("Entering main loop\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       while (1) {</span><br><span style="color: hsl(0, 100%, 40%);">-             /* read data from SIMtrace2 device (local or via USB) */</span><br><span style="color: hsl(0, 100%, 40%);">-                rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.in,</span><br><span style="color: hsl(0, 100%, 40%);">-                     buf, sizeof(buf), &xfer_len, 100);</span><br><span style="color: hsl(0, 100%, 40%);">-         if (rc < 0 && rc != LIBUSB_ERROR_TIMEOUT &&</span><br><span style="color: hsl(0, 100%, 40%);">-                  rc != LIBUSB_ERROR_INTERRUPTED &&</span><br><span style="color: hsl(0, 100%, 40%);">-                       rc != LIBUSB_ERROR_IO) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        fprintf(stderr, "BULK IN transfer error: %s\n", libusb_error_name(rc));</span><br><span style="color: hsl(0, 100%, 40%);">-                       return;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-               /* dispatch any incoming data */</span><br><span style="color: hsl(0, 100%, 40%);">-                if (xfer_len > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  process_usb_msg(ci, buf, xfer_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                     msg_count++;</span><br><span style="color: hsl(0, 100%, 40%);">-                    byte_count += xfer_len;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-               // handle remote SIM client fsm</span><br><span style="color: hsl(0, 100%, 40%);">-         // TODO register the USB fd for this select</span><br><span style="color: hsl(0, 100%, 40%);">-             osmo_select_main(true);</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (xfer->status) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case LIBUSB_TRANSFER_COMPLETED:</span><br><span style="color: hsl(120, 100%, 40%);">+               /* hand the message up the stack */</span><br><span style="color: hsl(120, 100%, 40%);">+           process_usb_msg(ci, xfer->buffer, xfer->actual_length);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case LIBUSB_TRANSFER_NO_DEVICE:</span><br><span style="color: hsl(120, 100%, 40%);">+               fprintf(stderr, "USB device disappeared\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                exit(23);</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_panic("USB IN transfer failed, status=%u\n", xfer->status);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span>       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* re-submit the IN transfer */</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = libusb_submit_transfer(xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(rc == 0);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void allocate_and_submit_in(struct cardem_inst *ci)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct st_transport *transp = ci->slot->transp;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct libusb_transfer *xfer;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     xfer = libusb_alloc_transfer(0);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+    xfer->dev_handle = transp->usb_devh;</span><br><span style="color: hsl(120, 100%, 40%);">+    xfer->flags = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   xfer->type = LIBUSB_TRANSFER_TYPE_BULK;</span><br><span style="color: hsl(120, 100%, 40%);">+    xfer->endpoint = transp->usb_ep.in;</span><br><span style="color: hsl(120, 100%, 40%);">+     xfer->timeout = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ xfer->user_data = ci;</span><br><span style="color: hsl(120, 100%, 40%);">+      xfer->length = 16*256;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   xfer->buffer = libusb_dev_mem_alloc(xfer->dev_handle, xfer->length);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(xfer->buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+ xfer->callback = usb_in_xfer_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* submit the IN transfer */</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = libusb_submit_transfer(xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(rc == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void usb_irq_xfer_cb(struct libusb_transfer *xfer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (xfer->status) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case LIBUSB_TRANSFER_COMPLETED:</span><br><span style="color: hsl(120, 100%, 40%);">+               /* FIXME: do something with the received data */</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case LIBUSB_TRANSFER_NO_DEVICE:</span><br><span style="color: hsl(120, 100%, 40%);">+               fprintf(stderr, "USB device disappeared\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                exit(23);</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_panic("USB IRQ transfer failed, status=%u\n", xfer->status);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* re-submit the IN transfer */</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = libusb_submit_transfer(xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(rc == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void allocate_and_submit_irq(struct cardem_inst *ci)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct st_transport *transp = ci->slot->transp;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct libusb_transfer *xfer;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     xfer = libusb_alloc_transfer(0);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+    xfer->dev_handle = transp->usb_devh;</span><br><span style="color: hsl(120, 100%, 40%);">+    xfer->flags = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   xfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT;</span><br><span style="color: hsl(120, 100%, 40%);">+       xfer->endpoint = transp->usb_ep.irq_in;</span><br><span style="color: hsl(120, 100%, 40%);">+ xfer->timeout = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ xfer->user_data = ci;</span><br><span style="color: hsl(120, 100%, 40%);">+      xfer->length = 64;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       xfer->buffer = libusb_dev_mem_alloc(xfer->dev_handle, xfer->length);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(xfer->buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+ xfer->callback = usb_irq_xfer_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* submit the IN transfer */</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = libusb_submit_transfer(xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(rc == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct st_transport _transp;</span><br><span> </span><br><span> static struct st_slot _slot = {</span><br><span>@@ -652,7 +750,7 @@</span><br><span> static void print_welcome(void)</span><br><span> {</span><br><span>     printf("simtrace2-remsim-client - Remote SIM card client for SIMtrace\n"</span><br><span style="color: hsl(0, 100%, 40%);">-             "(C) 2010-2017, Harald Welte <laforge@gnumonks.org>\n"</span><br><span style="color: hsl(120, 100%, 40%);">+        "(C) 2010-2019, Harald Welte <laforge@gnumonks.org>\n"</span><br><span>               "(C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>\n\n");</span><br><span> }</span><br><span> </span><br><span>@@ -794,7 +892,7 @@</span><br><span>    msgb_talloc_ctx_init(g_tall_ctx, 0);</span><br><span>         osmo_init_logging2(g_tall_ctx, &log_info);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      rc = libusb_init(NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = osmo_libusb_init(NULL);</span><br><span>         if (rc < 0) {</span><br><span>             fprintf(stderr, "libusb initialization failed\n");</span><br><span>                 goto do_exit;</span><br><span>@@ -941,7 +1039,15 @@</span><br><span>                /* select remote (forwarded) SIM */</span><br><span>          st_modem_reset_pulse(ci->slot, 300);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-             run_mainloop(ci);</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Entering main loop\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           allocate_and_submit_irq(ci);</span><br><span style="color: hsl(120, 100%, 40%);">+          allocate_and_submit_in(ci);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   osmo_select_main(false);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>          ret = 0;</span><br><span> </span><br><span>                 libusb_release_interface(transp->usb_devh, 0);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-remsim/+/16610">change 16610</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-remsim/+/16610"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-remsim </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ic18690b3c2cbc5e99de0665c0b68b7555433b3cd </div>
<div style="display:none"> Gerrit-Change-Number: 16610 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>