# HG changeset patch # User Mychaela Falconia # Date 1613162355 0 # Node ID f5a26c1d0b93f05f96eb0056a59abf569dc6ab18 # Parent acf343dace04bd333355234a1dff0c4d549ff7b9 fc-simtool smsp-dump implemented diff -r acf343dace04 -r f5a26c1d0b93 libcommon/number_decode.c --- a/libcommon/number_decode.c Fri Feb 12 17:50:42 2021 +0000 +++ b/libcommon/number_decode.c Fri Feb 12 20:39:15 2021 +0000 @@ -35,3 +35,24 @@ *out = '\0'; return(0); } + +decode_address_digits(inbuf, outbuf, ndigits) + u_char *inbuf; + char *outbuf; + unsigned ndigits; +{ + u_char *inp = inbuf; + char *outp = outbuf; + unsigned n = 0, b; + + while (n < ndigits) { + b = *inp++; + *outp++ = gsm_address_digits[b & 0xF]; + n++; + if (n >= ndigits) + break; + *outp++ = gsm_address_digits[b >> 4]; + n++; + } + *outp = '\0'; +} diff -r acf343dace04 -r f5a26c1d0b93 simtool/Makefile --- a/simtool/Makefile Fri Feb 12 17:50:42 2021 +0000 +++ b/simtool/Makefile Fri Feb 12 20:39:15 2021 +0000 @@ -4,7 +4,8 @@ OBJS= a38.o chv.o curfile.o dispatch.o dumpdir.o grcard1.o grcard2.o hlread.o\ main.o pbcommon.o pbdump.o pberase.o pbupd_file.o pbupd_imm.o \ pbupd_immhex.o readcmd.o readops.o restorebin.o savebin.o script.o \ - select.o sysmo.o telsum.o writecmd.o writeops.o + select.o smsp_common.o smsp_dump.o sysmo.o telsum.o writecmd.o \ + writeops.o LIBS= ../libcommon/libcommon.a INSTBIN=/opt/freecalypso/bin diff -r acf343dace04 -r f5a26c1d0b93 simtool/dispatch.c --- a/simtool/dispatch.c Fri Feb 12 17:50:42 2021 +0000 +++ b/simtool/dispatch.c Fri Feb 12 20:39:15 2021 +0000 @@ -38,6 +38,7 @@ extern int cmd_savebin(); extern int cmd_save_sms_bin(); extern int cmd_select(); +extern int cmd_smsp_dump(); extern int cmd_spn(); extern int cmd_telecom_sum(); extern int cmd_uicc_dir(); @@ -101,6 +102,7 @@ {"save-sms-bin", 1, 1, cmd_save_sms_bin}, {"select", 1, 1, cmd_select}, {"sim-resp", 0, 0, display_sim_resp_in_hex}, + {"smsp-dump", 0, 1, cmd_smsp_dump}, {"spn", 0, 0, cmd_spn}, {"telecom-sum", 0, 0, cmd_telecom_sum}, {"uicc-dir", 0, 0, cmd_uicc_dir}, diff -r acf343dace04 -r f5a26c1d0b93 simtool/smsp_common.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simtool/smsp_common.c Fri Feb 12 20:39:15 2021 +0000 @@ -0,0 +1,33 @@ +/* + * This module implements some common functions for working with EF_SMSP. + */ + +#include +#include "curfile.h" +#include "file_id.h" + +select_ef_smsp() +{ + int rc; + + rc = select_op(DF_TELECOM); + if (rc < 0) + return(rc); + rc = select_op(EF_SMSP); + if (rc < 0) + return(rc); + rc = parse_ef_select_response(); + if (rc < 0) + return(rc); + if (curfile_structure != 0x01) { + fprintf(stderr, "error: EF_SMSP is not linear fixed\n"); + return(-1); + } + if (curfile_record_len < 28) { + fprintf(stderr, + "error: EF_SMSP has record length of %u bytes, less than minimum 28\n", + curfile_record_len); + return(-1); + } + return(0); +} diff -r acf343dace04 -r f5a26c1d0b93 simtool/smsp_dump.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simtool/smsp_dump.c Fri Feb 12 20:39:15 2021 +0000 @@ -0,0 +1,143 @@ +/* + * This module implements intelligent dumping of EF_SMSP (smsp-dump). + */ + +#include +#include +#include "simresp.h" +#include "curfile.h" + +static +check_blank_area(dp, endp) + u_char *dp, *endp; +{ + while (dp < endp) + if (*dp++ != 0xFF) + return(-1); + return(0); +} + +static void +dump_da_field(binaddr, outf) + u_char *binaddr; + FILE *outf; +{ + char digits[21]; + + fputs("DA=", outf); + if (binaddr[0] < 1 || binaddr[0] > 20) { +malformed: fputs("malformed ", outf); + return; + } + if ((binaddr[0] & 1) && (binaddr[(binaddr[0] >> 1) + 2] & 0xF0) != 0xF0) + goto malformed; + if (check_blank_area(binaddr + 2 + ((binaddr[0] + 1) >> 1), + binaddr + 12) < 0) + goto malformed; + /* all checks passed */ + decode_address_digits(binaddr + 2, digits, binaddr[0]); + fprintf(outf, "%s,0x%02X ", digits, binaddr[1]); +} + +static void +dump_sca_field(binaddr, outf) + u_char *binaddr; + FILE *outf; +{ + char digits[21]; + int rc; + + fputs("SC=", outf); + if (binaddr[0] < 2 || binaddr[0] > 11) { +malformed: fputs("malformed ", outf); + return; + } + rc = decode_phone_number(binaddr + 2, binaddr[0] - 1, digits); + if (rc < 0) + goto malformed; + rc = check_blank_area(binaddr + 1 + binaddr[0], binaddr + 12); + if (rc < 0) + goto malformed; + /* all checks passed */ + fprintf(outf, "%s,0x%02X ", digits, binaddr[1]); +} + +static void +dump_record(recno, outf) + unsigned recno; + FILE *outf; +{ + int rc; + unsigned textlen; + u_char *fixp; + + fprintf(outf, "#%u: ", recno); + if (sim_resp_data_len > 28) { + rc = validate_alpha_field(sim_resp_data, + sim_resp_data_len - 28, + &textlen); + if (rc < 0) { +malformed: fprintf(outf, "malformed record\n"); + return; + } + } else + textlen = 0; + fixp = sim_resp_data + sim_resp_data_len - 28; + if ((fixp[0] & 0xE0) != 0xE0) + goto malformed; + if ((fixp[0] & 0x01) && check_blank_area(fixp + 1, fixp + 13) < 0) + goto malformed; + if ((fixp[0] & 0x02) && check_blank_area(fixp + 13, fixp + 25) < 0) + goto malformed; + if ((fixp[0] & 0x04) && fixp[25] != 0xFF) + goto malformed; + if ((fixp[0] & 0x08) && fixp[26] != 0xFF) + goto malformed; + if ((fixp[0] & 0x10) && fixp[27] != 0xFF) + goto malformed; + /* basic checks passed, emit present fields */ + if (!(fixp[0] & 0x01)) + dump_da_field(fixp + 1, outf); + if (!(fixp[0] & 0x02)) + dump_sca_field(fixp + 13, outf); + if (!(fixp[0] & 0x04)) + fprintf(outf, "PID=0x%02X ", fixp[25]); + if (!(fixp[0] & 0x08)) + fprintf(outf, "DCS=0x%02X ", fixp[26]); + if (!(fixp[0] & 0x10)) + fprintf(outf, "VP=%u ", fixp[27]); + print_alpha_field(sim_resp_data, textlen, outf); + putc('\n', outf); +} + +cmd_smsp_dump(argc, argv) + char **argv; +{ + int rc; + FILE *outf; + unsigned recno; + + rc = select_ef_smsp(); + if (rc < 0) + return(rc); + if (argv[1]) { + outf = fopen(argv[1], "w"); + if (!outf) { + perror(argv[1]); + return(-1); + } + } else + outf = stdout; + for (recno = 1; recno <= curfile_record_count; recno++) { + rc = readrec_op(recno, 0x04, curfile_record_len); + if (rc < 0) { + if (argv[1]) + fclose(outf); + return(rc); + } + dump_record(recno, outf); + } + if (argv[1]) + fclose(outf); + return(0); +}