FreeCalypso > hg > fc-sim-tools
comparison simtool/pnndump.c @ 10:ddd767f6e15b
fc-simtool ported over
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Sun, 14 Mar 2021 07:11:25 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 9:c9ef9e91dd8e | 10:ddd767f6e15b |
|---|---|
| 1 /* | |
| 2 * This module implements the pnn-dump command, providing a | |
| 3 * user-accessible way to identify MVNO SIMs. | |
| 4 */ | |
| 5 | |
| 6 #include <sys/types.h> | |
| 7 #include <stdio.h> | |
| 8 #include "simresp.h" | |
| 9 #include "curfile.h" | |
| 10 #include "file_id.h" | |
| 11 | |
| 12 select_ef_pnn() | |
| 13 { | |
| 14 int rc; | |
| 15 | |
| 16 rc = select_op(DF_GSM); | |
| 17 if (rc < 0) | |
| 18 return(rc); | |
| 19 rc = select_op(EF_PNN); | |
| 20 if (rc < 0) | |
| 21 return(rc); | |
| 22 rc = parse_ef_select_response(); | |
| 23 if (rc < 0) | |
| 24 return(rc); | |
| 25 if (curfile_structure != 0x01) { | |
| 26 fprintf(stderr, "error: EF_PNN is not linear fixed\n"); | |
| 27 return(-1); | |
| 28 } | |
| 29 if (curfile_record_len < 3) { | |
| 30 fprintf(stderr, | |
| 31 "error: EF_PNN record length is less than the spec minimum of 3 bytes\n"); | |
| 32 return(-1); | |
| 33 } | |
| 34 return(0); | |
| 35 } | |
| 36 | |
| 37 static void | |
| 38 dump_record(recno, outf) | |
| 39 unsigned recno; | |
| 40 FILE *outf; | |
| 41 { | |
| 42 u_char *dp, *endp; | |
| 43 char *name_kw; | |
| 44 unsigned ielen, code_byte, nsept; | |
| 45 u_char gsm7_buf[288]; | |
| 46 | |
| 47 fprintf(outf, "#%u:", recno); | |
| 48 dp = sim_resp_data; | |
| 49 endp = sim_resp_data + sim_resp_data_len; | |
| 50 while (dp < endp) { | |
| 51 if (*dp == 0xFF) | |
| 52 break; | |
| 53 switch (*dp++) { | |
| 54 case 0x43: | |
| 55 name_kw = "Ln"; | |
| 56 break; | |
| 57 case 0x45: | |
| 58 name_kw = "Sn"; | |
| 59 break; | |
| 60 default: | |
| 61 fprintf(outf, " unknown-IEI\n"); | |
| 62 return; | |
| 63 } | |
| 64 if (dp >= endp) { | |
| 65 fprintf(outf, " truncated-IE\n"); | |
| 66 return; | |
| 67 } | |
| 68 ielen = *dp++; | |
| 69 if (ielen < 1 || ielen > (endp - dp)) { | |
| 70 fprintf(outf, " bad-length\n"); | |
| 71 return; | |
| 72 } | |
| 73 code_byte = *dp++; | |
| 74 ielen--; | |
| 75 fprintf(outf, " %s=0x%02X", name_kw, code_byte); | |
| 76 if (!ielen) | |
| 77 continue; | |
| 78 putc(',', outf); | |
| 79 if ((code_byte & 0x70) == 0) { | |
| 80 nsept = ielen * 8 / 7; | |
| 81 gsm7_unpack(dp, gsm7_buf, nsept); | |
| 82 dp += ielen; | |
| 83 print_gsm7_string_to_file(gsm7_buf, nsept, outf); | |
| 84 } else { | |
| 85 for (; ielen; ielen--) | |
| 86 fprintf(outf, "%02X", *dp++); | |
| 87 } | |
| 88 } | |
| 89 for (; dp < endp; dp++) { | |
| 90 if (*dp != 0xFF) { | |
| 91 fprintf(outf, " bad-padding\n"); | |
| 92 return; | |
| 93 } | |
| 94 } | |
| 95 putc('\n', outf); | |
| 96 } | |
| 97 | |
| 98 cmd_pnn_dump(argc, argv, outf) | |
| 99 char **argv; | |
| 100 FILE *outf; | |
| 101 { | |
| 102 int rc; | |
| 103 unsigned recno; | |
| 104 | |
| 105 rc = select_ef_pnn(); | |
| 106 if (rc < 0) | |
| 107 return(rc); | |
| 108 for (recno = 1; recno <= curfile_record_count; recno++) { | |
| 109 rc = readrec_op(recno, 0x04, curfile_record_len); | |
| 110 if (rc < 0) | |
| 111 return(rc); | |
| 112 if (check_simresp_all_blank()) | |
| 113 continue; | |
| 114 dump_record(recno, outf); | |
| 115 } | |
| 116 return(0); | |
| 117 } |
