<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>