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 } |
