00001 /* ---------------------------------------------------------------------------- 00002 * SAM Software Package License 00003 * ---------------------------------------------------------------------------- 00004 * Copyright (c) 2014, Atmel Corporation 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * 00011 * - Redistributions of source code must retain the above copyright notice, 00012 * this list of conditions and the disclaimer below. 00013 * 00014 * Atmel's name may not be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00019 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 00020 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00023 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00024 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00025 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00026 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 * ---------------------------------------------------------------------------- 00028 */ 00029 /** 00030 * \page usart_iso7816 USART ISO7816 Example 00031 * 00032 * \section Purpose 00033 * This example sends ISO 7816 commands to a smartcard connected to the 00034 * SAM V71 Xplained Ultra board. 00035 * 00036 * \section Requirements 00037 * This example can be used on SAM V71 Xplained Ultra board. Please connect the 00038 * smartcard contacts with following pins which could be easily wired from 00039 * the board. 00040 * - <b>SAM V71 Xplained -- SMARTCARD</b> 00041 * - PB02 -- RST 00042 * - TXD0(PB01) -- I/O 00043 * - SCK0(PB13) -- CLK 00044 * 00045 * \section Description 00046 * The iso7816 software provide in this examples is use to transform APDU 00047 * commands to TPDU commands for the smart card. 00048 * The iso7816 provide here is for the protocol T=0 only. 00049 * The send and the receive of a character is made under polling. 00050 * In the file ISO7816_Init is defined all pins of the card. User must have to 00051 * change this pins according to his environment. 00052 * The driver is compliant with CASE 1, 2, 3 of the ISO7816-4 specification. 00053 * 00054 * \section Usage 00055 * -# Build the program and download it inside the SAM V71 Xplained Ultra board. 00056 * Please refer to the Getting Started with SAM V71 Microcontrollers.pdf 00057 * -# On the computer, open and configure a terminal application (e.g. 00058 * HyperTerminal on Microsoft Windows) with these settings: 00059 * - 115200 bauds 00060 * - 8 data bits 00061 * - No parity 00062 * - 1 stop bit 00063 * - No flow control 00064 * -# Connect the card reader to SAM V71 Xplained Ultra board: 00065 * <table border="1" cellpadding="2" cellspacing="0"> 00066 * <tr><td>C1: Vcc: 7816_3V5V </td><td> C5: Gnd</td> <td> C4: RFU</td></tr> 00067 * <tr><td> C2: Reset: 7816_RST</td> <td> C6: Vpp</td> <td> C8: RFU</td></tr> 00068 * <tr><td> C3: Clock: 7816_CLK</td> <td> C7: 7816_IO</td> </tr> 00069 * </table> 00070 * If necessary,another pin must be connected on the card reader for detecting the 00071 * insertion and removal: 7816_IRQ. 00072 * On Atmel boards, all this pins can be easily connecting with jumpers. 00073 * -# Start the application. The following traces shall appear on the terminal: 00074 * \code 00075 * -- USART ISO7816 Example xxx -- 00076 * -- SAMxxxxx-xx 00077 * -- Compiled: xxx xx xxxx xx:xx:xx -- 00078 * Display the ATR 00079 * \endcode 00080 * 00081 * \section References 00082 * - usart_iso7816/main.c 00083 * - iso7816_4.c 00084 * - usart.c 00085 * - pio.h 00086 * - usart.h 00087 * 00088 */ 00089 00090 /** \file 00091 * 00092 * This file contains all the specific code for the usart_iso7816 example. 00093 * 00094 */ 00095 00096 00097 /*------------------------------------------------------------------------------ 00098 * Headers 00099 *------------------------------------------------------------------------------*/ 00100 00101 #include "board.h" 00102 00103 #include <string.h> 00104 00105 /*------------------------------------------------------------------------------ 00106 * Internal definitions 00107 *------------------------------------------------------------------------------*/ 00108 00109 /** Maximum ucSize in bytes of the smart card answer to a command.*/ 00110 #define MAX_ANSWER_SIZE 10 00111 00112 /** Maximum ATR ucSize in bytes.*/ 00113 #define MAX_ATR_SIZE 55 00114 00115 /** Register base for USART */ 00116 #define USART USART0 00117 #define ID_USART ID_USART0 00118 /*------------------------------------------------------------------------------ 00119 * Internal variables 00120 *------------------------------------------------------------------------------*/ 00121 00122 /** Test command #1.*/ 00123 static const uint8_t testCommand1[] = {0x00, 0x10, 0x00, 0x00}; 00124 /** Test command #2.*/ 00125 static const uint8_t testCommand2[] = {0x00, 0x20, 0x00, 0x00, 0x02}; 00126 /** Test command #3.*/ 00127 static const uint8_t testCommand3[] = {0x00, 0x30, 0x00, 0x00, 0x02, 0x0A, 0x0B}; 00128 /** ISO7816 pins */ 00129 static const Pin pinsISO7816[] = {PINS_ISO7816}; 00130 /** ISO7816 RST pin */ 00131 static const Pin pinIso7816RstMC = PIN_ISO7816_RSTMC; 00132 00133 /*------------------------------------------------------------------------------ 00134 * Internal functions 00135 *------------------------------------------------------------------------------*/ 00136 00137 /*------------------------------------------------------------------------------ 00138 * Optional smartcard detection 00139 *------------------------------------------------------------------------------*/ 00140 00141 #ifdef SMARTCARD_CONNECT_PIN 00142 00143 /** Smartcard detection pin.*/ 00144 static const Pin pinSmartCard = SMARTCARD_CONNECT_PIN; 00145 00146 /** 00147 * PIO interrupt service routine. Checks if the smartcard has been connected 00148 * or disconnected. 00149 */ 00150 static void ISR_PioSmartCard( const Pin *pPin ) 00151 { 00152 /* Check all pending interrupts */ 00153 if ( (pinSmartCard.pio->PIO_ISR & pinSmartCard.mask) != 0 ) 00154 { 00155 /* Check current level on pin */ 00156 if ( PIO_Get( &pinSmartCard ) == 0 ) 00157 { 00158 printf( "-I- Smartcard inserted\n\r" ); 00159 } 00160 else 00161 { 00162 printf( "-I- Smartcard removed\n\r" ); 00163 } 00164 } 00165 } 00166 00167 /** 00168 * Configures the smartcard detection pin to trigger an interrupt. 00169 */ 00170 static void ConfigureCardDetection( void ) 00171 { 00172 PIO_Configure( &pinSmartCard, 1 ); 00173 PIO_ConfigureIt( &pinSmartCard, ISR_PioSmartCard ); 00174 PIO_EnableIt( &pinSmartCard ); 00175 } 00176 00177 #else 00178 00179 /** 00180 * Dummy implementation. 00181 */ 00182 static void ConfigureCardDetection( void ) 00183 { 00184 printf( "-I- Smartcard detection not supported.\n\r" ); 00185 } 00186 00187 #endif 00188 00189 /** 00190 * Displays a menu which enables the user to send several commands to the 00191 * smartcard and check its answers. 00192 */ 00193 static void SendReceiveCommands( void ) 00194 { 00195 uint8_t pMessage[MAX_ANSWER_SIZE]; 00196 uint8_t ucSize; 00197 uint8_t ucKey; 00198 uint8_t command; 00199 uint8_t i; 00200 00201 /* Clear message buffer */ 00202 memset( pMessage, 0, sizeof( pMessage ) ); 00203 00204 /* Display menu */ 00205 printf( "-I- The following three commands can be sent:\n\r" ); 00206 printf( " 1. " ); 00207 for ( i=0; i < sizeof( testCommand1 ); i++ ) 00208 { 00209 printf( "0x%X ", testCommand1[i] ); 00210 } 00211 printf( "\n\r 2. " ); 00212 00213 for ( i=0; i < sizeof( testCommand2 ); i++ ) 00214 { 00215 printf( "0x%X ", testCommand2[i] ); 00216 } 00217 printf( "\n\r 3. " ); 00218 00219 for ( i=0; i < sizeof( testCommand3 ); i++ ) 00220 { 00221 printf( "0x%X ", testCommand3[i] ); 00222 } 00223 printf( "\n\r" ); 00224 00225 /* Get user input */ 00226 ucKey = 0; 00227 while ( ucKey != 'q' ) 00228 { 00229 printf( "\r " ); 00230 printf( "\rChoice ? (q to quit): " ); 00231 ucKey = DBG_GetChar(); 00232 printf( "%c", ucKey ); 00233 command = ucKey - '0'; 00234 00235 /* Check user input */ 00236 ucSize = 0; 00237 if ( command == 1 ) 00238 { 00239 printf( "\n\r-I- Sending command " ); 00240 for ( i=0; i < sizeof( testCommand1 ); i++ ) 00241 { 00242 printf( "0x%02X ", testCommand1[i] ); 00243 } 00244 printf( "...\n\r" ); 00245 ucSize = ISO7816_XfrBlockTPDU_T0( testCommand1, pMessage, 00246 sizeof( testCommand1 ) ); 00247 } 00248 else 00249 { 00250 if ( command == 2 ) 00251 { 00252 printf( "\n\r-I- Sending command " ); 00253 for ( i=0; i < sizeof( testCommand2 ); i++ ) 00254 { 00255 printf("0x%02X ", testCommand2[i] ); 00256 } 00257 printf( "...\n\r" ); 00258 ucSize = ISO7816_XfrBlockTPDU_T0( testCommand2, pMessage, 00259 sizeof( testCommand2 ) ); 00260 } 00261 else 00262 { 00263 if ( command == 3 ) 00264 { 00265 printf( "\n\r-I- Sending command " ); 00266 for ( i=0; i < sizeof( testCommand3 ); i++ ) 00267 { 00268 printf( "0x%02X ", testCommand3[i] ); 00269 } 00270 printf( "...\n\r" ); 00271 ucSize = ISO7816_XfrBlockTPDU_T0( testCommand3, pMessage, 00272 sizeof( testCommand3 ) ); 00273 } 00274 } 00275 } 00276 00277 /* Output smartcard answer */ 00278 if ( ucSize > 0 ) 00279 { 00280 printf( "\n\rAnswer: " ); 00281 for ( i=0; i < ucSize; i++ ) 00282 { 00283 printf( "0x%02X ", pMessage[i] ); 00284 } 00285 printf( "\n\r" ); 00286 } 00287 } 00288 00289 printf( "Quitting ...\n\r" ); 00290 } 00291 00292 /*------------------------------------------------------------------------------ 00293 * Exported functions 00294 *------------------------------------------------------------------------------*/ 00295 00296 /** 00297 * Initializes the DBGU and ISO7816 driver, and starts some tests. 00298 * \return Unused (ANSI-C compatibility) 00299 */ 00300 extern int main( void ) 00301 { 00302 uint8_t pAtr[MAX_ATR_SIZE]; 00303 uint8_t ucSize; 00304 00305 /* Disable watchdog*/ 00306 WDT_Disable( WDT ); 00307 00308 /* Initialize Atr buffer */ 00309 memset( pAtr, 0, sizeof( pAtr ) ); 00310 00311 printf( "-- USART ISO7816 Example %s --\n\r", SOFTPACK_VERSION ); 00312 printf( "-- %s\n\r", BOARD_NAME ); 00313 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ; 00314 00315 /* Configure IT on Smart Card */ 00316 ConfigureCardDetection(); 00317 00318 /* Configure ISO7816 driver */ 00319 PIO_Configure( pinsISO7816, PIO_LISTSIZE( pinsISO7816 ) ); 00320 00321 ISO7816_Init( USART, ID_USART, pinIso7816RstMC ); 00322 00323 /* Read ATR */ 00324 ISO7816_warm_reset(); 00325 00326 ISO7816_Datablock_ATR( pAtr, &ucSize ); 00327 00328 /* Decode ATR */ 00329 ISO7816_Decode_ATR( pAtr ); 00330 00331 /* Allow user to send some commands */ 00332 SendReceiveCommands(); 00333 00334 return 0; 00335 } 00336