comparison gsm-fw/bsp/sim.c @ 163:5e0e41cd7c9f

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