FreeCalypso > hg > fc-sim-tools
view serial/collect_atr.c @ 93:6041c601304d
fcsim1-mkprov: revert OTA key addition
It appears that GrcardSIM2 cards (which is what we got for FCSIM1)
do not support OTA after all, contrary to what we were previously
led to believe by some tech support emails from Grcard - apparently
those support emails and OTA descriptions referred to some other
card model(s).
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 21 Apr 2021 05:38:39 +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'); }