comparison src/cs/drivers/drv_app/sim/sim.c @ 0:4e78acac3d88

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