mirror of https://gerrit.osmocom.org/simtrace2
card_emu: Clarify and differentiate F/Fi/F_index/Fi_index
The ISO7816 spec terms are well-defined, let's not abuse them. We used to consider "Fi" as the "index into the table of F values", while the spec actually considers Fi as the initial value for F. Let's make sure we use the terms quite clearly: * Fi and Di are the initial values for F and D * F*_index and D*_index are the indexes into the ISO7816-3 Tables Furthermore, let's track Fi separately from F, as e.g. the waiting time definition only considers Fi as indicated in the ATR, despite an actually different F value might have been negotiated via PTS meanwhile. Change-Id: Ieb2425e8380a81b79df7b2bd072902994e9c3ee7 Related: OS##1704
This commit is contained in:
parent
9454a062b5
commit
79f0ea73a2
|
@ -230,11 +230,17 @@ struct cardemu_usb_msg_status {
|
|||
uint32_t flags;
|
||||
/* phone-applied target voltage in mV */
|
||||
uint16_t voltage_mv;
|
||||
/* Fi/Di related information */
|
||||
uint8_t fi;
|
||||
uint8_t di;
|
||||
uint8_t wi;
|
||||
uint32_t waiting_time;
|
||||
/* F/D related information. Not actual Fn/Dn values but indexes into tables! */
|
||||
union {
|
||||
uint8_t F_index; /* <! Index to ISO7816-3 Table 7 (F and f_max values) */
|
||||
uint8_t fi; /* <! old, wrong name for API compatibility */
|
||||
};
|
||||
union {
|
||||
uint8_t D_index; /* <! Index to ISO7816-3 Table 8 (D value) */
|
||||
uint8_t di; /* <! old, wrong name for API compatibility */
|
||||
};
|
||||
uint8_t wi; /* <! Waiting Integer as defined in ISO7816-3 Section 10.2 */
|
||||
uint32_t waiting_time; /* <! Waiting Time in etu as defined in ISO7816-3 Section 8.1 */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* CEMU_USB_MSGT_DO_PTS */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ISO7816-3 state machine for the card side
|
||||
*
|
||||
* (C) 2010-2019 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2010-2021 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -154,19 +154,35 @@ struct card_handle {
|
|||
bool in_reset; /*< if card is in reset (true = RST low/asserted, false = RST high/ released) */
|
||||
bool clocked; /*< if clock is active ( true = active, false = inactive) */
|
||||
|
||||
/* timing parameters, from PTS */
|
||||
uint8_t Fi;
|
||||
uint8_t Di;
|
||||
/* All below variables with _index suffix are indexes from 0..15 into Tables 7 + 8
|
||||
* of ISO7816-3. */
|
||||
|
||||
/*! Index to clock rate conversion integer Fi (ISO7816-3 Table 7).
|
||||
* \note this represents the maximum value supported by the card, and can be indicated in TA1 */
|
||||
uint8_t Fi_index;
|
||||
/*! Current value of index to clock rate conversion integer F (ISO 7816-3 Section 7.1). */
|
||||
uint8_t F_index;
|
||||
|
||||
/*! Index to baud rate adjustment factor Di (ISO7816-3 Table 8).
|
||||
* \note this represents the maximum value supported by the card, and can be indicated in TA1 */
|
||||
uint8_t Di_index;
|
||||
/*! Current value of index to baud rate adjustment factor D (ISO 7816-3 Section 7.1). */
|
||||
uint8_t D_index;
|
||||
|
||||
/*! Waiting Integer (ISO7816-3 Section 10.2).
|
||||
* \note this value can be set in TA2 */
|
||||
uint8_t wi;
|
||||
|
||||
/*! Waiting Time, in ETU (ISO7816-3 Section 8.1).
|
||||
* \note this depends on Fi, Di, and WI if T=0 is used */
|
||||
uint32_t waiting_time; /* in etu */
|
||||
|
||||
uint8_t tc_chan; /* TC channel number */
|
||||
uint8_t uart_chan; /* UART channel */
|
||||
|
||||
uint8_t in_ep; /* USB IN EP */
|
||||
uint8_t irq_ep; /* USB IN EP */
|
||||
|
||||
uint32_t waiting_time; /* in etu */
|
||||
|
||||
/* ATR state machine */
|
||||
struct {
|
||||
uint8_t idx;
|
||||
|
@ -361,16 +377,16 @@ static void emu_update_fidi(struct card_handle *ch)
|
|||
{
|
||||
int rc;
|
||||
|
||||
rc = compute_fidi_ratio(ch->Fi, ch->Di);
|
||||
rc = compute_fidi_ratio(ch->F_index, ch->D_index);
|
||||
if (rc > 0 && rc < 0x400) {
|
||||
TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
|
||||
ch->num, ch->Fi, ch->Di, rc);
|
||||
TRACE_INFO("%u: computed F(%u)/D(%u) ratio: %d\r\n", ch->num,
|
||||
ch->F_index, ch->D_index, rc);
|
||||
/* make sure UART uses new F/D ratio */
|
||||
card_emu_uart_update_fidi(ch->uart_chan, rc);
|
||||
/* notify ETU timer about this */
|
||||
tc_etu_set_etu(ch->tc_chan, rc);
|
||||
} else
|
||||
TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
|
||||
TRACE_INFO("%u: computed F/D ratio %d unsupported\r\n",
|
||||
ch->num, rc);
|
||||
}
|
||||
|
||||
|
@ -395,8 +411,10 @@ static void card_set_state(struct card_handle *ch,
|
|||
break;
|
||||
case ISO_S_WAIT_ATR:
|
||||
/* Reset to initial Fi / Di ratio */
|
||||
ch->Fi = 1;
|
||||
ch->Di = 1;
|
||||
ch->Fi_index = ch->F_index = 1;
|
||||
ch->Di_index = ch->D_index = 1;
|
||||
ch->wi = ISO7816_3_DEFAULT_WI;
|
||||
ch->waiting_time = ISO7816_3_INIT_WTIME;
|
||||
emu_update_fidi(ch);
|
||||
/* the ATR should only be sent 400 to 40k clock cycles after the RESET.
|
||||
* we use the tc_etu mechanism to wait this time.
|
||||
|
@ -490,7 +508,7 @@ static int tx_byte_atr(struct card_handle *ch)
|
|||
}
|
||||
}
|
||||
/* update waiting time (see ISO 7816-3 10.2) */
|
||||
ch->waiting_time = ch->wi * 960 * ch->Fi;
|
||||
ch->waiting_time = ch->wi * 960 * fi_table[ch->F_index];
|
||||
tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
|
||||
/* go to next state */
|
||||
card_set_state(ch, ISO_S_WAIT_TPDU);
|
||||
|
@ -626,9 +644,11 @@ static int tx_byte_pts(struct card_handle *ch)
|
|||
case PTS_S_WAIT_RESP_PTS1:
|
||||
byte = ch->pts.resp[_PTS1];
|
||||
/* This must be TA1 */
|
||||
ch->Fi = byte >> 4;
|
||||
ch->Di = byte & 0xf;
|
||||
TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num, ch->Fi, ch->Di);
|
||||
ch->F_index = byte >> 4;
|
||||
ch->D_index = byte & 0xf;
|
||||
TRACE_DEBUG("%u: found F=%u D=%u\r\n", ch->num,
|
||||
fi_table[ch->F_index], di_table[ch->D_index]);
|
||||
/* FIXME: if F or D are 0, become unresponsive to signal error condition */
|
||||
break;
|
||||
case PTS_S_WAIT_RESP_PTS2:
|
||||
byte = ch->pts.resp[_PTS2];
|
||||
|
@ -653,7 +673,7 @@ static int tx_byte_pts(struct card_handle *ch)
|
|||
switch (ch->pts.state) {
|
||||
case PTS_S_WAIT_RESP_PCK:
|
||||
card_emu_uart_wait_tx_idle(ch->uart_chan);
|
||||
/* update baud rate generator with Fi/Di */
|
||||
/* update baud rate generator with F/D */
|
||||
emu_update_fidi(ch);
|
||||
/* Wait for the next TPDU */
|
||||
card_set_state(ch, ISO_S_WAIT_TPDU);
|
||||
|
@ -1024,8 +1044,8 @@ void card_emu_report_status(struct card_handle *ch, bool report_on_irq)
|
|||
if (ch->in_reset)
|
||||
sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
|
||||
/* FIXME: voltage + card insert */
|
||||
sts->fi = ch->Fi;
|
||||
sts->di = ch->Di;
|
||||
sts->F_index = ch->F_index;
|
||||
sts->D_index = ch->D_index;
|
||||
sts->wi = ch->wi;
|
||||
sts->waiting_time = ch->waiting_time;
|
||||
|
||||
|
@ -1231,8 +1251,8 @@ struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uar
|
|||
ch->in_reset = in_reset;
|
||||
ch->clocked = clocked;
|
||||
|
||||
ch->Fi = 0;
|
||||
ch->Di = 1;
|
||||
ch->Fi_index = ch->F_index = 1;
|
||||
ch->Di_index = ch->D_index = 1;
|
||||
ch->wi = ISO7816_3_DEFAULT_WI;
|
||||
|
||||
ch->tc_chan = tc_chan;
|
||||
|
|
Loading…
Reference in New Issue