fixed typos in comments
[osmocom-bb.git] / src / target / firmware / apps / simtest / main.c
1 /* main program of Free Software for Calypso Phone */
2
3 /* (C) 2010 by Harald Welte <laforge@gnumonks.org>
4  *
5  * All Rights Reserved
6  *
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.
11  *
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.
16  *
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.
20  *
21  */
22
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <string.h>
26
27 #include <debug.h>
28 #include <memory.h>
29 #include <rffe.h>
30 #include <keypad.h>
31 #include <board.h>
32 #include <abb/twl3025.h>
33 #include <display.h>
34 #include <rf/trf6151.h>
35 #include <calypso/clock.h>
36 #include <calypso/tpu.h>
37 #include <calypso/tsp.h>
38 #include <calypso/dsp.h>
39 #include <calypso/irq.h>
40 #include <calypso/misc.h>
41 #include <comm/sercomm.h>
42 #include <comm/timer.h>
43
44
45 #include <calypso/sim.h>
46
47
48 #define DEBUG
49
50 /* Dump bytes in hex on the console */
51 static void myHexdump(uint8_t *data, int len)
52 {
53         int i;
54
55         for(i=0;i<len;i++)
56                 printf("%x ",data[i]);
57
58         printf("(%i bytes)\n", len);
59
60         return;
61 }
62
63 /* SIM instructions 
64    All instructions a standard sim card must feature: */
65 #define SIM_CLASS 0xA0                  /* Class that contains the following instructions */
66 #define SIM_SELECT 0xA4                 /* Select a file on the card */
67 #define SIM_STATUS 0xF2                 /* Get the status of the currently selected file */
68 #define SIM_READ_BINARY 0xB0            /* Read file in binary mode */
69 #define SIM_UPDATE_BINARY 0xD6          /* Write file in binary mode */
70 #define SIM_READ_RECORD 0xB2            /* Read record of a record based file */
71 #define SIM_UPDATE_RECORD 0xDC          /* Write record of a record based file */
72 #define SIM_SEEK 0xA2                   /* Seek in a record based file */
73 #define SIM_INCREASE 0x32               /* Increase a record in a record based file */
74 #define SIM_VERIFY_CHV 0x20             /* Authenticate with card (enter pin) */
75 #define SIM_CHANGE_CHV 0x24             /* Change pin */
76 #define SIM_DISABLE_CHV 0x26            /* Disable pin so that no authentication is needed anymore */
77 #define SIM_ENABLE_CHV 0x28             /* Enable pin, authentication is now needed again */
78 #define SIM_UNBLOCK_CHV 0x2C            /* Unblock pin when it is blocked by entering a wrong pin three times */
79 #define SIM_INVALIDATE 0x04             /* Invalidate the current elementry file (file in a subdirectory) */
80 #define SIM_REHABILITATE 0x44           /* Rehabilitate the current elementry file (file in a subdirectory) */
81 #define SIM_RUN_GSM_ALGORITHM 0x88      /* Run the GSM A3 authentication algorithm in the card */
82 #define SIM_SLEEP 0xFA                  /* Sleep command (only used in Phase 1 GSM) */
83 #define SIM_GET_RESPONSE 0xC0           /* Get the response of a command from the card */
84
85 /* File identifiers (filenames)
86    The file identifiers are the standardized file identifiers mentioned in the
87    GSM-11-11 specification. */
88 #define SIM_MF          0x3F00
89 #define SIM_EF_ICCID    0x2FE2
90 #define SIM_DF_TELECOM  0x7F10
91 #define SIM_EF_ADN      0x6F3A
92 #define SIM_EF_FDN      0x6F3B
93 #define SIM_EF_SMS      0x6F3C
94 #define SIM_EF_CCP      0x6F3D
95 #define SIM_EF_MSISDN   0x6F40
96 #define SIM_EF_SMSP     0x6F42
97 #define SIM_EF_SMSS     0x6F43
98 #define SIM_EF_LND      0x6F44
99 #define SIM_EF_EXT1     0x6F4A
100 #define SIM_EF_EXT2     0x6F4B
101 #define SIM_DF_GSM      0x7F20
102 #define SIM_EF_LP       0x6F05
103 #define SIM_EF_IMSI     0x6F07
104 #define SIM_EF_KC       0x6F20
105 #define SIM_EF_PLMNsel  0x6F30
106 #define SIM_EF_HPLMN    0x6F31
107 #define SIM_EF_ACMmax   0x6F37
108 #define SIM_EF_SST      0x6F38
109 #define SIM_EF_ACM      0x6F39
110 #define SIM_EF_GID1     0x6F3E
111 #define SIM_EF_GID2     0x6F3F
112 #define SIM_EF_PUCT     0x6F41
113 #define SIM_EF_CBMI     0x6F45
114 #define SIM_EF_SPN      0x6F46
115 #define SIM_EF_BCCH     0x6F74
116 #define SIM_EF_ACC      0x6F78
117 #define SIM_EF_FPLMN    0x6F7B
118 #define SIM_EF_LOCI     0x6F7E
119 #define SIM_EF_AD       0x6FAD
120 #define SIM_EF_PHASE    0x6FAE
121
122 /* Select a file on the card */
123 uint16_t sim_select(uint16_t fid)
124 {
125         uint8_t txBuffer[2];
126         uint8_t status_word[2];
127
128         txBuffer[1] = (uint8_t) fid;
129         txBuffer[0] = (uint8_t) (fid >> 8);
130
131         if(calypso_sim_transceive(SIM_CLASS, SIM_SELECT, 0x00, 0x00, 0x02,txBuffer,status_word, SIM_APDU_PUT) != 0)
132                 return 0xFFFF;
133
134         return (status_word[0] << 8) | status_word[1];
135 }
136
137 /* Get the status of the currently selected file */
138 uint16_t sim_status(void) 
139 {
140         uint8_t status_word[2];
141
142         if(calypso_sim_transceive(SIM_CLASS, SIM_STATUS, 0x00, 0x00, 0x00,0,status_word, SIM_APDU_PUT) != 0)
143                 return 0xFFFF;
144
145         return (status_word[0] << 8) | status_word[1];
146 }
147
148 /* Read file in binary mode */
149 uint16_t sim_readbinary(uint8_t offset_high, uint8_t offset_low, uint8_t length, uint8_t *data)
150 {
151         uint8_t status_word[2];
152         if(calypso_sim_transceive(SIM_CLASS, SIM_READ_BINARY, offset_high, offset_low, length, data ,status_word, SIM_APDU_GET) != 0)
153                 return 0xFFFF;
154
155         return (status_word[0] << 8) | status_word[1];
156 }
157
158
159
160
161
162 /* FIXME: We need properly calibrated delay loops at some point! */
163 void delay_us(unsigned int us)
164 {
165         volatile unsigned int i;
166
167         for (i= 0; i < us*4; i++) { i; }
168 }
169
170 void delay_ms(unsigned int ms)
171 {
172         volatile unsigned int i;
173         for (i= 0; i < ms*1300; i++) { i; }
174 }
175
176
177
178
179 /* Execute my (dexter's) personal test */
180 void do_sim_test(void)
181 {
182         uint8_t testBuffer[20];
183         uint8_t testtxBuffer[20];
184
185         uint8_t testDataBody[257];
186         uint8_t testStatusWord[2];
187         int recivedChars;
188         int i;
189
190         uint8_t atr[20];
191         uint8_t atrLength = 0;
192         
193         memset(atr,0,sizeof(atr));
194
195
196
197         uint8_t buffer[20];
198
199
200         memset(testtxBuffer,0,sizeof(testtxBuffer));
201
202         puts("----------------SIMTEST----8<-----------------\n");
203
204         /* Initialize Sim-Controller driver */
205         puts("Initializing driver:\n");
206         calypso_sim_init();
207
208         /* Power up sim and display ATR */
209         puts("Power up simcard:\n");
210         memset(atr,0,sizeof(atr));
211         atrLength = calypso_sim_powerup(atr);
212         myHexdump(atr,atrLength);
213
214         /* Reset sim and display ATR */
215         puts("Reset simcard:\n");
216         memset(atr,0,sizeof(atr));
217         atrLength = calypso_sim_reset(atr);
218         myHexdump(atr,atrLength);
219
220
221
222         testDataBody[0] = 0x3F;
223         testDataBody[1] = 0x00;
224         calypso_sim_transceive(0xA0, 0xA4, 0x00, 0x00, 0x02, testDataBody,0, SIM_APDU_PUT);
225         calypso_sim_transceive(0xA0, 0xC0, 0x00, 0x00, 0x0f, testDataBody,0, SIM_APDU_GET);
226         myHexdump(testDataBody,0x0F);
227
228         puts("Test Phase 1: Testing bare sim commands...\n");
229
230         puts(" * Testing SELECT: Selecting MF\n");
231         printf("   ==> Status word: %x\n", sim_select(SIM_MF));
232
233         puts(" * Testing SELECT: Selecting DF_GSM\n");
234         printf("   ==> Status word: %x\n", sim_select(SIM_DF_GSM));
235
236         puts(" * Testing SELECT: Selecting EF_IMSI\n");
237         printf("   ==> Status word: %x\n", sim_select(SIM_EF_IMSI));
238
239         puts(" * Testing STATUS:\n");
240         printf("   ==> Status word: %x\n", sim_status());
241
242         memset(buffer,0,sizeof(buffer));
243         puts(" * Testing READ BINARY:\n");      
244         printf("   ==> Status word: %x\n", sim_readbinary(0,0,9,buffer));
245         printf("       Data: ");
246         myHexdump(buffer,9);
247
248         delay_ms(5000);
249
250         calypso_sim_powerdown();
251
252         puts("------------END SIMTEST----8<-----------------\n");
253 }
254
255
256
257
258 /* Main Program */
259 const char *hr = "======================================================================\n";
260
261 void key_handler(enum key_codes code, enum key_states state);
262
263 static void *console_rx_cb(uint8_t dlci, struct msgb *msg)
264 {
265         if (dlci != SC_DLCI_CONSOLE) {
266                 printf("Message for unknown DLCI %u\n", dlci);
267                 return;
268         }
269
270         printf("Message on console DLCI: '%s'\n", msg->data);
271         msgb_free(msg);
272 }
273
274 int main(void)
275 {
276         board_init();
277
278         puts("\n\nOSMOCOM SIM Test (revision " GIT_REVISION ")\n");
279         puts(hr);
280
281         /* Dump device identification */
282         dump_dev_id();
283         puts(hr);
284
285         /* Dump clock config before PLL set */
286         calypso_clk_dump();
287         puts(hr);
288
289         keypad_set_handler(&key_handler);
290
291         /* Dump clock config after PLL set */
292         calypso_clk_dump();
293         puts(hr);
294
295         /* Dump all memory */
296         //dump_mem();
297 #if 0
298         /* Dump Bootloader */
299         memdump_range((void *)0x00000000, 0x2000);
300         puts(hr);
301 #endif
302
303         display_set_attr(DISP_ATTR_INVERT);
304         display_puts("SIM-TEST");
305
306         sercomm_register_rx_cb(SC_DLCI_CONSOLE, console_rx_cb);
307
308         do_sim_test();
309
310         /* beyond this point we only react to interrupts */
311         puts("entering interrupt loop\n");
312         while (1) {
313         }
314
315         twl3025_power_off();
316         while (1) {}
317 }
318
319 void key_handler(enum key_codes code, enum key_states state)
320 {
321         if (state != PRESSED)
322                 return;
323
324         switch (code) {
325         default:
326                 break;
327         }
328 }