mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-18 14:28:33 +03:00
Compare commits
15 Commits
laforge/ca
...
laforge/ca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d2ff9a173 | ||
|
|
b6e421bcbe | ||
|
|
e145a7aed4 | ||
|
|
f83c69ff69 | ||
|
|
2619862fba | ||
|
|
deb322c36d | ||
|
|
351dfd65d9 | ||
|
|
bc9b927569 | ||
|
|
e5c8833a97 | ||
|
|
1a32601be7 | ||
|
|
ed3067e2ea | ||
|
|
841a0b70ff | ||
|
|
7a3d93682f | ||
|
|
01868775ba | ||
|
|
9ec3de9346 |
@@ -89,7 +89,7 @@
|
||||
/// \param condition Condition to verify.
|
||||
#define ASSERT(condition) { \
|
||||
if (!(condition)) { \
|
||||
printf("-F- ASSERT: %s %s:%d\n\r", #condition, __BASE_FILE__, __LINE__); \
|
||||
printf_sync("-F- ASSERT: %s %s:%d\n\r", #condition, __BASE_FILE__, __LINE__); \
|
||||
while (1); \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ enum card_io {
|
||||
|
||||
/** initialise card slot
|
||||
* @param[in] slot_num slot number (arbitrary number)
|
||||
* @param[in] tc_chan timer counter channel (to measure the ETU)
|
||||
* @param[in] uart_chan UART peripheral channel
|
||||
* @param[in] in_ep USB IN end point number
|
||||
* @param[in] irq_ep USB INTerrupt end point number
|
||||
@@ -40,7 +39,7 @@ enum card_io {
|
||||
* @param[in] clocked initial CLK signat state (true = active)
|
||||
* @return main card handle reference
|
||||
*/
|
||||
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked);
|
||||
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked);
|
||||
|
||||
/* process a single byte received from the reader */
|
||||
void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte);
|
||||
|
||||
@@ -230,9 +230,15 @@ struct cardemu_usb_msg_status {
|
||||
uint32_t flags;
|
||||
/* phone-applied target voltage in mV */
|
||||
uint16_t voltage_mv;
|
||||
/* Fi/Di related information */
|
||||
uint8_t F_index; /* <! Index to ISO7816-3 Table 7 (F and f_max values) */
|
||||
uint8_t D_index; /* <! Index into ISO7816-3 Table 8 (D value) */
|
||||
/* 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));
|
||||
|
||||
@@ -176,7 +176,6 @@ struct card_handle {
|
||||
* \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 */
|
||||
@@ -431,7 +430,7 @@ static void card_set_state(struct card_handle *ch,
|
||||
/* update waiting time to initial waiting time */
|
||||
ch->waiting_time = ISO7816_3_INIT_WTIME;
|
||||
/* set initial waiting time */
|
||||
card_emu_uart_update_wt(ch->tc_chan, ch->waiting_time);
|
||||
card_emu_uart_update_wt(ch->uart_chan, ch->waiting_time);
|
||||
/* Set ATR sub-state to initial state */
|
||||
ch->atr.idx = 0;
|
||||
/* enable USART transmission to reader */
|
||||
@@ -506,8 +505,11 @@ static int tx_byte_atr(struct card_handle *ch)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* update waiting time (see ISO 7816-3 10.2) */
|
||||
ch->waiting_time = ch->wi * 960 * iso7816_3_fi_table[ch->F_index];
|
||||
/* update waiting time (see ISO 7816-3 10.2). We can drop the Fi
|
||||
* multiplier as we store the waiting time in units of 'etu', and
|
||||
* don't really care what the number of clock cycles or the absolute
|
||||
* wall clock time is */
|
||||
ch->waiting_time = ch->wi * 960;
|
||||
/* go to next state */
|
||||
card_set_state(ch, ISO_S_WAIT_TPDU);
|
||||
return 0;
|
||||
@@ -1245,7 +1247,7 @@ int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_con
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked)
|
||||
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked)
|
||||
{
|
||||
struct card_handle *ch;
|
||||
|
||||
@@ -1270,7 +1272,6 @@ struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uar
|
||||
ch->Di_index = ch->D_index = 1;
|
||||
ch->wi = ISO7816_3_DEFAULT_WI;
|
||||
|
||||
ch->tc_chan = tc_chan;
|
||||
ch->uart_chan = uart_chan;
|
||||
ch->waiting_time = ISO7816_3_INIT_WTIME;
|
||||
|
||||
|
||||
@@ -213,6 +213,22 @@ int card_emu_uart_tx(uint8_t uart_chan, uint8_t byte)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint16_t compute_next_timeout(struct cardem_inst *ci)
|
||||
{
|
||||
uint32_t want_to_expire;
|
||||
|
||||
if (ci->wt.total == 0)
|
||||
return 0;
|
||||
|
||||
if (!ci->wt.half_time_notified) {
|
||||
/* we need to make sure to expire after half the total waiting time */
|
||||
OSMO_ASSERT(ci->wt.remaining > (ci->wt.total / 2));
|
||||
want_to_expire = ci->wt.remaining - (ci->wt.total / 2);
|
||||
} else
|
||||
want_to_expire = ci->wt.remaining;
|
||||
/* if value exceeds the USART TO range, use the maximum possible value for one round */
|
||||
return OSMO_MIN(want_to_expire, 0xffff);
|
||||
}
|
||||
|
||||
/*! common handler if interrupt was received.
|
||||
* \param[in] inst_num Instance number, range 0..1 (some boards only '0' permitted) */
|
||||
@@ -256,6 +272,9 @@ static void usart_irq_rx(uint8_t inst_num)
|
||||
* how many etu have expired since we last sent a byte. See section
|
||||
* 33.7.3.11 "Receiver Time-out" of the SAM3S8 Data Sheet */
|
||||
if (csr & US_CSR_TIMEOUT) {
|
||||
/* clear timeout flag (and stop timeout until next character is received) */
|
||||
usart->US_CR |= US_CR_STTTO;
|
||||
|
||||
/* RX has been inactive for some time */
|
||||
if (ci->wt.remaining <= (usart->US_RTOR & 0xffff)) {
|
||||
/* waiting time is over; will stop the timer */
|
||||
@@ -268,17 +287,26 @@ static void usart_irq_rx(uint8_t inst_num)
|
||||
if (ci->wt.remaining == 0) {
|
||||
/* let the FSM know that WT has expired */
|
||||
card_emu_wtime_expired(ci->ch);
|
||||
} else if (ci->wt.remaining <= ci->wt.total / 2 && !ci->wt.half_time_notified) {
|
||||
/* let the FS know that half of the WT has expired */
|
||||
card_emu_wtime_half_expired(ci->ch);
|
||||
ci->wt.half_time_notified = true;
|
||||
/* don't automatically re-start in this case */
|
||||
} else {
|
||||
bool half_time_just_reached = false;
|
||||
|
||||
if (ci->wt.remaining <= ci->wt.total / 2 && !ci->wt.half_time_notified) {
|
||||
ci->wt.half_time_notified = true;
|
||||
/* don't immediately call card_emu_wtime_half_expired(), as that
|
||||
* in turn may calls card_emu_uart_update_wt() which will change
|
||||
* the timeout but would be overridden 4 lines below */
|
||||
half_time_just_reached = true;
|
||||
}
|
||||
|
||||
/* update the counter no matter if we reached half time or not */
|
||||
usart->US_RTOR = compute_next_timeout(ci);
|
||||
/* restart the counter (if wt is 0, the timeout is not started) */
|
||||
usart->US_CR |= US_CR_RETTO;
|
||||
|
||||
if (half_time_just_reached)
|
||||
card_emu_wtime_half_expired(ci->ch);
|
||||
}
|
||||
/* if value exceeds the USART TO range, use the maximum for now */
|
||||
usart->US_RTOR = OSMO_MIN(ci->wt.remaining, 0xffff);
|
||||
/* clear timeout flag (and stop timeout until next character is received) */
|
||||
usart->US_CR |= US_CR_STTTO;
|
||||
/* restart the counter (it wt is 0, the timeout is not started) */
|
||||
usart->US_CR |= US_CR_RETTO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,10 +345,14 @@ void card_emu_uart_update_wt(uint8_t uart_chan, uint32_t wt)
|
||||
struct cardem_inst *ci = &cardem_inst[uart_chan];
|
||||
Usart *usart = get_usart_by_chan(uart_chan);
|
||||
|
||||
if (ci->wt.total != wt) {
|
||||
TRACE_DEBUG("%u: USART WT changed from %lu to %lu ETU\r\n", uart_chan,
|
||||
ci->wt.total, wt);
|
||||
}
|
||||
|
||||
ci->wt.total = wt;
|
||||
/* reset and start the timer */
|
||||
card_emu_uart_reset_wt(uart_chan);
|
||||
TRACE_INFO("%u: USART WT set to %lu ETU\r\n", uart_chan, wt);
|
||||
}
|
||||
|
||||
/*! Reset and re-start waiting timeout count down on USART peripheral.
|
||||
@@ -334,8 +366,7 @@ void card_emu_uart_reset_wt(uint8_t uart_chan)
|
||||
/* FIXME: guard against race with interrupt handler */
|
||||
ci->wt.remaining = ci->wt.total;
|
||||
ci->wt.half_time_notified = false;
|
||||
/* if value exceeds the USART TO range, use the maximum for now */
|
||||
usart->US_RTOR = OSMO_MIN(ci->wt.remaining, 0xffff);
|
||||
usart->US_RTOR = compute_next_timeout(ci);
|
||||
/* restart the counter (if wt is 0, the timeout is not started) */
|
||||
usart->US_CR |= US_CR_RETTO;
|
||||
}
|
||||
@@ -520,20 +551,7 @@ void mode_cardemu_init(void)
|
||||
|
||||
/* configure USART as ISO-7816 slave (e.g. card) */
|
||||
ISO7816_Init(&cardem_inst[0].usart_info, CLK_SLAVE);
|
||||
#ifdef BOARD_simtrace
|
||||
/* simtrace board uses uart timeouts */
|
||||
|
||||
/* don't use receive timeout timer for now */
|
||||
cardem_inst[0].usart_info.base->US_RTOR = 0;
|
||||
/* enable interrupts to indicate when data has been received or timeout occurred */
|
||||
USART_EnableIt(cardem_inst[0].usart_info.base, US_IER_RXRDY | US_IER_TIMEOUT);
|
||||
#else
|
||||
/* enable interrupts to indicate when data has been received */
|
||||
USART_EnableIt(cardem_inst[0].usart_info.base, US_IER_RXRDY );
|
||||
#endif
|
||||
/* enable interrupt requests for the USART peripheral */
|
||||
NVIC_EnableIRQ(USART1_IRQn);
|
||||
|
||||
PIO_ConfigureIt(&pin_usim1_rst, usim1_rst_irqhandler);
|
||||
PIO_EnableIt(&pin_usim1_rst);
|
||||
|
||||
@@ -549,7 +567,7 @@ void mode_cardemu_init(void)
|
||||
do {} while (!adc_triggered); /* wait for first ADC reading */
|
||||
#endif /* DETECT_VCC_BY_ADC */
|
||||
|
||||
cardem_inst[0].ch = card_emu_init(0, 2, 0, SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN,
|
||||
cardem_inst[0].ch = card_emu_init(0, 0, SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN,
|
||||
SIMTRACE_CARDEM_USB_EP_USIM1_INT, cardem_inst[0].vcc_active,
|
||||
cardem_inst[0].rst_active, cardem_inst[0].vcc_active);
|
||||
sim_switch_use_physical(0, 1);
|
||||
@@ -572,7 +590,7 @@ void mode_cardemu_init(void)
|
||||
do {} while (!adc_triggered); /* wait for first ADC reading */
|
||||
#endif /* DETECT_VCC_BY_ADC */
|
||||
|
||||
cardem_inst[1].ch = card_emu_init(1, 0, 1, SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN,
|
||||
cardem_inst[1].ch = card_emu_init(1, 1, SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN,
|
||||
SIMTRACE_CARDEM_USB_EP_USIM2_INT, cardem_inst[1].vcc_active,
|
||||
cardem_inst[1].rst_active, cardem_inst[1].vcc_active);
|
||||
sim_switch_use_physical(1, 1);
|
||||
|
||||
@@ -46,7 +46,7 @@ static osmo_panic_handler_t osmo_panic_handler = (void*)0;
|
||||
__attribute__ ((format (printf, 1, 0)))
|
||||
static void osmo_panic_default(const char *fmt, va_list args)
|
||||
{
|
||||
vfprintf(stderr, fmt, args);
|
||||
vfprintf_sync(stderr, fmt, args);
|
||||
osmo_generate_backtrace();
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ static int process_irq_status(struct osmo_st2_cardem_inst *ci, const uint8_t *bu
|
||||
const struct cardemu_usb_msg_status *status = (struct cardemu_usb_msg_status *) buf;
|
||||
|
||||
LOGCI(ci, LOGL_INFO, "SIMtrace IRQ STATUS: flags=0x%x, fi=%u, di=%u, wi=%u wtime=%u\n",
|
||||
status->flags, status->F_index, status->D_index, status->wi,
|
||||
status->flags, status->fi, status->di, status->wi,
|
||||
status->waiting_time);
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user