FreeCalypso > hg > fc-sim-tools
view serial/exchange.c @ 99:97ba63d9361a
scripts/fcsim1-sst: turn off STK & OTA services
In the initial unprogrammed state of the cards from Grcard, SST has
services 25 through 29 set to allocated and activated. However,
these cards appear to not actually support OTA, ENVELOPE commands
do nothing (just return SW 9000), and they were never observed
issuing any proactive SIM commands, even after a feature-generous
TERMINAL PROFILE. Therefore, let's list these STK & OTA services
as allocated, but not activated in our FCSIM1 SST.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 05 May 2021 04:26:07 +0000 |
parents | be27d1c85861 |
children |
line wrap: on
line source
/* * This module implements the main function of our back end: * exchanging APDUs with the SIM. */ #include <sys/types.h> #include <stdio.h> static collect_one_byte() { u_char buf; int rc; rc = collect_bytes_from_sim(&buf, 1); if (rc < 0) return rc; else return buf; } static void finish_sw(sw1, data, datalen) unsigned sw1, datalen; u_char *data; { unsigned sw2, n; int rc; rc = collect_one_byte(); if (rc < 0) { printf("back end error at SW2 Rx step\n"); return; } sw2 = rc; for (n = 0; n < datalen; n++) printf("%02X", data[n]); printf("%02X%02X\n", sw1, sw2); } static void exchange_data_out(ins, data, datalen) unsigned ins, datalen; u_char *data; { int rc; unsigned null_count, bytes_sent, ack, ack1; ack = ins & 0xFE; ack1 = ~ins & 0xFE; bytes_sent = 0; null_count = 0; for (;;) { rc = collect_one_byte(); if (rc < 0) { printf("back end error at procedure byte step\n"); return; } if (rc == 0x60) { null_count++; if (null_count >= 32) { printf( "ERROR: too many stalling NULL bytes received from SIM\n"); return; } continue; } if ((rc & 0xF0) == 0x60 || (rc & 0xF0) == 0x90) { finish_sw(rc, 0, 0); return; } if ((rc & 0xFE) == ack) { if (bytes_sent >= datalen) { bad_xfer_req: printf( "ERROR: SIM requests more xfer after we sent everything\n"); return; } rc = send_bytes_to_sim(data + bytes_sent, datalen - bytes_sent); if (rc < 0) { printf("back end error at data output step\n"); return; } bytes_sent = datalen; continue; } if ((rc & 0xFE) == ack1) { if (bytes_sent >= datalen) goto bad_xfer_req; rc = send_bytes_to_sim(data + bytes_sent, 1); if (rc < 0) { printf("back end error at data output step\n"); return; } bytes_sent++; continue; } printf("ERROR: non-understood procedure byte %02X\n", rc); return; } } static void exchange_data_in(ins, datalen) unsigned ins, datalen; { int rc; unsigned null_count, bytes_rcvd, ack, ack1; u_char data[256]; if (!datalen) datalen = 256; ack = ins & 0xFE; ack1 = ~ins & 0xFE; bytes_rcvd = 0; null_count = 0; for (;;) { rc = collect_one_byte(); if (rc < 0) { printf("back end error at procedure byte step\n"); return; } if (rc == 0x60) { null_count++; if (null_count >= 32) { printf( "ERROR: too many stalling NULL bytes received from SIM\n"); return; } continue; } if ((rc & 0xF0) == 0x60 || (rc & 0xF0) == 0x90) { finish_sw(rc, data, bytes_rcvd); return; } if ((rc & 0xFE) == ack) { if (bytes_rcvd >= datalen) { bad_xfer_req: printf( "ERROR: SIM requests more xfer after we received all expected data\n"); return; } rc = collect_bytes_from_sim(data + bytes_rcvd, datalen - bytes_rcvd); if (rc < 0) { printf("back end error at data input step\n"); return; } bytes_rcvd = datalen; continue; } if ((rc & 0xFE) == ack1) { if (bytes_rcvd >= datalen) goto bad_xfer_req; rc = collect_one_byte(); if (rc < 0) { printf("back end error at data input step\n"); return; } data[bytes_rcvd++] = rc; continue; } printf("ERROR: non-understood procedure byte %02X\n", rc); return; } } void apdu_exchange(cmd_apdu, cmd_apdu_len) u_char *cmd_apdu; unsigned cmd_apdu_len; { int rc; rc = send_bytes_to_sim(cmd_apdu, 5); if (rc < 0) { printf("back end error at the command sending step\n"); return; } if (cmd_apdu_len > 5) exchange_data_out(cmd_apdu[1], cmd_apdu + 5, cmd_apdu_len - 5); else exchange_data_in(cmd_apdu[1], cmd_apdu[4]); }