<p>laforge <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/15695">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">make ccid_main_functionfs use iso7816_fsm and cuart_driver_tty<br><br>This works up to the point that we're getting the ATR displayed in<br>pcsc_scan<br><br>Change-Id: Ic656fff4a9c6b9aaf4b91aa16f66972ad28f8423<br>---<br>A ccid_common/ccid_slot_fsm.c<br>M ccid_host/Makefile<br>M ccid_host/ccid_main_functionfs.c<br>3 files changed, 218 insertions(+), 3 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/ccid_common/ccid_slot_fsm.c b/ccid_common/ccid_slot_fsm.c</span><br><span>new file mode 100644</span><br><span>index 0000000..06c14f1</span><br><span>--- /dev/null</span><br><span>+++ b/ccid_common/ccid_slot_fsm.c</span><br><span>@@ -0,0 +1,210 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* Code providing a ccid_slot_ops implementation based on iso7716_fsm,</span><br><span style="color: hsl(120, 100%, 40%);">+ * (which in turn sits on top of card_uart) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <unistd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+</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/core/timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "ccid_device.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "cuart.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "iso7816_fsm.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct iso_fsm_slot {</span><br><span style="color: hsl(120, 100%, 40%);">+  /* CCID slot above us */</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ccid_slot *cs;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* main ISO7816-3 FSM instance beneath us */</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_fsm_inst *fi;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* UART beneath the ISO7816-3 FSM */</span><br><span style="color: hsl(120, 100%, 40%);">+  struct card_uart *cuart;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* bSeq of the operation currently in progress */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t seq;</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%);">+struct iso_fsm_slot_instance {</span><br><span style="color: hsl(120, 100%, 40%);">+    struct iso_fsm_slot slot[NR_SLOTS];</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 struct iso_fsm_slot_instance g_si;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct iso_fsm_slot *ccid_slot2iso_fsm_slot(struct ccid_slot *cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_ASSERT(cs->slot_nr < ARRAY_SIZE(g_si.slot));</span><br><span style="color: hsl(120, 100%, 40%);">+       return &g_si.slot[cs->slot_nr];</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 uint8_t sysmousim_sjs1_atr[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+            0x3B, 0x9F, 0x96, 0x80, 0x1F, 0xC7, 0x80, 0x31,</span><br><span style="color: hsl(120, 100%, 40%);">+               0xA0, 0x73, 0xBE, 0x21, 0x13, 0x67, 0x43, 0x20,</span><br><span style="color: hsl(120, 100%, 40%);">+               0x07, 0x18, 0x00, 0x00, 0x01, 0xA5 };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct ccid_pars_decoded iso_fsm_def_pars = {</span><br><span style="color: hsl(120, 100%, 40%);">+   .fi = 372,</span><br><span style="color: hsl(120, 100%, 40%);">+    .di = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+      .clock_stop = CCID_CLOCK_STOP_NOTALLOWED,</span><br><span style="color: hsl(120, 100%, 40%);">+     .inverse_convention = false,</span><br><span style="color: hsl(120, 100%, 40%);">+  .t0 = {</span><br><span style="color: hsl(120, 100%, 40%);">+               .guard_time_etu = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+          .waiting_integer = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+    /* FIXME: T=1 */</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 iso_fsm_slot_pre_proc_cb(struct ccid_slot *cs, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       /* do nothing; real hardware would update the slot related state here */</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 iso_fsm_slot_icc_power_on_async(struct ccid_slot *cs, struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    const struct ccid_pc_to_rdr_icc_power_on *ipo)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       ss->seq = ipo->hdr.bSeq;</span><br><span style="color: hsl(120, 100%, 40%);">+        LOGPCS(cs, LOGL_DEBUG, "scheduling power-up\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* FIXME: do this via a FSM? */</span><br><span style="color: hsl(120, 100%, 40%);">+       card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);</span><br><span style="color: hsl(120, 100%, 40%);">+    card_uart_ctrl(ss->cuart, CUART_CTL_POWER, true);</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_POWER_UP_IND, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      cs->icc_powered = true;</span><br><span style="color: hsl(120, 100%, 40%);">+    card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, true);</span><br><span style="color: hsl(120, 100%, 40%);">+  usleep(10000);</span><br><span style="color: hsl(120, 100%, 40%);">+        card_uart_ctrl(ss->cuart, CUART_CTL_RST, false);</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_REL_IND, NULL);</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%);">+       /* continues in iso_fsm_clot_user_cb once ATR is received */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+static void iso_fsm_clot_user_cb(struct osmo_fsm_inst *fi, int event, int cause, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct iso_fsm_slot *ss = iso7816_fsm_get_user_priv(fi);</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ccid_slot *cs = ss->cs;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct msgb *tpdu, *resp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, cause=%d, data=%p)\n", __func__, event, cause, data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case ISO7816_E_ATR_DONE_IND:</span><br><span style="color: hsl(120, 100%, 40%);">+          tpdu = data;</span><br><span style="color: hsl(120, 100%, 40%);">+          /* FIXME: copy response data over */</span><br><span style="color: hsl(120, 100%, 40%);">+          resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        msgb_data(tpdu), msgb_length(tpdu));</span><br><span style="color: hsl(120, 100%, 40%);">+               ccid_slot_send_unbusy(cs, resp);</span><br><span style="color: hsl(120, 100%, 40%);">+              msgb_free(tpdu);</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case ISO7816_E_TPDU_DONE_IND:</span><br><span style="color: hsl(120, 100%, 40%);">+         tpdu = data;</span><br><span style="color: hsl(120, 100%, 40%);">+          /* FIXME: copy response data over */</span><br><span style="color: hsl(120, 100%, 40%);">+          resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0, msgb_l2(tpdu), msgb_l2len(tpdu));</span><br><span style="color: hsl(120, 100%, 40%);">+           ccid_slot_send_unbusy(cs, resp);</span><br><span style="color: hsl(120, 100%, 40%);">+              msgb_free(tpdu);</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%);">+static void iso_fsm_slot_xfr_block_async(struct ccid_slot *cs, struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+                              const struct ccid_pc_to_rdr_xfr_block *xfb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGPCS(cs, LOGL_DEBUG, "scheduling TPDU transfer\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       ss->seq = xfb->hdr.bSeq;</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_XCEIVE_TPDU_CMD, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+    /* continues in iso_fsm_clot_user_cb once response/error/timeout is received */</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 iso_fsm_slot_set_power(struct ccid_slot *cs, bool enable)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (enable) {</span><br><span style="color: hsl(120, 100%, 40%);">+         card_uart_ctrl(ss->cuart, CUART_CTL_POWER, true);</span><br><span style="color: hsl(120, 100%, 40%);">+  } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              card_uart_ctrl(ss->cuart, CUART_CTL_POWER, false);</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 iso_fsm_slot_set_clock(struct ccid_slot *cs, enum ccid_clock_command cmd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CCID_CLOCK_CMD_STOP:</span><br><span style="color: hsl(120, 100%, 40%);">+             card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, false);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CCID_CLOCK_CMD_RESTART:</span><br><span style="color: hsl(120, 100%, 40%);">+          card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, true);</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_ASSERT(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 int iso_fsm_slot_set_params(struct ccid_slot *cs, enum ccid_protocol_num proto,</span><br><span style="color: hsl(120, 100%, 40%);">+                                const struct ccid_pars_decoded *pars_dec)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  /* we always acknowledge all parameters */</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 iso_fsm_slot_set_rate_and_clock(struct ccid_slot *cs, uint32_t freq_hz, uint32_t rate_bps)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      /* we always acknowledge all rates/clocks */</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int iso_fsm_slot_init(struct ccid_slot *cs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       void *ctx = NULL; /* FIXME */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct card_uart *cuart = talloc_zero(ctx, struct card_uart);</span><br><span style="color: hsl(120, 100%, 40%);">+ char id_buf[16];</span><br><span style="color: hsl(120, 100%, 40%);">+      char *devname = "/dev/null";</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%);">+     LOGPCS(cs, LOGL_DEBUG, "%s\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (cs->slot_nr == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            cs->icc_present = true;</span><br><span style="color: hsl(120, 100%, 40%);">+            devname = "/dev/ttyUSB5";</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%);">+   if (!cuart)</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%);">+     snprintf(id_buf, sizeof(id_buf), "SIM%d", cs->slot_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = card_uart_open(cuart, "tty", devname);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              talloc_free(cuart);</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%);">+     ss->fi = iso7816_fsm_alloc(ctx, LOGL_DEBUG, id_buf, cuart, iso_fsm_clot_user_cb, ss);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!ss->fi) {</span><br><span style="color: hsl(120, 100%, 40%);">+             talloc_free(cuart);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   cs->default_pars = &iso_fsm_def_pars;</span><br><span style="color: hsl(120, 100%, 40%);">+  ss->cuart = cuart;</span><br><span style="color: hsl(120, 100%, 40%);">+ ss->cs = cs;</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%);">+const struct ccid_slot_ops iso_fsm_slot_ops = {</span><br><span style="color: hsl(120, 100%, 40%);">+       .init = iso_fsm_slot_init,</span><br><span style="color: hsl(120, 100%, 40%);">+    .pre_proc_cb = iso_fsm_slot_pre_proc_cb,</span><br><span style="color: hsl(120, 100%, 40%);">+      .icc_power_on_async = iso_fsm_slot_icc_power_on_async,</span><br><span style="color: hsl(120, 100%, 40%);">+        .xfr_block_async = iso_fsm_slot_xfr_block_async,</span><br><span style="color: hsl(120, 100%, 40%);">+      .set_power = iso_fsm_slot_set_power,</span><br><span style="color: hsl(120, 100%, 40%);">+  .set_clock = iso_fsm_slot_set_clock,</span><br><span style="color: hsl(120, 100%, 40%);">+  .set_params = iso_fsm_slot_set_params,</span><br><span style="color: hsl(120, 100%, 40%);">+        .set_rate_and_clock = iso_fsm_slot_set_rate_and_clock,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span>diff --git a/ccid_host/Makefile b/ccid_host/Makefile</span><br><span>index d7bc3be..e9f34cc 100644</span><br><span>--- a/ccid_host/Makefile</span><br><span>+++ b/ccid_host/Makefile</span><br><span>@@ -4,10 +4,14 @@</span><br><span> all: ccid_functionfs hub_functionfs cuart_test cuart_fsm_test</span><br><span> </span><br><span> ccid_functionfs: ccid_main_functionfs.o \</span><br><span style="color: hsl(0, 100%, 40%);">-            ccid_slot_sim.o \</span><br><span style="color: hsl(120, 100%, 40%);">+             cuart_driver_tty.o \</span><br><span style="color: hsl(120, 100%, 40%);">+          utils_ringbuffer.o \</span><br><span>                 logging.o \</span><br><span style="color: hsl(120, 100%, 40%);">+           ../ccid_common/cuart.o \</span><br><span>             ../ccid_common/ccid_proto.o \</span><br><span style="color: hsl(0, 100%, 40%);">-           ../ccid_common/ccid_device.o</span><br><span style="color: hsl(120, 100%, 40%);">+          ../ccid_common/ccid_device.o \</span><br><span style="color: hsl(120, 100%, 40%);">+                ../ccid_common/ccid_slot_fsm.o \</span><br><span style="color: hsl(120, 100%, 40%);">+              ../ccid_common/iso7816_fsm.o</span><br><span>        $(CC) $(CFLAGS) -o $@ $^ $(LIBS) -laio</span><br><span> </span><br><span> hub_functionfs: hub_main_functionfs.o</span><br><span>diff --git a/ccid_host/ccid_main_functionfs.c b/ccid_host/ccid_main_functionfs.c</span><br><span>index 5c0bc3b..d45a936 100644</span><br><span>--- a/ccid_host/ccid_main_functionfs.c</span><br><span>+++ b/ccid_host/ccid_main_functionfs.c</span><br><span>@@ -152,6 +152,7 @@</span><br><span> </span><br><span> #include "ccid_device.h"</span><br><span> #include "ccid_slot_sim.h"</span><br><span style="color: hsl(120, 100%, 40%);">+extern struct ccid_slot_ops iso_fsm_slot_ops;</span><br><span> </span><br><span> #ifndef FUNCTIONFS_SUPPORTS_POLL</span><br><span> #include <libaio.h></span><br><span>@@ -528,7 +529,7 @@</span><br><span> </span><br><span>       signal(SIGUSR1, &signal_handler);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       ccid_instance_init(&g_ci, &c_ops, &slotsim_slot_ops, &descriptors.fs_descs.ccid,</span><br><span style="color: hsl(120, 100%, 40%);">+      ccid_instance_init(&g_ci, &c_ops, &iso_fsm_slot_ops, &descriptors.fs_descs.ccid,</span><br><span>                        data_rates, clock_freqs, "", &ufh);</span><br><span>         ufh.ccid_handle = &g_ci;</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/15695">change 15695</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-ccid-firmware/+/15695"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-ccid-firmware </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ic656fff4a9c6b9aaf4b91aa16f66972ad28f8423 </div>
<div style="display:none"> Gerrit-Change-Number: 15695 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>