comparison bsp/sim.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*
2 * SIM.C
3 *
4 * Pole Star SIM
5 *
6 * Target : ARM
7 *
8 *
9 * SIM card driver. This module contents all functions
10 * included in specifications GSM 11.11 V4.10
11 *
12 *
13 * Copyright (c) Texas Instruments 1995-1997
14 *
15 */
16
17 #define SIM_C 1
18
19 #include "../include/config.h"
20 #include "../include/sys_types.h"
21
22 #include "mem.h"
23
24 #if (CHIPSET == 12)
25 #include "sys_inth.h"
26 #else
27 #include "iq.h"
28 #endif
29 #include "sim.h"
30 #include <string.h>
31 #include "armio.h"
32 #include "../L1/cust0/ind_os.h"
33 #include "abb+spi/abb.h" //controls level shifter of ABB
34
35
36 //current voltage mode 3V or 5V, or 1.8V
37 SYS_UWORD8 CurrentVolt;
38
39
40
41 #ifdef SIM_DEBUG_TRACE
42
43 #ifdef SIM_RETRY
44 /* one byte more to trace the number of retry for each functions */
45 #define SIM_DBG_NULL 5
46 #else
47 /* size of buffer tracing the reception of NULL byte */
48 #define SIM_DBG_NULL 4
49 #endif
50
51 /* working buffer for NULL BYTE and number of RETRY */
52 SYS_UWORD8 SIM_dbg_null[SIM_DBG_NULL];
53 /* size of buffer tracing the chronology of calls */
54 #define SIM_DBG_CMD 7500
55 /* working buffer for chronology calls */
56 SYS_UWORD8 SIM_dbg_cmd[SIM_DBG_CMD];
57 /* index for positionning in working buffer for chronology calls */
58 SYS_UWORD16 SIM_dbg_cmd_cmpt;
59 /* working variable to calculate the TDMA ecart */
60 SYS_UWORD16 SIM_dbg_tdma_diff;
61 /* working variable to store the maximum TDMA frame between two characters */
62 SYS_UWORD16 SIM_dbg_max_interchardelay;
63 /* working variable used in each L2/L3 access function */
64 SYS_UWORD8 SIM_dbg_tmp[10];
65 /* internal function due to factorization of use of traces */
66 void SIM_dbg_write_trace(SYS_UWORD8 *ptr, SYS_UWORD16 len);
67
68 #endif
69
70 #ifdef SIM_RETRY
71 /* number of retry */
72 #define NUM_SIM_RETRIES 10
73 /* Add variables to support sim retry */
74 SYS_UWORD8 SimRetries;
75 #endif
76
77
78 /*
79 * Low level routines : mapped to hardware
80 * SIM_WriteBuffer
81 * SIM_Command
82 * SIM_Reset
83 *
84 */
85
86
87 /*
88 * SIM_WriteBuffer
89 *
90 * Write n bytes to SIM card in interrupt mode:
91 * return the line, write first byte and let interrupt handler do the rest
92 * return the line, write first byte and let interrupt handler do the rest
93 *
94 * Parameters :
95 * SIM_PORT *p : buffer for received chars
96 * offset : starting point for reading data.
97 * n : number of chars to read.
98 */
99 void SIM_WriteBuffer(SIM_PORT *p, SYS_UWORD16 offset, SYS_UWORD16 n)
100 {
101 unsigned volatile i;
102
103 // Set write direction
104 p->conf1 |= SIM_CONF1_TXRX;
105 p->c->conf1 = p->conf1;
106
107 p->SWcount = 0;
108 p->rx_index = 0;
109 p->expected_data = 0;
110
111 p->xOut = p->xbuf + offset;
112 p->xIn = p->xbuf + offset + n;
113
114 if ((p->xIn - p->xOut) == 1) //if only one char is transmitted
115 { //need to wait a minimum of 1 ETU
116 ind_os_sleep (1); //for IO line to stay in TX mode
117 }
118 // Write first byte
119 p->c->tx = *(p->xOut); // transmit
120
121 if ((p->xIn - p->xOut) == 1) //if only one char to transmit
122 { // return the direction to rx
123 p->conf1 &= ~SIM_CONF1_TXRX; //to be able to receive ACK char
124 p->c->conf1 = p->conf1;
125 }
126 }
127
128 /*
129 * SIM_Result
130 *
131 * Parameters : SIM port, buffer for received chars, pointer to receive size
132 *
133 * Return the result code (SW1/SW2) at the end of the string
134 */
135 SYS_UWORD16 SIM_Result(SIM_PORT *p, SYS_UWORD8 *rP, SYS_UWORD16 *lenP, SYS_UWORD8 offset)
136 {
137 SYS_UWORD8 sw1, sw2;
138 SYS_UWORD8 verdict;
139 SYS_UWORD16 len;
140
141 // Check if all characters were transmitted
142 if (p->xIn - 1 != p->xOut)
143 return (SIM_ERR_XMIT);
144
145 len = p->rx_index;
146 *lenP = len - offset;
147 if ((*lenP == 0) && (p->apdu_ans_length == 256))
148 *lenP = 256;
149
150 if (p->expected_data == 256)
151 {
152 verdict = SIM_Memcpy(rP, ((p->rbuf) + offset), 256 - offset);
153 if (verdict != 0)
154 {
155 return (verdict);
156 }
157 }
158 else if ((len != 0) && (len >= offset))
159 {
160 verdict = SIM_Memcpy(rP, ((p->rbuf) + offset), len - offset);
161 if (verdict != 0)
162 {
163 return (verdict);
164 }
165 }
166
167 // change to remove SW1 and SW2 bytes from the receive buffer of data
168 sw1 = p->rSW12[0];
169 sw2 = p->rSW12[1];
170
171 return((sw1 << 8) | sw2);
172 }
173
174 /*
175 * SIM_Command_base
176 *
177 * Perform a command with the SIM T=0 protocol
178 *
179 * Arguments : pointer to SIM port structure
180 * number of characters above 5
181 * expected command time in TDMA
182 *
183 * Returns an error code :
184 * SIM_ERR_READ : no answer from the card to a command
185 * SIM_ERR_LEN : the answer is not corresponding to a
186 * correct answer of T=0 protocol
187 * 06/11/2002 JYT
188 * Modified to be base command function. New SIM_Command() created to call it
189 * with wrapper. Created to manage retries on Internals errors of the driver.
190 */
191
192 SYS_UWORD16 SIM_Command_Base(SIM_PORT *p, SYS_UWORD16 n, SYS_UWORD8 *dP,
193 SYS_UWORD16 *lP)
194 {
195 SYS_UWORD16 res;
196 SYS_UWORD8 err;
197 SYS_UWORD8 ins;
198 SYS_UWORD8 nack;
199 SYS_UWORD8 nack1;
200 SYS_UWORD16 offset;
201
202 if (SIM_sleep_status == SIM_SLEEP_DESACT)
203 { //freeze the timer
204 status_os_sim = NU_Control_Timer (&SIM_timer, NU_DISABLE_TIMER);
205 }
206 else if (SIM_sleep_status == SIM_SLEEP_ACT)
207 { //get out sleep mode
208 status_os_sim = NU_Control_Timer (&SIM_timer, NU_DISABLE_TIMER);
209 SIM_SleepMode_Out (p); //get up SIM card of sleep mode
210 // before executing the command
211 }
212
213 SIM_WriteBuffer(p, 0, 5);
214
215 //adaptative driver
216
217 if (n > 0) //need to send data to the card, TX mode
218 {
219 offset = 0;
220 // protocol T=0 returns a acknowledge char which is
221 // ins or (ins+1) : transmit the rest of the command in one time
222 // ~ins or ~(ins+1) : transmit the rest of the command char by char
223 ins = p->xbuf[1] & p->hw_mask;
224 nack = (~p->xbuf[1]) & p->hw_mask;;
225
226 p->moderx = 6; //mode of wait for ACK char
227
228 NEXT_CHAR_PROC:
229
230 if (err = SIM_Waitforchars(p, p->etu9600))
231 {
232 if ((SIM_sleep_status == SIM_SLEEP_DESACT) ||
233 (SIM_sleep_status == SIM_SLEEP_ACT))
234 { //enable to count 2.5s before entering in sleep mode
235 status_os_sim = NU_Reset_Timer (&SIM_timer, SIM_SleepMode_In,
236 SIM_SLEEP_WAITING_TIME,
237 0, NU_ENABLE_TIMER);
238 }
239 return (err);
240 }
241
242 if (p->moderx == 5) //return SW1/SW2
243 {
244 res = SIM_Result(p, dP, lP, 0);
245
246 if ((SIM_sleep_status == SIM_SLEEP_DESACT) ||
247 (SIM_sleep_status == SIM_SLEEP_ACT))
248 { //enable to count 2.5s before entering in sleep mode
249 status_os_sim = NU_Reset_Timer (&SIM_timer, SIM_SleepMode_In,
250 SIM_SLEEP_WAITING_TIME,
251 0, NU_ENABLE_TIMER);
252 }
253
254 return(res);
255 }
256 else if ((p->ack & p->hw_mask) == ins)
257 {
258 // Write the rest of the command if needed
259 // if more than 5 characters, the ack character will disappear
260
261 SIM_WriteBuffer(p, 5 + offset, n - offset);
262 }
263 // special transmission mode if ACK = ~INS or ~(INS + 1).
264 // refer to ISO/CEI 7816-3 [8.2.2]
265 // need to send char by char
266 else if ((p->ack & p->hw_mask) == nack)
267 {
268 SIM_WriteBuffer(p, 5 + offset, 1);
269 offset++;
270 goto NEXT_CHAR_PROC;
271 }
272
273 p->moderx = 5;
274 if (err = SIM_Waitforchars (p, p->etu9600)) //wait SW1 / SW2
275 {
276 if ((SIM_sleep_status == SIM_SLEEP_DESACT) ||
277 (SIM_sleep_status == SIM_SLEEP_ACT))
278 { //enable to count 2.5s before entering in sleep mode
279 status_os_sim = NU_Reset_Timer (&SIM_timer, SIM_SleepMode_In,
280 SIM_SLEEP_WAITING_TIME,
281 0, NU_ENABLE_TIMER);
282 }
283 return (err);
284 }
285
286 }
287 else //receive mode
288 {
289 if (err = SIM_WaitReception(p)) //wait for next procedure character
290 {
291 if ((SIM_sleep_status == SIM_SLEEP_DESACT) ||
292 (SIM_sleep_status == SIM_SLEEP_ACT))
293 { //enable to count 2.5s before entering in sleep mode
294 status_os_sim = NU_Reset_Timer (&SIM_timer, SIM_SleepMode_In,
295 SIM_SLEEP_WAITING_TIME,
296 0, NU_ENABLE_TIMER);
297 }
298 return (err);
299 }
300 }
301
302 res = SIM_Result(p, dP, lP, 0);
303
304 if ((SIM_sleep_status == SIM_SLEEP_DESACT) ||
305 (SIM_sleep_status == SIM_SLEEP_ACT))
306 { //enable to count 2.5s before entering in sleep mode
307 status_os_sim = NU_Reset_Timer (&SIM_timer, SIM_SleepMode_In,
308 SIM_SLEEP_WAITING_TIME,
309 0, NU_ENABLE_TIMER);
310 }
311
312 return(res);
313 }
314
315
316 /* Main function to manage the retry mechanism */
317 SYS_UWORD16 SIM_Command(SIM_PORT *p, SYS_UWORD16 n, SYS_UWORD8 *dP,
318 SYS_UWORD16 *lP)
319 {
320 int res;
321
322 #ifdef SIM_DEBUG_TRACE
323 memset(SIM_dbg_null, 0x00, SIM_DBG_NULL);
324 SIM_dbg_tdma_diff = 0;
325 #endif
326
327 // Issue initial SIM_Command() call
328 res = SIM_Command_Base(p, n, dP, lP);
329 /* Change from to 10 to 15 for specific SIM card (Racal) */
330
331 #ifdef SIM_RETRY
332 // While there is an error then retry NUM_SIM_RETRIES times
333 while ((res & 0xFF00) == 0) { // Reissue command
334 p->errorSIM = 0;
335 if(++SimRetries > NUM_SIM_RETRIES) { // return special retry failure
336 res = SIM_ERR_RETRY_FAILURE;
337 break;
338 }
339 res = SIM_Command_Base(p, n, dP, lP);
340 }
341
342 #ifdef SIM_DEBUG_TRACE
343 SIM_dbg_null[SIM_DBG_NULL-1] = SimRetries;
344 #endif
345
346 SimRetries = 0;
347 #endif
348
349 return(res);
350 }
351
352 /*
353 * SIM_ByteReverse
354 *
355 * Reverse a byte, both up/down (1 <> 0) and left/right (0001 <> 1000)
356 *
357 */
358 SYS_UWORD8 SIM_ByteReverse(SYS_UWORD8 b)
359 {
360 SYS_UWORD8 bh, bl;
361 int i;
362 const SYS_UWORD8 Reverse[] = {0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE,
363 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF };
364
365 // Up/Down
366 b = ~ b;
367
368 // left / right (by nibble)
369 bh = (b >> 4) & 0xF;
370 bl = b & 0xF;
371
372 b = (Reverse[bl]) << 4 | Reverse[bh];
373 return(b);
374 }
375
376 /*
377 * SIM_TxParityErrors
378 *
379 * return number of transmit parity errors occured since the last reset
380 * of the SIM card
381 *
382 */
383 SYS_UWORD16 SIM_TxParityErrors(void)
384 {
385 SIM_PORT *p;
386
387 p= &(Sim[0]);
388
389 return(p->txParityErr);
390 }
391
392
393 /*
394 * SIM_Reset
395 *
396 * Reset SIM card
397 * Call-back SIM insert if successful
398 * or SIM remove otherwise
399 *
400 * Returns 0 for success, or
401 * SIM_ERR_NOCARD : no card
402 * SIM_ERR_NATR : no answer to reset
403 * SIM_ERR_NOINT : no
404 * SIM_ERR_READ : unknown data return by the card
405 * SIM_ERR_CARDREJECT : card not accepted
406 *
407 * 29/01/02, JYT, adding of low voltage managment for IOTA device
408 * 06/10/03, JYT, Split of Reset to handle Restart
409 */
410 SYS_UWORD16 SIM_Reset(SIM_CARD *cP)
411 {
412 return(SIM_Reset_Restart_Internal(cP, 1));
413 }
414
415 /*
416 * SIM_Restart
417 *
418 * Restart SIM card
419 *
420 * Returns 0 for success, or
421 * SIM_ERR_NOCARD : no card
422 * SIM_ERR_NATR : no answer to reset
423 * SIM_ERR_NOINT : no
424 * SIM_ERR_READ : unknown data return by the card
425 * SIM_ERR_CARDREJECT : card not accepted
426 *
427 * 06/10/03, JYT, Split of Reset to handle Restart
428 */
429 SYS_UWORD16 SIM_Restart(SIM_CARD *cP)
430 {
431 return(SIM_Reset_Restart_Internal(cP, 0));
432 }
433
434
435 /*
436 * SIM_Reset_Restart_Internal
437 *
438 * Reset SIM card
439 * Call-back SIM insert if successful
440 * or SIM remove otherwise
441 *
442 * Returns 0 for success, or
443 * SIM_ERR_NOCARD : no card
444 * SIM_ERR_NATR : no answer to reset
445 * SIM_ERR_NOINT : no
446 * SIM_ERR_READ : unknown data return by the card
447 * SIM_ERR_CARDREJECT : card not accepted
448 *
449 * 29/01/02, JYT, adding of low voltage managment for IOTA device
450 * 06/10/03, JYT, Split of Reset to handle Restart, ResetFlag added.
451 */
452 SYS_UWORD16 SIM_Reset_Restart_Internal(SIM_CARD *cP, SYS_UWORD8 ResetFlag)
453 {
454 SIM_PORT *p;
455 unsigned int ATR_Attempt;
456 SYS_UWORD8 BackValue;
457 SYS_UWORD8 Result_ATR;
458
459 #ifdef SIM_DEBUG_TRACE
460 memset(SIM_dbg_null, 0x00, SIM_DBG_NULL);
461 SIM_dbg_cmd_cmpt = 0;
462 memset(SIM_dbg_cmd, 0x00, SIM_DBG_CMD);
463 #endif
464
465 // Initialize pointers
466 p = &(Sim[0]);
467
468 // begin of JYT modifications
469 if ( (BackValue = SIM_StartVolt(ResetFlag)) != SIM_OK)
470 return((SYS_UWORD16)BackValue);
471 // end of JYT modifications
472
473 p->etu9600 = 867; // old = 239, increase of 363%
474 p->etu400 = 20;
475 p->hw_mask = MASK_INS;
476
477 ATR_Attempt = 1;
478
479 COLD_RESET:
480
481 p->SWcount = 0;
482 p->Freq_Algo = 0;
483 p->PTS_Try = 0; //use to calculate how many PTS try were already done
484
485 // Initialize pointers
486 p->xIn = p->xOut = p->xbuf;
487 p->rx_index = 0;
488 p->errorSIM = 0;
489 p->moderx = 0;
490 p->null_received = 0;
491
492 BackValue = SIM_ManualStart(p);
493 if (BackValue != 0)
494 return ((SYS_UWORD16)BackValue);
495
496
497 p->c->conf1 = p->conf1 &= ~SIM_CONF1_BYPASS; //switch to automatic mode
498
499 //#else //SW_WRK_AROUND_H_S == 0 // Automatic procedure -> fails with test 27.11.2.1
500 //
501 // // Mask all interrupts
502 // p->c->maskit = SIM_MASK_NATR | SIM_MASK_WT | SIM_MASK_OV |
503 // SIM_MASK_TX | SIM_MASK_RX | SIM_MASK_CD;
504 //
505 //
506 // IQ_Unmask (IQ_SIM); // Unmask interrupt controller
507 //
508 //
509 // p->c->cmd = (p->c->cmd & MASK_CMD) | SIM_CMD_STOP;
510 // ind_os_sleep(1);
511 //
512 // p->c->cmd = (p->c->cmd & MASK_CMD) | SIM_CMD_SWRST; // Set START bit and wait a while
513 // ind_os_sleep(1);
514 // // Unmask all sources of interrupts except WT, OV, and NATR
515 // p->c->maskit = SIM_MASK_OV | SIM_MASK_WT | SIM_MASK_NATR;
516 //
517 // // Set Configuration bits
518 // p->c->conf1 = p->conf1 = SIM_CONF1_SRSTLEV | SIM_CONF1_SCLKEN;
519 // p->c->conf2 = 0x0940;
520 //
521 // //enable VCC
522 // #if(ANALOG == 1)
523 // SPIABB_wa_VRPC (SPIRead_ABB_Register (PAGE1,VRPCCTRL1) | MODE_ENA_VCC);
524 // #elif(ANALOG == 2)
525 // SPIABB_wa_VRPC (SPIRead_ABB_Register (PAGE1,VRPCSIM) | MODE_ENA_VCC);
526 // #endif
527 // p->c->cmd = (p->c->cmd & MASK_CMD) | SIM_CMD_START;
528 //
529 //#endif
530
531 /*-----------------------------------------------------------*/
532
533 while (p->PTS_Try != 5)
534 {
535 while (ATR_Attempt != 0)
536 {
537 // Treat ATR response
538 BackValue = SIM_ATRdynamictreatement (p, cP);
539
540 if (BackValue == SIM_ERR_NOCARD)
541 {
542 SIM_PowerOff ();
543 return (SIM_ERR_NOCARD);
544 }
545 // ATR received but wrong characters value
546 // Comply with Test 27.11.2.4.5 and Test 27.11.1.3
547 else if (BackValue == SIM_ERR_CARDREJECT)
548 {
549 if (ATR_Attempt >= 3)
550 {
551 SIM_PowerOff ();
552 return ((SYS_UWORD16)BackValue);
553 }
554
555 ATR_Attempt++;
556 SIM_WARMReset(p); // assert a reset during at least 400 ETU
557 }
558 else if (BackValue != 0) //SIM_ERR_WAIT
559 {
560 if (ATR_Attempt == 3)
561 { // switch to 5V (ANALOG1) or 3V (ANALOG2) if card send wrong ATR 3 consecutive times
562 // Apply 3 consecutive resets at 5V (ANALOG1) or 3V (ANALOG2)
563 // fix prb for old chinese card not GSM compliant
564
565 if ((BackValue = SIM_SwitchVolt(ResetFlag)) != SIM_OK)
566 {
567 // SIM cannot be supplied at 3V (ANALOG2), because of an Hardware failure
568 SIM_PowerOff ();
569 return((SYS_UWORD16)BackValue);
570 }
571
572 ATR_Attempt++;
573 goto COLD_RESET;
574 }
575 if (ATR_Attempt >= 6)
576 {
577 SIM_PowerOff ();
578 return ((SYS_UWORD16)BackValue);
579 }
580
581 ATR_Attempt++;
582 SIM_WARMReset(p); // assert a reset during at least 400 ETU
583 }
584
585 else
586 {
587 ATR_Attempt = 0;
588 }
589 }
590 /*-----------------------------------------------------------*/
591 // PTS procedure
592 BackValue = SIM_PTSprocedure(cP,p); //assert PTS if needed
593 // need upgrade with FIFO use to avoid CPU overloading
594
595 if (BackValue)
596 {
597 if (BackValue == SIM_ERR_CARDREJECT)
598 {
599 SIM_PowerOff (); //must be done by protocol stack
600 return (SIM_ERR_CARDREJECT);
601 }
602 if (p->PTS_Try <= 4) //else error treatement
603 {
604 SIM_WARMReset(p); // assert a reset during at least 400 ETU
605 }
606 }
607 else
608 {
609 p->PTS_Try = 5;
610 }
611 }
612 /*-----------------------------------------------------------*/
613
614 //interpret SIM coding concerning SIM supply voltage
615
616 if (SIM_GetFileCharacteristics(p))
617 {
618 #if ((SIM_TYPE == SIM_TYPE_3V) || (SIM_TYPE == SIM_TYPE_1_8V))
619 SIM_PowerOff(); // Needed for tests 27.17.1.5.1 and 27.17.1.5.5
620 #endif
621 return (SIM_ERR_READ);
622 }
623
624 // JYT, certainly unused because of previous test
625 if(p->errorSIM)
626 {
627 return(p->errorSIM);
628 }
629
630 if ((p->FileC & SIM_MASK_INFO_VOLT) == SIM_5V)
631 {
632 #if ((SIM_TYPE == SIM_TYPE_3V ) || (SIM_TYPE == SIM_TYPE_1_8_3V) || (SIM_TYPE == SIM_TYPE_1_8V))
633 SIM_PowerOff (); // required by ETSI if 5V only card is detected and 3V only ME chosen
634 return (SIM_ERR_CARDREJECT); // Test 27.17.1.5.2
635 #elif (SIM_TYPE == SIM_TYPE_3_5V)
636 if (CurrentVolt == SIM_3V) //if 5V only SIM present -> the ME may switch to 5V operation
637 {
638 if ((BackValue = SIM_SwitchVolt(ResetFlag)) != SIM_OK) // switch to 5V
639 {
640 SIM_PowerOff ();
641 return ((SYS_UWORD16)BackValue);
642 }
643 ATR_Attempt = 1;
644 goto COLD_RESET; // Test 27.17.1.5.3
645 }
646 #endif
647 }
648 else
649 {
650 if ((p->FileC & SIM_MASK_INFO_VOLT) == SIM_3V)
651 {
652 #if (SIM_TYPE == SIM_TYPE_1_8V)
653 SIM_PowerOff (); // required by ETSI if 3V only card is detected and 1.8V only ME chosen
654 return (SIM_ERR_CARDREJECT); // Test 27.17.1.5.2
655 #elif (SIM_TYPE == SIM_TYPE_1_8_3V)
656 if (CurrentVolt == SIM_1_8V) //if 3V only SIM present -> the ME may switch to 3V operation
657 {
658 if ((BackValue = SIM_SwitchVolt(ResetFlag)) != SIM_OK) // switch to 3V
659 {
660 SIM_PowerOff ();
661 return ((SYS_UWORD16)BackValue);
662 }
663 ATR_Attempt = 1;
664 goto COLD_RESET; // Test 27.17.1.5.3
665 }
666 #endif
667 }
668 else
669 {
670 if ((p->FileC & SIM_MASK_INFO_VOLT) == SIM_1_8V)
671 {
672 #if (SIM_TYPE == SIM_TYPE_5V)
673 SIM_PowerOff (); // required by ETSI if 5V only card is detected and 3V only ME chosen
674 return (SIM_ERR_CARDREJECT); // Test 27.17.1.5.2
675 #endif
676 }
677 else
678 {
679 // future class of sim card voltage !!!!!! never use it
680 SIM_PowerOff (); // Rec. 11.18
681 return (SIM_ERR_CARDREJECT);
682 }
683 }
684 }
685
686 SIM_Interpret_FileCharacteristics(p); //find which frequency (13/4 or 13/8 Mhz)
687
688 if(p->errorSIM)
689 {
690 return(p->errorSIM);
691 }
692
693 status_os_sim = NU_Control_Timer (&SIM_timer, NU_ENABLE_TIMER);
694 //enable starting of the os timer for sleep mode
695 if (ResetFlag) {
696 if (p->InsertFunc != NULL)
697 (p->InsertFunc)(cP);
698 }
699
700 return(0);
701 }
702
703 /* SIM manual start
704 *
705 * purpose : manage manual start of the SIM interface
706 * input : pointer on sim structure SIM_PORT
707 * output : none
708 */
709
710 SYS_UWORD16 SIM_ManualStart (SIM_PORT *p)
711 {
712 volatile int i;
713
714 //!!
715 p->c->conf1 = p->conf1 = 0x8004; //set conf1 to automatic mode SIO low
716 //enable sim interface clock module
717 p->c->cmd = SIM_CMD_CLKEN;
718
719 //#if (SW_WRK_AROUND_H_S == 1)
720
721 // Mask all interrupts
722 p->c->maskit = SIM_MASK_NATR | SIM_MASK_WT | SIM_MASK_OV |
723 SIM_MASK_TX | SIM_MASK_RX | SIM_MASK_CD;
724
725 // Unmask interrupt controller
726 IQ_Unmask (IQ_SIM);
727
728 p->c->cmd = (p->c->cmd & MASK_CMD) | SIM_CMD_STOP;
729 ind_os_sleep (4); //wait 5 TDMA due to SVCC falling down duration
730
731 p->c->cmd = (p->c->cmd & MASK_CMD) | SIM_CMD_SWRST;
732 ind_os_sleep (1); //wait 5 TDMA due to SVCC falling down duration
733
734
735 p->c->conf2 = 0x0940;
736
737 i = p->c->it;
738 // Unmask all sources of interrupts except WT and OV and NATR
739 p->c->maskit = SIM_MASK_WT | SIM_MASK_OV | SIM_MASK_NATR;
740
741
742 //enter in manual mode to start the ATR sequence
743 p->c->conf1 = p->conf1 |= SIM_CONF1_BYPASS;
744 ind_os_sleep(1);
745
746 p->c->conf1 = p->conf1 |= SIM_CONF1_SVCCLEV;
747 ind_os_sleep(1);
748
749 #if(ANALOG == 1)
750 //set OMEGA to 3V mode
751 //enable VCC
752 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCCTRL1) | MODE_ENA_SIMLDOEN);
753 ind_os_sleep(1);
754 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCCTRL1) | MODE_ENA_SIMEN);
755 ind_os_sleep(1);
756 #elif(ANALOG == 2)
757 //set IOTA to 3V mode
758 //enable VCC
759 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCSIM) | MODE_ENA_SIMEN);
760 ind_os_sleep(1);
761 #elif(ANALOG == 3)
762 //set SYREN to 3V mode
763 //enable VCC
764 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCSIMR) | MODE_ENA_SIMEN);
765 ind_os_sleep(1);
766 #endif
767
768 p->c->conf1 = p->conf1 &= ~SIM_CONF1_SIOLOW;
769
770 ind_os_sleep(1);
771
772 p->c->conf1 = p->conf1 |= SIM_CONF1_SCLKEN;
773
774 p->c->conf1 = p->conf1 &= ~SIM_CONF1_TXRX; //set to receive mode
775
776
777 if(p->errorSIM) //check for card detection
778 {
779 return(p->errorSIM);
780 }
781
782 i = 0;
783 while ((p->rx_index == 0) && (i < 3)) //wait 40000*Tsclk
784 {
785 ind_os_sleep (1);
786 i++;
787 }
788
789 if ((p->rx_index == 0) && (i >= 3)) //external reset card ATR treatement
790 {
791 i = 0;
792
793 p->c->conf1 = p->conf1 |= SIM_CONF1_SRSTLEV;//set reset level to high level
794
795 while ((p->rx_index == 0) && (i < 3)) //wait 40000*Tsclk
796 {
797 ind_os_sleep (1);
798 i++;
799 }
800 }
801
802 return (0);
803 }
804
805 /* SIM manual stop
806 *
807 * purpose : manage manual start of the SIM interface
808 * input : pointer on sim structure SIM_PORT
809 * output : none
810 */
811
812 void SIM_ManualStop (SIM_PORT *p)
813 {
814 // to write
815 }
816
817 /* Power off SIM == SIM_CMD_STOP
818 * input : none
819 * output : none
820 */
821
822 void SIM_PowerOff(void)
823 {
824 SIM_PORT *p;
825 volatile SYS_UWORD16 cmd;
826
827 // Initialize pointers
828 p = &(Sim[0]);
829
830 // Reset and wait a while
831 cmd = p->c->cmd;
832 p->c->cmd = (cmd & MASK_CMD) | SIM_CMD_STOP;
833
834 ind_os_sleep(5); //wait for falling of SIM signals (RESET/CLK/IO)
835
836 #if(ANALOG == 1)
837 //disable VCC : disable level shifter then SVDD
838 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCCTRL1) & MODE_DIS_SIMEN);
839 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCCTRL1) & MODE_DIS_SIMLDOEN);
840 #elif(ANALOG == 2)
841 //disable VCC : disable level shifter then SVDD
842 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCSIM) & MODE_DIS_SIMEN);
843 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCSIM) & MODE_DIS_SIMLDOEN);
844 #elif(ANALOG == 3)
845 //disable VCC : disable level shifter then SVDD
846 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCSIMR) & MODE_DIS_SIMEN);
847 ABB_wa_VRPC (ABB_Read_Register_on_page(PAGE1,VRPCSIMR) & MODE_DIS_SIMLDOEN);
848 #endif
849
850 ind_os_sleep(10); //wait for falling of VCC commanf by ABB
851
852 p->c->cmd = 0x0000; //disable clock of sim module
853
854 if ((SIM_sleep_status == SIM_SLEEP_DESACT) || (SIM_sleep_status == SIM_SLEEP_ACT))
855 { //SIM sleep timer is not more needed
856 status_os_sim = NU_Delete_Timer (&SIM_timer);
857 }
858 }
859
860
861 /*
862 * SIM_Init
863 *
864 * Function for backward compatibility only
865 *
866 */
867
868 void SIM_Init(void (Insert(SIM_CARD *cP)), void (Remove(void)))
869 {
870 // Call SIM Registration function.
871 (void) SIM_Register (Insert, Remove);
872 }
873
874 /*
875 * SIM_Initialize
876 *
877 * Initialize data structures.
878 *
879 */
880
881 void SIM_Initialize(void)
882 {
883 int n;
884 SIM_PORT *p;
885 volatile SYS_UWORD32 dum;
886
887 // Initialize registers
888 p = &(Sim[0]);
889 p->c = (SIM_CONTROLLER *) SIM_CMD;
890
891 p->errorSIM = 0;
892 dum = (volatile SYS_UWORD32) SIM_Dummy; // to force linking SIM32
893
894 status_os_sim = NU_Create_Timer (&SIM_timer, "SIM_sleep_timer", &SIM_SleepMode_In,
895 0, SIM_SLEEP_WAITING_TIME, 0, NU_DISABLE_TIMER);
896 //timer start only with NU_Control_Timer function
897 //waiting time set to 2.3s
898 SIM_sleep_status = SIM_SLEEP_NONE;
899
900 #ifdef SIM_RETRY
901 SimRetries = 0;
902 #endif
903 }
904
905 /*
906 * SIM_Register
907 *
908 * SIM Registration function: Initialize callback functions
909 *
910 * Insert(void) : pointer to the function called when a card is inserted
911 * Remove(void) : pointer to the function called when the card is removed
912 *
913 */
914
915 SYS_UWORD16 SIM_Register(void (Insert(SIM_CARD *cP)), void (Remove(void)))
916 {
917 SIM_PORT *p;
918
919 // Initialize pointers
920 p = &(Sim[0]);
921
922 p->InsertFunc = Insert;
923 p->RemoveFunc = Remove;
924
925 return (SIM_OK);
926 }
927
928
929 /*
930 * High level routines : mapped to GSM 11.11 function calls
931 *
932 * Uses a Nucleus semaphore to ensure no simultaneous access to SIM and buffer
933 *
934 * Each routine does :
935 * write command
936 * sleep long enough for the expected transmission and reception
937 * return rest code
938 *
939 * SYS_UWORD8 *result : pointer to the string return by the SIM card
940 * SYS_UWORD8 *rcvSize : size of the string return by the SIM card
941 *
942 * other parameters : parameters needed by the SIM card to
943 * execute the function.
944 *
945 */
946 //unsigned char SIM_flag = 0;
947
948
949 /*
950 * SIM_Select
951 *
952 * Select a DF or a EF
953 */
954 SYS_UWORD16 SIM_Select(SYS_UWORD16 id, SYS_UWORD8 *dat, SYS_UWORD16 *rcvSize)
955 {
956 SIM_PORT *p;
957 int res;
958
959 p = &(Sim[0]);
960
961 p->xbuf[0] = GSM_CLASS;
962 p->xbuf[1] = SIM_SELECT;
963 p->xbuf[2] = 0;
964 p->xbuf[3] = 0;
965 p->xbuf[4] = 2;
966 p->xbuf[5] = id >> 8; // high byte
967 p->xbuf[6] = id & 0xFF; // low byte
968
969 res = SIM_Command(p, 2, dat, rcvSize);
970 /* Change from to 10 to 15 for specific SIM card (Racal) */
971
972 // if (id == 0x6F07)
973 // SIM_flag = 1;
974
975 #ifdef SIM_DEBUG_TRACE
976 SIM_dbg_write_trace((SYS_UWORD8 *)"AACMD", 5);
977 SIM_dbg_write_trace(p->xbuf, 7);
978 SIM_dbg_write_trace((SYS_UWORD8 *)"AAANS", 5);
979 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
980 SIM_dbg_tmp[1] = (SYS_WORD8)res;
981 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
982 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
983 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
984 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
985 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
986 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
987 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
988 #endif
989
990 return(res);
991 }
992
993
994 /*
995 * SIM_Status
996 *
997 * Returns data received from card and number of bytes received
998 */
999 SYS_UWORD16 SIM_Status(SYS_UWORD8 *dat, SYS_UWORD16 *rcvSize)
1000 {
1001 SIM_PORT *p;
1002
1003 short len = 0x16; // length specified in GSM 11.11
1004 int res;
1005
1006 p = &(Sim[0]);
1007
1008 p->xbuf[0] = GSM_CLASS;
1009 p->xbuf[1] = SIM_STATUS;
1010 p->xbuf[2] = 0;
1011 p->xbuf[3] = 0;
1012 p->xbuf[4] = len;
1013
1014 res = SIM_Command(p, 0, dat, rcvSize);
1015
1016 #ifdef SIM_DEBUG_TRACE
1017 SIM_dbg_write_trace((SYS_UWORD8 *)"ABCMD", 5);
1018 SIM_dbg_write_trace(p->xbuf, 5);
1019 SIM_dbg_write_trace((SYS_UWORD8 *)"ABANS", 5);
1020 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1021 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1022 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1023 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1024 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1025 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1026 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1027 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1028 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1029 #endif
1030
1031 return(res);
1032 }
1033
1034 /*
1035 * SIM_Status_Extended
1036 *
1037 * Returns data received from card and number of bytes received
1038 * Add extra parameter len : number of returned byte
1039 */
1040 SYS_UWORD16 SIM_Status_Extended(SYS_UWORD8 *dat, SYS_UWORD16 len,
1041 SYS_UWORD16 *rcvSize)
1042 {
1043 SIM_PORT *p;
1044 int res;
1045 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
1046
1047 p = &(Sim[0]);
1048
1049 p->xbuf[0] = GSM_CLASS;
1050 p->xbuf[1] = SIM_STATUS;
1051 p->xbuf[2] = 0;
1052 p->xbuf[3] = 0;
1053 p->xbuf[4] = (SYS_UWORD8)llen;
1054
1055 res = SIM_Command(p, 0, dat, rcvSize);
1056
1057 #ifdef SIM_DEBUG_TRACE
1058 SIM_dbg_write_trace((SYS_UWORD8 *)"ACCMD", 5);
1059 SIM_dbg_write_trace(p->xbuf, 5);
1060 SIM_dbg_write_trace((SYS_UWORD8 *)"ACANS", 5);
1061 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1062 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1063 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1064 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1065 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1066 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1067 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1068 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1069 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1070 #endif
1071
1072 return(res);
1073 }
1074
1075
1076 /*
1077 * SIM_ReadBinary
1078 *
1079 * Read data from the current EF
1080 */
1081 SYS_UWORD16 SIM_ReadBinary(SYS_UWORD8 *dat, SYS_UWORD16 offset,
1082 SYS_UWORD16 len, SYS_UWORD16 *rcvSize)
1083 {
1084 SIM_PORT *p;
1085 int res;
1086 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
1087
1088 p = &(Sim[0]);
1089
1090 p->xbuf[0] = GSM_CLASS;
1091 p->xbuf[1] = SIM_READ_BINARY;
1092 p->xbuf[2] = offset >> 8;
1093 p->xbuf[3] = offset & 0xFF;
1094 p->xbuf[4] = (SYS_UWORD8)llen;
1095
1096 res = SIM_Command(p, 0, dat, rcvSize);
1097
1098 // if (SIM_flag) {
1099 // SIM_flag = 0;
1100 // dat[0] = 0x08;
1101 // }
1102
1103 #ifdef SIM_DEBUG_TRACE
1104 SIM_dbg_write_trace((SYS_UWORD8 *)"ADCMD", 5);
1105 SIM_dbg_write_trace(p->xbuf, 5);
1106 SIM_dbg_write_trace((SYS_UWORD8 *)"ADANS", 5);
1107 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize>>8);
1108 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
1109 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1110 SIM_dbg_write_trace(dat, *rcvSize);
1111 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1112 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1113 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1114 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1115 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1116 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1117 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1118 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1119 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1120 #endif
1121
1122 return(res);
1123 }
1124
1125 /*
1126 * SIM_VerifyChv
1127 *
1128 * Verify the specified CHV (chvType)
1129 */
1130 SYS_UWORD16 SIM_VerifyCHV(SYS_UWORD8 *result, SYS_UWORD8 *dat,
1131 SYS_UWORD8 chvType, SYS_UWORD16 *rcvSize)
1132 {
1133 SIM_PORT *p;
1134 SYS_UWORD8 len;
1135 int i;
1136 int res;
1137
1138 p = &(Sim[0]);
1139 len = 8;
1140
1141 p->xbuf[0] = GSM_CLASS;
1142 p->xbuf[1] = SIM_VERIFY_CHV;
1143 p->xbuf[2] = 0;
1144 p->xbuf[3] = chvType;
1145 p->xbuf[4] = len;
1146 for (i=0;i<8;i++)
1147 {
1148 p->xbuf[5+i] = *(dat+i);
1149 }
1150 res = SIM_Command(p, 8, result, rcvSize);
1151
1152 #ifdef SIM_DEBUG_TRACE
1153 SIM_dbg_write_trace((SYS_UWORD8 *)"AECMD", 5);
1154 SIM_dbg_write_trace(p->xbuf, len+5);
1155 SIM_dbg_write_trace((SYS_UWORD8 *)"AEANS", 5);
1156 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
1157 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
1158 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1159 SIM_dbg_write_trace(result, *rcvSize);
1160 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1161 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1162 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1163 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1164 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1165 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1166 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1167 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1168 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1169 #endif
1170
1171 return(res);
1172 }
1173
1174
1175 /*
1176 * SIM_RunGSMAlgo
1177 *
1178 * Authentication procedure
1179 */
1180 SYS_UWORD16 SIM_RunGSMAlgo(SYS_UWORD8 *result, SYS_UWORD8 *dat,
1181 SYS_UWORD16 *rcvSize)
1182 {
1183 SIM_PORT *p;
1184 int len;
1185 int i;
1186 int res;
1187
1188 p = &(Sim[0]);
1189
1190 if(p->Freq_Algo) //13/4 Mhz mandatory ??
1191 p->c->conf1 = p->conf1 &= ~SIM_CONF1_SCLKDIV;
1192
1193 len = 16;
1194
1195 p->xbuf[0] = GSM_CLASS;
1196 p->xbuf[1] = SIM_RUN_GSM_ALGO;
1197 p->xbuf[2] = 0;
1198 p->xbuf[3] = 0;
1199 p->xbuf[4] = len;
1200
1201 for (i=0;i<len;i++)
1202 {
1203 p->xbuf[5+i] = *(dat+i);
1204 }
1205 res = SIM_Command(p, len, result, rcvSize);
1206
1207 #ifdef SIM_DEBUG_TRACE
1208 SIM_dbg_write_trace((SYS_UWORD8 *)"AFCMD", 5);
1209 SIM_dbg_write_trace(p->xbuf, len+5);
1210 SIM_dbg_write_trace((SYS_UWORD8 *)"AFANS", 5);
1211 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
1212 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
1213 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1214 SIM_dbg_write_trace(result, *rcvSize);
1215 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1216 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1217 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1218 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1219 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1220 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1221 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1222 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1223 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1224 #endif
1225
1226 if(p->Freq_Algo)
1227 p->c->conf1 = p->conf1 |= SIM_CONF1_SCLKDIV;
1228
1229 return(res);
1230 }
1231
1232
1233 /*
1234 * SIM_GetResponse
1235 *
1236 * Get data from the card
1237 *
1238 * SYS_UWORD8 len : length of the data to get
1239 */
1240 SYS_UWORD16 SIM_GetResponse(SYS_UWORD8 *dat, SYS_UWORD16 len,
1241 SYS_UWORD16 *rcvSize)
1242 {
1243 SIM_PORT *p;
1244 int res;
1245 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
1246
1247 p = &(Sim[0]);
1248
1249 p->xbuf[0] = GSM_CLASS;
1250 p->xbuf[1] = SIM_GET_RESPONSE;
1251 p->xbuf[2] = 0;
1252 p->xbuf[3] = 0;
1253 p->xbuf[4] = (SYS_UWORD8)llen;
1254
1255 res = SIM_Command(p, 0, dat, rcvSize);
1256
1257 #ifdef SIM_DEBUG_TRACE
1258 SIM_dbg_write_trace((SYS_UWORD8 *)"AGCMD", 5);
1259 SIM_dbg_write_trace(p->xbuf, 5);
1260 SIM_dbg_write_trace((SYS_UWORD8 *)"AGANS", 5);
1261 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
1262 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
1263 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1264 SIM_dbg_write_trace(dat, *rcvSize);
1265 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1266 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1267 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1268 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1269 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1270 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1271 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1272 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1273 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1274 #endif
1275
1276 return(res);
1277 }
1278
1279
1280 /*
1281 * SIM_ChangeCHV
1282 *
1283 * Change the specified CHV (chvType)
1284 */
1285 SYS_UWORD16 SIM_ChangeCHV(SYS_UWORD8 *result,SYS_UWORD8 *oldChv,
1286 SYS_UWORD8 *newChv, SYS_UWORD8 chvType,
1287 SYS_UWORD16 *lP)
1288 {
1289 SIM_PORT *p;
1290 SYS_UWORD16 len;
1291 int i;
1292 SYS_UWORD16 res;
1293
1294 p = &(Sim[0]);
1295 len = 16;
1296
1297 p->xbuf[0] = GSM_CLASS;
1298 p->xbuf[1] = SIM_CHANGE_CHV;
1299 p->xbuf[2] = 0;
1300 p->xbuf[3] = chvType;
1301 p->xbuf[4] = (SYS_UWORD8)len;
1302
1303 // Copy bytes to buffer
1304 for (i=0;i<8;i++)
1305 {
1306 p->xbuf[5+i] = *(oldChv+i);
1307 }
1308 for (i=0;i<8;i++)
1309 {
1310 p->xbuf[13+i] = *(newChv+i);
1311 }
1312 res = SIM_Command(p, len, result, lP);
1313
1314 #ifdef SIM_DEBUG_TRACE
1315 SIM_dbg_write_trace((SYS_UWORD8 *)"AHCMD", 5);
1316 SIM_dbg_write_trace(p->xbuf, len+5);
1317 SIM_dbg_write_trace((SYS_UWORD8 *)"AHANS", 5);
1318 SIM_dbg_tmp[0] = (SYS_UWORD8)(*lP >> 8);
1319 SIM_dbg_tmp[1] = (SYS_UWORD8)(*lP);
1320 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1321 SIM_dbg_write_trace(result, *lP);
1322 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1323 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1324 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1325 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1326 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1327 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1328 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1329 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1330 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1331 #endif
1332
1333 return(res);
1334 }
1335
1336
1337 /*
1338 * SIM_DisableCHV
1339 *
1340 * Disable CHV 1
1341 */
1342 SYS_UWORD16 SIM_DisableCHV(SYS_UWORD8 *result, SYS_UWORD8 *dat, SYS_UWORD16 *lP)
1343 {
1344 SIM_PORT *p;
1345 int len;
1346 int i;
1347 int res;
1348
1349 p = &(Sim[0]);
1350
1351 len = 8;
1352 p->xbuf[0] = GSM_CLASS;
1353 p->xbuf[1] = SIM_DISABLE_CHV;
1354 p->xbuf[2] = 0;
1355 p->xbuf[3] = 1;
1356 p->xbuf[4] = 8;
1357 for (i=0;i<8;i++)
1358 {
1359 p->xbuf[5+i] = *(dat+i);
1360 }
1361 res = SIM_Command(p, len, result, lP);
1362
1363 #ifdef SIM_DEBUG_TRACE
1364 SIM_dbg_write_trace((SYS_UWORD8 *)"AICMD", 5);
1365 SIM_dbg_write_trace(p->xbuf, 8+5);
1366 SIM_dbg_write_trace((SYS_UWORD8 *)"AIANS", 5);
1367 SIM_dbg_tmp[0] = (SYS_UWORD8)(*lP >> 8);
1368 SIM_dbg_tmp[1] = (SYS_UWORD8)(*lP);
1369 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1370 SIM_dbg_write_trace(result, *lP);
1371 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1372 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1373 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1374 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1375 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1376 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1377 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1378 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1379 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1380 #endif
1381
1382 return(res);
1383 }
1384
1385
1386 /*
1387 * SIM_EnableCHV
1388 *
1389 * Enable CHV 1
1390 */
1391 SYS_UWORD16 SIM_EnableCHV(SYS_UWORD8 *result, SYS_UWORD8 *dat, SYS_UWORD16 *lP)
1392 {
1393 SIM_PORT *p;
1394 int len;
1395 int i;
1396 int res;
1397
1398 p = &(Sim[0]);
1399
1400 len = 8;
1401
1402 p->xbuf[0] = GSM_CLASS;
1403 p->xbuf[1] = SIM_ENABLE_CHV;
1404 p->xbuf[2] = 0;
1405 p->xbuf[3] = 1;
1406 p->xbuf[4] = (SYS_UWORD8)len;
1407
1408 for (i=0;i<len;i++)
1409 {
1410 p->xbuf[5+i] = *(dat+i);
1411 }
1412
1413 res = SIM_Command(p, len, result, lP);
1414
1415 #ifdef SIM_DEBUG_TRACE
1416 SIM_dbg_write_trace((SYS_UWORD8 *)"AJCMD", 5);
1417 SIM_dbg_write_trace(p->xbuf, len+5);
1418 SIM_dbg_write_trace((SYS_UWORD8 *)"AJANS", 5);
1419 SIM_dbg_tmp[0] = (SYS_UWORD8)(*lP >> 8);
1420 SIM_dbg_tmp[1] = (SYS_UWORD8)(*lP);
1421 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1422 SIM_dbg_write_trace(result, *lP);
1423 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1424 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1425 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1426 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1427 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1428 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1429 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1430 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1431 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1432 #endif
1433
1434 return(res);
1435 }
1436
1437 /*
1438 * SIM_UnblockCHV
1439 *
1440 * Unblock the specified CHV (chvType) and store a new CHV
1441 */
1442 SYS_UWORD16 SIM_UnblockCHV(SYS_UWORD8 *result, SYS_UWORD8 *unblockChv,
1443 SYS_UWORD8 *newChv, SYS_UWORD8 chvType,
1444 SYS_UWORD16 *lP)
1445 {
1446 SIM_PORT *p;
1447 int len;
1448 int i;
1449 int res;
1450
1451 p = &(Sim[0]);
1452 len = 16;
1453
1454 p->xbuf[0] = GSM_CLASS;
1455 p->xbuf[1] = SIM_UNBLOCK_CHV;
1456 p->xbuf[2] = 0;
1457 p->xbuf[3] = chvType;
1458 p->xbuf[4] = (SYS_UWORD8)len;
1459 for (i=0;i<8;i++)
1460 {
1461 p->xbuf[5+i] = *(unblockChv+i);
1462 }
1463 for (i=0;i<8;i++)
1464 {
1465 p->xbuf[13+i] = *(newChv+i);
1466 }
1467
1468 res = SIM_Command(p, len, result, lP);
1469
1470 #ifdef SIM_DEBUG_TRACE
1471 SIM_dbg_write_trace((SYS_UWORD8 *)"AKCMD", 5);
1472 SIM_dbg_write_trace(p->xbuf, len+5);
1473 SIM_dbg_write_trace((SYS_UWORD8 *)"AKANS", 5);
1474 SIM_dbg_tmp[0] = (SYS_UWORD8)(*lP >> 8);
1475 SIM_dbg_tmp[1] = (SYS_UWORD8)(*lP);
1476 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1477 SIM_dbg_write_trace(result, *lP);
1478 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1479 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1480 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1481 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1482 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1483 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1484 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1485 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1486 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1487 #endif
1488
1489 return(res);
1490 }
1491
1492 /*
1493 * SIM_Invalidate
1494 *
1495 * Invalidate the current EF
1496 */
1497 SYS_UWORD16 SIM_Invalidate(SYS_UWORD8 *rP, SYS_UWORD16 *lP)
1498 {
1499 SIM_PORT *p;
1500 int i;
1501 int res;
1502
1503 p = &(Sim[0]);
1504
1505 p->xbuf[0] = GSM_CLASS;
1506 p->xbuf[1] = SIM_INVALIDATE;
1507 p->xbuf[2] = 0;
1508 p->xbuf[3] = 0;
1509 p->xbuf[4] = 0;
1510
1511 res = SIM_Command(p, 0, rP, lP);
1512
1513 #ifdef SIM_DEBUG_TRACE
1514 SIM_dbg_write_trace((SYS_UWORD8 *)"ALCMD", 5);
1515 SIM_dbg_write_trace(p->xbuf, 5);
1516 SIM_dbg_write_trace((SYS_UWORD8 *)"ALANS", 5);
1517 SIM_dbg_tmp[0] = (SYS_UWORD8)(*lP >> 8);
1518 SIM_dbg_tmp[1] = (SYS_UWORD8)(*lP);
1519 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1520 SIM_dbg_write_trace(rP, *lP);
1521 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1522 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1523 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1524 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1525 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1526 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1527 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1528 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1529 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1530 #endif
1531
1532 return(res);
1533 }
1534
1535 /*
1536 * SIM_Rehabilitate
1537 *
1538 * Rehabilitate the current EF
1539 */
1540 SYS_UWORD16 SIM_Rehabilitate(SYS_UWORD8 *rP, SYS_UWORD16 *lP)
1541 {
1542 SIM_PORT *p;
1543 int len;
1544 int res;
1545
1546 p = &(Sim[0]);
1547
1548 p->xbuf[0] = GSM_CLASS;
1549 p->xbuf[1] = SIM_REHABILITATE;
1550 p->xbuf[2] = 0;
1551 p->xbuf[3] = 0;
1552 p->xbuf[4] = 0;
1553
1554 res = SIM_Command(p, 0, rP, lP);
1555
1556 #ifdef SIM_DEBUG_TRACE
1557 SIM_dbg_write_trace((SYS_UWORD8 *)"AMCMD", 5);
1558 SIM_dbg_write_trace(p->xbuf, 5);
1559 SIM_dbg_write_trace((SYS_UWORD8 *)"AMANS", 5);
1560 SIM_dbg_tmp[0] = (SYS_UWORD8)(*lP >> 8);
1561 SIM_dbg_tmp[1] = (SYS_UWORD8)(*lP);
1562 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1563 SIM_dbg_write_trace(rP, *lP);
1564 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1565 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1566 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1567 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1568 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1569 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1570 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1571 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1572 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1573 #endif
1574
1575 return(res);
1576 }
1577
1578
1579 /*
1580 * SIM_UpdateBinary
1581 *
1582 * Store data in the current transparent EF
1583 */
1584 SYS_UWORD16 SIM_UpdateBinary(SYS_UWORD8 *result, SYS_UWORD8 *dat,
1585 SYS_UWORD16 offset, SYS_UWORD16 len,
1586 SYS_UWORD16 *rcvSize)
1587 {
1588 SIM_PORT *p;
1589 int i;
1590 int res;
1591 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
1592
1593 p = &(Sim[0]);
1594
1595 p->xbuf[0] = GSM_CLASS;
1596 p->xbuf[1] = SIM_UPDATE_BINARY;
1597 p->xbuf[2] = offset >> 8;
1598 p->xbuf[3] = offset & 0xFF;
1599 p->xbuf[4] = (SYS_UWORD8)llen;
1600
1601 for (i=0;i<llen;i++)
1602 {
1603 p->xbuf[5+i] = *(dat+i);
1604 }
1605 res = SIM_Command(p, llen, result, rcvSize);
1606
1607 #ifdef SIM_DEBUG_TRACE
1608 SIM_dbg_write_trace((SYS_UWORD8 *)"ANCMD", 5);
1609 SIM_dbg_write_trace(p->xbuf, llen+5);
1610 SIM_dbg_write_trace((SYS_UWORD8 *)"ANANS", 5);
1611 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
1612 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
1613 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1614 SIM_dbg_write_trace(result, *rcvSize);
1615 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1616 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1617 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1618 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1619 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1620 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1621 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1622 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1623 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1624 #endif
1625
1626 return(res);
1627 }
1628
1629
1630 /*
1631 * SIM_ReadRecord
1632 *
1633 * Read a record (recNum) from the current linear fixed or cyclic EF
1634 */
1635 SYS_UWORD16 SIM_ReadRecord(SYS_UWORD8 *dat, SYS_UWORD8 mode, SYS_UWORD8 recNum,
1636 SYS_UWORD16 len, SYS_UWORD16 *rcvSize)
1637 {
1638 SIM_PORT *p;
1639 int res;
1640 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
1641
1642 p = &(Sim[0]);
1643
1644 p->xbuf[0] = GSM_CLASS;
1645 p->xbuf[1] = SIM_READ_RECORD;
1646 p->xbuf[2] = recNum;
1647 p->xbuf[3] = mode;
1648 p->xbuf[4] = (SYS_UWORD8)llen;
1649
1650 res = SIM_Command(p, 0, dat, rcvSize);
1651
1652 #ifdef SIM_DEBUG_TRACE
1653 SIM_dbg_write_trace((SYS_UWORD8 *)"AOCMD", 5);
1654 SIM_dbg_write_trace(p->xbuf, llen+5);
1655 SIM_dbg_write_trace((SYS_UWORD8 *)"AOANS", 5);
1656 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
1657 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
1658 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1659 SIM_dbg_write_trace(dat, *rcvSize);
1660 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1661 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1662 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1663 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1664 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1665 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1666 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1667 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1668 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1669 #endif
1670
1671 return(res);
1672 }
1673
1674 #ifdef SIM_APDU_TEST
1675 SYS_UWORD8 snd[270];
1676 SYS_UWORD8 rec[270];
1677 SYS_UWORD8 logchan;
1678 SYS_UWORD16 recl;
1679 unsigned short resopen, resclose, rescmd;
1680 #endif
1681
1682 #ifdef SIM_SAT_REFRESH_TEST
1683 SIM_CARD ptr;
1684 SYS_UWORD16 lrcvSize;
1685 SYS_UWORD8 ldat[20];
1686 #endif
1687
1688 /*
1689 * SIM_UpdateRecord
1690 *
1691 * Store a record (recNum) in the current linear fixed or cyclic EF
1692 */
1693 SYS_UWORD16 SIM_UpdateRecord(SYS_UWORD8 *result, SYS_UWORD8 *dat,
1694 SYS_UWORD8 mode, SYS_UWORD8 recNum,
1695 SYS_UWORD16 len, SYS_UWORD16 *rcvSize)
1696 {
1697 SIM_PORT *p;
1698 int i;
1699 int res;
1700 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
1701
1702 #ifdef SIM_SAT_REFRESH_TEST
1703 // do 1000 times the following sequence
1704 for (i=0;i<1000;i++) {
1705 SIM_PowerOff();
1706 SIM_Restart(&ptr);
1707 SIM_Select((SYS_UWORD16)0x7f10, ldat, &lrcvSize);
1708 SIM_Select((SYS_UWORD16)0x6f3a, ldat, &lrcvSize);
1709 }
1710 #endif
1711 #ifdef SIM_APDU_TEST
1712 // send OPEN LOGICAL CHANNEL
1713 snd[0] = 0x00;
1714 snd[1] = 0x70;
1715 snd[2] = 0x00;
1716 snd[3] = 0x00;
1717 snd[4] = 0x01;
1718 resopen = SIM_XchTPDU(&snd[0], 5, &rec[0], 1, &recl);
1719 if (resopen == 0x9000) {
1720 logchan = rec[0];
1721
1722 // Select AID PKCS
1723 snd[0] = logchan;
1724 snd[1] = 0xA4;
1725 snd[2] = 0x04;
1726 snd[3] = 0x00;
1727 snd[4] = 0x0C;
1728 snd[5] = 0xA0;
1729 snd[6] = 0x00;
1730 snd[7] = 0x00;
1731 snd[8] = 0x00;
1732 snd[9] = 0x63;
1733 snd[10] = 0x50;
1734 snd[11] = 0x4B;
1735 snd[12] = 0x43;
1736 snd[13] = 0x53;
1737 snd[14] = 0x2D;
1738 snd[15] = 0x31;
1739 snd[16] = 0x35;
1740 rescmd = SIM_XchTPDU(&snd[0], 17, &rec[0], 0, &recl);
1741
1742 // Select file EF odf
1743 snd[0] = 0x80 | logchan;
1744 snd[1] = 0xA4;
1745 snd[2] = 0x00;
1746 snd[3] = 0x00;
1747 snd[4] = 0x02;
1748 snd[5] = 0x50;
1749 snd[6] = 0x31;
1750 rescmd = SIM_XchTPDU(&snd[0], 7, &rec[0], 0, &recl);
1751
1752 // get response EF odf
1753 snd[0] = logchan;
1754 snd[1] = 0xC0;
1755 snd[2] = 0x00;
1756 snd[3] = 0x00;
1757 snd[4] = rescmd;
1758 rescmd = SIM_XchTPDU(&snd[0], 5, &rec[0], snd[4], &recl);
1759
1760 // read binary EF odf
1761 snd[0] = 0x80 | logchan;
1762 snd[1] = 0xB0;
1763 snd[2] = 0x00;
1764 snd[3] = 0x00;
1765 snd[4] = rec[3]-16;
1766 rescmd = SIM_XchTPDU(&snd[0], 5, &rec[0], snd[4], &recl);
1767
1768 // Select file EF cdf
1769 snd[0] = 0x80 | logchan;
1770 snd[1] = 0xA4;
1771 snd[2] = 0x00;
1772 snd[3] = 0x00;
1773 snd[4] = 0x02;
1774 snd[5] = 0x51;
1775 snd[6] = 0x03;
1776 rescmd = SIM_XchTPDU(&snd[0], 7, &rec[0], 0, &recl);
1777
1778 // get response EF odf
1779 snd[0] = logchan;
1780 snd[1] = 0xC0;
1781 snd[2] = 0x00;
1782 snd[3] = 0x00;
1783 snd[4] = rescmd;
1784 rescmd = SIM_XchTPDU(&snd[0], 5, &rec[0], snd[4], &recl);
1785
1786 // read binary EF cdf
1787 snd[0] = 0x80 | logchan;
1788 snd[1] = 0xB0;
1789 snd[2] = 0x00;
1790 snd[3] = 0x00;
1791 snd[4] = 0xff;
1792 rescmd = SIM_XchTPDU(&snd[0], 5, &rec[0], snd[4], &recl);
1793
1794 // read binary EF cdf
1795 snd[0] = 0x80 | logchan;
1796 snd[1] = 0xB0;
1797 snd[2] = 0x00;
1798 snd[3] = 0x00;
1799 snd[4] = 0x00;
1800 rescmd = SIM_XchTPDU(&snd[0], 5, &rec[0], 256, &recl);
1801 }
1802 #endif
1803
1804 p = &(Sim[0]);
1805
1806 p->xbuf[0] = GSM_CLASS;
1807 p->xbuf[1] = SIM_UPDATE_RECORD;
1808 p->xbuf[2] = recNum;
1809 p->xbuf[3] = mode;
1810 p->xbuf[4] = (SYS_UWORD8)llen;
1811
1812 for (i=0;i<llen;i++)
1813 {
1814 p->xbuf[5+i] = *(dat+i);
1815 }
1816
1817 res = SIM_Command(p, llen, result, rcvSize);
1818
1819 #ifdef SIM_DEBUG_TRACE
1820 SIM_dbg_write_trace((SYS_UWORD8 *)"APCMD", 5);
1821 SIM_dbg_write_trace(p->xbuf, llen+5);
1822 SIM_dbg_write_trace((SYS_UWORD8 *)"APANS", 5);
1823 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
1824 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
1825 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1826 SIM_dbg_write_trace(result, *rcvSize);
1827 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1828 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1829 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1830 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1831 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1832 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1833 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1834 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1835 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1836 #endif
1837
1838 #ifdef SIM_APDU_TEST
1839 // send CLOSE LOGICAL CHANNEL
1840 snd[0] = 0x00;
1841 snd[1] = 0x70;
1842 snd[2] = 0x80;
1843 snd[3] = logchan;
1844 snd[4] = 0x00;
1845 resclose = SIM_XchTPDU(&snd[0], 5, &rec[0], 0, &recl);
1846 #endif
1847
1848 return(res);
1849 }
1850
1851 /*
1852 * SIM_Seek
1853 *
1854 * Search data in a linear fixed or cyclic EF.
1855 * return the first record number in which it found the data.
1856 */
1857 SYS_UWORD16 SIM_Seek(SYS_UWORD8 *result, SYS_UWORD8 *dat, SYS_UWORD8 mode,
1858 SYS_UWORD16 len, SYS_UWORD16 *rcvSize)
1859 {
1860 SIM_PORT *p;
1861 int i;
1862 int res;
1863 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
1864
1865 p = &(Sim[0]);
1866
1867 p->xbuf[0] = GSM_CLASS;
1868 p->xbuf[1] = SIM_SEEK;
1869 p->xbuf[2] = 0;
1870 p->xbuf[3] = mode;
1871 p->xbuf[4] = (SYS_UWORD8)llen;
1872
1873 for (i=0;i<llen;i++)
1874 {
1875 p->xbuf[5+i] = *(dat+i);
1876 }
1877
1878 res = SIM_Command(p, llen, result, rcvSize);
1879
1880 #ifdef SIM_DEBUG_TRACE
1881 SIM_dbg_write_trace((SYS_UWORD8 *)"AQCMD", 5);
1882 SIM_dbg_write_trace(p->xbuf, llen+5);
1883 SIM_dbg_write_trace((SYS_UWORD8 *)"AQANS", 5);
1884 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
1885 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
1886 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1887 SIM_dbg_write_trace(result, *rcvSize);
1888 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1889 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1890 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1891 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1892 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1893 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1894 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1895 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1896 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1897 #endif
1898
1899 return(res);
1900 }
1901
1902 /*
1903 * SIM_Increase
1904 *
1905 * Add value to a record of a cyclic EF
1906 */
1907 SYS_UWORD16 SIM_Increase(SYS_UWORD8 *result, SYS_UWORD8 *dat,
1908 SYS_UWORD16 *rcvSize)
1909 {
1910 SIM_PORT *p;
1911 int len;
1912 int i;
1913 int res;
1914
1915 p = &(Sim[0]);
1916
1917 len = 3;
1918
1919 p->xbuf[0] = GSM_CLASS;
1920 p->xbuf[1] = SIM_INCREASE;
1921 p->xbuf[2] = 0;
1922 p->xbuf[3] = 0;
1923 p->xbuf[4] = 3;
1924
1925 for (i=0;i<3;i++)
1926 {
1927 p->xbuf[5+i] = *(dat+i);
1928 }
1929
1930 res = SIM_Command(p, len, result, rcvSize);
1931
1932 #ifdef SIM_DEBUG_TRACE
1933 SIM_dbg_write_trace((SYS_UWORD8 *)"ARCMD", 5);
1934 SIM_dbg_write_trace(p->xbuf, 3+5);
1935 SIM_dbg_write_trace((SYS_UWORD8 *)"ARANS", 5);
1936 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
1937 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
1938 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1939 SIM_dbg_write_trace(result, *rcvSize);
1940 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1941 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1942 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1943 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1944 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1945 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1946 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1947 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1948 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1949 #endif
1950
1951 return(res);
1952 }
1953
1954 /*
1955 * SIM_TerminalProfile
1956 *
1957 * Used by ME to send its toolkit capabilities to SIM
1958 */
1959 SYS_UWORD16 SIM_TerminalProfile(SYS_UWORD8 *result, SYS_UWORD8 *dat,
1960 SYS_UWORD16 len, SYS_UWORD16 *rcvSize)
1961 {
1962 SIM_PORT *p;
1963 int i;
1964 int res;
1965 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
1966
1967 p = &(Sim[0]);
1968
1969 p->xbuf[0] = GSM_CLASS;
1970 p->xbuf[1] = SIM_TERMINAL_PROFILE;
1971 p->xbuf[2] = 0;
1972 p->xbuf[3] = 0;
1973 p->xbuf[4] = (SYS_UWORD8)llen;
1974
1975 for (i=0;i<llen;i++)
1976 {
1977 p->xbuf[5+i] = *(dat+i);
1978 }
1979
1980 res = SIM_Command(p, llen, result, rcvSize);
1981
1982 #ifdef SIM_DEBUG_TRACE
1983 SIM_dbg_write_trace((SYS_UWORD8 *)"ASCMD", 5);
1984 SIM_dbg_write_trace(p->xbuf, llen+5);
1985 SIM_dbg_write_trace((SYS_UWORD8 *)"ASANS", 5);
1986 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
1987 SIM_dbg_tmp[1] = (SYS_WORD8)res;
1988 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1989 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
1990 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
1991 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
1992 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
1993 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
1994 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
1995 #endif
1996
1997 return(res);
1998 }
1999
2000
2001 /*
2002 * SIM_FETCH
2003 *
2004 * Used by ME to inquiry of what SIM toolkit need to do
2005 */
2006 SYS_UWORD16 SIM_Fetch(SYS_UWORD8 *result, SYS_UWORD16 len, SYS_UWORD16 *rcvSize)
2007 {
2008 SIM_PORT *p;
2009 int i;
2010 int res;
2011 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
2012
2013 p = &(Sim[0]);
2014
2015 p->xbuf[0] = GSM_CLASS;
2016 p->xbuf[1] = SIM_FETCH;
2017 p->xbuf[2] = 0;
2018 p->xbuf[3] = 0;
2019 p->xbuf[4] = (SYS_UWORD8)llen;
2020
2021 res = SIM_Command(p, 0, result, rcvSize);
2022
2023 #ifdef SIM_DEBUG_TRACE
2024 SIM_dbg_write_trace((SYS_UWORD8 *)"ATCMD", 5);
2025 SIM_dbg_write_trace(p->xbuf, 5);
2026 SIM_dbg_write_trace((SYS_UWORD8 *)"ATANS", 5);
2027 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
2028 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
2029 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2030 SIM_dbg_write_trace(result, *rcvSize);
2031 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
2032 SIM_dbg_tmp[1] = (SYS_WORD8)res;
2033 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2034 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
2035 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
2036 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
2037 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
2038 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
2039 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2040 #endif
2041
2042 return(res);
2043 }
2044
2045
2046 /*
2047 * SIM_TerminalResponse *
2048 * Used for ME to respond at a SIM toolkit command
2049 */
2050 SYS_UWORD16 SIM_TerminalResponse(SYS_UWORD8 *result, SYS_UWORD8 *dat,
2051 SYS_UWORD16 len, SYS_UWORD16 *rcvSize)
2052 {
2053 SIM_PORT *p;
2054 int i;
2055 int res;
2056 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
2057
2058 p = &(Sim[0]);
2059
2060 p->xbuf[0] = GSM_CLASS;
2061 p->xbuf[1] = SIM_TERMINAL_RESPONSE;
2062 p->xbuf[2] = 0;
2063 p->xbuf[3] = 0;
2064 p->xbuf[4] = (SYS_UWORD8)llen;
2065
2066 for (i=0;i<llen;i++)
2067 {
2068 p->xbuf[5+i] = *(dat+i);
2069 }
2070
2071 res = SIM_Command(p, llen, result, rcvSize);
2072
2073 #ifdef SIM_DEBUG_TRACE
2074 SIM_dbg_write_trace((SYS_UWORD8 *)"AUCMD", 5);
2075 SIM_dbg_write_trace(p->xbuf, llen+5);
2076 SIM_dbg_write_trace((SYS_UWORD8 *)"AUANS", 5);
2077 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
2078 SIM_dbg_tmp[1] = (SYS_WORD8)res;
2079 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2080 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
2081 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
2082 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
2083 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
2084 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
2085 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2086 #endif
2087
2088 return(res);
2089 }
2090
2091
2092 /*
2093 * SIM_Envelope
2094 *
2095 * Used by Network to tansfert data download to the SIM
2096 * in a transparent way for user
2097 */
2098 SYS_UWORD16 SIM_Envelope(SYS_UWORD8 *result, SYS_UWORD8 *dat, SYS_UWORD16 len,
2099 SYS_UWORD16 *rcvSize)
2100 {
2101 SIM_PORT *p;
2102 int i;
2103 int res;
2104 SYS_UWORD16 llen = len & SIM_UWORD16_MASK;
2105
2106 p = &(Sim[0]);
2107
2108 p->xbuf[0] = GSM_CLASS;
2109 p->xbuf[1] = SIM_ENVELOPE;
2110 p->xbuf[2] = 0;
2111 p->xbuf[3] = 0;
2112 p->xbuf[4] = (SYS_UWORD8)llen;
2113
2114 for (i=0;i<llen;i++)
2115 {
2116 p->xbuf[5+i] = *(dat+i);
2117 }
2118
2119 res = SIM_Command(p, llen, result, rcvSize);
2120
2121 #ifdef SIM_DEBUG_TRACE
2122 SIM_dbg_write_trace((SYS_UWORD8 *)"AVCMD", 5);
2123 SIM_dbg_write_trace(p->xbuf, llen+5);
2124 SIM_dbg_write_trace((SYS_UWORD8 *)"AVANS", 5);
2125 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
2126 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
2127 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2128 SIM_dbg_write_trace(result, *rcvSize);
2129 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
2130 SIM_dbg_tmp[1] = (SYS_WORD8)res;
2131 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2132 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
2133 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
2134 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
2135 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
2136 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
2137 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2138 #endif
2139
2140 return(res);
2141 }
2142
2143 /*
2144 * SIM_XchTPDU *
2145 * Used for ME to send generic command to WIM Card
2146 */
2147 SYS_UWORD16 SIM_XchTPDU(SYS_UWORD8 *dat, SYS_UWORD16 trxLen, SYS_UWORD8 *result,
2148 SYS_UWORD16 rcvLen, SYS_UWORD16 *rcvSize)
2149 {
2150 SIM_PORT *p;
2151 int i;
2152 int res;
2153
2154 p = &(Sim[0]);
2155
2156 p->xbuf[0] = dat[0];
2157 p->xbuf[1] = dat[1];
2158 p->xbuf[2] = dat[2];
2159 p->xbuf[3] = dat[3];
2160 p->xbuf[4] = dat[4];
2161
2162 for (i=5;i<trxLen;i++)
2163 {
2164 p->xbuf[i] = dat[i];
2165 }
2166
2167 // enable the WIM behavior of the sim driver
2168 p->apdu_ans_length = rcvLen;
2169
2170 res = SIM_Command(p, (trxLen - 5), result, rcvSize);
2171
2172 // disable the WIM behavior of the sim driver
2173 p->apdu_ans_length = 0;
2174
2175 #ifdef SIM_DEBUG_TRACE
2176 SIM_dbg_write_trace((SYS_UWORD8 *)"AWCMD", 5);
2177 SIM_dbg_write_trace(p->xbuf, trxLen);
2178 SIM_dbg_write_trace((SYS_UWORD8 *)"AWANS", 5);
2179 SIM_dbg_tmp[0] = (SYS_UWORD8)(*rcvSize >> 8);
2180 SIM_dbg_tmp[1] = (SYS_UWORD8)(*rcvSize);
2181 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2182 SIM_dbg_write_trace(result, *rcvSize);
2183 SIM_dbg_tmp[0] = (SYS_WORD8)(res>>8);
2184 SIM_dbg_tmp[1] = (SYS_WORD8)res;
2185 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2186 SIM_dbg_write_trace(SIM_dbg_null, SIM_DBG_NULL);
2187 if (SIM_dbg_tdma_diff > SIM_dbg_max_interchardelay)
2188 SIM_dbg_max_interchardelay = SIM_dbg_tdma_diff;
2189 SIM_dbg_tmp[0] = (SYS_UWORD8)(SIM_dbg_tdma_diff >> 8);
2190 SIM_dbg_tmp[1] = (SYS_UWORD8)(SIM_dbg_tdma_diff);
2191 SIM_dbg_write_trace(SIM_dbg_tmp, 2);
2192 #endif
2193
2194 return(res);
2195 }
2196
2197 /*
2198 * Use to detect end of characters reception
2199 * input: p pointer on sim structure
2200 * n number of extra character to send
2201 *
2202 * output: return 0 if sucess
2203 * SIM_ERR_x in case of error
2204 *
2205 */
2206
2207 SYS_UWORD16 SIM_WaitReception(SIM_PORT *p)
2208 {
2209 SYS_UWORD16 returncode;
2210
2211 //analyse the nature of the command to execute
2212
2213 if (
2214 (p->xbuf[1] == 0x12) ||
2215 (p->xbuf[1] == 0xB2) ||
2216 (p->xbuf[1] == 0xB0) ||
2217 (p->xbuf[1] == 0xF2) ||
2218 (p->xbuf[1] == 0xC0) ||
2219 (p->apdu_ans_length != 0)
2220 )
2221 //FETCH, READ_RECORD, READ_BINARY, STATUS, GET_RESPONSE commands == receive command
2222 {
2223 if (p->xbuf[4] == 0) //if P3 == 0 when sending receive command
2224 {
2225 p->expected_data = 256;
2226 }
2227 else
2228 {
2229 p->expected_data = p->xbuf[4];
2230 }
2231
2232 p->moderx = 1; //wait for procedure byte
2233
2234 if (returncode = SIM_Waitforchars (p, p->etu9600))
2235 {
2236 return returncode;
2237 }
2238 }
2239 else //direct command : INVALIDATE, REHABILITATE, SLEEP
2240 {
2241 p->moderx = 5; //mode reception of SW1/SW2
2242
2243 if (returncode = SIM_Waitforchars (p, p->etu9600))
2244 {
2245 return returncode;
2246 }
2247 }
2248 return (0);
2249 }
2250
2251 /*
2252 * Use to read file characteristics information
2253 * input: p pointer on sim structure
2254 *
2255 * output: return 0 if sucess
2256 * 1 in case of error
2257 *
2258 */
2259
2260 SYS_UWORD8 SIM_GetFileCharacteristics(SIM_PORT *p)
2261 {
2262 int res;
2263 SYS_UWORD8 ubuf[40];
2264 SYS_UWORD16 sz;
2265
2266 res = SIM_Select(DF_GSM, ubuf, &sz);
2267 if ((res & 0xFF00) != 0x9F00)
2268 {
2269 res = SIM_Select(DF_DCS1800, ubuf, &sz);
2270 if ((res & 0xFF00) != 0x9F00)
2271 {
2272 return (1);
2273 }
2274 }
2275 res = SIM_GetResponse( ubuf, res & 0x00FF , &sz);
2276 if (res != 0x9000)
2277 return (1);
2278
2279 p->FileC = ubuf[13];
2280 return (0);
2281 }
2282
2283 /*
2284 * Use to determine value of b2 in file caracteristics contained in response
2285 * of SELECT Master File command
2286 * return 0 if no preferred speed during authentication
2287 * 1 if 13/4Mhz mandatory
2288 *
2289 *
2290 */
2291
2292 void SIM_Interpret_FileCharacteristics(SIM_PORT *p)
2293 {
2294 //interpret b2 bit for operating authentication speed
2295 if((p->conf1 & 0x0020) && (p->FileC & 0x02))
2296 {
2297 p->Freq_Algo = 1;
2298 }
2299
2300 //interpret Clock stop behavior
2301 // modified by J. Yp-Tcha to integrate all the behaviors required by ETSI.
2302 // 18/11/2002 : TI Chip always allowed low level,
2303 // high level is hard dependant
2304
2305 if ((p->FileC & SIM_CLK_STOP_MASK) == SIM_CLK_STOP_NOT_ALLWD) {
2306 /* Sim Clock Stop Not Allowed */
2307 SIM_sleep_status = SIM_SLEEP_NOT_ALLOWED;
2308 /* There is not need to modifiy p->conf1 */
2309 status_os_sim = NU_Delete_Timer (&SIM_timer);
2310 }
2311 else {
2312 if ((p->FileC & SIM_CLK_STOP_MASK) == SIM_CLK_STOP_ALLWD) {
2313 /* Sim Clock Stop Allowed, no prefered level */
2314 /* Default value for TI Chip shall always be Low Level */
2315 SIM_sleep_status = SIM_SLEEP_DESACT;
2316 p->c->conf1 = p->conf1 &= ~SIM_CONF1_SCLKLEV;
2317 }
2318 else {
2319 /* Clock Stop is allowed, the level shall be checked */
2320 if ((p->FileC & SIM_CLK_STOP_HIGH) == SIM_CLK_STOP_HIGH) {
2321 /* high level is mandatory */
2322 /* OMEGA/NAUSICA can not handle sim stop clock at high level */
2323 #ifndef ANALOG1
2324 SIM_sleep_status = SIM_SLEEP_DESACT;
2325 p->c->conf1 = p->conf1 |= SIM_CONF1_SCLKLEV;
2326 #else
2327 /*
2328 * Sim Clock Stop Not Allowed because the interface
2329 * do not support this level
2330 */
2331 SIM_sleep_status = SIM_SLEEP_NOT_ALLOWED;
2332 /* There is not need to modifiy p->conf1 */
2333 status_os_sim = NU_Delete_Timer (&SIM_timer);
2334 #endif
2335 }
2336 else {
2337 /* by default, Low Level is allowed */
2338 SIM_sleep_status = SIM_SLEEP_DESACT;
2339 p->c->conf1 = p->conf1 &= ~SIM_CONF1_SCLKLEV;
2340 }
2341 }
2342 }
2343 if (SIM_sleep_status == SIM_SLEEP_NONE)
2344 {
2345 status_os_sim = NU_Delete_Timer (&SIM_timer);
2346 }
2347 }
2348
2349 /*
2350 * Use to evaluate need of sending PTS procedure regarding
2351 * the ATR. If default not used, PTS initiates F and D adequate values
2352 * for speed enhancement.
2353 * In case of 2 wrong PTS answer (speed enhanced), a third PTS with default value
2354 * is used. If the third PTS attempt failed, the ME reset the SIM and use default
2355 * value.
2356 * Return Value : SIM_ERR_READ, SIM_ERRCARDREJECT, SIM_ERR_WAIT
2357 *
2358 */
2359
2360
2361 SYS_UWORD16 SIM_PTSprocedure(SIM_CARD *cP, SIM_PORT *p)
2362 {
2363
2364 SYS_UWORD8 TA1;
2365 SYS_UWORD8 n;
2366 SYS_UWORD8 err;
2367
2368 p->xbuf[0] = 0xFF; //character of PTS proc to send
2369 p->xbuf[1] = 0;
2370 p->xbuf[2] = 0xFF;
2371 p->xbuf[3] = 0x7B;
2372
2373 //TA1,TB1,TC1,TD1 present in ATR ?
2374
2375 n = 3;
2376
2377 p->PTS_Try++;
2378
2379 if (p->PTS_Try > 4)
2380 {
2381 return (SIM_ERR_CARDREJECT);
2382 } // at the fourth attempt,
2383 // PTS procedure is unusefull. Use default value.
2384 //TA1 present? Test 27.11.2.6
2385 else if ( p->PTS_Try == 4)
2386 {
2387 SIM_Calcetu (p);
2388 return (0);
2389 }
2390
2391 if(cP->AtrData[1] & 0x10)
2392 {
2393 TA1 = cP->AtrData[2];
2394 }
2395 else //if TA1 not present, return
2396 {
2397 SIM_Calcetu (p);
2398 return (0);
2399 }
2400
2401 #if 0 // Dmitriy: removed by TI patch
2402 if (TA1 >= 0x94) //speed enhancement
2403 {
2404 // JYT 26/9/2003 to check correct behavior of the SIM Driver vs the PPS.
2405 //#ifdef NOTTOLOADBECAUSENOTTESTED
2406 // SIM_Calcetu (p);
2407 // return (0); //temporary disabling of speed enhancement feature
2408
2409 if (p->PTS_Try <= 2)
2410 {
2411 n = 4;
2412 p->xbuf[1] = 0x10;
2413 p->xbuf[2] = 0x94; // if speed enhancement, then at least (and at most) F = 512 and D = 8 is supported
2414 }
2415 //#endif
2416 }
2417 #endif
2418
2419 if ((TA1 == 0x11) || (TA1 == 0x01))
2420 {
2421 SIM_Calcetu (p);
2422 return (0);
2423 } //if TA1 != 0x11 and 0x94, need to send PTS request
2424 //transmit request of speed enhancement : PTS
2425 SIM_WriteBuffer(p, 0, n);
2426
2427 p->moderx = 0; //mode of normal reception
2428 p->expected_data = n;
2429
2430 if (err = SIM_Waitforchars (p, p->etu9600))
2431 {
2432 return (err);
2433 }
2434 //should received same chars as PTS request
2435 if ((p->rbuf[0] != p->xbuf[0]) || (p->rbuf[1] != p->xbuf[1]) ||
2436 (p->rbuf[2] != p->xbuf[2]))
2437 {
2438 return(SIM_ERR_READ);
2439 }
2440
2441 if (n == 4)
2442 {
2443 if (p->rbuf[3] != p->xbuf[3])
2444 {
2445 return(SIM_ERR_READ);
2446 }
2447
2448 //correct response from SIM : with speed enhanced
2449 p->c->conf1 = p->conf1 |= SIM_CONF1_ETU; //set F=512 D=8
2450 }
2451
2452 SIM_Calcetu (p);
2453 return (0);
2454 }
2455
2456 /*
2457 * procedure of WARM reset consists on asserting
2458 * reset signal at 0 during at least 400 ETU
2459 * input p pointer of type SIM_PORT
2460 */
2461
2462 void SIM_WARMReset (SIM_PORT *p)
2463 {
2464 p->c->conf1 = p->conf1 &= ~SIM_CONF1_SRSTLEV;
2465 ind_os_sleep (p->etu400); /// wait 400 ETU
2466 p->c->conf1 = p->conf1 |= SIM_CONF1_SRSTLEV;
2467 p->rx_index = 0;
2468 }
2469
2470
2471 /*
2472 * procedure use to get out sleepMode
2473 * input p pointer of type SIM_PORT
2474 */
2475
2476 void SIM_SleepMode_In (SYS_UWORD32 param)
2477 {
2478 if (SIM_sleep_status == SIM_SLEEP_DESACT)
2479 {
2480 (&(Sim[0]))->c->conf1 &= ~SIM_CONF1_SCLKEN; //disabled the clock for the SIM card
2481 SIM_sleep_status = SIM_SLEEP_ACT;
2482 }
2483 status_os_sim = NU_Control_Timer (&SIM_timer, NU_DISABLE_TIMER);
2484 }
2485
2486 /*
2487 * procedure use to get out sleepMode
2488 * input p pointer of type SIM_PORT
2489 */
2490
2491 void SIM_SleepMode_Out (SIM_PORT *p)
2492 {
2493 if (SIM_sleep_status == SIM_SLEEP_ACT)
2494 {
2495 p->c->conf1 = p->conf1 |= SIM_CONF1_SCLKEN;
2496 // WCS patch for NU_Sleep(0) bug
2497 if (p->startclock > 0)
2498 ind_os_sleep (p->startclock);
2499 // End WCS patch
2500 SIM_sleep_status = SIM_SLEEP_DESACT;
2501 }
2502 }
2503
2504 /*
2505 * procedure to parse ATR dynamically
2506 * input p pointer of type SIM_PORT
2507 * output return error code
2508 * SIM_ERR_WAIT, p->errorSIM
2509 * SIM_ERR_CARDREJECT,
2510 *
2511 *
2512 */
2513
2514 SYS_UWORD16 SIM_ATRdynamictreatement (SIM_PORT *p, SIM_CARD *cP)
2515 {
2516 volatile SYS_UWORD8 HistChar;
2517 volatile SYS_UWORD8 InterfChar;
2518 SYS_UWORD16 countT;
2519 SYS_UWORD16 mask;
2520 SYS_UWORD16 returncode;
2521 SYS_UWORD8 i;
2522 SYS_UWORD8 firstprotocol;
2523 SYS_UWORD8 Tx,T;
2524 SYS_UWORD8 TDi;
2525 SYS_UWORD8 position_of_TC1, position_of_TB1;
2526 SYS_UWORD8 another_protocol_present;
2527 SYS_UWORD16 wait80000clk;
2528
2529 i = 0;
2530 //wait for TS and T0
2531 p->moderx = 0;
2532 p->expected_data= 1;
2533 firstprotocol = 0;
2534 position_of_TC1 = 0;
2535 position_of_TB1 = 0;
2536 another_protocol_present = 0;
2537 wait80000clk = 6; // > 24 ms
2538
2539 //wait for first character TS of ATR sequence. It should arrive before 80000sclk
2540 if (returncode = SIM_Waitforchars (p, wait80000clk))
2541 {
2542 return returncode;
2543 }
2544
2545 //wait for T0
2546 p->expected_data++;
2547 if (returncode = SIM_Waitforchars (p, p->etu9600))
2548 {
2549 return returncode;
2550 }
2551
2552 ind_os_sleep(220);
2553
2554 if (((p->rbuf[0] & 0xF0) == 0x30) && (p->rx_index != 0))
2555 {
2556 cP->Inverse = 0;
2557 }
2558 /*-----------------------------------------------------------*/
2559 /* Inverse convention card */
2560 // If first byte is correct for inverse card, return success
2561 else if (((p->rbuf[0] & 0x0F) == 0x03) && (p->rx_index != 0))
2562 {
2563 cP->Inverse = 1;
2564 }
2565 else
2566 {
2567 return (SIM_ERR_CARDREJECT); //Test 27.11.2.4.5
2568 }
2569
2570 countT = 0;
2571 mask = 0x10;
2572 InterfChar = 2;
2573 TDi = 1;
2574
2575
2576 Tx = SIM_Translate_atr_char (p->rbuf[1], cP);
2577
2578 HistChar = Tx & 0x0F; //get K, number of transmitted historical character
2579
2580
2581 while (TDi != 0)
2582 {
2583 while (mask < 0x100) //monitors interface chars
2584 {
2585 if ((Tx & mask) == mask) //monitors if interface character TAx,TBx,TCx,TDc present
2586 {
2587 InterfChar++;
2588 }
2589 //wait for TC1 and save its position
2590 if ((firstprotocol == 0) && ((Tx & 0x40) == mask))
2591 {
2592 position_of_TC1 = InterfChar - 1;
2593 }
2594 if ((firstprotocol == 0) && ((Tx & 0x20) == mask))
2595 {
2596 position_of_TB1 = InterfChar - 1;
2597 }
2598
2599 mask = mask << 1;
2600 }
2601
2602 p->expected_data = InterfChar; //wait for TAi,TBi,TCi,TDi if present
2603
2604 if (returncode = SIM_Waitforchars (p, p->etu9600))
2605 {
2606 return returncode;
2607 }
2608
2609 //need to monitor if TC1 present and if equal to 0 or 255
2610 // on first protocol
2611 if ((firstprotocol == 0) && (position_of_TC1 != 0))
2612 {
2613 T = SIM_Translate_atr_char (p->rbuf[position_of_TC1], cP);
2614
2615 if ((T != 0) && (T != 255)) //test 27.11.1.3
2616 { //return Error in case of bad TC1 value
2617 return (SIM_ERR_CARDREJECT);
2618 }
2619 }
2620 //need to monitor if TB1 present and if differente from 0
2621 // on first protocol
2622 if ((firstprotocol == 0) && (position_of_TB1 != 0))
2623 {
2624 T = SIM_Translate_atr_char (p->rbuf[position_of_TB1], cP);
2625
2626 if (T != 0) //ITU
2627 { //return Error in case of bad TB1 value
2628 return (SIM_ERR_CARDREJECT);
2629 }
2630 }
2631
2632 if ((Tx & 0x80) == 0x80) //TDi byte on first protocol must be 0
2633 { //get new TD char
2634 Tx = SIM_Translate_atr_char (p->rbuf[InterfChar - 1], cP);
2635
2636 if ((Tx & 0x0F) != 0)
2637 {
2638 if (firstprotocol == 0) //if first protocol received is not T=0, card is rejected
2639 {
2640 return (SIM_ERR_CARDREJECT); //protocol other than T=0
2641 }
2642 else
2643 { //if an another protocol T != 0 present, need to wait for TCK char
2644 another_protocol_present = 1;
2645 }
2646 }
2647 mask = 0x10;
2648 firstprotocol++; //indicate another protocol T
2649 }
2650 else
2651 {
2652 TDi = 0;
2653 }
2654 }
2655 //add TCK if necessary
2656 p->expected_data = HistChar + InterfChar + another_protocol_present;
2657
2658 if (returncode = SIM_Waitforchars (p, p->etu9600))
2659 {
2660 return returncode;
2661 }
2662
2663 cP->AtrSize = p->rx_index;
2664
2665 if (cP->Inverse) //inverse card
2666 {
2667 // Copy ATR data
2668 for (i=0;i<cP->AtrSize;i++)
2669 {
2670 cP->AtrData[i] = SIM_ByteReverse(p->rbuf[i]);
2671 }
2672 p->c->conf1 = p->conf1 |= SIM_CONF1_CONV | SIM_CONF1_CHKPAR;
2673 }
2674 else //direct card
2675 {
2676 p->c->conf1 = p->conf1 |= SIM_CONF1_CHKPAR; //0x0409
2677 // Copy ATR data
2678 for (i=0;i<cP->AtrSize;i++)
2679 {
2680 cP->AtrData[i] = p->rbuf[i];
2681 }
2682 }
2683
2684 return (0);
2685 }
2686
2687 /*
2688 ** SIM_Translate_atr_char
2689 *
2690 * FILENAME: sim.c
2691 *
2692 * PARAMETERS: input char to translate
2693 * cP sim structure (indicates if inverse card present)
2694 * DESCRIPTION: return the correct value of input for inverse card
2695 *
2696 * RETURNS: character after parsing
2697 * stays the same if direct card
2698 */
2699
2700 SYS_UWORD8 SIM_Translate_atr_char (SYS_UWORD8 input, SIM_CARD *cP)
2701 {
2702 SYS_UWORD8 translated;
2703
2704 if (cP->Inverse)
2705 {
2706 translated = SIM_ByteReverse(input);
2707 }
2708 else
2709 {
2710 translated = input; //get character next char T0
2711 }
2712 return (translated);
2713 }
2714
2715 /*
2716 * SIM_Waitforchars is used for waiting nbchar characters from SIM
2717 * input p sim port
2718 * max_wait max number of TDMA to wait between 2 characters
2719 * output
2720 * error code 0 if OK
2721 */
2722
2723 SYS_UWORD16 SIM_Waitforchars (SIM_PORT *p, SYS_UWORD16 max_wait)
2724 {
2725 volatile SYS_UWORD8 old_nb_char;
2726 volatile SYS_UWORD16 countT;
2727
2728 if (p->moderx == 6) //use for reception of ACK when command need to transmit rest of data
2729 {
2730 p->ack = 0;
2731 countT = 0;
2732
2733 while((p->ack == 0) && (p->moderx == 6))
2734 { //if p->moderx change from 6 to 5, need to wait for SW1 and SW2
2735
2736 ind_os_sleep(1);
2737 countT++; //implementation of software Waiting time overflow
2738
2739 if (p->null_received) //if NULL char received, wait for next procedure char
2740 {
2741 countT = 0;
2742 p->null_received = 0;
2743 }
2744
2745 if (countT > max_wait)
2746 {
2747 return (SIM_ERR_WAIT);
2748 }
2749 if (p->errorSIM)
2750 {
2751 return(p->errorSIM);
2752 }
2753 }
2754 if (p->moderx == 6) //if transition to moderx = 5 in synchronous part
2755 { //need to quit for SW1/SW2 reception
2756 return (0);
2757 }
2758 }
2759
2760 if ((p->moderx != 6) && (p->moderx != 5)) //treatement of mode 0, 1, 2, 3, 4
2761 {
2762 countT = 0;
2763 old_nb_char = p->rx_index;
2764 //leave while if moderx == 5
2765 while((p->rx_index < p->expected_data) && (p->moderx != 5))
2766 {
2767 ind_os_sleep(1);
2768 countT++; //implementation of software Waiting time overflow
2769
2770 if (p->null_received) //if NULL char received, wait for next procedure char
2771 {
2772 countT = 0;
2773 p->null_received = 0;
2774 }
2775
2776 if (countT > max_wait)
2777 {
2778 return (SIM_ERR_WAIT);
2779 }
2780 if (p->errorSIM)
2781 {
2782 return(p->errorSIM);
2783 }
2784 if (p->rx_index > old_nb_char)
2785 {
2786 old_nb_char = p->rx_index; //if char received before max_wait TDMA, reset the counter
2787 countT = 0;
2788 }
2789 } //end while
2790 if (p->moderx == 0)
2791 {
2792 return (0);
2793 }
2794 }
2795
2796 if (p->moderx == 5) //use for reception of SW1 SW2
2797 {
2798 countT = 0;
2799 old_nb_char = p->SWcount;
2800
2801 while(p->SWcount < 2)
2802 { //if p->moderx change from 6 to 5, need to wait for SW1 and SW2
2803
2804 ind_os_sleep(1);
2805 countT++; //implementation of software Waiting time overflow
2806
2807 if (p->null_received) //if NULL char received, wait for next procedure char
2808 {
2809 countT = 0;
2810 p->null_received = 0;
2811 }
2812
2813 if (countT > max_wait)
2814 {
2815 return (SIM_ERR_WAIT);
2816 }
2817 if (p->errorSIM)
2818 {
2819 return(p->errorSIM);
2820 }
2821 if (p->SWcount > old_nb_char)
2822 {
2823 old_nb_char = p->SWcount; //if char received before max_wait TDMA, reset the counter
2824 countT = 0;
2825 }
2826 }
2827 p->SWcount = 0; //reset SWcount buffer index when SW1 SW2 received
2828 return (0);
2829 }
2830 else //treatement of abnormal case of the asynchronous state machine
2831 {
2832 return (SIM_ERR_ABNORMAL_CASE1);
2833 }
2834 }
2835
2836 /*
2837 * SIM_Calcetu is used for calculating 9600 etu and 400 etu depending on sim clock freq
2838 * and etu period
2839 * input p sim port
2840 */
2841
2842 void SIM_Calcetu (SIM_PORT *p)
2843 {
2844 if (p->conf1 & SIM_CONF1_SCLKDIV) //clock input is 13/8 Mhz
2845 {
2846 if (p->conf1 & SIM_CONF1_ETU) //etu period is 512/8*Tsclk
2847 {
2848 p->etu9600 = 319; // old = 88, increase of 363%
2849 p->etu400 = 6;
2850 p->stopclock = 18;
2851 p->startclock = 8;
2852 }
2853 else //etu period is 372/1*Tsclk
2854 {
2855 p->etu9600 = 1815; // old = 500, increase of 363%
2856 p->etu400 = 28;
2857 p->stopclock = 94;
2858 p->startclock = 38;
2859 }
2860 }
2861 else //clock input is 13/4 Mhz
2862 {
2863 if (p->conf1 & SIM_CONF1_ETU) //etu period is 512/8*Tsclk
2864 {
2865 p->etu9600 = 159; // old = 44, increase of 363%
2866 p->etu400 = 3;
2867 p->stopclock = 9;
2868 p->startclock = 4;
2869 }
2870 else //etu period is 372/1*Tsclk
2871 {
2872 p->etu9600 = 907; // old = 250, increase of 363%
2873 p->etu400 = 14;
2874 p->stopclock = 47;
2875 p->startclock = 19;
2876 }
2877 }
2878 }
2879
2880 /*
2881 * Set the level shifter voltage for start up sequence
2882 *
2883 */
2884
2885 SYS_UWORD8 SIM_StartVolt (SYS_UWORD8 ResetFlag)
2886 {
2887 SYS_UWORD8 abbmask;
2888
2889 #if(ANALOG == 1)
2890 // we assume that in SIM_TYPE_5V there is nothing to do because it is the reset value
2891 #if ((SIM_TYPE == SIM_TYPE_3V) || (SIM_TYPE == SIM_TYPE_3_5V)) // { shut down VCC from ABB and prepare to start at 3V mode
2892 if (ResetFlag) {
2893 abbmask = MODE_INIT_OMEGA_3V;
2894 CurrentVolt = SIM_3V; // we assume the sim is 3v tech. from beginning.
2895 }
2896 else {
2897 if (CurrentVolt == SIM_3V)
2898 abbmask = MODE_INIT_OMEGA_3V;
2899 else
2900 abbmask = MODE5V_OMEGA;
2901 }
2902 ABB_wa_VRPC ((ABB_Read_Register_on_page(PAGE1,VRPCCTRL1) & 0xC0) | abbmask);
2903 ind_os_sleep(1); //wait for charge pump regulation
2904 return(SIM_OK);
2905 #endif
2906 #endif
2907
2908 #if(ANALOG == 2)
2909 SYS_UWORD8 count = 0;
2910 // code for Iota
2911 // reset value for IOTA is for 1.8V, but specific procedure is needed
2912 #if ((SIM_TYPE == SIM_TYPE_1_8V) || (SIM_TYPE == SIM_TYPE_1_8_3V)) // shut down VCC from ABB and prepare to start at 1.8V mode
2913 if (ResetFlag) {
2914 abbmask = MODE_INIT_IOTA_1_8V;
2915 // we assume the sim is 1.8v tech. from beginning.
2916 CurrentVolt = SIM_1_8V;
2917 }
2918 else {
2919 if (CurrentVolt == SIM_1_8V)
2920 abbmask = MODE_INIT_IOTA_1_8V;
2921 else
2922 abbmask = MODE_INIT_IOTA_3V;
2923 }
2924 ABB_wa_VRPC ((ABB_Read_Register_on_page(PAGE1,VRPCSIM) & 0xF4) | abbmask);
2925 while(count++ < 5)
2926 {
2927 if (ABB_Read_Register_on_page(PAGE1,VRPCSIM) & 0x04) // test RSIMRSU
2928 return(SIM_OK);
2929 ind_os_sleep(1);
2930 }
2931 // IOTA failure activation
2932 return(SIM_ERR_HARDWARE_FAIL);
2933 #endif
2934 // 3V only
2935 #if (SIM_TYPE == SIM_TYPE_3V)
2936 abbmask = MODE_INIT_IOTA_3V;
2937 CurrentVolt = SIM_3V; // we assume the sim is 3v tech. from beginning.
2938 ABB_wa_VRPC ((ABB_Read_Register_on_page(PAGE1,VRPCSIM) & 0xF4) | abbmask);
2939 while(count++ < 5)
2940 {
2941 if (ABB_Read_Register_on_page(PAGE1,VRPCSIM) & 0x04) // test RSIMRSU
2942 return(SIM_OK);
2943 ind_os_sleep(1);
2944 }
2945 // IOTA failure activation
2946 return(SIM_ERR_HARDWARE_FAIL);
2947 #endif
2948 #endif
2949
2950 #if(ANALOG == 3)
2951 SYS_UWORD8 count = 0;
2952 // code for Syren
2953 // reset value for SYREN is for 1.8V, but specific procedure is needed
2954 #if ((SIM_TYPE == SIM_TYPE_1_8V) || (SIM_TYPE == SIM_TYPE_1_8_3V)) // { shut down VCC from ABB and prepare to start at 1.8V mode
2955 if (ResetFlag) {
2956 abbmask = MODE_INIT_SYREN_1_8V;
2957 // we assume the sim is 1.8v tech. from beginning.
2958 CurrentVolt = SIM_1_8V;
2959 }
2960 else {
2961 if (CurrentVolt == SIM_1_8V)
2962 abbmask = MODE_INIT_SYREN_1_8V;
2963 else
2964 abbmask = MODE_INIT_SYREN_3V;
2965 }
2966 ABB_wa_VRPC ((ABB_Read_Register_on_page(PAGE1,VRPCSIMR) & 0x1F4) | abbmask);
2967 while(count++ < 5)
2968 {
2969 if (ABB_Read_Register_on_page(PAGE1,VRPCSIMR) & 0x04) // test RSIMRSU
2970 return(SIM_OK);
2971 ind_os_sleep(1);
2972 }
2973 // SYREN failure activation
2974 return(SIM_ERR_HARDWARE_FAIL);
2975 #endif
2976
2977 // 3V only
2978 #if (SIM_TYPE == SIM_TYPE_3V)
2979 abbmask = MODE_INIT_SYREN_3V;
2980 CurrentVolt = SIM_3V; // we assume the sim is 3v tech. from beginning.
2981 ABB_wa_VRPC ((ABB_Read_Register_on_page(PAGE1,VRPCSIMR) & 0x1F4) | abbmask);
2982 while(count++ < 5)
2983 {
2984 if (ABB_Read_Register_on_page(PAGE1,VRPCSIMR) & 0x04) // test RSIMRSU
2985 return(SIM_OK);
2986 ind_os_sleep(1);
2987 }
2988 // SYREN failure activation
2989 return(SIM_ERR_HARDWARE_FAIL);
2990 #endif
2991 #endif
2992 }
2993
2994
2995 /*
2996 * Set the level shifter to switch from 3V to 5V
2997 *
2998 */
2999
3000 SYS_UWORD8 SIM_SwitchVolt (SYS_UWORD8 ResetFlag)
3001 {
3002 SYS_UWORD8 count = 0;
3003 SYS_UWORD8 abbmask;
3004
3005 SIM_PowerOff();
3006
3007 #if(ANALOG == 1)
3008 #if (SIM_TYPE == SIM_TYPE_3_5V) // shut down VCC from ABB and prepare to start at 5V mode
3009 if (ResetFlag) {
3010 abbmask = MODE5V_OMEGA;
3011 CurrentVolt = SIM_5V;
3012 }
3013 else {
3014 if (CurrentVolt == SIM_3V)
3015 abbmask = MODE_INIT_OMEGA_3V;
3016 else
3017 abbmask = MODE5V_OMEGA;
3018 }
3019 ABB_wa_VRPC ((ABB_Read_Register_on_page(PAGE1,VRPCCTRL1) & 0xC0) | abbmask);
3020 return(SIM_OK);
3021 #endif
3022 #elif(ANALOG == 2)
3023 #if (SIM_TYPE == SIM_TYPE_1_8_3V) // shut down VCC from ABB and prepare to start at 3V mode
3024 if (ResetFlag) {
3025 abbmask = MODE_INIT_IOTA_3V;
3026 CurrentVolt = SIM_3V;
3027 }
3028 else {
3029 if (CurrentVolt == SIM_1_8V)
3030 abbmask = MODE_INIT_IOTA_1_8V;
3031 else
3032 abbmask = MODE_INIT_IOTA_3V;
3033 }
3034 ABB_wa_VRPC ((ABB_Read_Register_on_page(PAGE1,VRPCSIM) & 0xF4) | abbmask);
3035 while(count++ < 5)
3036 {
3037 if (ABB_Read_Register_on_page(PAGE1,VRPCSIM) & 0x04)
3038 return(SIM_OK);
3039 ind_os_sleep(1);
3040 }
3041 // IOTA failure activation
3042 return(SIM_ERR_HARDWARE_FAIL);
3043 #endif
3044 #elif(ANALOG == 3)
3045 #if (SIM_TYPE == SIM_TYPE_1_8_3V) // shut down VCC from ABB and prepare to start at 3V mode
3046 if (ResetFlag) {
3047 abbmask = MODE_INIT_SYREN_3V;
3048 CurrentVolt = SIM_3V;
3049 }
3050 else {
3051 if (CurrentVolt == SIM_1_8V)
3052 abbmask = MODE_INIT_SYREN_1_8V;
3053 else
3054 abbmask = MODE_INIT_SYREN_3V;
3055 }
3056 ABB_wa_VRPC ((ABB_Read_Register_on_page(PAGE1,VRPCSIMR) & 0x1F4) | abbmask);
3057 while(count++ < 5)
3058 {
3059 if (ABB_Read_Register_on_page(PAGE1,VRPCSIMR) & 0x04)
3060 return(SIM_OK);
3061 ind_os_sleep(1);
3062 }
3063 // SYREN failure activation
3064 return(SIM_ERR_HARDWARE_FAIL);
3065 #endif
3066 #endif // ANALOG == 1, 2, 3
3067 }
3068
3069 SYS_UWORD8 SIM_Memcpy(SYS_UWORD8 *Buff_target, SYS_UWORD8 Buff_source[],
3070 SYS_UWORD16 len)
3071 {
3072 SYS_UWORD16 i; //unsigned short type counter chosen for copy of 256 bytes
3073
3074 for (i = 0; i < len; i++)
3075 {
3076 if (i == RSIMBUFSIZE)
3077 {
3078 return (SIM_ERR_BUFF_OVERFL);
3079 }
3080 else
3081 {
3082 (*(Buff_target+i)) = Buff_source[i];
3083 }
3084 }
3085 return (0);
3086 }
3087
3088 /*
3089 * SIM_SleepStatus
3090 *
3091 * Return SIM status for sleep manager
3092 *
3093 */
3094 SYS_BOOL SIM_SleepStatus(void)
3095 {
3096 if ((SIM_sleep_status == SIM_SLEEP_ACT) ||
3097 (SIM_sleep_status == SIM_SLEEP_NONE))
3098 return(1); // SIM is ready for deep sleep
3099 else
3100 return(0);
3101 }
3102
3103 /*
3104 * Special lock function to force SIM entity to use adequat SIM Driver
3105 */
3106 void SIM_lock_cr17689(void) {
3107 }
3108
3109
3110 #ifdef SIM_DEBUG_TRACE
3111 void SIM_dbg_write_trace(SYS_UWORD8 *ptr, SYS_UWORD16 len) {
3112 SYS_UWORD16 i;
3113 for(i=0;i<len;i++) {
3114 if (SIM_dbg_cmd_cmpt == SIM_DBG_CMD)
3115 SIM_dbg_cmd_cmpt = 0;
3116 SIM_dbg_cmd[SIM_dbg_cmd_cmpt++] = ptr[i];
3117 }
3118 }
3119 #endif