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 }