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/.
Harald Welte gerrit-no-reply at lists.osmocom.orgHarald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/13681 ) Change subject: add sim-atr command ...................................................................... add sim-atr command the sim-atr command resets the card and read the resulting answer to reset. Change-Id: I30b284cab60a50d4cd3080f46f4d332193bbf1ee --- M sysmoOCTSIM/main.c 1 file changed, 91 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/sysmoOCTSIM/main.c b/sysmoOCTSIM/main.c index 369e3ef..5b10c5f 100644 --- a/sysmoOCTSIM/main.c +++ b/sysmoOCTSIM/main.c @@ -31,6 +31,13 @@ #include "command.h" +// TODO put declaration in more global file +// TODO for now SIM7 is not present because used for debug +static struct usart_async_descriptor* SIM_peripheral_descriptors[] = {&SIM0, &SIM1, &SIM2, &SIM3, &SIM4, &SIM5, &SIM6, NULL}; + +static void SIM_rx_cb(const struct usart_async_descriptor *const io_descr) +{ +} static void board_init() { @@ -48,6 +55,15 @@ /* increase drive strength of 20Mhz SIM clock output to 8mA * (there are 8 inputs + traces to drive!) */ hri_port_set_PINCFG_DRVSTR_bit(PORT, 0, 11); + + // enable SIM interfaces + for (uint8_t i = 0; i < ARRAY_SIZE(SIM_peripheral_descriptors); i++) { + if (NULL == SIM_peripheral_descriptors[i]) { + continue; + } + usart_async_register_callback(SIM_peripheral_descriptors[i], USART_ASYNC_RXC_CB, SIM_rx_cb); // required for RX to work, even if the callback does nothing + usart_async_enable(SIM_peripheral_descriptors[i]); + } } static int validate_slotnr(int argc, char **argv, int idx) @@ -203,7 +219,81 @@ ncn8025_set(slotnr, &settings); } +DEFUN(sim_atr, cmd_sim_atr, "sim-atr", "Read ATR from SIM card") +{ + struct ncn8025_settings settings; + int slotnr = validate_slotnr(argc, argv, 1); + if (slotnr < 0 || slotnr >= ARRAY_SIZE(SIM_peripheral_descriptors) || NULL == SIM_peripheral_descriptors[slotnr]) { + return; + } + + // check if card is present (and read current settings) + ncn8025_get(slotnr, &settings); + if (!settings.simpres) { + printf("no card present in slot %d, aborting\r\n", slotnr); + return; + } + + // switch card off (assert reset and disable power) + // note: ISO/IEC 7816-3:2006 section 6.4 provides the deactivation sequence, but not the minimum corresponding times + settings.rstin = true; + settings.cmdvcc = false; + ncn8025_set(slotnr, &settings); + + // TODO wait some time for card to be completely deactivated + usart_async_flush_rx_buffer(SIM_peripheral_descriptors[slotnr]); // flush RX buffer to start from scratch + + //usart_async_set_baud_rate(SIM_peripheral_descriptors[slotnr], 2500000 / (372 / 1)); // set USART baud rate to match the interface (f = 2.5 MHz) and card default settings (Fd = 372, Dd = 1) + // set clock to lowest frequency (20 MHz / 8 = 2.5 MHz) + // note: according to ISO/IEC 7816-3:2006 section 5.2.3 the minimum value is 1 MHz, and maximum is 5 MHz during activation + settings.clkdiv = SIM_CLKDIV_8; + // set card voltage to 3.0 V (the most supported) + // note: according to ISO/IEC 7816-3:2006 no voltage should damage the card, and you should cycle from low to high + settings.vsel = SIM_VOLT_3V0; + // provide power (the NCN8025 should perform the activation according to spec) + // note: activation sequence is documented in ISO/IEC 7816-3:2006 section 6.2 + settings.cmdvcc = true; + ncn8025_set(slotnr, &settings); + + // wait for Tb=400 cycles before re-asserting reset + delay_us(400 * 10000 / 2500); // 400 cycles * 1000 for us, 2.5 MHz / 1000 for us + + // de-assert reset to switch card back on + settings.rstin = false; + ncn8025_set(slotnr, &settings); + + // wait for Tc=40000 cycles for transmission to start + uint32_t cycles = 40000; + while (cycles && !usart_async_is_rx_not_empty(SIM_peripheral_descriptors[slotnr])) { + delay_us(10); + cycles -= 25; // 10 us = 25 cycles at 2.5 MHz + } + if (!usart_async_is_rx_not_empty(SIM_peripheral_descriptors[slotnr])) { + delay_us(12 * 372 / 1 / 2); // wait more than one byte (approximate freq down to 2 MHz) + } + // verify if one byte has been received + if (!usart_async_is_rx_not_empty(SIM_peripheral_descriptors[slotnr])) { + printf("card in slot %d is not responding, aborting\r\n", slotnr); + return; + } + + // read ATR (just do it until there is no traffic anymore) + // TODO the ATR should be parsed to read the right number of bytes + printf("ATR: "); + uint8_t atr_byte; + while (usart_async_is_rx_not_empty(SIM_peripheral_descriptors[slotnr])) { + if (1 == io_read(&SIM_peripheral_descriptors[slotnr]->io, &atr_byte, 1)) { + printf("%02x ", atr_byte); + } + uint16_t wt = 9600; // waiting time in ETU + while (wt && !usart_async_is_rx_not_empty(SIM_peripheral_descriptors[slotnr])) { + delay_us(149); // wait for 1 ETU (372 / 1 / 2.5 MHz = 148.8 us) + wt--; + } + } + printf("\r\n"); +} extern void testmode_init(void); @@ -223,6 +313,7 @@ command_register(&cmd_sim_clkdiv); command_register(&cmd_sim_voltage); command_register(&cmd_sim_led); + command_register(&cmd_sim_atr); testmode_init(); printf("\r\n\r\nsysmocom sysmoOCTSIM\r\n"); -- To view, visit https://gerrit.osmocom.org/13681 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-ccid-firmware Gerrit-Branch: master Gerrit-MessageType: merged Gerrit-Change-Id: I30b284cab60a50d4cd3080f46f4d332193bbf1ee Gerrit-Change-Number: 13681 Gerrit-PatchSet: 9 Gerrit-Owner: Kévin Redon <kredon at sysmocom.de> Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Jenkins Builder (1000002) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190417/2c195261/attachment.htm>