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