?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /********************************************************************
2 FileName: SClib.c
3 Dependencies: See INCLUDES section
4 Processor: PIC18, PIC24 Microcontrollers
5 Hardware: This demo is natively intended to be used on Exp 16, LPC
6 & HPC Exp board. This demo can be modified for use on other hardware
7 platforms.
8 Complier: Microchip C18 (for PIC18), C30 (for PIC24)
9 Company: Microchip Technology, Inc.
10  
11 Software License Agreement:
12  
13 The software supplied herewith by Microchip Technology Incorporated
14 (the “Company”) for its PIC® Microcontroller is intended and
15 supplied to you, the Company’s customer, for use solely and
16 exclusively on Microchip PIC Microcontroller products. The
17 software is owned by the Company and/or its supplier, and is
18 protected under applicable copyright laws. All rights are reserved.
19 Any use in violation of the foregoing restrictions may subject the
20 user to criminal sanctions under applicable laws, as well as to
21 civil liability for the breach of the terms and conditions of this
22 license.
23  
24 THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
25 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
26 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
28 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
29 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
30  
31 ********************************************************************
32 File Description:
33  
34 Change History:
35 Rev Description
36 ---- -----------------------------------------
37 1.0 Initial release
38 1.01 Cleaned up unnecessary variables,supported T=1 protocol
39 and improvments in T=0 functions following the coding standards
40 ********************************************************************/
41  
42 #include <string.h>
43 #include "./Smart Card/SClib.h"
44 #include "sc_config.h"
45  
46 #if defined(__PIC24F__)
47 #include "./Smart Card/SCpic24.h"
48 #elif defined(__PIC32MX__)
49 #include "./Smart Card/SCpic32.h"
50 #else
51 #ifdef __18CXX
52 #include "./Smart Card/SCpic18.h"
53 #else
54 #error "Only PIC18 and PIC24F currently supported by SmartCard Library"
55 #endif
56 #endif
57  
58 #define MAX_ATR_LEN (BYTE)33
59  
60 BYTE scCardATR[MAX_ATR_LEN];
61 BYTE scATRLength = 0;
62  
63 BYTE scTA1, scTA2, scTA3;
64 BYTE scTB1, scTB2, scTB3;
65 BYTE scTC1, scTC2, scTC3;
66 BYTE scTD1, scTD2, scTD3;
67  
68 BYTE* scATR_HistoryBuffer = NULL;
69 BYTE scATR_HistoryLength = 0;
70  
71 typedef enum
72 {
73 UNKNOWN,
74 ATR_ON
75 } SC_STATUS;
76  
77 SC_STATUS gCardState = UNKNOWN;
78 SC_ERROR scLastError = SC_ERR_NONE;
79  
80 // Work Wait time for T=0 Protocol in units of etu's
81 unsigned long cgtETU;
82 unsigned long cgt;
83 unsigned long t0WWTetu;
84 unsigned long t0WWT;
85 BOOL delayLapsedFlag = FALSE;
86  
87 static void SC_WaitTime(void);
88 static void SC_Delay(unsigned int instructionCount);
89  
90 #ifdef SC_PROTO_T1
91  
92 #define R_BLOCK_IDENTIFIER (BYTE)0x80
93 #define S_BLOCK_IDENTIFIER (BYTE)0xC0
94 #define M_BIT_SET (BYTE)0x20
95 #define M_BIT_CLR (BYTE)0xDF
96 #define S_BIT_SET (BYTE)0x40
97 #define S_BIT_CLR (BYTE)0xBF
98 #define S_BIT_POSITION (BYTE)0x40
99  
100 unsigned long t1BWT;
101 unsigned long t1CWT;
102 unsigned long t1BGT;
103 unsigned int t1BWTetu;
104 unsigned int t1CWTetu;
105  
106 BYTE t1BGTetu = 22;
107  
108 BYTE edcType = SC_LRC_TYPE_EDC;
109 BYTE maxSegmentLength = 0x20;
110 BOOL txSbit = TRUE;
111  
112 static WORD SC_UpdateCRC(BYTE data,WORD crc);
113 static void SC_UpdateEDC(BYTE data,WORD *edc);
114 static void SC_SendT1Block(BYTE nad,BYTE pcb,WORD length,BYTE *buffer);
115 static BOOL SC_ReceiveT1Block(BYTE *rxNAD,BYTE *rxPCB,BYTE *rxLength,BYTE *buffer,unsigned long blockWaitTime);
116  
117 #endif
118  
119 // CLA set to '00' = no command chaining,
120 // no secure messaging,
121 // basic logical channel.
122  
123 /*******************************************************************************
124 Function:
125 void SC_Initialize(void)
126  
127 Description:
128 This function initializes the smart card library
129  
130 Precondition:
131 None
132  
133 Parameters:
134 None
135  
136 Return Values:
137 None
138  
139 Remarks:
140 None
141 *****************************************************************************/
142 void SC_Initialize()
143 {
144 //Initialize the low level driver
145 SCdrv_InitUART();
146 }
147  
148 /*******************************************************************************
149 Function:
150 BOOL SC_CardPresent(void)
151  
152 Description:
153 This macro checks if card is inserted in the socket
154  
155 Precondition:
156 SC_Initialize() is called
157  
158 Parameters:
159 None
160  
161 Return Values:
162 TRUE if Card is inserted, otherwise return FALSE
163  
164 Remarks:
165 None
166 *****************************************************************************/
167 BOOL SC_CardPresent()
168 {
169 return SCdrv_CardPresent();
170 }
171  
172 /*******************************************************************************
173 Function:
174 BOOL SC_PowerOnATR(void)
175  
176 Description:
177 This function performs the power on sequence of the SmartCard and
178 interprets the Answer-to-Reset data received from the card.
179  
180 Precondition:
181 SC_Initialize() is called, and card is present
182  
183 Parameters:
184 None
185  
186 Return Values:
187 TRUE if Answer to Reset (ATR) was successfuly received and processed
188  
189 Remarks:
190 None
191 *****************************************************************************/
192 BOOL SC_PowerOnATR()
193 {
194 unsigned long atrDelayCnt;
195  
196 if( !SCdrv_CardPresent() ) //check card present
197 {
198 gCardState = UNKNOWN;
199 return FALSE;
200 }
201  
202 SCdrv_SetSwitchCardReset(0); //make sure card in reset
203 memset( scCardATR, 0xFF, sizeof scCardATR );
204 WaitMilliSec(2);
205  
206 #ifdef ENABLE_SC_POWER_THROUGH_PORT_PIN
207 SCdrv_SetSwitchCardPower(1); //Turn on power
208 #endif
209  
210 scATR_HistoryLength = 0;
211 scATR_HistoryBuffer = NULL;
212 gCardState = UNKNOWN;
213 scLastError = SC_ERR_NONE;
214 scATRLength = 0;
215 // t0WWT = (9600UL * (FCY/baudRate))/4;
216 atrDelayCnt = 40000UL * (FCY/scReferenceClock);
217 WaitMilliSec(2);
218  
219 SCdrv_EnableUART();
220  
221 WaitMilliSec(2);
222  
223 //Start the clock
224 SCdrv_EnableClock();
225  
226 // Wait for atleast 400 Clock Cycles after applying reference clock to card.
227 WaitMilliSec(2);
228  
229 SCdrv_SetSwitchCardReset(1); //Release card reset line. set to high state
230  
231 while(1) ///////////////// Read Answer to RESET
232 {
233 if( SCdrv_GetRxData( &scCardATR[scATRLength], atrDelayCnt ) ) //wait for data byte from CARD
234 {
235 scATRLength++;
236  
237 if( scATRLength == MAX_ATR_LEN )
238 break;
239 // else
240 // atrDelayCnt = t0WWT;
241 }
242 else
243 break; //no data
244 }
245  
246 //decode the ATR values
247 if( scATRLength >= 3 ) //min TS, T0 and setup byte
248 {
249 BYTE T0 = scCardATR[1];
250 BYTE atrIdx = 2;
251  
252 //Extract Interface bytes TAx TBx TCx and TDx from ATR
253  
254 scTA1 = scTB1 = scTC1 = scTD1 = 0;
255 scTA2 = scTB2 = scTC2 = scTD2 = 0;
256 scTA3 = scTB3 = scTC3 = scTD3 = 0;
257  
258 // Read the global interface bytes
259  
260 if( T0 & 0x10 )
261 scTA1 = scCardATR[atrIdx++];
262  
263 if( T0 & 0x20 )
264 scTB1 = scCardATR[atrIdx++];
265  
266 if( T0 & 0x40 )
267 scTC1 = scCardATR[atrIdx++];
268  
269 if( T0 & 0x80 )
270 scTD1 = scCardATR[atrIdx++];
271  
272 //read the next set of interface bytes if present
273 if( scTD1 & 0xF0 )
274 {
275 if( scTD1 & 0x10 )
276 scTA2 = scCardATR[atrIdx++];
277  
278 if( scTD1 & 0x20 )
279 scTB2 = scCardATR[atrIdx++];
280  
281 if( scTD1 & 0x40 )
282 scTC2 = scCardATR[atrIdx++];
283  
284 if( scTD1 & 0x80 )
285 scTD2 = scCardATR[atrIdx++];
286  
287 if( scTD2 & 0xF0 )
288 {
289 if( scTD2 & 0x10 )
290 {
291 scTA3 = scCardATR[atrIdx++];
292  
293 if ((scTA3 < 0x10) || (scTA3 == 0xFF))
294 {
295 SC_Shutdown();
296 scLastError = SC_ERR_ATR_DATA;
297 return FALSE;
298 }
299  
300 #ifdef SC_PROTO_T1
301 maxSegmentLength = scTA3;
302 #endif
303 }
304  
305 if( scTD2 & 0x20 )
306 scTB3 = scCardATR[atrIdx++];
307  
308 if( scTD2 & 0x40 )
309 {
310 scTC3 = scCardATR[atrIdx++];
311  
312 #ifdef SC_PROTO_T1
313 edcType = (scTC3 & 0x01) ? SC_CRC_TYPE_EDC : SC_LRC_TYPE_EDC;
314 #endif
315 }
316  
317 if( scTD2 & 0x80 )
318 scTD3 = scCardATR[atrIdx++];
319 }
320 }
321  
322 scATR_HistoryLength = T0 & 0x0F;
323 scATR_HistoryBuffer = (scATR_HistoryLength)?(&scCardATR[atrIdx]):NULL;
324 SC_WaitTime();
325 gCardState = ATR_ON;
326 SCdrv_EnableDelayTimerIntr();
327 return TRUE;
328 }
329 else
330 {
331 // Not a Valid ATR Reponse
332 scLastError = SC_ERR_BAR_OR_NO_ATR_RESPONSE;
333 gCardState = UNKNOWN;
334 SC_Shutdown();
335 return FALSE;
336 }
337 }
338  
339  
340 /*******************************************************************************
341 Function:
342 BOOL SC_DoPPS(void)
343  
344 Description:
345 This function does the PPS to the card & configures the baud rate of the PIC UART
346 to match with Answer-to-Reset data from smartcard.
347  
348 Precondition:
349 SC_PowerOnATR was success
350  
351 Parameters:
352 None
353  
354 Return Values:
355 TRUE if Baud rate is supported by the PIC
356  
357 Remarks:
358 This function is called when SC_PowerOnATR() returns TRUE. If the Baud
359 rate configration file inside the card is changed, these function should
360 be called again for the new baud to take effect.
361 *****************************************************************************/
362 BOOL SC_DoPPS()
363 {
364 if( !SCdrv_CardPresent() || gCardState != ATR_ON )
365 return FALSE;
366  
367 if( scTA1 == 0x11 ) //card using 9600 baud. no need to configure
368 return TRUE;
369  
370 // If TA2 is absent & TD1 is present
371 if(!(scTD1 & 0x10) && (scCardATR[1] & 0x80) && !(scTD1 & 0x0F))
372 {
373 SCdrv_SendTxData( 0xFF ); // PPSS Byte = 0xFF always
374  
375 if(scCardATR[1] & 0x10)
376 {
377 SCdrv_SendTxData( 0x10 ); // PPS0
378 SCdrv_SendTxData( scTA1 ); // PPS1
379 SCdrv_SendTxData( 0xFF ^ 0x10 ^ scTA1 ); // PCK
380  
381 SCdrv_SetBRG( scTA1 ); //tell the driver to configure baud rate
382 SC_WaitTime();
383 }
384 else
385 {
386 SCdrv_SendTxData( 0x00 ); // PPS0
387 SCdrv_SendTxData( 0xFF); // PCK
388 }
389 }
390  
391 return TRUE;
392 }
393  
394 /*******************************************************************************
395 Function:
396 int SC_GetCardState(void)
397  
398 Description:
399 This function returns the current state of SmartCard
400  
401 Precondition:
402 SC_Initialize is called.
403  
404 Parameters:
405 None
406  
407 Return Values:
408 SC_STATE_CARD_NOT_PRESENT: No Card Detected
409 SC_STATE_CARD_ACTIVE: Card is powered and ATR received
410 SC_STATE_CARD_INACTIVE: Card present but not powered
411  
412 Remarks:
413 None
414 *****************************************************************************/
415 int SC_GetCardState()
416 {
417 if( !SCdrv_CardPresent() )
418 return SC_STATE_CARD_NOT_PRESENT;
419 else if( gCardState == ATR_ON )
420 return SC_STATE_CARD_ACTIVE;
421 else
422 return SC_STATE_CARD_INACTIVE;
423 }
424  
425 /*******************************************************************************
426 Function:
427 void SC_Shutdown(void)
428  
429 Description:
430 This function Performs the Power Down sequence of the SmartCard
431  
432 Precondition:
433 SC_Initialize is called.
434  
435 Parameters:
436 None
437  
438 Return Values:
439 None
440  
441 Remarks:
442 None
443 *****************************************************************************/
444 void SC_Shutdown()
445 {
446 SCdrv_SetSwitchCardReset(0); //bring reset line low
447 WaitMilliSec(1);
448 SCdrv_CloseUART(); //shut down UART and remove any pullups
449 #ifdef ENABLE_SC_POWER_THROUGH_PORT_PIN
450 SCdrv_SetSwitchCardPower(0); //Turn Off Card Power
451 #endif
452 gCardState = UNKNOWN;
453 }
454  
455  
456 /*******************************************************************************
457 Function:
458 void SC_WaitTime(void)
459  
460 Description:
461 This function calculates the work wait time for T=0 Protocol
462  
463 Precondition:
464 SC_PowerOnATR is called.
465  
466 Parameters:
467 None
468  
469 Return Values:
470 None
471  
472 Remarks:
473 This function is planned to calculate CWT & BWT for T=1 protocol in future.
474 *****************************************************************************/
475 static void SC_WaitTime(void)
476 {
477 float factorD = 1;
478 unsigned int factorF = 372;
479 BYTE ta1Code,tb2Code,index;
480 unsigned int tempVariable;
481  
482 ta1Code = scTA1 & 0x0F;
483  
484 // Calculate Factor 'D' from TA1 value
485 switch(ta1Code)
486 {
487 case 0x00:
488 case 0x07:
489 case 0x01:
490 break;
491  
492 case 0x02:
493 factorD = 2;
494 break;
495  
496 case 0x03:
497 factorD = 4;
498 break;
499  
500 case 0x04:
501 factorD = 8;
502 break;
503  
504 case 0x05:
505 factorD = 16;
506 break;
507  
508 case 0x06:
509 factorD = 32;
510 break;
511  
512 case 0x08:
513 factorD = 12;
514 break;
515  
516 case 0x09:
517 factorD = 20;
518 break;
519  
520 case 0x0A:
521 factorD = 0.5;
522 break;
523  
524 case 0x0B:
525 factorD = 0.25;
526 break;
527  
528 case 0x0C:
529 factorD = 0.125;
530 break;
531  
532 case 0x0D:
533 factorD = 0.0625;
534 break;
535  
536 case 0x0E:
537 factorD = 0.03125;
538 break;
539  
540 case 0x0F:
541 factorD = 0.015625;
542 break;
543 }
544  
545 ta1Code = (scTA1 & 0xF0) >> 4;
546  
547 // Calculate Factor 'F' from TA1 value
548 switch(ta1Code)
549 {
550 case 0x00:
551 case 0x07:
552 case 0x08:
553 case 0x0E:
554 case 0x0F:
555 break;
556  
557 case 0x01:
558 factorF = 372;
559 break;
560  
561 case 0x02:
562 factorF = 558;
563 break;
564  
565 case 0x03:
566 factorF = 744;
567 break;
568  
569 case 0x04:
570 factorF = 1116;
571 break;
572  
573 case 0x05:
574 factorF = 1488;
575 break;
576  
577 case 0x06:
578 factorF = 1860;
579 break;
580  
581 case 0x09:
582 factorF = 512;
583 break;
584  
585 case 0x0A:
586 factorF = 768;
587 break;
588  
589 case 0x0B:
590 factorF = 1024;
591 break;
592  
593 case 0x0C:
594 factorF = 1536;
595 break;
596  
597 case 0x0D:
598 factorF = 2048;
599 break;
600 }
601  
602 // Check whether T=0 or T=1 protocol ?
603 switch(scTD1 & 0x0F)
604 {
605 case 1 :
606 // Calculate Character Guard Time in ETU's for T=1 Protocol
607 if(scTC1 == 0xFF)
608 {
609 cgtETU = 11;
610 }
611 else
612 {
613 cgtETU = 12 + (unsigned long)((float)((float)(factorF * scTC1)/factorD)/scReferenceClock);
614 }
615  
616 #ifdef SC_PROTO_T1
617  
618 if(scTD1 & 0x20)
619 {
620 tb2Code = scTB2 & 0x0F;
621  
622 tempVariable = 1;
623 for(index = 0;index < tb2Code;index++)
624 tempVariable = tempVariable * 2;
625 // Calculate Character Wait Time in ETU's for T=1 Protocol as set in the card
626 t1CWTetu = 11 + tempVariable;
627  
628 tb2Code = (scTB2 & 0xF0) >> 4;
629  
630 tempVariable = 1;
631 for(index = 0;index < tb2Code;index++)
632 tempVariable = tempVariable * 2;
633  
634 // Calculate Block Wait Time in ETU's for T=1 Protocol as set in the card
635 t1BWTetu = 11 + (unsigned int)((unsigned long)(tempVariable * 35712UL)/(scReferenceClock/10));
636 }
637 else
638 {
639 for(index = 0;index < SC_CWI;index++)
640 tempVariable = tempVariable * 2;
641  
642 // Calculate default value of Character Wait Time in ETU's for T=1 Protocol.
643 t1CWTetu = 11 + tempVariable;
644  
645 tempVariable = 1;
646 for(index = 0;index < SC_BWI;index++)
647 tempVariable = tempVariable * 2;
648  
649 // Calculate default value of Block Wait Time in ETU's for T=1 Protocol.
650 t1BWTetu = 11 + (unsigned int)((unsigned long)(tempVariable * 357120UL)/scReferenceClock);
651 }
652  
653 #endif
654  
655 break;
656 case 0 :
657 default :
658 // If scTC2 is transmitted by the card then calculate work wait time
659 // or else use default value
660 if(scTD1 & 0x40)
661 {
662 t0WWTetu = (unsigned long)(scTC2 * factorD * 960);
663 }
664 else
665 {
666 t0WWTetu = (unsigned long)(SC_WI * factorD * 960);
667 }
668  
669 // Calculate Character Guard Time in ETU's for T=1 Protocol
670 if(scTC1 == 0xFF)
671 {
672 cgtETU = 12;
673 }
674 else
675 {
676 cgtETU = 12 + (unsigned long)((float)((float)(factorF * scTC1)/factorD)/scReferenceClock);
677 }
678  
679 break;
680 }
681  
682 if(t0WWTetu <= cgtETU)
683 t0WWTetu = cgtETU * 100;
684  
685 // Calculate Character Guard Time in number of Instruction Counts for T=0/T=1 Protocol
686 cgt = cgtETU * (FCY/baudRate);
687  
688 // Calculate Work Wait Time in number of Instruction Counts for T=0 Protocol
689 t0WWT = t0WWTetu * (FCY/baudRate);
690  
691 #ifdef SC_PROTO_T1
692  
693 if(t1BWTetu <= t1BGTetu)
694 t1BWTetu = t1BGTetu * 100;
695  
696 if(t1CWTetu <= cgtETU)
697 t1CWTetu = cgtETU * 100;
698  
699 // Calculate Character Wait Time in number of Instruction Counts for T=1 Protocol
700 t1CWT = t1CWTetu * (FCY/baudRate);
701  
702 // Calculate Block Guard Time in number of Instruction Counts for T=1 Protocol
703 t1BGT = t1BGTetu * (FCY/baudRate);
704  
705 // Calculate Block Wait Time in number of Instruction Counts for T=1 Protocol
706 t1BWT = t1BWTetu * (FCY/baudRate);
707  
708 #endif
709 }
710  
711 /*******************************************************************************
712 Function:
713 BOOL SC_TransactT0(SC_APDU_COMMAND* apduCommand, SC_APDU_RESPONSE* apduResponse, BYTE* apduDataBuffer)
714  
715 Description:
716 This function Sends the ISO 7816-4 compaliant APDU commands to the card.
717 It also receive the expected response from the card as defined by the
718 command data.
719  
720 Precondition:
721 SC_DoPPS was success
722  
723 Parameters:
724 SC_APDU_COMMAND* apduCommand - Pointer to APDU Command Structure
725 SC_APDU_RESPONSE* pResp - Pointer to APDU Response structure
726 BYTE* pResp - Pointer to the Command/Response Data buffer
727  
728 Return Values:
729 TRUE if transaction was success, and followed the ISO 7816-4 protocol.
730  
731 Remarks:
732 In the APDU command structure, the LC field defines the number of bytes to
733 transmit from the APDUdat array. This array can hold max 256 bytes, which
734 can be redefined by the user. The LE field in APDU command defines the number
735 of bytes to receive from the card. This array can hold max 256 bytes, which
736 can be redefined by the user.
737  
738 *****************************************************************************/
739 BOOL SC_TransactT0(SC_APDU_COMMAND* apduCommand, SC_APDU_RESPONSE* apduResponse, BYTE* apduDataBuffer)
740 {
741 BYTE* apduCommandBuffer;
742 BYTE index,lc = apduCommand->LC,le = apduCommand->LE,ins = apduCommand->INS;
743 BYTE rx_char;
744 BYTE lcLength = 0,leLength = 0;
745 unsigned int txDelay;
746  
747 // Return False if there is no Card inserted in the Slot
748 if( !SCdrv_CardPresent() || gCardState != ATR_ON )
749 {
750 scLastError = SC_ERR_CARD_NOT_PRESENT;
751 return FALSE;
752 }
753  
754 // Clear APDU Response data if present before getting the new one's
755 memset( apduResponse, 0, sizeof(SC_APDU_RESPONSE) );
756  
757 apduCommandBuffer = (BYTE*)apduCommand;
758  
759 txDelay = cgt/8;
760  
761 //Send the Command Bytes: CLA INS P1 P2
762 for( index = 0; index < 4; index++ )
763 {
764 SCdrv_SendTxData( apduCommandBuffer[index] );
765 SC_Delay(txDelay);
766 }
767  
768 //Now transmit LE or LC field if non zero
769 if( lc )
770 SCdrv_SendTxData( lc );
771 else if( le )
772 SCdrv_SendTxData( le );
773  
774 while (1)
775 {
776 // Get Procedure byte
777 if(!SCdrv_GetRxData( &rx_char, t0WWT ) ) //wait for data byte from CARD
778 {
779 scLastError = SC_ERR_CARD_NO_RESPONSE;
780 return FALSE; //no response received
781 }
782  
783 // Process Procedure Byte
784 if (rx_char == 0x60)
785 {
786 // Do Nothing
787 }
788 else if (((rx_char & 0xF0) == 0x60) || ((rx_char & 0xF0) == 0x90))
789 {
790 // SW1, get SW2
791 apduResponse->SW1 = rx_char; //save SW1
792  
793 //now receive SW2
794 if( SCdrv_GetRxData( &rx_char, t0WWT ) ) //wait for data byte from CARD
795 apduResponse->SW2 = rx_char;
796 else
797 {
798 scLastError = SC_ERR_CARD_NO_RESPONSE;
799 return FALSE; //no response received
800 }
801  
802 break;
803 }
804 else if(rx_char == ins)
805 {
806 // Send all remaining bytes
807 if( lcLength < lc) //transmit app data if any
808 {
809 WaitMicroSec( 700 ); //cannot send the message data right away after the initial response
810 SC_Delay(txDelay);
811  
812 for(;lcLength < lc; lcLength++ )
813 {
814 SCdrv_SendTxData( apduDataBuffer[lcLength] );
815 SC_Delay(txDelay);
816 }
817 }
818 else
819 {
820 // Recive all remaining bytes
821 for(;leLength < le; leLength++ )
822 {
823 if( SCdrv_GetRxData( &rx_char, t0WWT ) ) //wait for data byte from CARD
824 apduDataBuffer[leLength] = rx_char;
825 else
826 {
827 scLastError = SC_ERR_CARD_NO_RESPONSE;
828 return FALSE; //no response received
829 }
830 }
831 }
832 }
833 else if(rx_char == ~ins)
834 {
835 // ACK, send one byte if remaining
836 if (lcLength < lc)
837 {
838 SC_Delay(txDelay);
839  
840 SCdrv_SendTxData( apduDataBuffer[lcLength++] );
841 }
842 else
843 {
844 //wait for data byte from CARD or timeout
845 if( SCdrv_GetRxData( &rx_char, t0WWT ) )
846 apduDataBuffer[leLength++] = rx_char;
847 else
848 {
849 scLastError = SC_ERR_CARD_NO_RESPONSE;
850 return FALSE; //no response received
851 }
852 }
853 }
854 else
855 {
856 // Do Nothing
857 }
858 }
859  
860 // Store the number of recieved data bytes other than the
861 // status codes to make the life of Smart Card Reader easier
862 apduResponse->RXDATALEN = leLength;
863  
864 return TRUE;
865 }
866  
867 /*******************************************************************************
868 Function:
869 void SC_Delay(void)
870  
871 Description:
872 This function waits for delay to get completed
873  
874 Precondition:
875 None.
876  
877 Parameters:
878 unsigned int instructionCount - Number of instruction counts to be waited
879  
880 Return Values:
881 None
882  
883 Remarks:
884 None.
885 *****************************************************************************/
886 static void SC_Delay(unsigned int instructionCount)
887 {
888 // Set the Timer Count as per the delay needed
889 SCdrv_SetDelayTimerCnt(0xFFFF - instructionCount);
890  
891 // Enable the delay timer
892 SCdrv_EnableDelayTimer();
893  
894 // Wait until the delay is elapsed
895 while(!delayLapsedFlag);
896  
897 // Clear the delay flag
898 delayLapsedFlag = FALSE;
899 }
900  
901 #ifdef SC_PROTO_T1
902  
903 /*******************************************************************************
904 Function:
905 void SC_UpdateCRC(void)
906  
907 Description:
908 This function calculates 16 bit CRC for T=1 Protocol
909  
910 Precondition:
911 Initial value of crc should be 0xFFFF.
912  
913 Parameters:
914 BYTE data - Data that has to be used to update CRC.
915 WORD *edc - Pointer to CRC
916  
917 Return Values:
918 WORD - updated CRC
919  
920 Remarks:
921 CRC 16 - X^16 + X^12 + X^5 + 1
922  
923 *****************************************************************************/
924 static WORD SC_UpdateCRC(BYTE data,WORD crc)
925 {
926 WORD index;
927 WORD tempData = (WORD)data << 8;
928  
929 // Update the CRC & return it Back
930 for (index = 0;index < 8;index++)
931 {
932 if ((crc ^ tempData) & 0x8000)
933 {
934 crc <<= 1;
935 crc ^= (WORD)0x1021; // X^12 + X^5 + 1
936 }
937 else
938 {
939 crc <<= 1;
940 }
941  
942 tempData <<= 1;
943 }
944  
945 return(crc);
946 }
947  
948 /*******************************************************************************
949 Function:
950 void SC_UpdateEDC(BYTE data,WORD *edc)
951  
952 Description:
953 This function updates Error Data Check value depending on the EDC type
954 for T=1 Protocol
955  
956 Precondition:
957 None.
958  
959 Parameters:
960 BYTE data - Data that has to be used to update EDC.
961 WORD *edc - Pointer to EDC
962  
963 Return Values:
964 None
965  
966 Remarks:
967 None
968  
969 *****************************************************************************/
970 static void SC_UpdateEDC(BYTE data,WORD *edc)
971 {
972 // Store the updated LRC/CRC in the EDC
973 if (edcType == SC_CRC_TYPE_EDC) // type = CRC
974 {
975 *edc = SC_UpdateCRC(data,*edc);
976 }
977 else // type = LRC
978 {
979 *edc = *edc ^ data;
980 }
981 }
982  
983 /*******************************************************************************
984 Function:
985 static void SC_SendT1Block(BYTE nad,BYTE pcb,WORD length,BYTE *buffer)
986  
987 Description:
988 This function transmits a T=1 formatted block
989  
990 Precondition:
991 Complete ATR...
992  
993 Parameters:
994 BYTE nad - NAD to be transmitted to the card
995 BYTE pcb - PCB to be transmitted to the card
996 WORD length - Length of I-Field transmitted to the card
997 BYTE *buffer - Pointer to data that is to be transmitted to the card
998  
999 Return Values:
1000 None
1001  
1002 Remarks:
1003 None
1004  
1005 *****************************************************************************/
1006 static void SC_SendT1Block(BYTE nad,BYTE pcb,WORD length,BYTE *buffer)
1007 {
1008 WORD index;
1009 WORD edc;
1010  
1011 // Choose the initial value of edc depending upon LRC or CRC
1012 if (edcType == SC_CRC_TYPE_EDC)
1013 {
1014 edc = 0xFFFF;
1015 }
1016 else
1017 {
1018 edc = 0;
1019 }
1020 // Update the edc for Node Address Data Byte
1021 SC_UpdateEDC(nad,&edc);
1022  
1023 // Update the edc for Protocol Control Byte
1024 SC_UpdateEDC(pcb,&edc);
1025  
1026 // Update the edc for length of tx Bytes
1027 SC_UpdateEDC(length,&edc);
1028  
1029 // Update the edc for the data to be transmitted
1030 for (index=0;index<length;index++)
1031 {
1032 SC_UpdateEDC(buffer[index],&edc);
1033 }
1034  
1035 // Transmit Node Address
1036 SCdrv_SendTxData(nad);
1037  
1038 // Transmit Protocol Control Byte
1039 SCdrv_SendTxData(pcb);
1040  
1041 // Transmit length of Data Byte
1042 SCdrv_SendTxData(length);
1043  
1044 // Transmit Data Bytes
1045 for (index=0;index<length;index++)
1046 {
1047 SCdrv_SendTxData(buffer[index]);
1048 }
1049  
1050 // Transmit EDC
1051 if (edcType == SC_LRC_TYPE_EDC)
1052 {
1053 SCdrv_SendTxData(edc);
1054 }
1055 else
1056 {
1057 SCdrv_SendTxData(edc);
1058 SCdrv_SendTxData(edc>>8);
1059 }
1060 }
1061  
1062 /*******************************************************************************
1063 Function:
1064 void SC_ReceiveT1Block(void)
1065  
1066 Description:
1067 This function receives a T=1 formatted block
1068  
1069 Precondition:
1070 Transmit a block before expecting the response...
1071  
1072 Parameters:
1073 BYTE *rxNAD - Pointer to NAD recieved from the card
1074 BYTE *rxPCB - Pointer to PCB recieved from the card
1075 BYTE *rxLength - Pointer to Length of I-Field recieved from the card
1076 BYTE *buffer - Pointer to data recieved from the card
1077 unsigned long blockWaitTime - value of Block Wait Time
1078  
1079 Return Values:
1080 TRUE if block recieve is successful, and follows the ISO 7816-4 protocol.
1081  
1082 Remarks:
1083 None
1084 *****************************************************************************/
1085 static BOOL SC_ReceiveT1Block(BYTE *rxNAD,BYTE *rxPCB,BYTE *rxLength,BYTE *buffer,unsigned long blockWaitTime)
1086 {
1087 WORD edc;
1088 WORD index;
1089 BYTE expectedLength;
1090  
1091 // Get NAD
1092 if(!SCdrv_GetRxData( rxNAD, blockWaitTime ))
1093 {
1094 scLastError = SC_ERR_CARD_NO_RESPONSE;
1095 return FALSE;
1096 }
1097  
1098 // Get PCB
1099 if(!SCdrv_GetRxData( rxPCB, t1CWT ))
1100 {
1101 scLastError = SC_ERR_CARD_NO_RESPONSE;
1102 return FALSE;
1103 }
1104  
1105 // Get Length
1106 if(!SCdrv_GetRxData( rxLength, t1CWT ))
1107 {
1108 scLastError = SC_ERR_CARD_NO_RESPONSE;
1109 return FALSE;
1110 }
1111  
1112 // Add one to the expected length for LRC
1113 expectedLength = *rxLength + 1;
1114  
1115 // Add additional byte to the length if using CRC
1116 if (edcType == SC_CRC_TYPE_EDC)
1117 expectedLength++;
1118  
1119 // Get all the data bytes plus EDC (1 or 2 bytes at end)
1120 for (index = 0;index < expectedLength;)
1121 {
1122 if(!SCdrv_GetRxData( buffer + index, t1CWT ))
1123 {
1124 scLastError = SC_ERR_CARD_NO_RESPONSE;
1125 return FALSE;
1126 }
1127  
1128 ++index;
1129 }
1130  
1131 // Check the LRC or CRC Error
1132 if (edcType == SC_LRC_TYPE_EDC)
1133 {
1134 edc = 0;
1135 SC_UpdateEDC(*rxNAD,&edc);
1136 SC_UpdateEDC(*rxPCB,&edc);
1137 SC_UpdateEDC(*rxLength,&edc);
1138 for (index = 0;index < expectedLength;)
1139 {
1140 SC_UpdateEDC(*(buffer + index),&edc);
1141 ++index;
1142 }
1143  
1144 if (edc != 0)
1145 {
1146 scLastError = SC_ERR_RECEIVE_LRC;
1147 return FALSE;
1148 }
1149 }
1150 else // EDC is CRC
1151 {
1152 edc = 0xFFFF;
1153 SC_UpdateEDC(*rxNAD,&edc);
1154 SC_UpdateEDC(*rxPCB,&edc);
1155 SC_UpdateEDC(*rxLength,&edc);
1156 for (index = 0;index < (expectedLength-2);)
1157 {
1158 SC_UpdateEDC(*(buffer + index),&edc);
1159 ++index;
1160 }
1161  
1162 if (((edc >> 8) != buffer[expectedLength-2]) || ((edc & 0xFF) != buffer[expectedLength-1]))
1163 {
1164 scLastError = SC_ERR_RECEIVE_CRC;
1165 return FALSE;
1166 }
1167 }
1168  
1169 // Return TRUE if there is no LRC or CRC error & data bytes are recieved sucessfully
1170 return TRUE;
1171 }
1172  
1173 /*******************************************************************************
1174 Function:
1175 BOOL SC_TransactT1(SC_T1_PROLOGUE_FIELD* pfield,BYTE* iField,SC_APDU_RESPONSE* apduResponse)
1176  
1177 Description:
1178 This function Sends the ISO 7816-4 compaliant APDU commands to the card.
1179 It also receive the expected response from the card as defined by the
1180 command data.
1181  
1182 Precondition:
1183 SC_DoPPS was success
1184  
1185 Parameters:
1186 SC_T1_PROLOGUE_FIELD* pfield - Pointer to Prologue Field
1187 BYTE* iField - Pointer to the Information Field of Tx/Rx Data
1188 SC_APDU_RESPONSE* apduResponse - Pointer to APDU Response structure
1189  
1190 Return Values:
1191 TRUE if transaction was success, and followed the ISO 7816-4 protocol.
1192  
1193 Remarks:
1194 *****************************************************************************/
1195  
1196 BOOL SC_TransactT1(SC_T1_PROLOGUE_FIELD* pfield,BYTE* iField,SC_APDU_RESPONSE* apduResponse)
1197 {
1198 BOOL t1TransactCompleted = FALSE,txMbit = FALSE;
1199 BOOL rxMbit = FALSE,rxSbit = FALSE,transmitNextSegment = TRUE;
1200 BYTE txLength,txPCB = pfield->PCB,rxNAD,rxPCB,rxLEN;
1201 BYTE initialLength = pfield->LENGTH,iFieldLength,retryR = 0,retrySync = 0;
1202 WORD rxLength = 0;
1203 BYTE* rxField = iField;
1204 BYTE* txField = iField;
1205 BYTE* initialField = iField;
1206 unsigned long currT1BWT = t1BWT;
1207 T1BLOCK_TYPE t1TxBlockType,currentT1RxBlockType;
1208  
1209 iFieldLength = initialLength;
1210  
1211 // Determine which type of block is to be transmitted to the card
1212 if((txPCB & 0x80) == 0x00)
1213 {
1214 // I-Block
1215 t1TxBlockType = I_BLOCK;
1216  
1217 if(txSbit)
1218 {
1219 txPCB = txPCB & S_BIT_CLR;
1220 txSbit = FALSE;
1221 }
1222 else
1223 {
1224 txPCB = txPCB | S_BIT_SET;
1225 txSbit = TRUE;
1226 }
1227 }
1228 else if((txPCB & 0xC0) == 0xC0)
1229 {
1230 // S-Block
1231 t1TxBlockType = S_BLOCK;
1232 }
1233 else if((txPCB & 0xC0) == 0x80)
1234 {
1235 // R-Block
1236 t1TxBlockType = R_BLOCK;
1237 }
1238 else
1239 {
1240 // INVALID BLOCK
1241 return FALSE;
1242 }
1243  
1244 // Go to appropriate case depending upon the type of block
1245 switch(t1TxBlockType)
1246 {
1247 case I_BLOCK:
1248 // Continue Untill Transaction is Passed or Failed...
1249 while (!t1TransactCompleted)
1250 {
1251 // If Next segment has to be transmitted to the card
1252 if(transmitNextSegment)
1253 {
1254 txMbit = FALSE;
1255  
1256 if(iFieldLength > maxSegmentLength)
1257 {
1258 txLength = maxSegmentLength;
1259 txMbit = TRUE;
1260 txPCB = txPCB | M_BIT_SET;
1261 }
1262 else
1263 {
1264 txLength = iFieldLength;
1265 txPCB = txPCB & M_BIT_CLR;
1266 }
1267  
1268 txField = iField;
1269 }
1270  
1271 // Send block with chaining mode, current sequence number, and maximum length.
1272 SC_SendT1Block(pfield->NAD,txPCB,txLength,txField);
1273  
1274 // Recieve the Block
1275 if(SC_ReceiveT1Block(&rxNAD,&rxPCB,&rxLEN,rxField,currT1BWT))
1276 {
1277 // Determine the type of Block recieved from the card
1278 if((rxPCB & 0x80) == 0x00)
1279 {
1280 // I-Block
1281 currentT1RxBlockType = I_BLOCK;
1282  
1283 if((rxPCB & 0x20) == 0x20)
1284 rxMbit = TRUE;
1285 else
1286 rxMbit = FALSE;
1287  
1288 if((rxPCB & 0x40) == 0x40)
1289 rxSbit = TRUE;
1290 else
1291 rxSbit = FALSE;
1292  
1293 transmitNextSegment = FALSE;
1294  
1295 retryR = 0;retrySync = 0;
1296 }
1297 else if((rxPCB & 0xC0) == 0xC0)
1298 {
1299 // S-Block
1300 currentT1RxBlockType = S_BLOCK;
1301  
1302 retryR = 0;retrySync = 0;
1303 }
1304 else if((rxPCB & 0xC0) == 0x80)
1305 {
1306 // R-Block
1307 currentT1RxBlockType = R_BLOCK;
1308  
1309 retryR = 0;retrySync = 0;
1310 }
1311 else
1312 {
1313 // INVALID BLOCK
1314 currentT1RxBlockType = INVALID_BLOCK;
1315 }
1316 }
1317 else
1318 {
1319 // No Block Recieved or Error Block Recieved
1320 currentT1RxBlockType = INVALID_BLOCK;
1321 }
1322  
1323 currT1BWT = t1BWT;
1324  
1325 switch(currentT1RxBlockType)
1326 {
1327 case I_BLOCK :
1328 rxField = rxField + (BYTE)rxLEN;
1329 rxLength = rxLength + rxLEN;
1330 iFieldLength = 0;
1331  
1332 // If More Bit is set by the card,
1333 // send the apprpriate R Block
1334 if(rxMbit)
1335 {
1336 // Transmit R(N) - Expected Seq
1337 txLength = 0x00;
1338  
1339 if(rxSbit)
1340 txPCB = 0x80;
1341 else
1342 txPCB = 0x90;
1343 }
1344 else
1345 {
1346 // No More Bit set from the card,
1347 // Data is recieved with the status
1348 // codes...we are done
1349 if(rxLEN)
1350 {
1351 // We are Done here
1352 t1TransactCompleted = TRUE;
1353 if(rxLength >= 2)
1354 {
1355 apduResponse->RXDATALEN = rxLength - 2;
1356 apduResponse->SW1 = *(initialField + (BYTE)rxLength - (BYTE)2);
1357 apduResponse->SW2 = *(initialField + (BYTE)rxLength - (BYTE)1);
1358 }
1359 }
1360 else
1361 {
1362 // Transmit Forced Acknowledge I Block
1363 txLength = 0x00;
1364  
1365 if(txSbit)
1366 {
1367 txPCB = 0x00;
1368 txSbit = FALSE;
1369 }
1370 else
1371 {
1372 txPCB = 0x40;
1373 txSbit = TRUE;
1374 }
1375 }
1376 }
1377  
1378 break;
1379  
1380 case S_BLOCK :
1381 // Card can only send Resync Response...
1382 // Card cant do Resync request
1383 if((rxPCB & 0x3F) == 0x20) // Resync Response from the card
1384 {
1385 txSbit = FALSE;
1386 return FALSE;
1387 }
1388 else if((rxPCB & 0x3F) == 0x01) // Request IFS Change
1389 {
1390 txPCB = SC_IFS_RESPONSE;
1391 txLength = 1;
1392 txField = rxField;
1393 maxSegmentLength = *rxField;
1394 transmitNextSegment = FALSE;
1395 continue;
1396 }
1397 else if((rxPCB & 0x3F) == 0x03) // Request Wait time Extension
1398 {
1399 currT1BWT = t1BWT * *rxField;
1400 txPCB = SC_WAIT_TIME_EXT_RESPONSE;
1401 txLength = 1;
1402 txField = rxField;
1403 transmitNextSegment = FALSE;
1404 continue;
1405 }
1406 else if((rxPCB & 0x3F) == 0x24) // VPP Error Response
1407 {
1408 scLastError = SC_CARD_VPP_ERR;
1409 return FALSE;
1410 }
1411 else if((rxPCB & 0x3F) == 0x02) // Abort Request
1412 {
1413 txPCB = SC_ABORT_RESPONSE;
1414 txLength = 0;
1415 if(txMbit)
1416 {
1417 // Do this so that there is last byte transmission to terminate
1418 // the communication
1419 iFieldLength = maxSegmentLength + 1;
1420 }
1421 transmitNextSegment = FALSE;
1422 continue;
1423 }
1424 break;
1425  
1426 case R_BLOCK :
1427 // If Recieved Seq Number not equal
1428 // to transmitted Seq Number
1429 if(rxSbit != txSbit)
1430 {
1431 // If More Bit is set by the reader
1432 if(txMbit)
1433 {
1434 // Transmission of previous segment was
1435 // succesful. Transmit next segment.
1436 transmitNextSegment = TRUE;
1437  
1438 iFieldLength = iFieldLength - maxSegmentLength;
1439 iField = iField + maxSegmentLength;
1440  
1441 // Toggle the Sequence Bit
1442 if(txSbit)
1443 {
1444 txPCB = 0x00;
1445 txSbit = FALSE;
1446 }
1447 else
1448 {
1449 txPCB = 0x40;
1450 txSbit = TRUE;
1451 }
1452 }
1453 else
1454 {
1455 // There was some error, trasmit previous
1456 // block
1457 transmitNextSegment = FALSE;
1458 }
1459 }
1460 else
1461 {
1462 // Retransmit the I-Block
1463 transmitNextSegment = TRUE;
1464 }
1465  
1466 break;
1467  
1468 case INVALID_BLOCK :
1469 // If 1st Block transaction itself
1470 // is failing transmit R(0)
1471 if(initialLength == iFieldLength)
1472 {
1473 txPCB = 0x82;
1474 txLength = 0x00;
1475 transmitNextSegment = FALSE;
1476 retryR++;
1477 retrySync = 0;
1478  
1479 // Try transmitting R(0) twice
1480 // before telling error to the
1481 // Smart Card Reader
1482 if(retryR > 2)
1483 {
1484 scLastError = SC_ERR_CARD_NO_RESPONSE;
1485 return FALSE;
1486 }
1487 }
1488 else
1489 {
1490 transmitNextSegment = FALSE;
1491  
1492 // Try transmitting R(0) twice // Try transmitting R(0) twice
1493 // before transmitting ReSync
1494 // Request to the card
1495 if(retryR < 2)
1496 {
1497 if(rxMbit)
1498 txPCB = 0x82;
1499 else
1500 txPCB = 0x92;
1501  
1502 txLength = 0x00;
1503 retryR++;
1504 retrySync = 0;
1505 }
1506 else
1507 {
1508 txPCB = 0xC0;
1509 txLength = 0x00;
1510 retrySync++;
1511 // Try transmitting R(0) twice // Try transmitting R(0) twice
1512 // Try transmitting Resync Request
1513 // thrice before telling error to the
1514 // Smart Card Reader
1515 if(retrySync > 3)
1516 {
1517 scLastError = SC_ERR_CARD_NO_RESPONSE;
1518 return FALSE;
1519 }
1520 }
1521 }
1522  
1523 continue;
1524  
1525 break;
1526 }
1527 }
1528  
1529 break;
1530  
1531 case S_BLOCK:
1532 // Continue Untill Transaction is Passed or Failed...
1533 while (!t1TransactCompleted)
1534 {
1535 // Send mode, current sequence number, and maximum length.
1536 SC_SendT1Block(pfield->NAD,txPCB,0,txField);
1537  
1538 // Recieve the Block
1539 if(SC_ReceiveT1Block(&rxNAD,&rxPCB,&rxLEN,rxField,currT1BWT))
1540 {
1541 // Determine the type of Block recieved from the card
1542 if((rxPCB & 0x80) == 0x00)
1543 {
1544 // I-Block
1545 currentT1RxBlockType = I_BLOCK;
1546 }
1547 else if((rxPCB & 0xC0) == 0xC0)
1548 {
1549 // S-Block
1550 currentT1RxBlockType = S_BLOCK;
1551 }
1552 else if((rxPCB & 0xC0) == 0x80)
1553 {
1554 // R-Block
1555 currentT1RxBlockType = R_BLOCK;
1556 }
1557 else
1558 {
1559 // INVALID BLOCK
1560 currentT1RxBlockType = INVALID_BLOCK;
1561 }
1562 }
1563 else
1564 {
1565 // No Block Recieved or Error Block Recieved
1566 currentT1RxBlockType = INVALID_BLOCK;
1567 }
1568  
1569 switch(currentT1RxBlockType)
1570 {
1571 case S_BLOCK :
1572 // If Acknowledged properly, return
1573 // TRUE to the card reader
1574 if((txPCB | 0x20) == rxPCB)
1575 {
1576 t1TransactCompleted = TRUE;
1577 break;
1578 }
1579 else
1580 {
1581 // Try transmitting thrice before
1582 // telling error to the Smart
1583 // Card Reader
1584 retrySync++;
1585  
1586 if(retrySync > 3)
1587 {
1588 scLastError = SC_ERR_CARD_NO_RESPONSE;
1589 return FALSE;
1590 }
1591  
1592 continue;
1593 }
1594 break;
1595 case R_BLOCK :
1596 case I_BLOCK :
1597 case INVALID_BLOCK :
1598 // Try transmitting thrice before
1599 // telling error to the Smart
1600 // Card Reader
1601 retrySync++;
1602 if(retrySync > 3)
1603 {
1604 scLastError = SC_ERR_CARD_NO_RESPONSE;
1605 return FALSE;
1606 }
1607 continue;
1608 break;
1609 }
1610 }
1611 break;
1612  
1613 case R_BLOCK:
1614 default:
1615 break;
1616 }
1617  
1618 // Return TRUE if everything is fine
1619 return TRUE;
1620 }
1621  
1622 #endif
1623  
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3