1 /* SIM test application */
3 /* (C) 2010 by Harald Welte <laforge@gnumonks.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <abb/twl3025.h>
35 #include <rf/trf6151.h>
36 #include <calypso/clock.h>
37 #include <calypso/tpu.h>
38 #include <calypso/tsp.h>
39 #include <calypso/dsp.h>
40 #include <calypso/irq.h>
41 #include <calypso/misc.h>
42 #include <comm/sercomm.h>
43 #include <comm/timer.h>
45 #include <calypso/sim.h>
49 /* Dump bytes in hex on the console */
50 static void myHexdump(uint8_t *data, int len)
55 printf("%02x ",data[i]);
57 printf("(%i bytes)\n", len);
63 All instructions a standard sim card must feature: */
64 #define SIM_CLASS 0xA0 /* Class that contains the following instructions */
65 #define SIM_SELECT 0xA4 /* Select a file on the card */
66 #define SIM_STATUS 0xF2 /* Get the status of the currently selected file */
67 #define SIM_READ_BINARY 0xB0 /* Read file in binary mode */
68 #define SIM_UPDATE_BINARY 0xD6 /* Write file in binary mode */
69 #define SIM_READ_RECORD 0xB2 /* Read record of a record based file */
70 #define SIM_UPDATE_RECORD 0xDC /* Write record of a record based file */
71 #define SIM_SEEK 0xA2 /* Seek in a record based file */
72 #define SIM_INCREASE 0x32 /* Increase a record in a record based file */
73 #define SIM_VERIFY_CHV 0x20 /* Authenticate with card (enter pin) */
74 #define SIM_CHANGE_CHV 0x24 /* Change pin */
75 #define SIM_DISABLE_CHV 0x26 /* Disable pin so that no authentication is needed anymore */
76 #define SIM_ENABLE_CHV 0x28 /* Enable pin, authentication is now needed again */
77 #define SIM_UNBLOCK_CHV 0x2C /* Unblock pin when it is blocked by entering a wrong pin three times */
78 #define SIM_INVALIDATE 0x04 /* Invalidate the current elementry file (file in a subdirectory) */
79 #define SIM_REHABILITATE 0x44 /* Rehabilitate the current elementry file (file in a subdirectory) */
80 #define SIM_RUN_GSM_ALGORITHM 0x88 /* Run the GSM A3 authentication algorithm in the card */
81 #define SIM_SLEEP 0xFA /* Sleep command (only used in Phase 1 GSM) */
82 #define SIM_GET_RESPONSE 0xC0 /* Get the response of a command from the card */
84 /* File identifiers (filenames)
85 The file identifiers are the standardized file identifiers mentioned in the
86 GSM-11-11 specification. */
88 #define SIM_EF_ICCID 0x2FE2
89 #define SIM_DF_TELECOM 0x7F10
90 #define SIM_EF_ADN 0x6F3A
91 #define SIM_EF_FDN 0x6F3B
92 #define SIM_EF_SMS 0x6F3C
93 #define SIM_EF_CCP 0x6F3D
94 #define SIM_EF_MSISDN 0x6F40
95 #define SIM_EF_SMSP 0x6F42
96 #define SIM_EF_SMSS 0x6F43
97 #define SIM_EF_LND 0x6F44
98 #define SIM_EF_EXT1 0x6F4A
99 #define SIM_EF_EXT2 0x6F4B
100 #define SIM_DF_GSM 0x7F20
101 #define SIM_EF_LP 0x6F05
102 #define SIM_EF_IMSI 0x6F07
103 #define SIM_EF_KC 0x6F20
104 #define SIM_EF_PLMNsel 0x6F30
105 #define SIM_EF_HPLMN 0x6F31
106 #define SIM_EF_ACMmax 0x6F37
107 #define SIM_EF_SST 0x6F38
108 #define SIM_EF_ACM 0x6F39
109 #define SIM_EF_GID1 0x6F3E
110 #define SIM_EF_GID2 0x6F3F
111 #define SIM_EF_PUCT 0x6F41
112 #define SIM_EF_CBMI 0x6F45
113 #define SIM_EF_SPN 0x6F46
114 #define SIM_EF_BCCH 0x6F74
115 #define SIM_EF_ACC 0x6F78
116 #define SIM_EF_FPLMN 0x6F7B
117 #define SIM_EF_LOCI 0x6F7E
118 #define SIM_EF_AD 0x6FAD
119 #define SIM_EF_PHASE 0x6FAE
121 /* Select a file on the card */
122 uint16_t sim_select(uint16_t fid)
125 uint8_t status_word[2];
127 txBuffer[1] = (uint8_t) fid;
128 txBuffer[0] = (uint8_t) (fid >> 8);
130 if(calypso_sim_transceive(SIM_CLASS, SIM_SELECT, 0x00, 0x00, 0x02,
131 txBuffer, status_word, SIM_APDU_PUT) != 0)
134 return (status_word[0] << 8) | status_word[1];
137 /* Get the status of the currently selected file */
138 uint16_t sim_status(void)
140 uint8_t status_word[2];
142 if(calypso_sim_transceive(SIM_CLASS, SIM_STATUS, 0x00, 0x00, 0x00, 0,
143 status_word, SIM_APDU_PUT) != 0)
146 return (status_word[0] << 8) | status_word[1];
149 /* Read file in binary mode */
150 uint16_t sim_readbinary(uint8_t offset_high, uint8_t offset_low, uint8_t length, uint8_t *data)
152 uint8_t status_word[2];
153 if(calypso_sim_transceive(SIM_CLASS, SIM_READ_BINARY, offset_high,
154 offset_low, length, data ,status_word,
158 return (status_word[0] << 8) | status_word[1];
161 uint16_t sim_verify(char *pin)
164 uint8_t status_word[2];
166 memset(txBuffer, 0xFF, 8);
167 memcpy(txBuffer, pin, strlen(pin));
169 if(calypso_sim_transceive(SIM_CLASS, SIM_VERIFY_CHV, 0x00, 0x01, 0x08, txBuffer,status_word, SIM_APDU_PUT) != 0)
172 return (status_word[0] << 8) | status_word[1];
175 uint16_t sim_run_gsm_algorith(uint8_t *data)
177 uint8_t status_word[2];
179 if(calypso_sim_transceive(SIM_CLASS, SIM_RUN_GSM_ALGORITHM, 0x00, 0x00, 0x10, data, status_word, SIM_APDU_PUT) != 0)
182 printf(" ==> Status word: %x\n", (status_word[0] << 8) | status_word[1]);
184 if(status_word[0] != 0x9F || status_word[1] != 0x0C)
185 return (status_word[0] << 8) | status_word[1];
189 if(calypso_sim_transceive(SIM_CLASS, SIM_GET_RESPONSE, 0, 0, 0x0C, data ,status_word, SIM_APDU_GET) != 0)
192 return (status_word[0] << 8) | status_word[1];
196 /* FIXME: We need proper calibrated delay loops at some point! */
197 void delay_us(unsigned int us)
199 volatile unsigned int i;
201 for (i= 0; i < us*4; i++) { i; }
204 void delay_ms(unsigned int ms)
206 volatile unsigned int i;
207 for (i= 0; i < ms*1300; i++) { i; }
213 /* Execute my (dexter's) personal test */
214 void do_sim_test(void)
216 uint8_t testBuffer[20];
217 uint8_t testtxBuffer[20];
219 uint8_t testDataBody[257];
220 uint8_t testStatusWord[2];
225 uint8_t atrLength = 0;
227 memset(atr,0,sizeof(atr));
234 memset(testtxBuffer,0,sizeof(testtxBuffer));
236 puts("----------------SIMTEST----8<-----------------\n");
238 /* Initialize Sim-Controller driver */
239 puts("Initializing driver:\n");
240 calypso_sim_init(NULL);
242 /* Power up sim and display ATR */
243 puts("Power up simcard:\n");
244 memset(atr,0,sizeof(atr));
245 atrLength = calypso_sim_powerup(atr);
246 myHexdump(atr,atrLength);
248 /* Reset sim and display ATR */
249 puts("Reset simcard:\n");
250 memset(atr,0,sizeof(atr));
251 atrLength = calypso_sim_reset(atr);
252 myHexdump(atr,atrLength);
256 testDataBody[0] = 0x3F;
257 testDataBody[1] = 0x00;
258 calypso_sim_transceive(0xA0, 0xA4, 0x00, 0x00, 0x02, testDataBody,0, SIM_APDU_PUT);
259 calypso_sim_transceive(0xA0, 0xC0, 0x00, 0x00, 0x0f, testDataBody,0, SIM_APDU_GET);
260 myHexdump(testDataBody,0x0F);
262 puts("Test Phase 1: Testing bare sim commands...\n");
264 puts(" * Testing SELECT: Selecting MF\n");
265 printf(" ==> Status word: %x\n", sim_select(SIM_MF));
267 puts(" * Testing SELECT: Selecting DF_GSM\n");
268 printf(" ==> Status word: %x\n", sim_select(SIM_DF_GSM));
270 puts(" * Testing PIN VERIFY\n");
271 printf(" ==> Status word: %x\n", sim_verify("1234"));
273 puts(" * Testing SELECT: Selecting EF_IMSI\n");
274 printf(" ==> Status word: %x\n", sim_select(SIM_EF_IMSI));
276 puts(" * Testing STATUS:\n");
277 printf(" ==> Status word: %x\n", sim_status());
279 memset(buffer,0,sizeof(buffer));
280 puts(" * Testing READ BINARY:\n");
281 printf(" ==> Status word: %x\n", sim_readbinary(0,0,9,buffer));
285 memset(buffer,0,sizeof(buffer));
286 memcpy(buffer,"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff",16);
287 puts(" * Testing RUN GSM ALGORITHM\n");
288 printf(" ==> Status word: %x\n", sim_run_gsm_algorith(buffer));
290 myHexdump(buffer,12);
294 calypso_sim_powerdown();
296 puts("------------END SIMTEST----8<-----------------\n");
300 const char *hr = "======================================================================\n";
302 void key_handler(enum key_codes code, enum key_states state);
304 static void *console_rx_cb(uint8_t dlci, struct msgb *msg)
306 if (dlci != SC_DLCI_CONSOLE) {
307 printf("Message for unknown DLCI %u\n", dlci);
311 printf("Message on console DLCI: '%s'\n", msg->data);
319 puts("\n\nOSMOCOM SIM Test (revision " GIT_REVISION ")\n");
322 /* Dump device identification */
326 /* Dump clock config before PLL set */
330 keypad_set_handler(&key_handler);
332 /* Dump clock config after PLL set */
336 /* Dump all memory */
339 /* Dump Bootloader */
340 memdump_range((void *)0x00000000, 0x2000);
344 display_set_attr(DISP_ATTR_INVERT);
345 display_puts("SIM-TEST");
347 sercomm_register_rx_cb(SC_DLCI_CONSOLE, console_rx_cb);
351 /* beyond this point we only react to interrupts */
352 puts("entering interrupt loop\n");
360 void key_handler(enum key_codes code, enum key_states state)
362 if (state != PRESSED)