changeset 86:54c444eb084b

fc-simtool: SELECT response decoding implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 24 Jan 2021 01:42:15 +0000
parents b57cf64ece29
children 2a0d1d5b9313
files simtool/select.c
diffstat 1 files changed, 94 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/simtool/select.c	Sun Jan 24 00:32:10 2021 +0000
+++ b/simtool/select.c	Sun Jan 24 01:42:15 2021 +0000
@@ -54,10 +54,36 @@
 	return(0);
 }
 
+static void
+show_secret_code_status(name, byte)
+	char *name;
+	unsigned byte;
+{
+	printf("Status of %s: %s, %u attempts left\n", name,
+		byte & 0x80 ? "initialized" : "not initialized",
+		byte & 0x0F);
+}
+
+static void
+show_access_conditions(oper_name, cond_code)
+	char *oper_name;
+	unsigned cond_code;
+{
+	static char *cond_names[16] =
+		{"ALW", "CHV1", "CHV2", "RFU3",
+		 "ADM4", "ADM5", "ADM6", "ADM7",
+		 "ADM8", "ADM9", "ADM10", "ADM11",
+		 "ADM12", "ADM13", "ADM14", "NEV"};
+
+	printf("Access condition for %s: %s\n", oper_name,
+		cond_names[cond_code]);
+}
+
 cmd_select(argc, argv)
 	char **argv;
 {
 	unsigned file_id;
+	int rc;
 
 	if (isxdigit(argv[1][0]) && isxdigit(argv[1][1]) &&
 	    isxdigit(argv[1][2]) && isxdigit(argv[1][3]) && !argv[1][4])
@@ -67,5 +93,72 @@
 			"select: only hex file IDs are currently supported\n");
 		return(-1);
 	}
-	return select_op(file_id);
+	rc = select_op(file_id);
+	if (rc < 0)
+		return(rc);
+	if (sim_resp_data_len < 14) {
+		fprintf(stderr,
+	"error: response length of %u bytes is too short for any file type\n",
+			sim_resp_data_len);
+		return(-1);
+	}
+	switch (sim_resp_data[6]) {
+	case 0x01:
+		printf("File type: MF\n");
+		goto mf_or_df;
+	case 0x02:
+		printf("File type: DF\n");
+	mf_or_df:
+		if (sim_resp_data_len < 22) {
+			fprintf(stderr,
+		"error: response length of %u bytes is too short for MF/DF\n",
+				sim_resp_data_len);
+			return(-1);
+		}
+		printf("File characteristics: %02X\n", sim_resp_data[13]);
+		printf("Number of DF children: %u\n", sim_resp_data[14]);
+		printf("Number of EF children: %u\n", sim_resp_data[15]);
+		printf("Number of secret codes: %u\n", sim_resp_data[16]);
+		show_secret_code_status("PIN1", sim_resp_data[18]);
+		show_secret_code_status("PUK1", sim_resp_data[19]);
+		show_secret_code_status("PIN2", sim_resp_data[20]);
+		show_secret_code_status("PUK2", sim_resp_data[21]);
+		break;
+	case 0x04:
+		printf("File type: EF\n");
+		printf("File size: %u\n",
+			(sim_resp_data[2] << 8) | sim_resp_data[3]);
+		switch (sim_resp_data[13]) {
+		case 0x00:
+			printf("Structure: transparent\n");
+			break;
+		case 0x01:
+			printf("Structure: linear fixed\n");
+			goto ef_record_based;
+		case 0x03:
+			printf("Structure: cyclic\n");
+		ef_record_based:
+			if (sim_resp_data_len < 15) {
+				fprintf(stderr,
+	"error: response length of %u bytes is too short for record-based EF\n",
+					sim_resp_data_len);
+				return(-1);
+			}
+			printf("Record length: %u\n", sim_resp_data[14]);
+			break;
+		default:
+			printf("Structure: %02X (unknown)\n",
+				sim_resp_data[13]);
+		}
+		printf("File status: %02X\n", sim_resp_data[11]);
+		show_access_conditions("UPDATE", sim_resp_data[8] & 0xF);
+		show_access_conditions("READ & SEEK", sim_resp_data[8] >> 4);
+		show_access_conditions("INCREASE", sim_resp_data[9] >> 4);
+		show_access_conditions("INVALIDATE", sim_resp_data[10] & 0xF);
+		show_access_conditions("REHABILITATE", sim_resp_data[10] >> 4);
+		break;
+	default:
+		printf("File type: %02X (unknown)\n", sim_resp_data[6]);
+	}
+	return(0);
 }