<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/simtrace2/+/23634">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">simtrace2-cardem-pcsc: Make it work again<br><br>* support Interrupt STATUS notifications<br>* use osmocom libusb abstraction<br>* use asynchronous URBs for interrupt + bulk<br><br>Change-Id: Ib04798572295f25477719124530b6584780c5b75<br>---<br>M host/src/simtrace2-cardem-pcsc.c<br>1 file changed, 159 insertions(+), 23 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/simtrace2 refs/changes/34/23634/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/host/src/simtrace2-cardem-pcsc.c b/host/src/simtrace2-cardem-pcsc.c</span><br><span>index f11330c..543780f 100644</span><br><span>--- a/host/src/simtrace2-cardem-pcsc.c</span><br><span>+++ b/host/src/simtrace2-cardem-pcsc.c</span><br><span>@@ -47,11 +47,13 @@</span><br><span> #include <osmocom/core/utils.h></span><br><span> #include <osmocom/core/socket.h></span><br><span> #include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/select.h></span><br><span> #include <osmocom/sim/class_tables.h></span><br><span> #include <osmocom/sim/sim.h></span><br><span> </span><br><span> #define ATR_MAX_LEN 33</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGCI(ci, lvl, fmt, args ...) printf(fmt, ## args)</span><br><span> </span><br><span> /* reasonable ATR offering all protocols and voltages</span><br><span>  * smartphones might not care, but other readers do</span><br><span>@@ -180,6 +182,9 @@</span><br><span>   case SIMTRACE_MSGT_DO_CEMU_RX_DATA:</span><br><span>          rc = process_do_rx_da(ci, buf, len);</span><br><span>                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case SIMTRACE_MSGT_BD_CEMU_CONFIG:</span><br><span style="color: hsl(120, 100%, 40%);">+            /* firmware confirms configuration change; ignore */</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span>       default:</span><br><span>             printf("unknown simtrace msg type 0x%02x\n", sh->msg_type);</span><br><span>             rc = -1;</span><br><span>@@ -189,6 +194,144 @@</span><br><span>     return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief Process a STATUS message on IRQ endpoint from the SIMtrace2 */</span><br><span style="color: hsl(120, 100%, 40%);">+static int process_irq_status(struct osmo_st2_cardem_inst *ci, const uint8_t *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        const struct cardemu_usb_msg_status *status = (struct cardemu_usb_msg_status *) buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        LOGCI(ci, LOGL_INFO, "SIMtrace IRQ STATUS: flags=0x%x, fi=%u, di=%u, wi=%u wtime=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+             status->flags, status->fi, status->di, status->wi,</span><br><span style="color: hsl(120, 100%, 40%);">+                status->waiting_time);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 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%);">+static int process_usb_msg_irq(struct osmo_st2_cardem_inst *ci, const uint8_t *buf, unsigned int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *)buf;</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%);">+     LOGCI(ci, LOGL_INFO, "SIMtrace IRQ %s\n", osmo_hexdump(buf, len));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        buf += sizeof(*sh);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (sh->msg_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case SIMTRACE_MSGT_BD_CEMU_STATUS:</span><br><span style="color: hsl(120, 100%, 40%);">+            rc = process_irq_status(ci, buf, len);</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%);">+              LOGCI(ci, LOGL_ERROR, "unknown simtrace msg type 0x%02x\n", sh->msg_type);</span><br><span style="color: hsl(120, 100%, 40%);">+               rc = -1;</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%);">+   return rc;</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_in_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 osmo_st2_cardem_inst *ci = xfer->user_data;</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%);">+               /* 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%);">+               LOGCI(ci, LOGL_FATAL, "USB device disappeared\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          exit(1);</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%);">+              LOGCI(ci, LOGL_FATAL, "USB IN transfer failed, status=%u\n", xfer->status);</span><br><span style="color: hsl(120, 100%, 40%);">+              exit(1);</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_in(struct osmo_st2_cardem_inst *ci)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_st2_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%);">+    struct osmo_st2_cardem_inst *ci = xfer->user_data;</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%);">+               process_usb_msg_irq(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%);">+               LOGCI(ci, LOGL_FATAL, "USB device disappeared\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          exit(1);</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%);">+              LOGCI(ci, LOGL_FATAL, "USB IN transfer failed, status=%u\n", xfer->status);</span><br><span style="color: hsl(120, 100%, 40%);">+              exit(1);</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 osmo_st2_cardem_inst *ci)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_st2_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 style="color: hsl(120, 100%, 40%);">+</span><br><span> static void print_welcome(void)</span><br><span> {</span><br><span>       printf("simtrace2-cardem-pcsc - Using PC/SC reader as SIM\n"</span><br><span>@@ -234,31 +377,9 @@</span><br><span> </span><br><span> static void run_mainloop(struct osmo_st2_cardem_inst *ci)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct osmo_st2_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(0, 100%, 40%);">-   int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>      printf("Entering main loop\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    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; rc=%d\n", 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%);">-                  printf("URB: %s\n", osmo_hexdump(buf, xfer_len));</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(120, 100%, 40%);">+             osmo_select_main(0);</span><br><span>         }</span><br><span> }</span><br><span> </span><br><span>@@ -307,6 +428,12 @@</span><br><span> </span><br><span>        print_welcome();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  rc = osmo_libusb_init(NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              fprintf(stderr, "libusb initialization failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  while (1) {</span><br><span>          int option_index = 0;</span><br><span> </span><br><span>@@ -413,6 +540,8 @@</span><br><span>              ifm->addr = addr;</span><br><span>                 if (path)</span><br><span>                    osmo_strlcpy(ifm->path, path, sizeof(ifm->path));</span><br><span style="color: hsl(120, 100%, 40%);">+               transp->udp_fd = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+               transp->usb_async = true;</span><br><span>                 transp->usb_devh = osmo_libusb_open_claim_interface(NULL, NULL, ifm);</span><br><span>             if (!transp->usb_devh) {</span><br><span>                  fprintf(stderr, "can't open USB device\n");</span><br><span>@@ -432,6 +561,13 @@</span><br><span>                     goto close_exit;</span><br><span>             }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         allocate_and_submit_irq(ci);</span><br><span style="color: hsl(120, 100%, 40%);">+          for (int i = 0; i < 4; i++)</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%);">+         /* request firmware to generate STATUS on IRQ endpoint */</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_st2_cardem_request_config(ci, CEMU_FEAT_F_STATUS_IRQ);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                /* simulate card-insert to modem (owhw, not qmod) */</span><br><span>                 osmo_st2_cardem_request_card_insert(ci, true);</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/simtrace2/+/23634">change 23634</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/simtrace2/+/23634"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: simtrace2 </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ib04798572295f25477719124530b6584780c5b75 </div>
<div style="display:none"> Gerrit-Change-Number: 23634 </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>