# HG changeset patch # User Mychaela Falconia # Date 1611452535 0 # Node ID 54c444eb084b9b6596a8bdecf351ae3203dccf50 # Parent b57cf64ece2982f4679ef03fdcf691837a8f40bf fc-simtool: SELECT response decoding implemented diff -r b57cf64ece29 -r 54c444eb084b simtool/select.c --- 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); }