1 /* main program of Free Software for Calypso Phone */
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.
32 #include <abb/twl3025.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>
45 #include <calypso/sim.h>
50 /* Dump bytes in hex on the console */
51 static void myHexdump(uint8_t *data, int len)
56 printf("%x ",data[i]);
58 printf("(%i bytes)\n", len);
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 */
85 /* File identifiers (filenames)
86 The file identifiers are the standardized file identifiers mentioned in the
87 GSM-11-11 specification. */
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
122 /* Select a file on the card */
123 uint16_t sim_select(uint16_t fid)
126 uint8_t status_word[2];
128 txBuffer[1] = (uint8_t) fid;
129 txBuffer[0] = (uint8_t) (fid >> 8);
131 if(calypso_sim_transceive(SIM_CLASS, SIM_SELECT, 0x00, 0x00, 0x02,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,status_word, SIM_APDU_PUT) != 0)
145 return (status_word[0] << 8) | status_word[1];
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)
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)
155 return (status_word[0] << 8) | status_word[1];
162 /* FIXME: We need properly calibrated delay loops at some point! */
163 void delay_us(unsigned int us)
165 volatile unsigned int i;
167 for (i= 0; i < us*4; i++) { i; }
170 void delay_ms(unsigned int ms)
172 volatile unsigned int i;
173 for (i= 0; i < ms*1300; i++) { i; }
179 /* Execute my (dexter's) personal test */
180 void do_sim_test(void)
182 uint8_t testBuffer[20];
183 uint8_t testtxBuffer[20];
185 uint8_t testDataBody[257];
186 uint8_t testStatusWord[2];
191 uint8_t atrLength = 0;
193 memset(atr,0,sizeof(atr));
200 memset(testtxBuffer,0,sizeof(testtxBuffer));
202 puts("----------------SIMTEST----8<-----------------\n");
204 /* Initialize Sim-Controller driver */
205 puts("Initializing driver:\n");
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);
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);
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);
228 puts("Test Phase 1: Testing bare sim commands...\n");
230 puts(" * Testing SELECT: Selecting MF\n");
231 printf(" ==> Status word: %x\n", sim_select(SIM_MF));
233 puts(" * Testing SELECT: Selecting DF_GSM\n");
234 printf(" ==> Status word: %x\n", sim_select(SIM_DF_GSM));
236 puts(" * Testing SELECT: Selecting EF_IMSI\n");
237 printf(" ==> Status word: %x\n", sim_select(SIM_EF_IMSI));
239 puts(" * Testing STATUS:\n");
240 printf(" ==> Status word: %x\n", sim_status());
242 memset(buffer,0,sizeof(buffer));
243 puts(" * Testing READ BINARY:\n");
244 printf(" ==> Status word: %x\n", sim_readbinary(0,0,9,buffer));
250 calypso_sim_powerdown();
252 puts("------------END SIMTEST----8<-----------------\n");
259 const char *hr = "======================================================================\n";
261 void key_handler(enum key_codes code, enum key_states state);
263 static void *console_rx_cb(uint8_t dlci, struct msgb *msg)
265 if (dlci != SC_DLCI_CONSOLE) {
266 printf("Message for unknown DLCI %u\n", dlci);
270 printf("Message on console DLCI: '%s'\n", msg->data);
278 puts("\n\nOSMOCOM SIM Test (revision " GIT_REVISION ")\n");
281 /* Dump device identification */
285 /* Dump clock config before PLL set */
289 keypad_set_handler(&key_handler);
291 /* Dump clock config after PLL set */
295 /* Dump all memory */
298 /* Dump Bootloader */
299 memdump_range((void *)0x00000000, 0x2000);
303 display_set_attr(DISP_ATTR_INVERT);
304 display_puts("SIM-TEST");
306 sercomm_register_rx_cb(SC_DLCI_CONSOLE, console_rx_cb);
310 /* beyond this point we only react to interrupts */
311 puts("entering interrupt loop\n");
319 void key_handler(enum key_codes code, enum key_states state)
321 if (state != PRESSED)