laforge has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/42779?usp=email )

 (

1 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted 
one.
 )Change subject: 7816fsm: reset stale cuart state on FSM RESET entry
......................................................................

7816fsm: reset stale cuart state on FSM RESET entry

Reset paths reached without power-cycling (WTIME_EXP, HW_ERR,
CARD_REMOVAL during a warm reset) leave the cuart with stale tx_busy,
rx_threshold and wtime_etu from the prior transaction. The next ATR
then hits card_uart_tx tx_busy assertion, or the ATR receive stalls
because the 33-byte ATR can never reach a multi-byte rx_threshold
left from a TPDU.

The new card_uart_tx_abort() clears tx_busy + rx_after_tx_compl + WT,
without driving a synthetic TX_COMPLETE through the FSM.

iso7816_3_reset_onenter is the right place to do this alongside
rx_threshold=1 and wtime_etu=default, this mirrors what
card_uart_ctrl(POWER_*=0) already does, but for the warm-reset paths
that don't touch power.

Change-Id: Iac8bd7f4f0eecccc9acce149277a4f5016fec7c1
---
M ccid_common/ccid_slot_fsm.c
M ccid_common/cuart.c
M ccid_common/cuart.h
M ccid_common/iso7816_fsm.c
4 files changed, 40 insertions(+), 0 deletions(-)

Approvals:
  jolly: Looks good to me, but someone else must approve
  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 22d3f70..fae2c3b 100644
--- a/ccid_common/ccid_slot_fsm.c
+++ b/ccid_common/ccid_slot_fsm.c
@@ -54,6 +54,8 @@

 static struct iso_fsm_slot_instance g_si;

+static void iso_fsm_slot_abort(struct ccid_slot *cs);
+
 static struct iso_fsm_slot *ccid_slot2iso_fsm_slot(struct ccid_slot *cs)
 {
        OSMO_ASSERT(cs->slot_nr < ARRAY_SIZE(g_si.slot));
diff --git a/ccid_common/cuart.c b/ccid_common/cuart.c
index 737a392..bb47da4 100644
--- a/ccid_common/cuart.c
+++ b/ccid_common/cuart.c
@@ -167,6 +167,24 @@
        return rc;
 }

+/*! Abort any in-flight TX on the cuart side.
+ *
+ * Clears tx_busy and rx_after_tx_compl without driving CUART_E_TX_COMPLETE
+ * through the FSM. Use this when the layer above (the ISO 7816-3 FSM) has
+ * given up on the current transaction (e.g. WTIME / HW_ERR / CARD_REMOVAL)
+ * and is moving to reset state. Any in-flight hardware TX is no longer of
+ * interest to the FSM; if the driver-level DMA happens to complete later,
+ * the resulting TX_COMPLETE notification will see tx_busy already false
+ * and rx_after_tx_compl already false, so it won't spuriously re-enable
+ * the receiver. */
+void card_uart_tx_abort(struct card_uart *cuart)
+{
+       OSMO_ASSERT(cuart);
+       card_uart_wtime_stop(cuart);
+       cuart->tx_busy = false;
+       cuart->rx_after_tx_compl = false;
+}
+
 int card_uart_tx(struct card_uart *cuart, const uint8_t *data, size_t len, 
bool rx_after_complete)
 {
        OSMO_ASSERT(cuart);
diff --git a/ccid_common/cuart.h b/ccid_common/cuart.h
index a9afc1d..a53dc18 100644
--- a/ccid_common/cuart.h
+++ b/ccid_common/cuart.h
@@ -153,6 +153,12 @@
 /*! Schedule (asynchronous) transmit data via UART; optionally enable Rx after 
completion */
 int card_uart_tx(struct card_uart *cuart, const uint8_t *data, size_t len, 
bool rx_after_complete);

+/*! Abort any in-flight TX. Clears tx_busy + stops WT timer. Used by the
+ *  ISO7816-3 FSM when transitioning to RESET, so subsequent transactions
+ *  don't trip card_uart_tx's "TX already in flight" assertion on the stale
+ *  tx_busy left behind by an aborted transfer. */
+void card_uart_tx_abort(struct card_uart *cuart);
+
 /*! Schedule (asynchronous) receive data via UART (after CUART_E_RX_COMPLETE) 
*/
 int card_uart_rx(struct card_uart *cuart, uint8_t *data, size_t len);

diff --git a/ccid_common/iso7816_fsm.c b/ccid_common/iso7816_fsm.c
index bad827a..2b3b41e 100644
--- a/ccid_common/iso7816_fsm.c
+++ b/ccid_common/iso7816_fsm.c
@@ -31,6 +31,7 @@

 #include "logging.h"
 #include "cuart.h"
+#include "iso7816_3.h"
 #include "iso7816_fsm.h"

 /* unionize to ensure at least properly aligned msgb struct */
@@ -312,7 +313,20 @@
        struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);
        OSMO_ASSERT(fi->fsm == &iso7816_3_fsm);

+       /* Bring the cuart back to its default per-transaction state, matching
+        * what card_uart_ctrl(CUART_CTL_POWER_*, 0) does, but without
+        * power-cycling (warm reset, HW_ERR, WTIME paths reach S_RESET without
+        * touching power). Any reset path could land here mid-transaction with
+        * stale state: tx_busy still set from an aborted TX, rx_threshold left
+        * at e.g. 256 from a multi-byte RX setup, wtime_etu still at a
+        * PPS-negotiated value rather than the ATR default. Leaving those
+        * stale breaks the next ATR (next card_uart_tx asserts; or ATR bytes
+        * pile up in the ringbuffer waiting for a threshold that ATR's max 33
+        * bytes can never reach). */
        card_uart_ctrl(ip->uart, CUART_CTL_RX_TIMER_HINT, 0);
+       card_uart_tx_abort(ip->uart);
+       card_uart_set_rx_threshold(ip->uart, 1);
+       card_uart_ctrl(ip->uart, CUART_CTL_WTIME, ISO7816_3_DEFAULT_WT);

        /* go back to initial state in child FSMs */
        osmo_fsm_inst_state_chg(ip->atr_fi, ATR_S_WAIT_TS, 0, 0);

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

Gerrit-MessageType: merged
Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-Change-Id: Iac8bd7f4f0eecccc9acce149277a4f5016fec7c1
Gerrit-Change-Number: 42779
Gerrit-PatchSet: 2
Gerrit-Owner: Hoernchen <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: jolly <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: lynxis lazus <[email protected]>

Reply via email to