Change in osmo-ccid-firmware[master]: 7816 fsm/cuart: support inverse condition cards

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Fri Nov 20 08:54:19 UTC 2020


laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/21114 )

Change subject: 7816 fsm/cuart: support inverse condition cards
......................................................................

7816 fsm/cuart: support inverse condition cards

This does not currently work with "pcsc-lite version 1.8.26." because
the inverse conditon cards I know do not support the PPS exchange, which
according to spec leads to card deactivation, so the slots needs to be
powered up again, which does not happen.

osmo-sim-test works after manually disabling the pps exchange code in
the firmware.

Change-Id: I892e1d883825111cc1e4ea09589c4fdd256da03c
---
M ccid_common/ccid_slot_fsm.c
M ccid_common/cuart.h
M ccid_common/iso7816_fsm.c
M sysmoOCTSIM/cuart_driver_asf4_usart_async.c
4 files changed, 52 insertions(+), 7 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/ccid_common/ccid_slot_fsm.c b/ccid_common/ccid_slot_fsm.c
index a8c4e54..4cf75bc 100644
--- a/ccid_common/ccid_slot_fsm.c
+++ b/ccid_common/ccid_slot_fsm.c
@@ -204,10 +204,16 @@
 		break;
 	case ISO7816_E_ATR_DONE_IND:
 		tpdu = data;
-		LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,
-			msgb_hexdump(tpdu));
-		resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0,
-					   msgb_data(tpdu), msgb_length(tpdu));
+
+		/* inverse condition, error interrupt is always disabled during atr and reenabled here after atr */
+		if(*msgb_data(tpdu) == 0x3f) {
+			card_uart_ctrl(ss->cuart, CUART_CTL_ERROR_AND_INV, true);
+		} else {
+			card_uart_ctrl(ss->cuart, CUART_CTL_ERROR_AND_INV, false);
+		}
+
+		LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event, msgb_hexdump(tpdu));
+		resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0, msgb_data(tpdu), msgb_length(tpdu));
 		ccid_slot_send_unbusy(cs, resp);
 		cs->event = 0;
 		break;
diff --git a/ccid_common/cuart.h b/ccid_common/cuart.h
index e5ec501..c0a3a52 100644
--- a/ccid_common/cuart.h
+++ b/ccid_common/cuart.h
@@ -54,6 +54,7 @@
 	CUART_CTL_SET_FD,
 	CUART_CTL_GET_BAUDRATE,
 	CUART_CTL_GET_CLOCK_FREQ,
+	CUART_CTL_ERROR_AND_INV, /* enable error interrupt and maybe inverse signalling according to arg */
 };
 
 struct card_uart;
diff --git a/ccid_common/iso7816_fsm.c b/ccid_common/iso7816_fsm.c
index e819e64..8e113b0 100644
--- a/ccid_common/iso7816_fsm.c
+++ b/ccid_common/iso7816_fsm.c
@@ -639,6 +639,15 @@
 	struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);
 	uint8_t byte = *(uint8_t *)data;
 
+	return byte;
+}
+
+/* obtain the 'byte' (possbily inverted) parameter of an ISO7816_E_RX event */
+static uint8_t get_atr_rx_byte_evt(struct osmo_fsm_inst *fi, void *data)
+{
+	struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);
+	uint8_t byte = *(uint8_t *)data;
+
 	/* apply inverse convention */
 	if (ip->convention_convert)
 		byte = convention_convert_lut[byte];
@@ -689,14 +698,14 @@
 	case ISO7816_E_RX_SINGLE:
 		OSMO_ASSERT(msgb_length(atp->atr) == 0);
 restart:
-		byte = get_rx_byte_evt(parent_fi, data);
+		byte = get_atr_rx_byte_evt(parent_fi, data);
 		LOGPFSML(fi, LOGL_DEBUG, "RX byte '%02x'\n", byte);
 		switch (byte) {
 		case 0x23:
 			/* direct convention used, but decoded using inverse
 			 * convention (a parity error should also have occurred) */
 			/* fall-through */
-		case 0x30:
+		case 0x03:
 			/* inverse convention used, but decoded using direct
 			 * convention (a parity error should also have occurred) */
 			ip->convention_convert = !ip->convention_convert;
@@ -732,7 +741,7 @@
 
 	switch (event) {
 	case ISO7816_E_RX_SINGLE:
-		byte = get_rx_byte_evt(fi->proc.parent, data);
+		byte = get_atr_rx_byte_evt(fi->proc.parent, data);
 		LOGPFSML(fi, LOGL_DEBUG, "RX byte '%02x'\n", byte);
 		atr_append_byte(fi, byte);
 		switch (fi->state) {
diff --git a/sysmoOCTSIM/cuart_driver_asf4_usart_async.c b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c
index 89cd734..e6d180c 100644
--- a/sysmoOCTSIM/cuart_driver_asf4_usart_async.c
+++ b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c
@@ -159,6 +159,19 @@
  */
 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};
 
+/** inverted signalling as per 7816-3 : inverted bit, inverted bit order
+ */
+static void set_inverted_signalling(void* hw, bool on) {
+
+	hri_sercomusart_clear_CTRLA_ENABLE_bit(hw);
+
+	hri_sercomusart_write_CTRLA_DORD_bit(hw, !on); // inverted == msb first
+	hri_sercomusart_write_CTRLA_TXINV_bit(hw, on);
+	hri_sercomusart_write_CTRLA_RXINV_bit(hw, on);
+	hri_sercomusart_write_CTRLB_PMODE_bit(hw, on); // inverted == even parity
+
+	hri_sercomusart_set_CTRLA_ENABLE_bit(hw);
+}
 
 /** change baud rate of card slot
  *  @param[in] slotnr slot number for which the baud rate should be set
@@ -237,6 +250,7 @@
 static bool slot_set_isorate(struct card_uart *cuart, enum ncn8025_sim_clkdiv clkdiv, uint16_t f, uint8_t d)
 {
 	uint8_t slotnr = cuart->u.asf4.slot_nr;
+	struct usart_async_descriptor* slot = SIM_peripheral_descriptors[slotnr];
 
 	// input checks
 	ASSERT(slotnr < ARRAY_SIZE(SIM_peripheral_descriptors));
@@ -275,6 +289,12 @@
 		break;
 	}
 
+	/* error interrupt off after reset due to possbile inverted atr and accompanying parity error
+	 * this was automatically enabled during error callback registration */
+	hri_sercomusart_write_INTEN_ERROR_bit(slot->device.hw, 0);
+
+	set_inverted_signalling(slot->device.hw, false);
+
 	// set baud rate
 	uint32_t baudrate = (freq * d) / f; // calculate actual baud rate
 	return slot_set_baudrate(cuart, baudrate); // set baud rate
@@ -435,6 +455,15 @@
 		ncn8025_get(cuart->u.asf4.slot_nr, &settings);
 		return 20e6 / ncn8025_div_val[settings.clkdiv];
 		break;
+	case CUART_CTL_ERROR_AND_INV:
+		set_inverted_signalling(sercom, arg);
+
+		/* clear pending errors that happened while the interrupt was off (ATR) and enable it*/
+		hri_sercomusart_clear_interrupt_ERROR_bit(sercom);
+		hri_sercomusart_clear_STATUS_reg(sercom, 0xff);
+		volatile uint8_t dummy = hri_sercomusart_read_RXERRCNT_reg(sercom);
+		hri_sercomusart_set_INTEN_ERROR_bit(sercom);
+		break;
 	default:
 		return 0;
 	}

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/21114
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-Change-Id: I892e1d883825111cc1e4ea09589c4fdd256da03c
Gerrit-Change-Number: 21114
Gerrit-PatchSet: 2
Gerrit-Owner: Hoernchen <ewild at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20201120/3a4271fe/attachment.htm>


More information about the gerrit-log mailing list