Change in osmo-ccid-firmware[master]: attempt at handling card insertion/removal

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

Hoernchen gerrit-no-reply at lists.osmocom.org
Wed Nov 27 18:44:10 UTC 2019


Hoernchen has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/16275 )


Change subject: attempt at handling card insertion/removal
......................................................................

attempt at handling card insertion/removal

Change-Id: I88130de7f889811425c0a2ca4063ea8822c83f66
---
M ccid_common/ccid_device.c
M ccid_common/ccid_device.h
M ccid_common/ccid_slot_fsm.c
M ccid_common/iso7816_fsm.c
M ccid_common/iso7816_fsm.h
M sysmoOCTSIM/main.c
6 files changed, 89 insertions(+), 31 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware refs/changes/75/16275/1

diff --git a/ccid_common/ccid_device.c b/ccid_common/ccid_device.c
index c67c52e..11edd3e 100644
--- a/ccid_common/ccid_device.c
+++ b/ccid_common/ccid_device.c
@@ -438,9 +438,20 @@
 {
 	const union ccid_pc_to_rdr *u = msgb_ccid_out(msg);
 	const struct ccid_header *ch = (const struct ccid_header *) u;
+	struct msgb *resp;
+	int rc;
 
 	/* handle this asynchronously */
-	cs->ci->slot_ops->xfr_block_async(cs, msg, &u->xfr_block);
+	rc = cs->ci->slot_ops->xfr_block_async(cs, msg, &u->xfr_block);
+	if (rc < 0) {
+		msgb_trim(msg, sizeof(struct ccid_rdr_to_pc_data_block));
+		resp = ccid_gen_data_block(cs, u->xfr_block.hdr.bSeq, CCID_CMD_STATUS_FAILED, -rc, 0, 0);
+		goto out;
+	}
+	/* busy */
+	return 1;
+out:
+	ccid_slot_send_unbusy(cs, resp);
 	return 1;
 }
 
diff --git a/ccid_common/ccid_device.h b/ccid_common/ccid_device.h
index 8390783..38a71db 100644
--- a/ccid_common/ccid_device.h
+++ b/ccid_common/ccid_device.h
@@ -78,13 +78,14 @@
 
 	void (*icc_power_on_async)(struct ccid_slot *cs, struct msgb *msg,
 				   const struct ccid_pc_to_rdr_icc_power_on *ipo);
-	void (*xfr_block_async)(struct ccid_slot *cs, struct msgb *msg,
+	int (*xfr_block_async)(struct ccid_slot *cs, struct msgb *msg,
 				const struct ccid_pc_to_rdr_xfr_block *xfb);
 	void (*set_power)(struct ccid_slot *cs, bool enable);
 	void (*set_clock)(struct ccid_slot *cs, enum ccid_clock_command cmd);
 	int (*set_params)(struct ccid_slot *cs, uint8_t seq, enum ccid_protocol_num proto,
 			  const struct ccid_pars_decoded *pars_dec);
 	int (*set_rate_and_clock)(struct ccid_slot *cs, uint32_t freq_hz, uint32_t rate_bps);
+	void (*icc_set_insertion_status)(struct ccid_slot *cs, bool present);
 };
 
 /* An instance of CCID (i.e. a card reader device) */
diff --git a/ccid_common/ccid_slot_fsm.c b/ccid_common/ccid_slot_fsm.c
index 8bdcfd5..8d38f29 100644
--- a/ccid_common/ccid_slot_fsm.c
+++ b/ccid_common/ccid_slot_fsm.c
@@ -66,6 +66,23 @@
 	/* do nothing; real hardware would update the slot related state here */
 }
 
+static void iso_fsm_slot_icc_set_insertion_status(struct ccid_slot *cs, bool present) {
+	struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
+
+	if(present == cs->icc_present)
+		return;
+
+	cs->icc_present = present;
+
+	if (!present) {
+		osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_CARD_REMOVAL, NULL);
+		card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);
+		card_uart_ctrl(ss->cuart, CUART_CTL_POWER, false);
+		cs->icc_powered = false;
+		cs->cmd_busy = false;
+	}
+}
+
 static void iso_fsm_slot_icc_power_on_async(struct ccid_slot *cs, struct msgb *msg,
 					const struct ccid_pc_to_rdr_icc_power_on *ipo)
 {
@@ -113,6 +130,15 @@
 		ccid_slot_send_unbusy(cs, resp);
 		msgb_free(tpdu);
 		break;
+	case ISO7816_E_TPDU_FAILED_IND:
+		tpdu = data;
+		LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, cause=%d, data=%s)\n", __func__, event, cause,
+			msgb_hexdump(tpdu));
+		/* FIXME: other error causes than card removal?*/
+		resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_FAILED, CCID_ERR_ICC_MUTE, msgb_l2(tpdu), 0);
+		ccid_slot_send_unbusy(cs, resp);
+		msgb_free(tpdu);
+		break;
 	case ISO7816_E_PPS_DONE_IND:
 		tpdu = data;
 		/* pps was successful, so we know these values are fine */
@@ -147,12 +173,15 @@
 	}
 }
 
-static void iso_fsm_slot_xfr_block_async(struct ccid_slot *cs, struct msgb *msg,
+static int iso_fsm_slot_xfr_block_async(struct ccid_slot *cs, struct msgb *msg,
 				const struct ccid_pc_to_rdr_xfr_block *xfb)
 {
 	struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
 	struct msgb *tpdu;
 
+	if(!cs->icc_present)
+		return -CCID_ERR_ICC_MUTE;
+
 	ss->seq = xfb->hdr.bSeq;
 
 	/* must be '0' for TPDU level exchanges or for short APDU */
@@ -171,6 +200,7 @@
 	LOGPCS(cs, LOGL_DEBUG, "scheduling TPDU transfer: %s\n", msgb_hexdump(tpdu));
 	osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_XCEIVE_TPDU_CMD, tpdu);
 	/* continues in iso_fsm_clot_user_cb once response/error/timeout is received */
+	return 0;
 }
 
 
@@ -296,6 +326,7 @@
 	.init = iso_fsm_slot_init,
 	.pre_proc_cb = iso_fsm_slot_pre_proc_cb,
 	.icc_power_on_async = iso_fsm_slot_icc_power_on_async,
+	.icc_set_insertion_status = iso_fsm_slot_icc_set_insertion_status,
 	.xfr_block_async = iso_fsm_slot_xfr_block_async,
 	.set_power = iso_fsm_slot_set_power,
 	.set_clock = iso_fsm_slot_set_clock,
diff --git a/ccid_common/iso7816_fsm.c b/ccid_common/iso7816_fsm.c
index d02a955..98c32d3 100644
--- a/ccid_common/iso7816_fsm.c
+++ b/ccid_common/iso7816_fsm.c
@@ -45,7 +45,6 @@
 	ISO7816_S_IN_ATR, /*!< while we are receiving the ATR */
 	ISO7816_S_WAIT_TPDU, /*!< waiting for start of new TPDU */
 	ISO7816_S_IN_TPDU, /*!< inside a single TPDU */
-	ISO7816_S_IN_PPS_REQ, /*!< while we are inside the PPS request */
 	ISO7816_S_WAIT_PPS_RSP, /*!< waiting for start of the PPS response */
 	ISO7816_S_IN_PPS_RSP, /*!< while we are inside the PPS request */
 };
@@ -230,6 +229,7 @@
 {
 	struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);
 	OSMO_ASSERT(fi->fsm == &iso7816_3_fsm);
+	struct msgb *msg;
 
 	switch (event) {
 	case ISO7816_E_RESET_REL_IND:
@@ -238,6 +238,16 @@
 		osmo_fsm_inst_state_chg_ms(fi, ISO7816_S_WAIT_ATR,
 					   fi_cycles2ms(fi, 40000), T_WAIT_ATR);
 		break;
+	case ISO7816_E_PPS_FAILED_IND:
+		msg = data;
+		/* notify user about PPS result */
+		ip->user_cb(fi, event, 0, msg);
+		break;
+	case ISO7816_E_TPDU_FAILED_IND:
+		msg = data;
+		/* hand finished TPDU to user */
+		ip->user_cb(fi, event, 0, msg);
+		break;
 	default:
 		OSMO_ASSERT(0);
 	}
@@ -375,19 +385,6 @@
 	}
 }
 
-static void iso7816_3_in_pps_req_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
-{
-	struct iso7816_3_priv *tfp = get_iso7816_3_priv(fi);
-
-	switch (event) {
-	case ISO7816_E_XCEIVE_PPS_CMD:
-		osmo_fsm_inst_state_chg(fi, ISO7816_S_WAIT_PPS_RSP, 0, 0);
-		break;
-	default:
-		OSMO_ASSERT(0);
-	}
-}
-
 
 static void iso7816_3_s_wait_pps_rsp_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
@@ -434,7 +431,9 @@
 static const struct osmo_fsm_state iso7816_3_states[] = {
 	[ISO7816_S_RESET] = {
 		.name = "RESET",
-		.in_event_mask =	S(ISO7816_E_RESET_REL_IND),
+		.in_event_mask =	S(ISO7816_E_RESET_REL_IND) |
+							S(ISO7816_E_PPS_FAILED_IND)|
+							S(ISO7816_E_TPDU_FAILED_IND),
 		.out_state_mask =	S(ISO7816_S_WAIT_ATR) |
 					S(ISO7816_S_RESET),
 		.action = iso7816_3_reset_action,
@@ -467,7 +466,6 @@
 		.out_state_mask =	S(ISO7816_S_RESET) |
 					S(ISO7816_S_WAIT_TPDU) |
 					S(ISO7816_S_IN_TPDU) |
-					S(ISO7816_S_IN_PPS_REQ) |
 					S(ISO7816_S_WAIT_PPS_RSP),
 		.action = iso7816_3_wait_tpdu_action,
 		.onenter = iso7816_3_wait_tpdu_onenter,
@@ -486,15 +484,6 @@
 					S(ISO7816_S_IN_TPDU),
 		.action = iso7816_3_in_tpdu_action,
 	},
-	[ISO7816_S_IN_PPS_REQ] = {
-		.name = "IN_PPS_REQ",
-		.in_event_mask =	S(ISO7816_E_XCEIVE_TPDU_CMD),
-		.out_state_mask =	S(ISO7816_S_RESET) |
-					S(ISO7816_S_WAIT_TPDU) |
-					S(ISO7816_S_IN_PPS_REQ) |
-					S(ISO7816_S_WAIT_PPS_RSP),
-		.action = iso7816_3_in_pps_req_action,
-	},
 	[ISO7816_S_WAIT_PPS_RSP] = {
 		.name = "WAIT_PPS_RESP",
 		.in_event_mask =	S(ISO7816_E_TX_COMPL) |
@@ -881,18 +870,27 @@
 	struct pps_fsm_priv *atp = fi->priv;
 
 	if (!atp->rx_cmd)
-		atp->rx_cmd = msgb_alloc_c(fi, 6, "ATR"); /* TS + 32 chars */
+		atp->rx_cmd = msgb_alloc_c(fi, 6, "PPSRSP"); /* at most 6 */
 	else
 		msgb_reset(atp->rx_cmd);
+
+	/* notify in case card got pulled out */
+	if (atp->tx_cmd){
+		osmo_fsm_inst_dispatch(fi->proc.parent,
+				ISO7816_E_PPS_FAILED_IND, atp->tx_cmd);
+		atp->tx_cmd = 0;
+	}
 }
 
 static void pps_s_tx_pps_req_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	struct pps_fsm_priv *atp = fi->priv;
-	atp->tx_cmd = data;
 	struct osmo_fsm_inst *parent_fi = fi->proc.parent;
 	struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi);
 
+	/* keep the buffer to compare it with the received response */
+	atp->tx_cmd = data;
+
 	switch (event) {
 	case ISO7816_E_XCEIVE_PPS_CMD:
 		osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPSS, 0, 0);
@@ -972,6 +970,8 @@
 					osmo_fsm_inst_dispatch(fi->proc.parent,
 							ISO7816_E_PPS_FAILED_IND, atp->tx_cmd);
 				}
+				/* ownership transfer */
+				atp->tx_cmd = 0;
 			}
 			break;
 		default:
@@ -1093,6 +1093,16 @@
 	return (struct tpdu_fsm_priv *) fi->priv;
 }
 
+static void tpdu_s_init_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
+{
+	struct tpdu_fsm_priv *tfp = get_tpdu_fsm_priv(fi);
+
+	/* notify in case card got pulled out */
+	if (tfp->tpdu){
+		osmo_fsm_inst_dispatch(fi->proc.parent, ISO7816_E_TPDU_FAILED_IND, tfp->tpdu);
+		tfp->tpdu = 0;
+	}
+}
 
 static void tpdu_s_init_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
@@ -1311,6 +1321,9 @@
 		osmo_fsm_inst_state_chg(fi, TPDU_S_DONE, 0, 0);
 		/* Notify parent FSM */
 		osmo_fsm_inst_dispatch(fi->proc.parent, ISO7816_E_TPDU_DONE_IND, tfp->tpdu);
+
+		/* ownership transfer */
+		tfp->tpdu = 0;
 		break;
 	default:
 		OSMO_ASSERT(0);
@@ -1342,6 +1355,7 @@
 		.out_state_mask = S(TPDU_S_INIT) |
 				  S(TPDU_S_TX_HDR),
 		.action = tpdu_s_init_action,
+		.onenter = tpdu_s_init_onenter,
 	},
 	[TPDU_S_TX_HDR] = {
 		.name = "TX_HDR",
diff --git a/ccid_common/iso7816_fsm.h b/ccid_common/iso7816_fsm.h
index f512709..d4aee59 100644
--- a/ccid_common/iso7816_fsm.h
+++ b/ccid_common/iso7816_fsm.h
@@ -32,6 +32,7 @@
 	ISO7816_E_ATR_DONE_IND,		/*!< ATR Done indication from ATR child FSM */
 	ISO7816_E_ATR_ERR_IND,		/*!< ATR Error indication from ATR child FSM */
 	ISO7816_E_TPDU_DONE_IND,	/*!< TPDU Done indication from TPDU child FSM */
+	ISO7816_E_TPDU_FAILED_IND,	/*!< TPDU Failed indication from TPDU child FSM */
 	ISO7816_E_TPDU_CLEAR_REQ,	/*!< Return TPDU FSM to TPDU_S_INIT */
 };
 
diff --git a/sysmoOCTSIM/main.c b/sysmoOCTSIM/main.c
index 7ddca92..959e7eb 100644
--- a/sysmoOCTSIM/main.c
+++ b/sysmoOCTSIM/main.c
@@ -303,7 +303,7 @@
 	for (i = 0; i < 8; i++){
 		bool level = ncn8025_interrupt_level(i);
 		new_mask |= level << i;
-		g_ci.slot[i].icc_present = level;
+		g_ci.slot_ops->icc_set_insertion_status(&g_ci.slot[i], level);
 	}
 
 	/* notify the user/host about any changes */

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/16275
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: I88130de7f889811425c0a2ca4063ea8822c83f66
Gerrit-Change-Number: 16275
Gerrit-PatchSet: 1
Gerrit-Owner: Hoernchen <ewild at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20191127/224bc639/attachment.htm>


More information about the gerrit-log mailing list