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

Change subject: ccid setparameters/PPS support
......................................................................

ccid setparameters/PPS support

Change-Id: I280969ec9fe681dedae14ae8e6806f69eed3ff5a
---
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
5 files changed, 322 insertions(+), 21 deletions(-)

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



diff --git a/ccid_common/ccid_device.c b/ccid_common/ccid_device.c
index 8183b16..c67c52e 100644
--- a/ccid_common/ccid_device.c
+++ b/ccid_common/ccid_device.c
@@ -23,9 +23,11 @@
 /* decode on-the-wire T0 parameters into their parsed form */
 static int decode_ccid_pars_t0(struct ccid_pars_decoded *out, const struct 
ccid_proto_data_t0 *in)
 {
-       /* input validation: only 0x00 and 0x02 permitted for bmTCCKST0 */
-       if (in->bmTCCKST0 & 0xFD)
-               return -11;
+       /* input validation: only 0x00 and 0x02 permitted for bmTCCKST0
+        * if (in->bmTCCKST0 & 0xFD)
+        *      return -11;
+        * 7816-3 6.1.7 says: "Note: the CCID ignores this bit", placeholder 
for GETparameters */
+
        /* input validation: only 0x00 to 0x03 permitted for bClockSTop */
        if (in->bClockStop & 0xFC)
                return -14;
@@ -254,7 +256,7 @@
        }
        return msg;
 }
-static struct msgb *ccid_gen_parameters_t0(struct ccid_slot *cs, uint8_t seq, 
uint8_t cmd_sts,
+struct msgb *ccid_gen_parameters_t0(struct ccid_slot *cs, uint8_t seq, uint8_t 
cmd_sts,
                                           enum ccid_error_code err)
 {
        return ccid_gen_parameters_t0_nr(cs->slot_nr, get_icc_status(cs), seq, 
cmd_sts, err, &cs->pars);
@@ -276,7 +278,7 @@
        }
        return msg;
 }
-static struct msgb *ccid_gen_parameters_t1(struct ccid_slot *cs, uint8_t seq, 
uint8_t cmd_sts,
+struct msgb *ccid_gen_parameters_t1(struct ccid_slot *cs, uint8_t seq, uint8_t 
cmd_sts,
                                           enum ccid_error_code err)
 {
        return ccid_gen_parameters_t1_nr(cs->slot_nr, get_icc_status(cs), seq, 
cmd_sts, err, &cs->pars);
@@ -465,7 +467,7 @@

        /* copy default parameters from somewhere */
        /* FIXME: T=1 */
-       cs->ci->slot_ops->set_params(cs, CCID_PROTOCOL_NUM_T0, 
cs->default_pars);
+       cs->ci->slot_ops->set_params(cs, seq, CCID_PROTOCOL_NUM_T0, 
cs->default_pars);
        cs->pars = *cs->default_pars;

        resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_OK, 0);
@@ -502,14 +504,16 @@
                goto out;
        }

+       cs->proposed_pars = pars_dec;
+
        /* validate parameters; abort if they are not supported */
-       rc = cs->ci->slot_ops->set_params(cs, spar->bProtocolNum, &pars_dec);
+       rc = cs->ci->slot_ops->set_params(cs, seq, spar->bProtocolNum, 
&pars_dec);
        if (rc < 0) {
                resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_FAILED, 
-rc);
-       } else {
-               cs->pars = pars_dec;
-               resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_OK, 0);
+               goto out;
        }
+       /* busy, tdpu like callback */
+       return 1;
 out:
        return ccid_slot_send_unbusy(cs, resp);
 }
diff --git a/ccid_common/ccid_device.h b/ccid_common/ccid_device.h
index ae3ab5b..8390783 100644
--- a/ccid_common/ccid_device.h
+++ b/ccid_common/ccid_device.h
@@ -53,6 +53,8 @@
        bool cmd_busy;
        /* decided CCID parameters */
        struct ccid_pars_decoded pars;
+       /* proposed CCID parameters */
+       struct ccid_pars_decoded proposed_pars;
        /* default parameters; applied on ResetParameters */
        const struct ccid_pars_decoded *default_pars;
 };
@@ -80,7 +82,7 @@
                                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, enum ccid_protocol_num proto,
+       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);
 };
@@ -118,6 +120,10 @@
                        const uint32_t *data_rates, const uint32_t *clock_freqs,
                        const char *name, void *priv);
 int ccid_handle_out(struct ccid_instance *ci, struct msgb *msg);
+struct msgb *ccid_gen_parameters_t0(struct ccid_slot *cs, uint8_t seq, uint8_t 
cmd_sts,
+                                          enum ccid_error_code err);
+struct msgb *ccid_gen_parameters_t1(struct ccid_slot *cs, uint8_t seq, uint8_t 
cmd_sts,
+                                          enum ccid_error_code err);

 /* Invalid request received: Please return STALL */
 #define CCID_CTRL_RET_INVALID  -1
diff --git a/ccid_common/ccid_slot_fsm.c b/ccid_common/ccid_slot_fsm.c
index 870cf35..8bdcfd5 100644
--- a/ccid_common/ccid_slot_fsm.c
+++ b/ccid_common/ccid_slot_fsm.c
@@ -13,6 +13,7 @@
 #include "ccid_device.h"
 #include "cuart.h"
 #include "iso7816_fsm.h"
+#include "iso7816_3.h"

 struct iso_fsm_slot {
        /* CCID slot above us */
@@ -112,6 +113,33 @@
                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 */
+               uint16_t F = iso7816_3_fi_table[cs->proposed_pars.fi];
+               uint8_t D = iso7816_3_di_table[cs->proposed_pars.di];
+               uint32_t fmax = iso7816_3_fmax_table[cs->proposed_pars.fi];
+
+               card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK_FREQ, fmax);
+               card_uart_ctrl(ss->cuart, CUART_CTL_FD, F/D);
+               card_uart_ctrl(ss->cuart, CUART_CTL_WTIME, 
cs->proposed_pars.t0.waiting_integer);
+
+               cs->pars = cs->proposed_pars;
+               resp = ccid_gen_parameters_t0(cs, ss->seq, CCID_CMD_STATUS_OK, 
0);
+
+               ccid_slot_send_unbusy(cs, resp);
+
+               /* this frees the pps req from the host, pps resp buffer stays 
with the pps fsm */
+               msgb_free(tpdu);
+               break;
+       case ISO7816_E_PPS_FAILED_IND:
+               tpdu = data;
+               /* failed fi/di */
+               resp = ccid_gen_parameters_t0(cs, ss->seq, 
CCID_CMD_STATUS_FAILED, 10);
+               ccid_slot_send_unbusy(cs, resp);
+               /* this frees the pps req from the host, pps resp buffer stays 
with the pps fsm */
+               msgb_free(tpdu);
+               break;
        default:
                LOGPCS(cs, LOGL_NOTICE, "%s(event=%d, cause=%d, data=%p) 
unhandled\n",
                        __func__, event, cause, data);
@@ -175,10 +203,36 @@
        }
 }

-static int iso_fsm_slot_set_params(struct ccid_slot *cs, enum 
ccid_protocol_num proto,
+static int iso_fsm_slot_set_params(struct ccid_slot *cs, uint8_t seq, enum 
ccid_protocol_num proto,
                                const struct ccid_pars_decoded *pars_dec)
 {
-       /* we always acknowledge all parameters */
+       struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
+       struct msgb *tpdu;
+
+       /* see 6.1.7 for error offsets */
+       if(proto != CCID_PROTOCOL_NUM_T0)
+               return -7;
+
+       if(pars_dec->t0.guard_time_etu != 0)
+               return -12;
+
+       if(pars_dec->clock_stop != CCID_CLOCK_STOP_NOTALLOWED)
+               return -14;
+
+       ss->seq = seq;
+
+       /* Hardware does not support SPU, so no PPS2, and PPS3 is reserved 
anyway */
+       tpdu = msgb_alloc(6, "PPSRQ");
+       OSMO_ASSERT(tpdu);
+       msgb_put_u8(tpdu, 0xff);
+       msgb_put_u8(tpdu, (1 << 4)); /* only PPS1, T=0 */
+       msgb_put_u8(tpdu, (pars_dec->fi << 4 | pars_dec->di));
+       msgb_put_u8(tpdu, 0xff ^ (1 << 4) ^ (pars_dec->fi << 4 | pars_dec->di));
+
+
+       LOGPCS(cs, LOGL_DEBUG, "scheduling PPS transfer: %s\n", 
msgb_hexdump(tpdu));
+       osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_XCEIVE_PPS_CMD, tpdu);
+       /* continues in iso_fsm_clot_user_cb once response/error/timeout is 
received */
        return 0;
 }

diff --git a/ccid_common/iso7816_fsm.c b/ccid_common/iso7816_fsm.c
index beda7ab..d02a955 100644
--- a/ccid_common/iso7816_fsm.c
+++ b/ccid_common/iso7816_fsm.c
@@ -69,6 +69,7 @@
  *  @note defined in ISO/IEC 7816-3:2006(E) section 9
  */
 enum pps_state {
+       PPS_S_TX_PPS_REQ,  /*!< tx pps request */
        PPS_S_WAIT_PPSS, /*!< initial byte */
        PPS_S_WAIT_PPS0, /*!< format byte */
        PPS_S_WAIT_PPS1, /*!< first parameter byte */
@@ -221,7 +222,7 @@

        /* go back to initial state in child FSMs */
        osmo_fsm_inst_state_chg(ip->atr_fi, ATR_S_WAIT_TS, 0, 0);
-       //osmo_fsm_inst_state_chg(ip->pps_fi, PPS_S_WAIT_PPSS, 0, 0);
+       osmo_fsm_inst_state_chg(ip->pps_fi, PPS_S_TX_PPS_REQ, 0, 0);
        osmo_fsm_inst_state_chg(ip->tpdu_fi, TPDU_S_INIT, 0, 0);
 }

@@ -311,6 +312,11 @@
                /* pass on to sub-fsm */
                osmo_fsm_inst_dispatch(ip->tpdu_fi, event, data);
                break;
+       case ISO7816_E_XCEIVE_PPS_CMD:
+               osmo_fsm_inst_state_chg(fi, ISO7816_S_WAIT_PPS_RSP, 0, 0);
+               osmo_fsm_inst_state_chg(ip->pps_fi, PPS_S_TX_PPS_REQ, 0, 0);
+               osmo_fsm_inst_dispatch(ip->pps_fi, event, data);
+               break;
        default:
                OSMO_ASSERT(0);
        }
@@ -369,6 +375,62 @@
        }
 }

+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)
+{
+       OSMO_ASSERT(fi->fsm == &iso7816_3_fsm);
+       switch (event) {
+       case ISO7816_E_TX_COMPL:
+               /* Rx of single byte is already enabled by previous 
card_uart_tx() call */
+               osmo_fsm_inst_state_chg(fi, ISO7816_S_IN_PPS_RSP, 0, 0);
+               break;
+       default:
+               OSMO_ASSERT(0);
+       }
+}
+
+static void iso7816_3_s_ins_pps_rsp_action(struct osmo_fsm_inst *fi, uint32_t 
event, void *data)
+{
+       struct iso7816_3_priv *ip = get_iso7816_3_priv(fi);
+       struct msgb *ppsrsp;
+       OSMO_ASSERT(fi->fsm == &iso7816_3_fsm);
+
+       switch (event) {
+       case ISO7816_E_RX_SINGLE:
+       case ISO7816_E_WTIME_EXP:
+               /* simply pass this through to the child FSM for the ATR */
+               osmo_fsm_inst_dispatch(ip->pps_fi, event, data);
+               break;
+       case ISO7816_E_PPS_DONE_IND:
+       case ISO7816_E_PPS_FAILED_IND:
+               ppsrsp = data;
+               osmo_fsm_inst_state_chg(fi, ISO7816_S_WAIT_TPDU, 0, 0);
+               /* notify user about PPS result */
+               ip->user_cb(fi, event, 0, ppsrsp);
+               break;
+       case ISO7816_E_RX_ERR_IND:
+               ppsrsp = data;
+               osmo_fsm_inst_state_chg(fi, ISO7816_S_RESET, 0, 0);
+               ip->user_cb(fi, event, 0, ppsrsp);
+               break;
+       default:
+               OSMO_ASSERT(0);
+       }
+}
+
 static const struct osmo_fsm_state iso7816_3_states[] = {
        [ISO7816_S_RESET] = {
                .name = "RESET",
@@ -400,11 +462,13 @@
        },
        [ISO7816_S_WAIT_TPDU] = {
                .name = "WAIT_TPDU",
-               .in_event_mask =        S(ISO7816_E_XCEIVE_TPDU_CMD),
+               .in_event_mask =        S(ISO7816_E_XCEIVE_TPDU_CMD) |
+                                                       
S(ISO7816_E_XCEIVE_PPS_CMD),
                .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_IN_PPS_REQ) |
+                                       S(ISO7816_S_WAIT_PPS_RSP),
                .action = iso7816_3_wait_tpdu_action,
                .onenter = iso7816_3_wait_tpdu_onenter,
        },
@@ -424,26 +488,36 @@
        },
        [ISO7816_S_IN_PPS_REQ] = {
                .name = "IN_PPS_REQ",
-               .in_event_mask =        0, /* FIXME */
+               .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 =        0, /* FIXME */
+               .in_event_mask =        S(ISO7816_E_TX_COMPL) |
+                                       S(ISO7816_E_TX_ERR_IND) |
+                                       S(ISO7816_E_WTIME_EXP),
                .out_state_mask =       S(ISO7816_S_RESET) |
                                        S(ISO7816_S_WAIT_TPDU) |
                                        S(ISO7816_S_WAIT_PPS_RSP) |
                                        S(ISO7816_S_IN_PPS_RSP),
+               .action = iso7816_3_s_wait_pps_rsp_action,
        },
        [ISO7816_S_IN_PPS_RSP] = {
                .name = "IN_PPS_RESP",
-               .in_event_mask =        0, /* FIXME */
+               .in_event_mask =        S(ISO7816_E_RX_SINGLE) |
+                                       S(ISO7816_E_RX_COMPL) |
+                                       S(ISO7816_E_RX_ERR_IND) |
+                                       S(ISO7816_E_PPS_DONE_IND) |
+                                       S(ISO7816_E_PPS_FAILED_IND) |
+                                       S(ISO7816_E_WTIME_EXP),
                .out_state_mask =       S(ISO7816_S_RESET) |
                                        S(ISO7816_S_WAIT_TPDU) |
                                        S(ISO7816_S_IN_PPS_RSP),
+               .action = iso7816_3_s_ins_pps_rsp_action,
        },
 };
 static struct osmo_fsm iso7816_3_fsm = {
@@ -796,28 +870,188 @@
 /***********************************************************************
  * PPS FSM
  ***********************************************************************/
+struct pps_fsm_priv {
+       struct msgb* tx_cmd;
+       struct msgb* rx_cmd;
+       uint8_t pps0_recv;
+};
+
+static void pps_s_wait_ppss_onenter(struct osmo_fsm_inst *fi, uint32_t 
old_state)
+{
+       struct pps_fsm_priv *atp = fi->priv;
+
+       if (!atp->rx_cmd)
+               atp->rx_cmd = msgb_alloc_c(fi, 6, "ATR"); /* TS + 32 chars */
+       else
+               msgb_reset(atp->rx_cmd);
+}
+
+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);
+
+       switch (event) {
+       case ISO7816_E_XCEIVE_PPS_CMD:
+               osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPSS, 0, 0);
+               card_uart_tx(ip->uart, msgb_data(data), msgb_length(data), 
true);
+               break;
+       default:
+               OSMO_ASSERT(0);
+       }
+}
+
+static void pps_wait_pX_action(struct osmo_fsm_inst *fi, uint32_t event, void 
*data)
+{
+       struct pps_fsm_priv *atp = fi->priv;
+//     uint32_t guard_time_ms = atr_fi_gt_ms(fi);
+       uint8_t byte;
+
+       switch (event) {
+       case ISO7816_E_RX_SINGLE:
+               byte = get_rx_byte_evt(fi->proc.parent, data);
+               LOGPFSML(fi, LOGL_DEBUG, "RX byte '%02x'\n", byte);
+               msgb_put_u8(atp->rx_cmd, byte);
+               switch (fi->state) {
+               case PPS_S_WAIT_PPSS:
+                       if (byte == 0xff)
+                               osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPS0, 0, 
0);
+                       break;
+               case PPS_S_WAIT_PPS0:
+                       atp->pps0_recv = byte;
+                       if(atp->pps0_recv & (1 << 4)) {
+                               osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPS1, 0, 
0);
+                               break;
+                       } else if (atp->pps0_recv & (1 << 5)) {
+                               osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPS2, 0, 
0);
+                               break;
+                       } else if (atp->pps0_recv & (1 << 6)) {
+                               osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPS3, 0, 
0);
+                               break;
+                       }
+                       osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PCK, 0, 0);
+                       break;
+               case PPS_S_WAIT_PPS1:
+                       if (atp->pps0_recv & (1 << 5)) {
+                               osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPS2, 0, 
0);
+                               break;
+                       } else if (atp->pps0_recv & (1 << 6)) {
+                               osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPS3, 0, 
0);
+                               break;
+                       }
+                       osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PCK, 0, 0);
+                       break;
+               case PPS_S_WAIT_PPS2:
+                       if (atp->pps0_recv & (1 << 6)) {
+                               osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PPS3, 0, 
0);
+                               break;
+                       }
+                       osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PCK, 0, 0);
+                       break;
+               case PPS_S_WAIT_PPS3:
+                       osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_PCK, 0, 0);
+                       break;
+               case PPS_S_WAIT_PCK:
+                       /* verify checksum if present */
+                       if (fi->state == PPS_S_WAIT_PCK) {
+                               uint8_t *pps_received = msgb_data(atp->rx_cmd);
+                               uint8_t *pps_sent = msgb_data(atp->tx_cmd);
+
+                               osmo_fsm_inst_state_chg(fi, PPS_S_WAIT_END, 0, 
0);
+
+                               /* pps was successful if response equals request
+                                * rx buffer stays with the fsm, tx buffer gets 
handed back and freed
+                                * by the cb */
+                               if (msgb_length(atp->rx_cmd) == 
msgb_length(atp->tx_cmd) &&
+                                       !memcmp(pps_received, pps_sent, 
msgb_length(atp->rx_cmd))) {
+                                       osmo_fsm_inst_dispatch(fi->proc.parent,
+                                                       ISO7816_E_PPS_DONE_IND, 
atp->tx_cmd);
+                               } else {
+                                       osmo_fsm_inst_dispatch(fi->proc.parent,
+                                                       
ISO7816_E_PPS_FAILED_IND, atp->tx_cmd);
+                               }
+                       }
+                       break;
+               default:
+                       OSMO_ASSERT(0);
+               }
+               break;
+       case ISO7816_E_WTIME_EXP:
+               /* FIXME: timeout handling if no pps supported ? */
+               osmo_fsm_inst_dispatch(fi->proc.parent, ISO7816_E_RX_ERR_IND, 
NULL);
+               break;
+       default:
+               OSMO_ASSERT(0);
+       }
+}
+

 static const struct osmo_fsm_state pps_states[] = {
+       [PPS_S_TX_PPS_REQ] = {
+               .name = "TX_PPS_REQ",
+               .in_event_mask =        S(ISO7816_E_XCEIVE_PPS_CMD) |
+                                                       S(ISO7816_E_WTIME_EXP),
+               .out_state_mask =       S(PPS_S_TX_PPS_REQ) |
+                                                       S(PPS_S_WAIT_PPSS),
+               .action = pps_s_tx_pps_req_action,
+               .onenter = pps_s_wait_ppss_onenter,
+       },
        [PPS_S_WAIT_PPSS] = {
                .name = "WAIT_PPSS",
+               .in_event_mask =        S(ISO7816_E_RX_SINGLE) |
+                                                       S(ISO7816_E_WTIME_EXP),
+               .out_state_mask =       S(PPS_S_WAIT_PPS0) |
+                                                       S(PPS_S_WAIT_PPSS),
+               .action = pps_wait_pX_action,
        },
        [PPS_S_WAIT_PPS0] = {
                .name = "WAIT_PPS0",
+               .in_event_mask =        S(ISO7816_E_RX_SINGLE) |
+                                                       S(ISO7816_E_WTIME_EXP),
+               .out_state_mask =       S(PPS_S_WAIT_PPS1) |
+                                                       S(PPS_S_WAIT_PPS2) |
+                                                       S(PPS_S_WAIT_PPS3) |
+                                                       S(PPS_S_WAIT_PCK),
+               .action = pps_wait_pX_action,
        },
        [PPS_S_WAIT_PPS1] = {
                .name = "WAIT_PPS1",
+               .in_event_mask =        S(ISO7816_E_RX_SINGLE) |
+                                                       S(ISO7816_E_WTIME_EXP),
+               .out_state_mask =       S(PPS_S_WAIT_PPS2) |
+                                                       S(PPS_S_WAIT_PPS3) |
+                                                       S(PPS_S_WAIT_PCK),
+               .action = pps_wait_pX_action,
        },
        [PPS_S_WAIT_PPS2] = {
                .name = "WAIT_PPS2",
+               .in_event_mask =        S(ISO7816_E_RX_SINGLE) |
+                                                       S(ISO7816_E_WTIME_EXP),
+               .out_state_mask =       S(PPS_S_WAIT_PPS3) |
+                                                       S(PPS_S_WAIT_PCK),
+               .action = pps_wait_pX_action,
        },
        [PPS_S_WAIT_PPS3] = {
                .name = "WAIT_PPS3",
+               .in_event_mask =        S(ISO7816_E_RX_SINGLE) |
+                                                       S(ISO7816_E_WTIME_EXP),
+               .out_state_mask =       S(PPS_S_WAIT_PCK),
+               .action = pps_wait_pX_action,
        },
        [PPS_S_WAIT_PCK] = {
                .name = "WAIT_PCK",
+               .in_event_mask =        S(ISO7816_E_RX_SINGLE) |
+                                                       S(ISO7816_E_WTIME_EXP),
+               .out_state_mask =       S(PPS_S_WAIT_END),
+               .action = pps_wait_pX_action,
        },
        [PPS_S_WAIT_END] = {
                .name = "WAIT_END",
+               .in_event_mask =        0,
+               .out_state_mask =       S(PPS_S_TX_PPS_REQ) |
+                                                       S(PPS_S_WAIT_PPSS),
        },
 };

@@ -1223,7 +1457,7 @@
        if (!ip->tpdu_fi->priv)
                goto out_tpdu;

-#if 0
+#if 1
        ip->pps_fi = osmo_fsm_inst_alloc_child(&pps_fsm, fi, 
ISO7816_E_SW_ERR_IND);
        if (!ip->pps_fi)
                goto out_tpdu;
@@ -1237,7 +1471,7 @@

        return fi;

-#if 0
+#if 1
 out_pps:
        osmo_fsm_inst_free(ip->pps_fi);
 #endif
diff --git a/ccid_common/iso7816_fsm.h b/ccid_common/iso7816_fsm.h
index f2c7483..f512709 100644
--- a/ccid_common/iso7816_fsm.h
+++ b/ccid_common/iso7816_fsm.h
@@ -21,6 +21,9 @@
        ISO7816_E_RESET_ACT_IND,        /*!< Reset activated */
        ISO7816_E_ABORT_REQ,            /*!< Abort request (e.g. from CCID) */
        /* TODO: PPS request */
+       ISO7816_E_XCEIVE_PPS_CMD,
+       ISO7816_E_PPS_DONE_IND,
+       ISO7816_E_PPS_FAILED_IND,
        /* TODO: Clock stop request */
        /* TODO: Rx FIFO overrun */
        /* TODO: Rx buffer overrun */

--
To view, visit https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/16274
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: I280969ec9fe681dedae14ae8e6806f69eed3ff5a
Gerrit-Change-Number: 16274
Gerrit-PatchSet: 4
Gerrit-Owner: Hoernchen <ew...@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <lafo...@osmocom.org>
Gerrit-MessageType: merged

Reply via email to