FreeCalypso > hg > fc-sim-tools
comparison simtool/miscadm.c @ 10:ddd767f6e15b
fc-simtool ported over
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 14 Mar 2021 07:11:25 +0000 |
parents | |
children | 1888d88478c4 |
comparison
equal
deleted
inserted
replaced
9:c9ef9e91dd8e | 10:ddd767f6e15b |
---|---|
1 /* | |
2 * This module implements write-iccid and write-imsi commands, | |
3 * available only in the admin programming phase after authenticating | |
4 * with some card-vendor-dependent ADM key. | |
5 */ | |
6 | |
7 #include <sys/types.h> | |
8 #include <stdio.h> | |
9 #include <stdlib.h> | |
10 #include <string.h> | |
11 #include <strings.h> | |
12 #include "curfile.h" | |
13 #include "file_id.h" | |
14 | |
15 static | |
16 write_iccid_bin(binrec) | |
17 u_char *binrec; | |
18 { | |
19 int rc; | |
20 | |
21 rc = select_op(FILEID_MF); | |
22 if (rc < 0) | |
23 return(rc); | |
24 rc = select_op(EF_ICCID); | |
25 if (rc < 0) | |
26 return(rc); | |
27 rc = parse_ef_select_response(); | |
28 if (rc < 0) | |
29 return(rc); | |
30 if (curfile_structure != 0x00 || curfile_total_size != 10) { | |
31 fprintf(stderr, | |
32 "error: EF_ICCID is not a transparent EF of 10 bytes\n"); | |
33 return(-1); | |
34 } | |
35 return update_bin_op(0, binrec, 10); | |
36 } | |
37 | |
38 cmd_write_iccid(argc, argv) | |
39 char **argv; | |
40 { | |
41 int rc; | |
42 u_char nibbles[20], binrec[10]; | |
43 | |
44 rc = parse_decimal_string_arg(argv[1], nibbles, 20); | |
45 if (rc < 0) | |
46 return(rc); | |
47 pack_reversed_nibbles(nibbles, binrec, 10); | |
48 return write_iccid_bin(binrec); | |
49 } | |
50 | |
51 cmd_write_iccid_sh18(argc, argv) | |
52 char **argv; | |
53 { | |
54 int rc; | |
55 u_char nibbles[20], binrec[10]; | |
56 | |
57 rc = parse_decimal_shorthand(argv[1], nibbles, 18); | |
58 if (rc < 0) | |
59 return(rc); | |
60 nibbles[18] = compute_iccid_luhn(nibbles); | |
61 nibbles[19] = 0xF; | |
62 pack_reversed_nibbles(nibbles, binrec, 10); | |
63 return write_iccid_bin(binrec); | |
64 } | |
65 | |
66 cmd_write_iccid_sh19(argc, argv) | |
67 char **argv; | |
68 { | |
69 int rc; | |
70 u_char nibbles[20], binrec[10]; | |
71 | |
72 rc = parse_decimal_shorthand(argv[1], nibbles, 19); | |
73 if (rc < 0) | |
74 return(rc); | |
75 if (nibbles[18] != compute_iccid_luhn(nibbles)) { | |
76 fprintf(stderr, "error: Luhn check digit mismatch\n"); | |
77 return(-1); | |
78 } | |
79 nibbles[19] = 0xF; | |
80 pack_reversed_nibbles(nibbles, binrec, 10); | |
81 return write_iccid_bin(binrec); | |
82 } | |
83 | |
84 static | |
85 write_imsi_bin(binrec) | |
86 u_char *binrec; | |
87 { | |
88 int rc; | |
89 | |
90 rc = select_op(DF_GSM); | |
91 if (rc < 0) | |
92 return(rc); | |
93 rc = select_op(EF_IMSI); | |
94 if (rc < 0) | |
95 return(rc); | |
96 rc = parse_ef_select_response(); | |
97 if (rc < 0) | |
98 return(rc); | |
99 if (curfile_structure != 0x00 || curfile_total_size != 9) { | |
100 fprintf(stderr, | |
101 "error: EF_IMSI is not a transparent EF of 9 bytes\n"); | |
102 return(-1); | |
103 } | |
104 return update_bin_op(0, binrec, 9); | |
105 } | |
106 | |
107 cmd_write_imsi(argc, argv) | |
108 char **argv; | |
109 { | |
110 int rc; | |
111 u_char nibbles[16], binrec[9]; | |
112 unsigned ndig; | |
113 | |
114 rc = parse_decimal_string_arg(argv[1], nibbles + 1, 15); | |
115 if (rc < 0) | |
116 return(rc); | |
117 ndig = rc; | |
118 if (ndig & 1) | |
119 nibbles[0] = 9; | |
120 else | |
121 nibbles[0] = 1; | |
122 binrec[0] = (ndig + 2) >> 1; | |
123 pack_reversed_nibbles(nibbles, binrec + 1, 8); | |
124 return write_imsi_bin(binrec); | |
125 } | |
126 | |
127 cmd_write_imsi_sh(argc, argv) | |
128 char **argv; | |
129 { | |
130 int rc; | |
131 u_char nibbles[16], binrec[9]; | |
132 | |
133 rc = parse_decimal_shorthand(argv[1], nibbles + 1, 15); | |
134 if (rc < 0) | |
135 return(rc); | |
136 nibbles[0] = 9; | |
137 binrec[0] = 8; | |
138 pack_reversed_nibbles(nibbles, binrec + 1, 8); | |
139 return write_imsi_bin(binrec); | |
140 } | |
141 | |
142 static | |
143 write_acc_bin(binrec) | |
144 u_char *binrec; | |
145 { | |
146 int rc; | |
147 | |
148 rc = select_op(DF_GSM); | |
149 if (rc < 0) | |
150 return(rc); | |
151 rc = select_op(EF_ACC); | |
152 if (rc < 0) | |
153 return(rc); | |
154 rc = parse_ef_select_response(); | |
155 if (rc < 0) | |
156 return(rc); | |
157 if (curfile_structure != 0x00 || curfile_total_size != 2) { | |
158 fprintf(stderr, | |
159 "error: EF_ACC is not a transparent EF of 2 bytes\n"); | |
160 return(-1); | |
161 } | |
162 return update_bin_op(0, binrec, 2); | |
163 } | |
164 | |
165 cmd_write_acc(argc, argv) | |
166 char **argv; | |
167 { | |
168 unsigned acc; | |
169 u_char binrec[2]; | |
170 | |
171 acc = strtoul(argv[1], 0, 16); | |
172 if (acc > 0xFFFF) { | |
173 fprintf(stderr, "error: ACC argument is out of range\n"); | |
174 return(-1); | |
175 } | |
176 binrec[0] = acc >> 8; | |
177 binrec[1] = acc; | |
178 return write_acc_bin(binrec); | |
179 } | |
180 | |
181 static | |
182 write_spn_bin(binrec) | |
183 u_char *binrec; | |
184 { | |
185 int rc; | |
186 | |
187 rc = select_op(DF_GSM); | |
188 if (rc < 0) | |
189 return(rc); | |
190 rc = select_op(EF_SPN); | |
191 if (rc < 0) | |
192 return(rc); | |
193 rc = parse_ef_select_response(); | |
194 if (rc < 0) | |
195 return(rc); | |
196 if (curfile_structure != 0x00 || curfile_total_size != 17) { | |
197 fprintf(stderr, | |
198 "error: EF_SPN is not a transparent EF of 17 bytes\n"); | |
199 return(-1); | |
200 } | |
201 return update_bin_op(0, binrec, 17); | |
202 } | |
203 | |
204 cmd_write_spn(argc, argv) | |
205 char **argv; | |
206 { | |
207 u_char binrec[17]; | |
208 int rc; | |
209 | |
210 binrec[0] = strtoul(argv[1], 0, 16); | |
211 memset(binrec + 1, 0xFF, 16); | |
212 rc = qstring_arg_to_gsm7(argv[2], binrec + 1, 16); | |
213 if (rc < 0) | |
214 return(rc); | |
215 return write_spn_bin(binrec); | |
216 } |