FreeCalypso > hg > fc-sim-tools
view serial/collect_atr.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 | 1d96f3b4f155 |
children |
line wrap: on
line source
/* * This module contains the code for collecting ATR bytes from the SIM, * as well as subsequent byte Rx. */ #include <sys/types.h> #include <sys/time.h> #include <sys/errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> extern int target_fd; #define MAX_ATR_BYTES 33 extern unsigned char inverse_coding_table[256]; u_char atr_buf[MAX_ATR_BYTES]; unsigned atr_length; int inverse_coding; void invert_bytes(buf, nbytes) u_char *buf; unsigned nbytes; { unsigned n; for (n = 0; n < nbytes; n++) buf[n] = inverse_coding_table[buf[n]]; } collect_bytes_from_sim(buf, expect_len) u_char *buf; unsigned expect_len; { fd_set fds; struct timeval tv; unsigned rcvd; int cc; for (rcvd = 0; rcvd < expect_len; ) { FD_ZERO(&fds); FD_SET(target_fd, &fds); tv.tv_sec = 2; tv.tv_usec = 0; cc = select(target_fd+1, &fds, NULL, NULL, &tv); if (cc < 0) { if (errno == EINTR) continue; perror("select"); return(-1); } if (cc < 1) { fprintf(stderr, "error: timeout waiting for byte(s) from SIM\n"); return(-1); } cc = read(target_fd, buf + rcvd, expect_len - rcvd); if (cc <= 0) { perror("read after successful select"); return(-1); } rcvd += cc; } if (inverse_coding) invert_bytes(buf, rcvd); return(0); } check_atr_tck() { unsigned b, p; b = 0; for (p = 1; p < atr_length; p++) b ^= atr_buf[p]; if (b) { fprintf(stderr, "error: ATR checksum is bad\n"); return(-1); } return(0); } collect_atr() { int rc; unsigned count, y, nhist, have_tck; rc = collect_bytes_from_sim(atr_buf, 2); if (rc < 0) return(rc); if (atr_buf[0] == 0x3B) { /* direct convention */ } else if (atr_buf[0] == 0x03) { /* inverse convention */ inverse_coding = 1; atr_buf[0] = 0x3F; atr_buf[1] = inverse_coding_table[atr_buf[1]]; } else { fprintf(stderr, "error: received TS=0x%02X, matches neither convention\n", atr_buf[0]); return(-1); } atr_length = 2; nhist = atr_buf[1] & 0x0F; y = atr_buf[1] & 0xF0; have_tck = 0; while (y) { count = 0; if (y & 0x10) count++; if (y & 0x20) count++; if (y & 0x40) count++; if (y & 0x80) count++; if (atr_length + count > MAX_ATR_BYTES) { atr_too_long: fprintf(stderr, "error: ATR exceeds 33 byte limit\n"); return(-1); } rc = collect_bytes_from_sim(atr_buf + atr_length, count); if (rc < 0) return(rc); atr_length += count; if (y & 0x80) { y = atr_buf[atr_length-1] & 0xF0; if (atr_buf[atr_length-1] & 0x0F) have_tck = 1; } else y = 0; } count = nhist + have_tck; if (count) { if (atr_length + count > MAX_ATR_BYTES) goto atr_too_long; rc = collect_bytes_from_sim(atr_buf + atr_length, count); if (rc < 0) return(rc); atr_length += count; } if (have_tck) return check_atr_tck(); else return 0; } void print_atr(head) char *head; { unsigned n; fputs(head, stdout); for (n = 0; n < atr_length; n++) { printf(" %02X", atr_buf[n]); } putchar('\n'); }