X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Ftarget%2Ffirmware%2Fapps%2Flayer1%2Fmain.c;h=749dde41c2fef79d8c59e0af722a227c306660d9;hb=cd59e3afac8019d0d45e5e8247776b32e01dcf72;hp=d918145b0391ea254b222edcc33844f112ed013c;hpb=8d1a687c10624ddab7b4c23bd4d6d4b557c632bd;p=osmocom-bb.git diff --git a/src/target/firmware/apps/layer1/main.c b/src/target/firmware/apps/layer1/main.c index d918145..749dde4 100644 --- a/src/target/firmware/apps/layer1/main.c +++ b/src/target/firmware/apps/layer1/main.c @@ -48,12 +48,122 @@ const char *hr = "======================================================================\n"; +/* SIM Stuff, TODO: clean it up */ + +#include + +#include + +#define SIM_CLASS 0xA0 /* Class that contains the following instructions */ +#define SIM_GET_RESPONSE 0xC0 /* Get the response of a command from the card */ +#define SIM_READ_BINARY 0xB0 /* Read file in binary mode */ + +#define L3_MSG_HEAD 4 + +static uint8_t sim_data[256]; /* buffer for SIM command */ +static volatile uint16_t sim_len = 0; /* lenght of data in sim_data[] */ + +void sim_apdu(uint16_t len, uint8_t *data) +{ + memcpy(sim_data, data, len); + sim_len = len; +} + +/* allocate a large enough buffer for the SIM response */ + +struct msgb *my_l1ctl_msgb_alloc(uint8_t msg_type) +{ + struct msgb *msg; + struct l1ctl_hdr *l1h; + + msg = msgb_alloc_headroom(256, L3_MSG_HEAD, "l1ctl1"); + if (!msg) { + while (1) { + puts("OOPS. Out of buffers...\n"); + } + + return NULL; + } + l1h = (struct l1ctl_hdr *) msgb_put(msg, sizeof(*l1h)); + l1h->msg_type = msg_type; + l1h->flags = 0; + + msg->l1h = (uint8_t *)l1h; + + return msg; +} + +static void sim_handler(void) +{ + uint8_t status_word[2]; + struct msgb *msg; + uint8_t *dat; + uint16_t length; + + if(sim_len) /* a new SIM command has arrived */ + { + status_word[0] = 0; + status_word[1] = 0; + + msg = my_l1ctl_msgb_alloc(L1CTL_SIM_CONF); + + /* check if instructions expects a response (TODO: add more instructions */ + if (/* GET RESPONSE needs SIM_APDU_GET */ + (sim_len == 5 && sim_data[0] == SIM_CLASS && + sim_data[1] == SIM_GET_RESPONSE && sim_data[2] == 0x00 && + sim_data[3] == 0x00) || + /* READ BINARY needs SIM_APDU_GET */ + (sim_len >= 5 && sim_data[0] == SIM_CLASS && + sim_data[1] == SIM_READ_BINARY)) + { + /* allocate space for expected response */ + length = sim_data[4]; + dat = msgb_put(msg, length + 2); + + if(calypso_sim_transceive(sim_data[0], sim_data[1], sim_data[2], sim_data[3], sim_data[4], dat, status_word, SIM_APDU_GET) != 0) + puts("SIM ERROR !\n"); + printf("Status 1: %02X %02X\n", status_word[0], status_word[1]); + + /* copy status at the end */ + memcpy(dat + length, status_word, 2); + + l1_queue_for_l2(msg); + } + else + { + if(calypso_sim_transceive(sim_data[0], sim_data[1], sim_data[2], sim_data[3], sim_data[4], &sim_data[5], status_word, SIM_APDU_PUT) != 0) + puts("SIM ERROR !\n"); + printf("Status 2: %02X %02X\n", status_word[0], status_word[1]); + + /* 2 bytes status */ + length = 2; + dat = msgb_put(msg, length); + memcpy(dat, status_word, length); + + l1_queue_for_l2(msg); + } + + sim_len = 0; + } +} + /* MAIN program **************************************************************/ static void key_handler(enum key_codes code, enum key_states state); +/* called while waiting for SIM */ + +void sim_wait_handler(void) +{ + l1a_compl_execute(); + update_timers(); +} + int main(void) { + uint8_t atr[20]; + uint8_t atrLength = 0; + board_init(); puts("\n\nOSMOCOM Layer 1 (revision " GIT_REVISION ")\n"); @@ -72,6 +182,14 @@ int main(void) display_set_attr(DISP_ATTR_INVERT); display_puts("layer1.bin"); + /* initialize SIM */ + calypso_sim_init(sim_wait_handler); + + puts("Power up simcard:\n"); + memset(atr,0,sizeof(atr)); + atrLength = calypso_sim_powerup(atr); + + layer1_init(); tpu_frame_irq_en(1, 1); @@ -79,6 +197,7 @@ int main(void) while (1) { l1a_compl_execute(); update_timers(); + sim_handler(); } /* NOT REACHED */ @@ -156,6 +275,9 @@ static void key_handler(enum key_codes code, enum key_states state) default: break; } + /* power down SIM, TODO: this will happen with every key pressed, + put it somewhere else ! */ + calypso_sim_powerdown(); }