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