1*65388dadSMauro Carvalho Chehab============================= 2*65388dadSMauro Carvalho ChehabISO7816 Serial Communications 3*65388dadSMauro Carvalho Chehab============================= 4*65388dadSMauro Carvalho Chehab 5*65388dadSMauro Carvalho Chehab1. Introduction 6*65388dadSMauro Carvalho Chehab=============== 7*65388dadSMauro Carvalho Chehab 8*65388dadSMauro Carvalho Chehab ISO/IEC7816 is a series of standards specifying integrated circuit cards (ICC) 9*65388dadSMauro Carvalho Chehab also known as smart cards. 10*65388dadSMauro Carvalho Chehab 11*65388dadSMauro Carvalho Chehab2. Hardware-related considerations 12*65388dadSMauro Carvalho Chehab================================== 13*65388dadSMauro Carvalho Chehab 14*65388dadSMauro Carvalho Chehab Some CPUs/UARTs (e.g., Microchip AT91) contain a built-in mode capable of 15*65388dadSMauro Carvalho Chehab handling communication with a smart card. 16*65388dadSMauro Carvalho Chehab 17*65388dadSMauro Carvalho Chehab For these microcontrollers, the Linux driver should be made capable of 18*65388dadSMauro Carvalho Chehab working in both modes, and proper ioctls (see later) should be made 19*65388dadSMauro Carvalho Chehab available at user-level to allow switching from one mode to the other, and 20*65388dadSMauro Carvalho Chehab vice versa. 21*65388dadSMauro Carvalho Chehab 22*65388dadSMauro Carvalho Chehab3. Data Structures Already Available in the Kernel 23*65388dadSMauro Carvalho Chehab================================================== 24*65388dadSMauro Carvalho Chehab 25*65388dadSMauro Carvalho Chehab The Linux kernel provides the serial_iso7816 structure (see [1]) to handle 26*65388dadSMauro Carvalho Chehab ISO7816 communications. This data structure is used to set and configure 27*65388dadSMauro Carvalho Chehab ISO7816 parameters in ioctls. 28*65388dadSMauro Carvalho Chehab 29*65388dadSMauro Carvalho Chehab Any driver for devices capable of working both as RS232 and ISO7816 should 30*65388dadSMauro Carvalho Chehab implement the iso7816_config callback in the uart_port structure. The 31*65388dadSMauro Carvalho Chehab serial_core calls iso7816_config to do the device specific part in response 32*65388dadSMauro Carvalho Chehab to TIOCGISO7816 and TIOCSISO7816 ioctls (see below). The iso7816_config 33*65388dadSMauro Carvalho Chehab callback receives a pointer to struct serial_iso7816. 34*65388dadSMauro Carvalho Chehab 35*65388dadSMauro Carvalho Chehab4. Usage from user-level 36*65388dadSMauro Carvalho Chehab======================== 37*65388dadSMauro Carvalho Chehab 38*65388dadSMauro Carvalho Chehab From user-level, ISO7816 configuration can be get/set using the previous 39*65388dadSMauro Carvalho Chehab ioctls. For instance, to set ISO7816 you can use the following code:: 40*65388dadSMauro Carvalho Chehab 41*65388dadSMauro Carvalho Chehab #include <linux/serial.h> 42*65388dadSMauro Carvalho Chehab 43*65388dadSMauro Carvalho Chehab /* Include definition for ISO7816 ioctls: TIOCSISO7816 and TIOCGISO7816 */ 44*65388dadSMauro Carvalho Chehab #include <sys/ioctl.h> 45*65388dadSMauro Carvalho Chehab 46*65388dadSMauro Carvalho Chehab /* Open your specific device (e.g., /dev/mydevice): */ 47*65388dadSMauro Carvalho Chehab int fd = open ("/dev/mydevice", O_RDWR); 48*65388dadSMauro Carvalho Chehab if (fd < 0) { 49*65388dadSMauro Carvalho Chehab /* Error handling. See errno. */ 50*65388dadSMauro Carvalho Chehab } 51*65388dadSMauro Carvalho Chehab 52*65388dadSMauro Carvalho Chehab struct serial_iso7816 iso7816conf; 53*65388dadSMauro Carvalho Chehab 54*65388dadSMauro Carvalho Chehab /* Reserved fields as to be zeroed */ 55*65388dadSMauro Carvalho Chehab memset(&iso7816conf, 0, sizeof(iso7816conf)); 56*65388dadSMauro Carvalho Chehab 57*65388dadSMauro Carvalho Chehab /* Enable ISO7816 mode: */ 58*65388dadSMauro Carvalho Chehab iso7816conf.flags |= SER_ISO7816_ENABLED; 59*65388dadSMauro Carvalho Chehab 60*65388dadSMauro Carvalho Chehab /* Select the protocol: */ 61*65388dadSMauro Carvalho Chehab /* T=0 */ 62*65388dadSMauro Carvalho Chehab iso7816conf.flags |= SER_ISO7816_T(0); 63*65388dadSMauro Carvalho Chehab /* or T=1 */ 64*65388dadSMauro Carvalho Chehab iso7816conf.flags |= SER_ISO7816_T(1); 65*65388dadSMauro Carvalho Chehab 66*65388dadSMauro Carvalho Chehab /* Set the guard time: */ 67*65388dadSMauro Carvalho Chehab iso7816conf.tg = 2; 68*65388dadSMauro Carvalho Chehab 69*65388dadSMauro Carvalho Chehab /* Set the clock frequency*/ 70*65388dadSMauro Carvalho Chehab iso7816conf.clk = 3571200; 71*65388dadSMauro Carvalho Chehab 72*65388dadSMauro Carvalho Chehab /* Set transmission factors: */ 73*65388dadSMauro Carvalho Chehab iso7816conf.sc_fi = 372; 74*65388dadSMauro Carvalho Chehab iso7816conf.sc_di = 1; 75*65388dadSMauro Carvalho Chehab 76*65388dadSMauro Carvalho Chehab if (ioctl(fd_usart, TIOCSISO7816, &iso7816conf) < 0) { 77*65388dadSMauro Carvalho Chehab /* Error handling. See errno. */ 78*65388dadSMauro Carvalho Chehab } 79*65388dadSMauro Carvalho Chehab 80*65388dadSMauro Carvalho Chehab /* Use read() and write() syscalls here... */ 81*65388dadSMauro Carvalho Chehab 82*65388dadSMauro Carvalho Chehab /* Close the device when finished: */ 83*65388dadSMauro Carvalho Chehab if (close (fd) < 0) { 84*65388dadSMauro Carvalho Chehab /* Error handling. See errno. */ 85*65388dadSMauro Carvalho Chehab } 86*65388dadSMauro Carvalho Chehab 87*65388dadSMauro Carvalho Chehab5. References 88*65388dadSMauro Carvalho Chehab============= 89*65388dadSMauro Carvalho Chehab 90*65388dadSMauro Carvalho Chehab [1] include/uapi/linux/serial.h 91