<p>Kévin Redon has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/9874">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">host USB: add host application to receive and display USB sniffing messages sent by firmware<br><br>Change-Id: Idefbf21e0bbd2a1e3647fe9aebaf88d1b62dae2d<br>---<br>M host/Makefile<br>A host/simtrace2-sniff.c<br>2 files changed, 535 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/simtrace2 refs/changes/74/9874/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/host/Makefile b/host/Makefile</span><br><span>index 47ccfec..50497c4 100644</span><br><span>--- a/host/Makefile</span><br><span>+++ b/host/Makefile</span><br><span>@@ -1,7 +1,7 @@</span><br><span> LDFLAGS=`pkg-config --libs libusb-1.0 libosmocore` -losmocore</span><br><span> CFLAGS=-Wall -g</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-all: simtrace2-remsim simtrace2-remsim-usb2udp simtrace2-list</span><br><span style="color: hsl(120, 100%, 40%);">+all: simtrace2-remsim simtrace2-remsim-usb2udp simtrace2-list simtrace2-sniff</span><br><span> </span><br><span> simtrace2-remsim: simtrace2-remsim.o apdu_dispatch.o simtrace2-discovery.o libusb_util.o</span><br><span>     $(CC) -o $@ $^ $(LDFLAGS) -losmosim</span><br><span>@@ -12,6 +12,9 @@</span><br><span> simtrace2-list: simtrace2_usb.o libusb_util.o</span><br><span>     $(CC) -o $@ $^ $(LDFLAGS)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+simtrace2-sniff: simtrace2-sniff.o simtrace2-discovery.o libusb_util.o</span><br><span style="color: hsl(120, 100%, 40%);">+ $(CC) -o $@ $^ $(LDFLAGS)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> %.o: %.c</span><br><span>      $(CC) $(CFLAGS) `pkg-config --cflags libusb-1.0 libosmocore` -o $@ -c $^</span><br><span> </span><br><span>diff --git a/host/simtrace2-sniff.c b/host/simtrace2-sniff.c</span><br><span>new file mode 100644</span><br><span>index 0000000..df3e28a</span><br><span>--- /dev/null</span><br><span>+++ b/host/simtrace2-sniff.c</span><br><span>@@ -0,0 +1,531 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* simtrace2-sniff - main program for the host PC to communicate with the SIMtrace 2 firmware in sniffer mode */</span><br><span style="color: hsl(120, 100%, 40%);">+/* This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 </span><br><span style="color: hsl(120, 100%, 40%);">+ * as published by the Free Software Foundation</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program; if not, write to the Free Software</span><br><span style="color: hsl(120, 100%, 40%);">+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2010-2017 by Harald Welte <hwelte@hmw-consulting.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018 by Kevin Redon <kredon@sysmocom.de></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%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <unistd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <signal.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <time.h></span><br><span style="color: hsl(120, 100%, 40%);">+#define _GNU_SOURCE</span><br><span style="color: hsl(120, 100%, 40%);">+#include <getopt.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/time.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/types.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <netinet/in.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arpa/inet.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <libusb.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "libusb_util.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "simtrace.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "simtrace_usb.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "simtrace_prot.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "simtrace2-discovery.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/gsmtap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/gsmtap_util.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/sim/class_tables.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/sim/sim.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* transport to a SIMtrace device */</span><br><span style="color: hsl(120, 100%, 40%);">+struct st_transport {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* USB */</span><br><span style="color: hsl(120, 100%, 40%);">+     struct libusb_device_handle *usb_devh;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              uint8_t in;</span><br><span style="color: hsl(120, 100%, 40%);">+           uint8_t out;</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t irq_in;</span><br><span style="color: hsl(120, 100%, 40%);">+       } usb_ep;</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%);">+/* global GSMTAP instance */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct gsmtap_inst *g_gti;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int gsmtap_send_sim(const uint8_t *apdu, unsigned int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsmtap_hdr *gh;</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int gross_len = len + sizeof(*gh);</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t *buf = malloc(gross_len);</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%);">+     if (!buf)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     memset(buf, 0, sizeof(*gh));</span><br><span style="color: hsl(120, 100%, 40%);">+  gh = (struct gsmtap_hdr *) buf;</span><br><span style="color: hsl(120, 100%, 40%);">+       gh->version = GSMTAP_VERSION;</span><br><span style="color: hsl(120, 100%, 40%);">+      gh->hdr_len = sizeof(*gh)/4;</span><br><span style="color: hsl(120, 100%, 40%);">+       gh->type = GSMTAP_TYPE_SIM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      memcpy(buf + sizeof(*gh), apdu, len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = write(gsmtap_inst_fd(g_gti), buf, gross_len);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              perror("write gsmtap");</span><br><span style="color: hsl(120, 100%, 40%);">+             free(buf);</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%);">+   free(buf);</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_change(uint8_t *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check if there is enough data for the structure */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (len<sizeof(struct sniff_change)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     struct sniff_change *change = (struct sniff_change *)buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (SNIFF_CHANGE_FLAG_TIMEOUT_WT!=change->flags) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printf("Card state change: ");</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (change->flags&SNIFF_CHANGE_FLAG_CARD_INSERT) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("card inserted ");</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (change->flags&SNIFF_CHANGE_FLAG_CARD_EJECT) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("card ejected ");</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (change->flags&SNIFF_CHANGE_FLAG_RESET_HOLD) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("reset hold ");</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (change->flags&SNIFF_CHANGE_FLAG_RESET_RELEASE) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("reset release ");</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (change->flags&SNIFF_CHANGE_FLAG_TIMEOUT_WT) {</span><br><span style="color: hsl(120, 100%, 40%);">+              // do nothing since this also triggers on inactivity</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (SNIFF_CHANGE_FLAG_TIMEOUT_WT!=change->flags) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printf("\n");</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 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%);">+/* Table 7 of ISO 7816-3:2006 */</span><br><span style="color: hsl(120, 100%, 40%);">+static const uint16_t fi_table[] = { 372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0, };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Table 8 from ISO 7816-3:2006 */</span><br><span style="color: hsl(120, 100%, 40%);">+static const uint8_t di_table[] = { 0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 2, 4, 8, 16, 32, 64, };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int process_fidi(uint8_t *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    /* check if there is enough data for the structure */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (len<sizeof(struct sniff_fidi)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     struct sniff_fidi *fidi = (struct sniff_fidi *)buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Fi/Di switched to %u/%u\n", fi_table[fidi->fidi>>4], di_table[fidi->fidi&0x0f]);</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_atr(uint8_t *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      /* check if there is enough data for the structure */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (len<sizeof(struct sniff_data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     struct sniff_data *atr = (struct sniff_data *)buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* check if the data is available */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (len<sizeof(struct sniff_data)+atr->length) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return -2;</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%);">+   printf("ATR%s: ", atr->complete ? "" : " (incomplete)");</span><br><span style="color: hsl(120, 100%, 40%);">+     for (uint16_t i=0; i<atr->length; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("%02x ", atr->data[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("\n");</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_pps(uint8_t *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      /* check if there is enough data for the structure */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (len<sizeof(struct sniff_data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     struct sniff_data *pps = (struct sniff_data *)buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* check if the data is available */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (len<sizeof(struct sniff_data)+pps->length) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return -2;</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%);">+   printf("PPS%s: ", pps->complete ? "" : " (incomplete) ");</span><br><span style="color: hsl(120, 100%, 40%);">+    for (uint16_t i=0; i<pps->length; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("%02x ", pps->data[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("\n");</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_tpdu(uint8_t *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     /* check if there is enough data for the structure */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (len<sizeof(struct sniff_data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     struct sniff_data *tpdu = (struct sniff_data *)buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* check if the data is available */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (len<sizeof(struct sniff_data)+tpdu->length) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return -2;</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%);">+   printf("TPDU%s: ", tpdu->complete ? "" : " (incomplete)");</span><br><span style="color: hsl(120, 100%, 40%);">+   for (uint16_t i=0; i<tpdu->length; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("%02x ", tpdu->data[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("\n");</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%);">+/*! \brief Process an incoming message from the SIMtrace2 */</span><br><span style="color: hsl(120, 100%, 40%);">+static int process_usb_msg(uint8_t *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    /* check if enough data for the header is present */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (len<sizeof(struct simtrace_msg_hdr)) {</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%);">+   /* check if message is complete */</span><br><span style="color: hsl(120, 100%, 40%);">+    struct simtrace_msg_hdr *msg_hdr = (struct simtrace_msg_hdr *)buf;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (len<msg_hdr->msg_len) {</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%);">+     //printf("msg: %s\n", osmo_hexdump(buf, msg_hdr->msg_len));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* check for message class */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (SIMTRACE_MSGC_SNIFF!=msg_hdr->msg_class) { /* we only care about sniffing messages */</span><br><span style="color: hsl(120, 100%, 40%);">+          return msg_hdr->msg_len; /* discard non-sniffing messaged */</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%);">+   /* process sniff message payload */</span><br><span style="color: hsl(120, 100%, 40%);">+   buf += sizeof(struct simtrace_msg_hdr);</span><br><span style="color: hsl(120, 100%, 40%);">+       len -= sizeof(struct simtrace_msg_hdr);</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (msg_hdr->msg_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case SIMTRACE_MSGT_SNIFF_CHANGE:</span><br><span style="color: hsl(120, 100%, 40%);">+              process_change(buf, len);</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case SIMTRACE_MSGT_SNIFF_FIDI:</span><br><span style="color: hsl(120, 100%, 40%);">+                process_fidi(buf, len);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case SIMTRACE_MSGT_SNIFF_ATR:</span><br><span style="color: hsl(120, 100%, 40%);">+         process_atr(buf, len);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case SIMTRACE_MSGT_SNIFF_PPS:</span><br><span style="color: hsl(120, 100%, 40%);">+         process_pps(buf, len);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case SIMTRACE_MSGT_SNIFF_TPDU:</span><br><span style="color: hsl(120, 100%, 40%);">+                process_tpdu(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%);">+              printf("unknown SIMtrace msg type 0x%02x\n", msg_hdr->msg_type);</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 msg_hdr->msg_len;</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%);">+/*! Transport to SIMtrace device (e.g. USB handle) */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct st_transport _transp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void run_mainloop()</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%);">+       uint8_t buf[16*256];</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned int buf_i = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       int xfer_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</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%);">+   while (true) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* read data from SIMtrace2 device (via USB) */</span><br><span style="color: hsl(120, 100%, 40%);">+               rc = libusb_bulk_transfer(_transp.usb_devh, _transp.usb_ep.in,</span><br><span style="color: hsl(120, 100%, 40%);">+                                          &buf[buf_i], sizeof(buf)-buf_i, &xfer_len, 100000);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (rc < 0 && rc != LIBUSB_ERROR_TIMEOUT &&</span><br><span style="color: hsl(120, 100%, 40%);">+                              rc != LIBUSB_ERROR_INTERRUPTED &&</span><br><span style="color: hsl(120, 100%, 40%);">+                             rc != LIBUSB_ERROR_IO) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        fprintf(stderr, "BULK IN transfer error; rc=%d\n", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+                     return;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             /* dispatch any incoming data */</span><br><span style="color: hsl(120, 100%, 40%);">+              if (xfer_len > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        //printf("URB: %s\n", osmo_hexdump(&buf[buf_i], xfer_len));</span><br><span style="color: hsl(120, 100%, 40%);">+                     buf_i += xfer_len;</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (buf_i>=sizeof(buf)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          perror("preventing USB buffer overflow");</span><br><span style="color: hsl(120, 100%, 40%);">+                           return;</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span style="color: hsl(120, 100%, 40%);">+                     int processed = process_usb_msg(buf, buf_i);</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (processed>0 && processed<=buf_i) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          for (unsigned int i=processed; i<buf_i; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                     buf[i-processed] = buf[i];</span><br><span style="color: hsl(120, 100%, 40%);">+                            }</span><br><span style="color: hsl(120, 100%, 40%);">+                             buf_i -= processed;</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 style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void print_welcome(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("simtrace2-sniff - Phone-SIM card communication sniffer \n"</span><br><span style="color: hsl(120, 100%, 40%);">+         "(C) 2010-2017 by Harald Welte <laforge@gnumonks.org>\n"</span><br><span style="color: hsl(120, 100%, 40%);">+              "(C) 2018 by Kevin Redon <kredon@sysmocom.de>\n"</span><br><span style="color: hsl(120, 100%, 40%);">+              "\n"</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 print_help(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      printf(</span><br><span style="color: hsl(120, 100%, 40%);">+               "\t-h\t--help\n"</span><br><span style="color: hsl(120, 100%, 40%);">+            "\t-i\t--gsmtap-ip\tA.B.C.D\n"</span><br><span style="color: hsl(120, 100%, 40%);">+              "\t-k\t--keep-running\n"</span><br><span style="color: hsl(120, 100%, 40%);">+            "\t-V\t--usb-vendor\tVENDOR_ID\n"</span><br><span style="color: hsl(120, 100%, 40%);">+           "\t-P\t--usb-product\tPRODUCT_ID\n"</span><br><span style="color: hsl(120, 100%, 40%);">+         "\t-C\t--usb-config\tCONFIG_ID\n"</span><br><span style="color: hsl(120, 100%, 40%);">+           "\t-I\t--usb-interface\tINTERFACE_ID\n"</span><br><span style="color: hsl(120, 100%, 40%);">+             "\t-S\t--usb-altsetting ALTSETTING_ID\n"</span><br><span style="color: hsl(120, 100%, 40%);">+            "\t-A\t--usb-address\tADDRESS\n"</span><br><span style="color: hsl(120, 100%, 40%);">+            "\n"</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 const struct option opts[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+        { "help", 0, 0, 'h' },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "gsmtap-ip", 1, 0, 'i' },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "keep-running", 0, 0, 'k' },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "usb-vendor", 1, 0, 'V' },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "usb-product", 1, 0, 'P' },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "usb-config", 1, 0, 'C' },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "usb-interface", 1, 0, 'I' },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "usb-altsetting", 1, 0, 'S' },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "usb-address", 1, 0, 'A' },</span><br><span style="color: hsl(120, 100%, 40%);">+       { NULL, 0, 0, 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%);">+/* Known USB device with SIMtrace firmware supporting sniffer */</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct dev_id compatible_dev_ids[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+        { USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { 0, 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 void signal_handler(int signal)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (signal) {</span><br><span style="color: hsl(120, 100%, 40%);">+     case SIGINT:</span><br><span style="color: hsl(120, 100%, 40%);">+          exit(0);</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%);">+              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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int main(int argc, char **argv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc, ret;</span><br><span style="color: hsl(120, 100%, 40%);">+  print_welcome();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Parse arguments */</span><br><span style="color: hsl(120, 100%, 40%);">+ char *gsmtap_host = "127.0.0.1";</span><br><span style="color: hsl(120, 100%, 40%);">+    int keep_running = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int vendor_id = -1, product_id = -1, addr = -1, config_id = -1, if_num = -1, altsetting = -1;</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%);">+           int option_index = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               char c = getopt_long(argc, argv, "hi:kV:P:C:I:S:A:", opts, &option_index);</span><br><span style="color: hsl(120, 100%, 40%);">+              if (c == -1)</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span style="color: hsl(120, 100%, 40%);">+                switch (c) {</span><br><span style="color: hsl(120, 100%, 40%);">+          case 'h':</span><br><span style="color: hsl(120, 100%, 40%);">+                     print_help();</span><br><span style="color: hsl(120, 100%, 40%);">+                 exit(0);</span><br><span style="color: hsl(120, 100%, 40%);">+                      break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'i':</span><br><span style="color: hsl(120, 100%, 40%);">+                     gsmtap_host = optarg;</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'k':</span><br><span style="color: hsl(120, 100%, 40%);">+                     keep_running = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'V':</span><br><span style="color: hsl(120, 100%, 40%);">+                     vendor_id = strtol(optarg, NULL, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'P':</span><br><span style="color: hsl(120, 100%, 40%);">+                     product_id = strtol(optarg, NULL, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'C':</span><br><span style="color: hsl(120, 100%, 40%);">+                     config_id = atoi(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'I':</span><br><span style="color: hsl(120, 100%, 40%);">+                     if_num = atoi(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'S':</span><br><span style="color: hsl(120, 100%, 40%);">+                     altsetting = atoi(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+                    break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'A':</span><br><span style="color: hsl(120, 100%, 40%);">+                     addr = atoi(optarg);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Scan for available SIMtrace USB devices supporting sniffing */</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = 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%);">+          goto do_exit;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     struct usb_interface_match ifm_scan[16];</span><br><span style="color: hsl(120, 100%, 40%);">+      int num_interfaces = usb_match_interfaces(NULL, compatible_dev_ids,</span><br><span style="color: hsl(120, 100%, 40%);">+                            USB_CLASS_PROPRIETARY, SIMTRACE_SNIFFER_USB_SUBCLASS, -1, ifm_scan, ARRAY_SIZE(ifm_scan));</span><br><span style="color: hsl(120, 100%, 40%);">+   if (num_interfaces <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         perror("No compatible USB devices found");</span><br><span style="color: hsl(120, 100%, 40%);">+          goto do_exit;</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%);">+   /* Only keep USB matching arguments */</span><br><span style="color: hsl(120, 100%, 40%);">+        struct usb_interface_match ifm_filtered[ARRAY_SIZE(ifm_scan)];</span><br><span style="color: hsl(120, 100%, 40%);">+        int num_filtered = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (unsigned int i = 0; i < num_interfaces; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (vendor_id>=0 && vendor_id!=ifm_scan[i].vendor) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (product_id>=0 && product_id!=ifm_scan[i].product) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (config_id>=0 && config_id!=ifm_scan[i].configuration) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (if_num>=0 && if_num!=ifm_scan[i].interface) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (altsetting>=0 && altsetting!=ifm_scan[i].altsetting) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (addr>=0 && addr!=ifm_scan[i].addr) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             ifm_filtered[num_filtered++] = ifm_scan[i];</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (1!=num_filtered) {</span><br><span style="color: hsl(120, 100%, 40%);">+                perror("No individual matching USB devices found");</span><br><span style="color: hsl(120, 100%, 40%);">+         printf("Available USB devices:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         for (unsigned int i = 0; i < num_interfaces; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        printf("\t%04x:%04x Addr=%u, Path=%s, Cfg=%u, Intf=%u, Alt=%u: %d/%d/%d ",</span><br><span style="color: hsl(120, 100%, 40%);">+                  ifm_scan[i].vendor, ifm_scan[i].product, ifm_scan[i].addr, ifm_scan[i].path,</span><br><span style="color: hsl(120, 100%, 40%);">+                  ifm_scan[i].configuration, ifm_scan[i].interface, ifm_scan[i].altsetting,</span><br><span style="color: hsl(120, 100%, 40%);">+                     ifm_scan[i].class, ifm_scan[i].sub_class, ifm_scan[i].protocol);</span><br><span style="color: hsl(120, 100%, 40%);">+                      libusb_device_handle *dev_handle;</span><br><span style="color: hsl(120, 100%, 40%);">+                     rc = libusb_open(ifm_scan[i].usb_dev, &dev_handle);</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                               perror("Cannot open device");</span><br><span style="color: hsl(120, 100%, 40%);">+                               continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     char strbuf[256];</span><br><span style="color: hsl(120, 100%, 40%);">+                     rc = libusb_get_string_descriptor_ascii(dev_handle, ifm_scan[i].string_idx,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   (unsigned char *)strbuf, sizeof(strbuf));</span><br><span style="color: hsl(120, 100%, 40%);">+                     libusb_close(dev_handle);</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                               perror("Cannot read string");</span><br><span style="color: hsl(120, 100%, 40%);">+                               continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("(%s)\n", strbuf);</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+             goto do_exit;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     struct usb_interface_match ifm_selected = ifm_filtered[0];</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("Using USB device %04x:%04x Addr=%u, Path=%s, Cfg=%u, Intf=%u, Alt=%u: %d/%d/%d ",</span><br><span style="color: hsl(120, 100%, 40%);">+   ifm_selected.vendor, ifm_selected.product, ifm_selected.addr, ifm_selected.path,</span><br><span style="color: hsl(120, 100%, 40%);">+      ifm_selected.configuration, ifm_selected.interface, ifm_selected.altsetting,</span><br><span style="color: hsl(120, 100%, 40%);">+  ifm_selected.class, ifm_selected.sub_class, ifm_selected.protocol);</span><br><span style="color: hsl(120, 100%, 40%);">+   libusb_device_handle *dev_handle;</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = libusb_open(ifm_selected.usb_dev, &dev_handle);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               perror("Cannot open device");</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     char strbuf[256];</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = libusb_get_string_descriptor_ascii(dev_handle, ifm_selected.string_idx,</span><br><span style="color: hsl(120, 100%, 40%);">+                  (unsigned char *)strbuf, sizeof(strbuf));</span><br><span style="color: hsl(120, 100%, 40%);">+     libusb_close(dev_handle);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               perror("Cannot read string");</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("(%s)\n", strbuf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!g_gti) {</span><br><span style="color: hsl(120, 100%, 40%);">+         perror("unable to open GSMTAP");</span><br><span style="color: hsl(120, 100%, 40%);">+            goto close_exit;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     gsmtap_source_add_sink(g_gti);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      signal(SIGINT, &signal_handler);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        do {</span><br><span style="color: hsl(120, 100%, 40%);">+          _transp.usb_devh = usb_open_claim_interface(NULL, &ifm_selected);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!_transp.usb_devh) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      fprintf(stderr, "can't open USB device\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                     goto close_exit;</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%);">+           rc = libusb_claim_interface(_transp.usb_devh, ifm_selected.interface);</span><br><span style="color: hsl(120, 100%, 40%);">+                if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      fprintf(stderr, "can't claim interface %d; rc=%d\n", ifm_selected.interface, rc);</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto close_exit;</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%);">+           rc = get_usb_ep_addrs(_transp.usb_devh, ifm_selected.interface, &_transp.usb_ep.out,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    &_transp.usb_ep.in, &_transp.usb_ep.irq_in);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      fprintf(stderr, "can't obtain EP addrs; rc=%d\n", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+                  goto close_exit;</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%);">+           run_mainloop();</span><br><span style="color: hsl(120, 100%, 40%);">+               ret = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (_transp.usb_devh)</span><br><span style="color: hsl(120, 100%, 40%);">+                 libusb_release_interface(_transp.usb_devh, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+close_exit:</span><br><span style="color: hsl(120, 100%, 40%);">+           if (_transp.usb_devh)</span><br><span style="color: hsl(120, 100%, 40%);">+                 libusb_close(_transp.usb_devh);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (keep_running)</span><br><span style="color: hsl(120, 100%, 40%);">+                     sleep(1);</span><br><span style="color: hsl(120, 100%, 40%);">+     } while (keep_running);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     libusb_exit(NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+do_exit:</span><br><span style="color: hsl(120, 100%, 40%);">+  return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9874">change 9874</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/9874"/><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-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Idefbf21e0bbd2a1e3647fe9aebaf88d1b62dae2d </div>
<div style="display:none"> Gerrit-Change-Number: 9874 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Kévin Redon <kredon@sysmocom.de> </div>