changeset 0:f7145c77b7fb

starting libcommon: factored out of fc-simtool
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 11 Feb 2021 22:28:45 +0000
parents
children 2071b28cd0c7
files .hgignore libcommon/Makefile libcommon/alpha_decode.c libcommon/alpha_valid.c libcommon/apdu.c libcommon/atr.c libcommon/cardconnect.c libcommon/cardif.h libcommon/exit.c libcommon/file_id.h libcommon/hexdump.c libcommon/hexread.c libcommon/hexstr.c libcommon/names.c libcommon/simresp.h
diffstat 15 files changed, 751 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,3 @@
+syntax: regexp
+
+\.[oa]$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/Makefile	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,14 @@
+CC=	gcc
+CFLAGS=	-O2 -I/usr/include/PCSC
+OBJS=	alpha_decode.o alpha_valid.o apdu.o atr.o cardconnect.o exit.o \
+	hexdump.o hexread.o hexstr.o names.o
+LIB=	libcommon.a
+
+all:	${LIB}
+
+${LIB}:	${OBJS}
+	ar rcu $@ ${OBJS}
+	ranlib $@
+
+clean:
+	rm -f *.[oa] errs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/alpha_decode.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,132 @@
+/*
+ * This module contains functions for decoding and displaying alpha fields
+ * that exist in various SIM files.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static char gsm7_decode_table[128] = {
+	'@', 0,   '$',  0,   0,   0,    0,   0,
+	0,   0,   '\n', 0,   0,   '\r', 0,   0,
+	0,   '_', 0,    0,   0,   0,    0,   0,
+	0,   0,   0,    0,   0,   0,    0,   0,
+	' ', '!', '"',  '#', 0,   '%',  '&', 0x27,
+	'(', ')', '*',  '+', ',', '-',  '.', '/',
+	'0', '1', '2',  '3', '4', '5',  '6', '7',
+	'8', '9', ':',  ';', '<', '=',  '>', '?',
+	0,   'A', 'B',  'C', 'D', 'E',  'F', 'G',
+	'H', 'I', 'J',  'K', 'L', 'M',  'N', 'O',
+	'P', 'Q', 'R',  'S', 'T', 'U',  'V', 'W',
+	'X', 'Y', 'Z',  0,   0,   0,    0,   0,
+	0,   'a', 'b',  'c', 'd', 'e',  'f', 'g',
+	'h', 'i', 'j',  'k', 'l', 'm',  'n', 'o',
+	'p', 'q', 'r',  's', 't', 'u',  'v', 'w',
+	'x', 'y', 'z',  0,   0,   0,    0,   0
+};
+
+static char gsm7ext_decode_table[128] = {
+	0,   0, 0, 0, 0,   0, 0, 0, 0,   0,   0, 0, 0,   0,   0,   0,
+	0,   0, 0, 0, '^', 0, 0, 0, 0,   0,   0, 0, 0,   0,   0,   0,
+	0,   0, 0, 0, 0,   0, 0, 0, '{', '}', 0, 0, 0,   0,   0,   '\\',
+	0,   0, 0, 0, 0,   0, 0, 0, 0,   0,   0, 0, '[', '~', ']', 0,
+	'|', 0, 0, 0, 0,   0, 0, 0, 0,   0,   0, 0, 0,   0,   0,   0,
+	0,   0, 0, 0, 0,   0, 0, 0, 0,   0,   0, 0, 0,   0,   0,   0,
+	0,   0, 0, 0, 0,   0, 0, 0, 0,   0,   0, 0, 0,   0,   0,   0,
+	0,   0, 0, 0, 0,   0, 0, 0, 0,   0,   0, 0, 0,   0,   0,   0
+};
+
+static
+is_gsm7_string_ok(data, nbytes)
+	u_char *data;
+	unsigned nbytes;
+{
+	u_char *dp, *endp;
+	int c;
+
+	dp = data;
+	endp = data + nbytes;
+	while (dp < endp) {
+		c = *dp++;
+		if (c == 0x1B && dp < endp)
+			c = gsm7ext_decode_table[*dp++];
+		else
+			c = gsm7_decode_table[c];
+		if (!c)
+			return(0);
+	}
+	return(1);
+}
+
+static void
+print_alpha_field_gsmdecode(data, nbytes, outf)
+	u_char *data;
+	unsigned nbytes;
+	FILE *outf;
+{
+	u_char *dp, *endp;
+	int c;
+
+	dp = data;
+	endp = data + nbytes;
+	putc('"', outf);
+	while (dp < endp) {
+		c = *dp++;
+		if (c == 0x1B && dp < endp)
+			c = gsm7ext_decode_table[*dp++];
+		else
+			c = gsm7_decode_table[c];
+		if (c == '\n') {
+			putc('\\', outf);
+			putc('n', outf);
+			continue;
+		}
+		if (c == '\r') {
+			putc('\\', outf);
+			putc('r', outf);
+			continue;
+		}
+		if (c == '"' || c == '\\')
+			putc('\\', outf);
+		putc(c, outf);
+	}
+	putc('"', outf);
+}
+
+static void
+print_alpha_field_hex(data, nbytes, outf)
+	u_char *data;
+	unsigned nbytes;
+	FILE *outf;
+{
+	u_char *dp, *endp;
+
+	fputs("HEX ", outf);
+	dp = data;
+	endp = data + nbytes;
+	while (dp < endp)
+		fprintf(outf, "%02X", *dp++);
+}
+
+void
+print_alpha_field(data, nbytes, outf)
+	u_char *data;
+	unsigned nbytes;
+	FILE *outf;
+{
+	if (!nbytes) {
+		fputs("\"\"", outf);
+		return;
+	}
+	if (data[0] & 0x80) {
+		print_alpha_field_hex(data, nbytes, outf);
+		return;
+	}
+	if (is_gsm7_string_ok(data, nbytes))
+		print_alpha_field_gsmdecode(data, nbytes, outf);
+	else
+		print_alpha_field_hex(data, nbytes, outf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/alpha_valid.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,152 @@
+/*
+ * This module contains functions for validating alpha fields
+ * that exist in various SIM files.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static
+validate_classic_gsm(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp;
+	unsigned n;
+
+	dp = data;
+	for (n = 0; n < nbytes; n++) {
+		if (*dp == 0xFF)
+			break;
+		if (*dp & 0x80)
+			return(-1);
+		dp++;
+	}
+	if (textlenp)
+		*textlenp = n;
+	for (; n < nbytes; n++)
+		if (*dp++ != 0xFF)
+			return(-1);
+	return(0);
+}
+
+static
+validate_ucs2_80(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp, *endp;
+
+	if (nbytes < 3)
+		return(-1);
+	dp = data + 1;
+	endp = data + nbytes;
+	while (dp < endp) {
+		if (dp + 1 == endp) {
+			if (*dp != 0xFF)
+				return(-1);
+			if (textlenp)
+				*textlenp = dp - data;
+			return(0);
+		}
+		if (dp[0] == 0xFF && dp[1] == 0xFF)
+			break;
+		dp += 2;
+	}
+	if (textlenp)
+		*textlenp = dp - data;
+	while (dp < endp)
+		if (*dp++ != 0xFF)
+			return(-1);
+	return(0);
+}
+
+static
+validate_ucs2_81(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp, *endp;
+	unsigned textlen;
+
+	if (nbytes < 4)
+		return(-1);
+	if (!data[1])
+		return(-1);
+	textlen = data[1] + 3;
+	if (textlen > nbytes)
+		return(-1);
+	if (textlenp)
+		*textlenp = textlen;
+	dp = data + textlen;
+	endp = data + nbytes;
+	while (dp < endp)
+		if (*dp++ != 0xFF)
+			return(-1);
+	return(0);
+}
+
+static
+validate_ucs2_82(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp, *endp;
+	unsigned textlen;
+
+	if (nbytes < 5)
+		return(-1);
+	if (!data[1])
+		return(-1);
+	textlen = data[1] + 4;
+	if (textlen > nbytes)
+		return(-1);
+	if (textlenp)
+		*textlenp = textlen;
+	dp = data + textlen;
+	endp = data + nbytes;
+	while (dp < endp)
+		if (*dp++ != 0xFF)
+			return(-1);
+	return(0);
+}
+
+static
+validate_empty(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp;
+	unsigned n;
+
+	dp = data;
+	for (n = 0; n < nbytes; n++)
+		if (*dp++ != 0xFF)
+			return(-1);
+	if (textlenp)
+		*textlenp = 0;
+	return(0);
+}
+
+validate_alpha_field(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	if (data[0] < 0x80)
+		return validate_classic_gsm(data, nbytes, textlenp);
+	switch (data[0]) {
+	case 0x80:
+		return validate_ucs2_80(data, nbytes, textlenp);
+	case 0x81:
+		return validate_ucs2_81(data, nbytes, textlenp);
+	case 0x82:
+		return validate_ucs2_82(data, nbytes, textlenp);
+	case 0xFF:
+		return validate_empty(data, nbytes, textlenp);
+	default:
+		return -1;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/apdu.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,36 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcsclite.h>
+#include <winscard.h>
+#include "cardif.h"
+
+u_char sim_resp_data[258];
+unsigned sim_resp_data_len, sim_resp_sw;
+
+apdu_exchange(cmd_apdu, cmd_apdu_len)
+	u_char *cmd_apdu;
+	unsigned cmd_apdu_len;
+{
+	LONG rv;
+	DWORD dwRecvLength;
+	u_char *sw;
+
+	dwRecvLength = 258;
+	rv = SCardTransmit(hCard, SCARD_PCI_T0, cmd_apdu, cmd_apdu_len, NULL,
+			   sim_resp_data, &dwRecvLength);
+	if (rv != SCARD_S_SUCCESS) {
+		fprintf(stderr, "SCardTransmit: %s\n",
+			pcsc_stringify_error(rv));
+		return(-1);
+	}
+	if (dwRecvLength < 2) {
+		fprintf(stderr,
+		"error: SCardTransmit response is shorter than 2 SW bytes\n");
+		return(-1);
+	}
+	sim_resp_data_len = dwRecvLength - 2;
+	sw = sim_resp_data + sim_resp_data_len;
+	sim_resp_sw = (sw[0] << 8) | sw[1];
+	return(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/atr.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,30 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcsclite.h>
+#include <winscard.h>
+#include <reader.h>
+#include "cardif.h"
+
+#define	MAX_ATR_BYTES	33
+
+retrieve_atr()
+{
+	u_char atrbuf[MAX_ATR_BYTES];
+	LONG rv;
+	DWORD dwAttrLen;
+	unsigned n;
+
+	dwAttrLen = MAX_ATR_BYTES;
+	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, atrbuf, &dwAttrLen);
+	if (rv != SCARD_S_SUCCESS) {
+		fprintf(stderr, "SCardGetAttrib for ATR: %s\n",
+			pcsc_stringify_error(rv));
+		return(-1);
+	}
+	printf("ATR:");
+	for (n = 0; n < dwAttrLen; n++)
+		printf(" %02X", atrbuf[n]);
+	putchar('\n');
+	return(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/cardconnect.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,85 @@
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcsclite.h>
+#include <winscard.h>
+
+SCARDCONTEXT hContext;
+SCARDHANDLE hCard;
+char *reader_name_buf;
+
+setup_pcsc_context()
+{
+	LONG rv;
+
+	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+	if (rv != SCARD_S_SUCCESS) {
+		fprintf(stderr, "SCardEstablishContext: %s\n",
+			pcsc_stringify_error(rv));
+		exit(1);
+	}
+	return(0);
+}
+
+get_reader_name()
+{
+	LONG rv;
+	DWORD dwReaders;
+
+	rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
+	if (rv != SCARD_S_SUCCESS) {
+		fprintf(stderr, "SCardListReaders 1st call: %s\n",
+			pcsc_stringify_error(rv));
+		SCardReleaseContext(hContext);
+		exit(1);
+	}
+	if (dwReaders < 1) {
+		fprintf(stderr,
+	"error: dwReaders returned by SCardListReaders() is less than 1\n");
+		SCardReleaseContext(hContext);
+		exit(1);
+	}
+	reader_name_buf = malloc(dwReaders);
+	if (!reader_name_buf) {
+		perror("malloc for readers list");
+		SCardReleaseContext(hContext);
+		exit(1);
+	}
+	reader_name_buf[0] = '\0';
+	rv = SCardListReaders(hContext, NULL, reader_name_buf, &dwReaders);
+	if (rv != SCARD_S_SUCCESS) {
+		fprintf(stderr, "SCardListReaders 2nd call: %s\n",
+			pcsc_stringify_error(rv));
+		SCardReleaseContext(hContext);
+		exit(1);
+	}
+	if (reader_name_buf[0] == '\0') {
+		fprintf(stderr,
+	"error: list returned by SCardListReaders() begins with a NUL byte\n");
+		SCardReleaseContext(hContext);
+		exit(1);
+	}
+	if (!memchr(reader_name_buf, 0, dwReaders)) {
+		fprintf(stderr,
+"error: list returned by SCardListReaders() does not contain a NUL byte\n");
+		SCardReleaseContext(hContext);
+		exit(1);
+	}
+	return(0);
+}
+
+connect_to_card()
+{
+	LONG rv;
+	DWORD dwActiveProtocol;
+
+	rv = SCardConnect(hContext, reader_name_buf, SCARD_SHARE_EXCLUSIVE,
+			  SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
+	if (rv != SCARD_S_SUCCESS) {
+		fprintf(stderr, "SCardConnect: %s\n", pcsc_stringify_error(rv));
+		SCardReleaseContext(hContext);
+		exit(1);
+	}
+	return(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/cardif.h	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,5 @@
+/* extern definitions for global vars defined in cardconnect.c */
+
+extern SCARDCONTEXT hContext;
+extern SCARDHANDLE hCard;
+extern char *reader_name_buf;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/exit.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcsclite.h>
+#include <winscard.h>
+#include "cardif.h"
+
+good_exit()
+{
+	SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
+	SCardReleaseContext(hContext);
+	exit(0);
+}
+
+error_exit()
+{
+	SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
+	SCardReleaseContext(hContext);
+	exit(1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/file_id.h	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,51 @@
+/* definitions of a few file IDs we find interesting */
+
+#define	FILEID_MF	0x3F00
+
+#define	DF_TELECOM	0x7F10
+#define	DF_GSM		0x7F20
+#define	DF_DCS1800	0x7F21
+
+/* EFs under MF */
+#define	EF_DIR		0x2F00
+#define	EF_ICCID	0x2FE2
+
+/* EFs under DF_GSM */
+#define	EF_LP		0x6F05
+#define	EF_IMSI		0x6F07
+#define	EF_Kc		0x6F20
+#define	EF_PLMNsel	0x6F30
+#define	EF_HPLMN	0x6F31
+#define	EF_ACMmax	0x6F37
+#define	EF_SST		0x6F38
+#define	EF_ACM		0x6F39
+#define	EF_GID1		0x6F3E
+#define	EF_GID2		0x6F3F
+#define	EF_PUCT		0x6F41
+#define	EF_CBMI		0x6F45
+#define	EF_SPN		0x6F46
+#define	EF_CBMID	0x6F48
+#define	EF_CBMIR	0x6F50
+#define	EF_BCCH		0x6F74
+#define	EF_ACC		0x6F78
+#define	EF_FPLMN	0x6F7B
+#define	EF_LOCI		0x6F7E
+#define	EF_AD		0x6FAD
+#define	EF_PHASE	0x6FAE
+#define	EF_ECC		0x6FB7
+#define	EF_PNN		0x6FC5
+#define	EF_OPL		0x6FC6
+
+/* EFs under DF_TELECOM */
+#define	EF_ADN		0x6F3A
+#define	EF_FDN		0x6F3B
+#define	EF_SMS		0x6F3C
+#define	EF_CCP		0x6F3D
+#define	EF_MSISDN	0x6F40
+#define	EF_SMSP		0x6F42
+#define	EF_SMSS		0x6F43
+#define	EF_LND		0x6F44
+#define	EF_SDN		0x6F49
+#define	EF_EXT1		0x6F4A
+#define	EF_EXT2		0x6F4B
+#define	EF_EXT3		0x6F4C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/hexdump.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,36 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include "simresp.h"
+
+display_sim_resp_in_hex()
+{
+	unsigned off, cc, n, c;
+
+	for (off = 0; off < sim_resp_data_len; off += cc) {
+		printf("%02X:", off);
+		cc = 16;
+		if (sim_resp_data_len - off < cc)
+			cc = sim_resp_data_len - off;
+		for (n = 0; n < 16; n++) {
+			if (n == 0 || n == 8)
+				putchar(' ');
+			putchar(' ');
+			if (n < cc)
+				printf("%02X", sim_resp_data[off + n]);
+			else {
+				putchar(' ');
+				putchar(' ');
+			}
+		}
+		putchar(' ');
+		putchar(' ');
+		for (n = 0; n < cc; n++) {
+			c = sim_resp_data[off + n];
+			if (c < 0x20 || c > 0x7E)
+				c = '.';
+			putchar(c);
+		}
+		putchar('\n');
+	}
+	return(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/hexread.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,56 @@
+/*
+ * This module contains the function for reading hex files,
+ * to be used in the implementation of manual write commands.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+read_hex_data_file(filename, databuf)
+	char *filename;
+	u_char *databuf;
+{
+	FILE *inf;
+	unsigned count;
+	int c, c2;
+
+	inf = fopen(filename, "r");
+	if (!inf) {
+		perror(filename);
+		return(-1);
+	}
+	for (count = 0; ; count++) {
+		do
+			c = getc(inf);
+		while (isspace(c));
+		if (c < 0)
+			break;
+		if (!isxdigit(c)) {
+inv_input:		fprintf(stderr, "%s: invalid hex file input\n",
+				filename);
+			fclose(inf);
+			return(-1);
+		}
+		c2 = getc(inf);
+		if (!isxdigit(c2))
+			goto inv_input;
+		if (count >= 255) {
+			fprintf(stderr, "%s: hex input data is too long\n",
+				filename);
+			fclose(inf);
+			return(-1);
+		}
+		databuf[count] = (decode_hex_digit(c) << 4) |
+				 decode_hex_digit(c2);
+	}
+	fclose(inf);
+	if (!count) {
+		fprintf(stderr, "%s: no hex data input found\n", filename);
+		return(-1);
+	}
+	return(count);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/hexstr.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,52 @@
+/*
+ * This module contains the function for decoding hex strings.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+decode_hex_digit(c)
+{
+	if (c >= '0' && c <= '9')
+		return(c - '0');
+	if (c >= 'A' && c <= 'F')
+		return(c - 'A' + 10);
+	if (c >= 'a' && c <= 'f')
+		return(c - 'a' + 10);
+	return(-1);
+}
+
+decode_hex_data_from_string(arg, databuf, minlen, maxlen)
+	char *arg;
+	u_char *databuf;
+	unsigned minlen, maxlen;
+{
+	unsigned count;
+
+	for (count = 0; ; count++) {
+		while (isspace(*arg))
+			arg++;
+		if (!*arg)
+			break;
+		if (!isxdigit(arg[0]) || !isxdigit(arg[1])) {
+			fprintf(stderr, "error: invalid hex string input\n");
+			return(-1);
+		}
+		if (count >= maxlen) {
+			fprintf(stderr, "error: hex string is too long\n");
+			return(-1);
+		}
+		databuf[count] = (decode_hex_digit(arg[0]) << 4) |
+				 decode_hex_digit(arg[1]);
+		arg += 2;
+	}
+	if (count < minlen) {
+		fprintf(stderr, "error: hex string is too short\n");
+		return(-1);
+	}
+	return(count);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/names.c	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,76 @@
+/*
+ * This module contains the table of user-friendly file names
+ * and a function for searching this table.
+ */
+
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "file_id.h"
+
+static struct nametab {
+	char	*name;
+	int	file_id;
+} name_table[] = {
+	{"MF",		FILEID_MF},
+	{"DF_GSM",	DF_GSM},
+	{"DF_DCS1800",	DF_DCS1800},
+	{"DF_TELECOM",	DF_TELECOM},
+	{"gsm",		DF_GSM},
+	{"telecom",	DF_TELECOM},
+	/* EFs under MF */
+	{"EF_DIR",	EF_DIR},
+	{"EF_ICCID",	EF_ICCID},
+	/* EFs under DF_GSM */
+	{"EF_LP",	EF_LP},
+	{"EF_IMSI",	EF_IMSI},
+	{"EF_Kc",	EF_Kc},
+	{"EF_PLMNsel",	EF_PLMNsel},
+	{"EF_HPLMN",	EF_HPLMN},
+	{"EF_ACMmax",	EF_ACMmax},
+	{"EF_SST",	EF_SST},
+	{"EF_ACM",	EF_ACM},
+	{"EF_GID1",	EF_GID1},
+	{"EF_GID2",	EF_GID2},
+	{"EF_PUCT",	EF_PUCT},
+	{"EF_CBMI",	EF_CBMI},
+	{"EF_SPN",	EF_SPN},
+	{"EF_CBMID",	EF_CBMID},
+	{"EF_CBMIR",	EF_CBMIR},
+	{"EF_BCCH",	EF_BCCH},
+	{"EF_ACC",	EF_ACC},
+	{"EF_FPLMN",	EF_FPLMN},
+	{"EF_LOCI",	EF_LOCI},
+	{"EF_AD",	EF_AD},
+	{"EF_PHASE",	EF_PHASE},
+	{"EF_ECC",	EF_ECC},
+	{"EF_PNN",	EF_PNN},
+	{"EF_OPL",	EF_OPL},
+	/* EFs under DF_TELECOM */
+	{"EF_ADN",	EF_ADN},
+	{"EF_FDN",	EF_FDN},
+	{"EF_SMS",	EF_SMS},
+	{"EF_CCP",	EF_CCP},
+	{"EF_MSISDN",	EF_MSISDN},
+	{"EF_SMSP",	EF_SMSP},
+	{"EF_SMSS",	EF_SMSS},
+	{"EF_LND",	EF_LND},
+	{"EF_SDN",	EF_SDN},
+	{"EF_EXT1",	EF_EXT1},
+	{"EF_EXT2",	EF_EXT2},
+	{"EF_EXT3",	EF_EXT3},
+	/* table search terminator */
+	{0,		-1}
+};
+
+find_symbolic_file_name(soughtname)
+	char *soughtname;
+{
+	struct nametab *tp;
+
+	for (tp = name_table; tp->name; tp++)
+		if (!strcmp(tp->name, soughtname))
+			break;
+	return tp->file_id;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/simresp.h	Thu Feb 11 22:28:45 2021 +0000
@@ -0,0 +1,4 @@
+/* extern definitions for SIM response global vars defined in apdu.c */
+
+extern u_char sim_resp_data[];
+extern unsigned sim_resp_data_len, sim_resp_sw;