Kévin Redon has uploaded this change for review. ( 
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, 90 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware 
refs/changes/81/13681/1

diff --git a/sysmoOCTSIM/main.c b/sysmoOCTSIM/main.c
index afd7bf2..788343e 100644
--- a/sysmoOCTSIM/main.c
+++ b/sysmoOCTSIM/main.c
@@ -21,6 +21,7 @@
 #include <parts.h>
 #include <hal_cache.h>
 #include <hri_port_e54.h>
+#include <utils_ringdmabuffer.h>

 #include "atmel_start.h"
 #include "atmel_start_pins.h"
@@ -31,6 +32,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()
 {
@@ -49,6 +57,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]);
+       }
 }

 DEFUN(hello_fn, cmd_hello,
@@ -210,6 +227,78 @@
        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\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 = false;
+       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;
+       ncn8025_set(slotnr, &settings);
+       // 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;
+       ncn8025_set(slotnr, &settings);
+       // 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 = true;
+       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\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");
+}
+
 int main(void)
 {
        atmel_start_init();
@@ -226,6 +315,7 @@
        command_register(&cmd_sim_clkdiv);
        command_register(&cmd_sim_voltage);
        command_register(&cmd_sim_led);
+       command_register(&cmd_sim_atr);

        printf("\r\n\r\nsysmocom sysmoOCTSIM\r\n");
        while (true) { // main loop

--
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: newchange
Gerrit-Change-Id: I30b284cab60a50d4cd3080f46f4d332193bbf1ee
Gerrit-Change-Number: 13681
Gerrit-PatchSet: 1
Gerrit-Owner: Kévin Redon <[email protected]>

Reply via email to