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.orgHoernchen has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/16238 ) Change subject: attempt at handling card insertion/removal ...................................................................... attempt at handling card insertion/removal Change-Id: Ib1a9a9c5cfb8c22cc3b885bc30a349e0f0145630 --- 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(+), 34 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware refs/changes/38/16238/1 diff --git a/ccid_common/ccid_device.c b/ccid_common/ccid_device.c index ba36988..84bd09a 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 c675ece..3d09a84 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); } @@ -376,22 +386,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); -// struct osmo_fsm_inst *parent_fi = fi->proc.parent; -// struct iso7816_3_priv *ip = get_iso7816_3_priv(parent_fi); - - switch (event) { - case ISO7816_E_XCEIVE_PPS_CMD: - osmo_fsm_inst_state_chg(fi, ISO7816_S_WAIT_PPS_RSP, 0, 0); -// card_uart_tx(tfp->uart, msgb_data(data), msgb_length(data), true); - break; - default: - OSMO_ASSERT(0); - } -} - static void iso7816_3_s_wait_pps_rsp_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) { @@ -438,7 +432,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, @@ -471,7 +467,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, @@ -490,15 +485,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) | @@ -885,18 +871,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); @@ -976,6 +971,8 @@ osmo_fsm_inst_dispatch(fi->proc.parent, ISO7816_E_PPS_FAILED_IND, atp->tx_cmd); } + /* ownership transfer */ + atp->tx_cmd = 0; } break; default: @@ -1097,6 +1094,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) { @@ -1315,6 +1322,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); @@ -1346,6 +1356,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 1949aa8..92091cd 100644 --- a/sysmoOCTSIM/main.c +++ b/sysmoOCTSIM/main.c @@ -353,7 +353,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/+/16238 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: Ib1a9a9c5cfb8c22cc3b885bc30a349e0f0145630 Gerrit-Change-Number: 16238 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/20191126/89253d90/attachment.htm>