<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/21114">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;">7816 fsm/cuart: support inverse condition cards<br><br>This does not currently work with "pcsc-lite version 1.8.26." because<br>the inverse conditon cards I know do not support the PPS exchange, which<br>according to spec leads to card deactivation, so the slots needs to be<br>powered up again, which does not happen.<br><br>osmo-sim-test works after manually disabling the pps exchange code in<br>the firmware.<br><br>Change-Id: I892e1d883825111cc1e4ea09589c4fdd256da03c<br>---<br>M ccid_common/ccid_slot_fsm.c<br>M ccid_common/cuart.h<br>M ccid_common/iso7816_fsm.c<br>M sysmoOCTSIM/cuart_driver_asf4_usart_async.c<br>4 files changed, 52 insertions(+), 7 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>index a8c4e54..4cf75bc 100644</span><br><span>--- a/ccid_common/ccid_slot_fsm.c</span><br><span>+++ b/ccid_common/ccid_slot_fsm.c</span><br><span>@@ -204,10 +204,16 @@</span><br><span>           break;</span><br><span>       case ISO7816_E_ATR_DONE_IND:</span><br><span>                 tpdu = data;</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,</span><br><span style="color: hsl(0, 100%, 40%);">-                    msgb_hexdump(tpdu));</span><br><span style="color: hsl(0, 100%, 40%);">-            resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                                          msgb_data(tpdu), msgb_length(tpdu));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             /* inverse condition, error interrupt is always disabled during atr and reenabled here after atr */</span><br><span style="color: hsl(120, 100%, 40%);">+           if(*msgb_data(tpdu) == 0x3f) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        card_uart_ctrl(ss->cuart, CUART_CTL_ERROR_AND_INV, 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_ERROR_AND_INV, 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%);">+           LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event, msgb_hexdump(tpdu));</span><br><span style="color: hsl(120, 100%, 40%);">+             resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0, msgb_data(tpdu), msgb_length(tpdu));</span><br><span>               ccid_slot_send_unbusy(cs, resp);</span><br><span>             cs->event = 0;</span><br><span>            break;</span><br><span>diff --git a/ccid_common/cuart.h b/ccid_common/cuart.h</span><br><span>index e5ec501..c0a3a52 100644</span><br><span>--- a/ccid_common/cuart.h</span><br><span>+++ b/ccid_common/cuart.h</span><br><span>@@ -54,6 +54,7 @@</span><br><span>  CUART_CTL_SET_FD,</span><br><span>    CUART_CTL_GET_BAUDRATE,</span><br><span>      CUART_CTL_GET_CLOCK_FREQ,</span><br><span style="color: hsl(120, 100%, 40%);">+     CUART_CTL_ERROR_AND_INV, /* enable error interrupt and maybe inverse signalling according to arg */</span><br><span> };</span><br><span> </span><br><span> struct card_uart;</span><br><span>diff --git a/ccid_common/iso7816_fsm.c b/ccid_common/iso7816_fsm.c</span><br><span>index e819e64..8e113b0 100644</span><br><span>--- a/ccid_common/iso7816_fsm.c</span><br><span>+++ b/ccid_common/iso7816_fsm.c</span><br><span>@@ -639,6 +639,15 @@</span><br><span>   struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);</span><br><span>  uint8_t byte = *(uint8_t *)data;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  return byte;</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%);">+/* obtain the 'byte' (possbily inverted) parameter of an ISO7816_E_RX event */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t get_atr_rx_byte_evt(struct osmo_fsm_inst *fi, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t byte = *(uint8_t *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   /* apply inverse convention */</span><br><span>       if (ip->convention_convert)</span><br><span>               byte = convention_convert_lut[byte];</span><br><span>@@ -689,14 +698,14 @@</span><br><span>         case ISO7816_E_RX_SINGLE:</span><br><span>            OSMO_ASSERT(msgb_length(atp->atr) == 0);</span><br><span> restart:</span><br><span style="color: hsl(0, 100%, 40%);">-         byte = get_rx_byte_evt(parent_fi, data);</span><br><span style="color: hsl(120, 100%, 40%);">+              byte = get_atr_rx_byte_evt(parent_fi, data);</span><br><span>                 LOGPFSML(fi, LOGL_DEBUG, "RX byte '%02x'\n", byte);</span><br><span>                switch (byte) {</span><br><span>              case 0x23:</span><br><span>                   /* direct convention used, but decoded using inverse</span><br><span>                          * convention (a parity error should also have occurred) */</span><br><span>                  /* fall-through */</span><br><span style="color: hsl(0, 100%, 40%);">-              case 0x30:</span><br><span style="color: hsl(120, 100%, 40%);">+            case 0x03:</span><br><span>                   /* inverse convention used, but decoded using direct</span><br><span>                          * convention (a parity error should also have occurred) */</span><br><span>                  ip->convention_convert = !ip->convention_convert;</span><br><span>@@ -732,7 +741,7 @@</span><br><span> </span><br><span>    switch (event) {</span><br><span>     case ISO7816_E_RX_SINGLE:</span><br><span style="color: hsl(0, 100%, 40%);">-               byte = get_rx_byte_evt(fi->proc.parent, data);</span><br><span style="color: hsl(120, 100%, 40%);">+             byte = get_atr_rx_byte_evt(fi->proc.parent, data);</span><br><span>                LOGPFSML(fi, LOGL_DEBUG, "RX byte '%02x'\n", byte);</span><br><span>                atr_append_byte(fi, byte);</span><br><span>           switch (fi->state) {</span><br><span>diff --git a/sysmoOCTSIM/cuart_driver_asf4_usart_async.c b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c</span><br><span>index 89cd734..e6d180c 100644</span><br><span>--- a/sysmoOCTSIM/cuart_driver_asf4_usart_async.c</span><br><span>+++ b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c</span><br><span>@@ -159,6 +159,19 @@</span><br><span>  */</span><br><span> static const uint8_t SIM_peripheral_GCLK_ID[] = {SERCOM0_GCLK_ID_CORE, SERCOM1_GCLK_ID_CORE, SERCOM2_GCLK_ID_CORE, SERCOM3_GCLK_ID_CORE, SERCOM4_GCLK_ID_CORE, SERCOM5_GCLK_ID_CORE, SERCOM6_GCLK_ID_CORE, SERCOM7_GCLK_ID_CORE};</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/** inverted signalling as per 7816-3 : inverted bit, inverted bit order</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void set_inverted_signalling(void* hw, bool on) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    hri_sercomusart_clear_CTRLA_ENABLE_bit(hw);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hri_sercomusart_write_CTRLA_DORD_bit(hw, !on); // inverted == msb first</span><br><span style="color: hsl(120, 100%, 40%);">+       hri_sercomusart_write_CTRLA_TXINV_bit(hw, on);</span><br><span style="color: hsl(120, 100%, 40%);">+        hri_sercomusart_write_CTRLA_RXINV_bit(hw, on);</span><br><span style="color: hsl(120, 100%, 40%);">+        hri_sercomusart_write_CTRLB_PMODE_bit(hw, on); // inverted == even parity</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   hri_sercomusart_set_CTRLA_ENABLE_bit(hw);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> /** change baud rate of card slot</span><br><span>  *  @param[in] slotnr slot number for which the baud rate should be set</span><br><span>@@ -237,6 +250,7 @@</span><br><span> static bool slot_set_isorate(struct card_uart *cuart, enum ncn8025_sim_clkdiv clkdiv, uint16_t f, uint8_t d)</span><br><span> {</span><br><span>  uint8_t slotnr = cuart->u.asf4.slot_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct usart_async_descriptor* slot = SIM_peripheral_descriptors[slotnr];</span><br><span> </span><br><span>        // input checks</span><br><span>      ASSERT(slotnr < ARRAY_SIZE(SIM_peripheral_descriptors));</span><br><span>@@ -275,6 +289,12 @@</span><br><span>           break;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* error interrupt off after reset due to possbile inverted atr and accompanying parity error</span><br><span style="color: hsl(120, 100%, 40%);">+  * this was automatically enabled during error callback registration */</span><br><span style="color: hsl(120, 100%, 40%);">+       hri_sercomusart_write_INTEN_ERROR_bit(slot->device.hw, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       set_inverted_signalling(slot->device.hw, false);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        // set baud rate</span><br><span>     uint32_t baudrate = (freq * d) / f; // calculate actual baud rate</span><br><span>    return slot_set_baudrate(cuart, baudrate); // set baud rate</span><br><span>@@ -435,6 +455,15 @@</span><br><span>           ncn8025_get(cuart->u.asf4.slot_nr, &settings);</span><br><span>                return 20e6 / ncn8025_div_val[settings.clkdiv];</span><br><span>              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CUART_CTL_ERROR_AND_INV:</span><br><span style="color: hsl(120, 100%, 40%);">+         set_inverted_signalling(sercom, arg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               /* clear pending errors that happened while the interrupt was off (ATR) and enable it*/</span><br><span style="color: hsl(120, 100%, 40%);">+               hri_sercomusart_clear_interrupt_ERROR_bit(sercom);</span><br><span style="color: hsl(120, 100%, 40%);">+            hri_sercomusart_clear_STATUS_reg(sercom, 0xff);</span><br><span style="color: hsl(120, 100%, 40%);">+               volatile uint8_t dummy = hri_sercomusart_read_RXERRCNT_reg(sercom);</span><br><span style="color: hsl(120, 100%, 40%);">+           hri_sercomusart_set_INTEN_ERROR_bit(sercom);</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span>       default:</span><br><span>             return 0;</span><br><span>    }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/21114">change 21114</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/+/21114"/><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: I892e1d883825111cc1e4ea09589c4fdd256da03c </div>
<div style="display:none"> Gerrit-Change-Number: 21114 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Hoernchen <ewild@sysmocom.de> </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>