├── iso7816.cpp └── iso7816.h /iso7816.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eonopchenko/iso7816/HEAD/iso7816.cpp -------------------------------------------------------------------------------- /iso7816.h: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | 3 | /** 4 | File: iso7816.h 5 | 6 | System: 7 | Component Name: ISO7816 driver module 8 | Status: Version 1.0 Release 1 9 | 10 | Language: C++ 11 | 12 | Address: 13 | St.Petersburg, Russia 14 | 15 | Author: Evgeny Onopchenko 16 | 17 | E-Mail: jake.spb@gmail.com 18 | 19 | Description: Header file for ISO7816 smartcard driver implementation 20 | This file contains the defined types 21 | 22 | */ 23 | // ---------------------------------------------------------------------------- 24 | 25 | #ifndef __ISO7816_H 26 | #define __ISO7816_H 27 | 28 | #include "timer.h" 29 | #include "ring_buffer.h" 30 | #include 31 | #include 32 | 33 | 34 | #define SC_USART USART6 35 | #define SC_USART_CLK RCC_APB2Periph_USART6 36 | #define SC_USART_APB_PERIPH_CLOCK RCC_APB2PeriphClockCmd 37 | #define SC_USART_IRQn USART6_IRQn 38 | #define SC_USART_IRQHandler USART6_IRQHandler 39 | 40 | #define SC_USART_TX_PIN GPIO_Pin_6 41 | #define SC_USART_TX_GPIO_PORT GPIOC 42 | #define SC_USART_TX_GPIO_CLK RCC_AHB1Periph_GPIOC 43 | #define SC_USART_TX_SOURCE GPIO_PinSource6 44 | #define SC_USART_TX_AF GPIO_AF_USART6 45 | 46 | #define SC_USART_CK_PIN GPIO_Pin_8 47 | #define SC_USART_CK_GPIO_PORT GPIOC 48 | #define SC_USART_CK_GPIO_CLK RCC_AHB1Periph_GPIOC 49 | #define SC_USART_CK_SOURCE GPIO_PinSource8 50 | #define SC_USART_CK_AF GPIO_AF_USART6 51 | 52 | #define SC_VCC_PIN GPIO_Pin_5 53 | #define SC_VCC_GPIO_PORT GPIOG 54 | #define SC_VCC_GPIO_CLK RCC_AHB1Periph_GPIOG 55 | 56 | #define SC_RST_PIN GPIO_Pin_7 57 | #define SC_RST_GPIO_PORT GPIOC 58 | #define SC_RST_GPIO_CLK RCC_AHB1Periph_GPIOC 59 | 60 | 61 | class ISO7816 62 | { 63 | public: 64 | /// Bit convention 65 | enum BitConvention 66 | { 67 | BIT_CONVETNTION_DIRECT = 0x3B ///< Direct convention 68 | }; 69 | 70 | /// Protocol (physical layer) 71 | enum Protocol_t 72 | { 73 | ///< T0 protocol (asynchronous, half-duplex, character) 74 | PROTOCOL_T0 = 0x00 75 | }; 76 | 77 | /// Error codes 78 | enum SW_t 79 | { 80 | SW_NO_ERROR = 0x9000, 81 | SW_BYTES_REMAINING_00 = 0x6100, 82 | }; 83 | 84 | #pragma pack(1) 85 | /// ATR (physical layer) 86 | struct ATR_t 87 | { 88 | uint8_t TS; 89 | uint8_t T0; 90 | uint8_t TA1; 91 | uint8_t TB1; 92 | uint8_t TC1; 93 | uint8_t TD1; 94 | uint8_t TA2; 95 | uint8_t TB2; 96 | uint8_t TC2; 97 | uint8_t TD2; 98 | uint8_t Hlength; 99 | uint8_t H[20]; 100 | }; 101 | 102 | /// PTS (physical layer) 103 | struct PTS_t 104 | { 105 | uint8_t PTSS; 106 | uint8_t PTS0; 107 | uint8_t PTS1; 108 | uint8_t PTS2; 109 | uint8_t PTS3; 110 | uint8_t PCK; 111 | }; 112 | 113 | /// TPDU (link layer) (P3 will be transmit separated) 114 | struct TPDU_t 115 | { 116 | uint8_t CLA; 117 | uint8_t INS; 118 | uint8_t P1; 119 | uint8_t P2; 120 | }; 121 | #pragma pack() 122 | 123 | /// Exchange cases 124 | enum Case_t 125 | { 126 | CASE_1, ///< No data in command, no data in response 127 | CASE_2, ///< No data in command, data in response 128 | CASE_3, ///< Data in command, no data in response 129 | CASE_4, ///< Data in command, data in response 130 | 131 | }; 132 | 133 | /// Instructions list 134 | enum INS_t 135 | { 136 | VERIFY = 0x20, 137 | SELECT_FILE = 0xA4, 138 | GET_RESPONSE = 0xC0, 139 | TERMINATE_CARD_USAGE = 0xFE, 140 | HANG_CARD = 0xFF, 141 | }; 142 | 143 | /// Card activation 144 | bool ActivateCard(); 145 | 146 | /// "Cold" reset 147 | bool ColdReset(); 148 | 149 | /// Card deactivation 150 | void DeactivateCard(); 151 | 152 | /// Select file 153 | bool SelectFile(uint8_t P1, uint8_t P2, const char* fileName, uint8_t nameLength); 154 | 155 | /// Verify 156 | bool Verify(uint8_t P1, uint8_t P2, const char* pin, uint8_t pinLength); 157 | 158 | /// Send TPDU 159 | uint16_t SendTPDU(const TPDU_t* tpdu, const void* data, uint8_t dataSize, Case_t exchangeCase); 160 | 161 | /// Get data 162 | int GetResponse(void* buffer, uint8_t dataSize); 163 | 164 | /// Interrupts handler 165 | void IrqHandler(); 166 | 167 | /// Constructor 168 | ISO7816(); 169 | 170 | private: 171 | SoftTimer Timer; ///< Timer 172 | 173 | char RxBuffer[128]; ///< Receive buffer 174 | RingBuffer* ReceiveBuffer; ///< Ring buffer 175 | 176 | uint8_t DataByte; ///< Last transmitted byte 177 | 178 | bool CardActivateFlag; ///< Card activation flag 179 | 180 | /// VCC on/off 181 | void VccHigh() { GPIO_ResetBits(SC_VCC_GPIO_PORT, SC_VCC_PIN); }; 182 | void VccLow() { GPIO_SetBits(SC_VCC_GPIO_PORT, SC_VCC_PIN); }; 183 | 184 | /// RST high/low 185 | void RstHigh() { GPIO_SetBits(SC_RST_GPIO_PORT, SC_RST_PIN); }; 186 | void RstLow() { GPIO_ResetBits(SC_RST_GPIO_PORT, SC_RST_PIN); }; 187 | 188 | /// Transmit data 189 | int8_t Transmit(const char* data, uint8_t size); 190 | 191 | /// Receive data 192 | int8_t Receive(char* buffer, uint8_t size, uint32_t timeout, bool remove = true); 193 | 194 | /// Calculate set bit count 195 | uint8_t GetBitsCount(uint8_t byte); 196 | 197 | /// Calculate TCK and PCK 198 | uint8_t CalcCK(char* data, uint8_t length); 199 | }; 200 | 201 | extern ISO7816 Smartcard; 202 | 203 | #endif 204 | --------------------------------------------------------------------------------