1  /*
2  * Copyright (C) 2017-2024 Alibaba Group Holding Limited
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 /******************************************************************************
20  * @file       drv/iso7816.h
21  * @brief      Header File for ISO7816 Driver
22  * @version    V1.0
23  * @date       9. Oct 2020
24  * @model      iso7816
25  ******************************************************************************/
26 
27 #ifndef _DRV_ISO7816_H_
28 #define _DRV_ISO7816_H_
29 
30 #include <stdint.h>
31 #include <drv/common.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 typedef enum {
38     A_5V,
39     B_3_3V,
40     C_1_8V,
41 } dcd_vclass_t;
42 
43 typedef enum {
44     T0,
45     T1,
46 } iso7816_tprotocol_t;
47 
48 typedef enum {
49     ISO7816_EVENT_CARD_DETECTED,
50     ISO7816_EVENT_READ_COMPLETE,
51     ISO7816_EVENT_WRITE_COMPLETE,
52     ISO7816_EVENT_READ_ERROR,
53     ISO7816_EVENT_WRITE_ERROR,
54     ISO7816_EVENT_ACTIVATE_SUCCESS,
55     ISO7816_EVENT_ACTIVATE_FAILED,
56     ISO7816_EVENT_CARD_ERROR_DEACTIVATE,
57     ISO7816_EVENT_CARD_SESSION_CLOSED,
58     ISO7816_EVENT_RX_FULL,
59     ISO7816_EVENT_CWT_TIME_OUT,
60     ISO7816_EVENT_RX_OVER,
61     ISO7816_EVENT_CRC_ERR,
62     ISO7816_EVENT_PARITY_ERR,
63     ISO7816_EVENT_SLAVE_ATR_DETECTED,
64     ISO7816_EVENT_SLAVE_ATR_DONE,
65 } iso7816_event_t;
66 
67 typedef void (*iso7816_event_cb_t)(iso7816_event_t event, void *arg);
68 
69 typedef enum {
70     ISO7816_SLAVE,
71     ISO7816_MASTER,
72 } iso7816_mode_t;
73 
74 typedef struct {
75     uint8_t           clk_div;
76     dcd_vclass_t      vclass;
77     iso7816_mode_t    mode;
78     int32_t           card_detected_en;
79 } iso7816_config_t;
80 
81 typedef enum {
82     ISO7816_A_ONLY = 1U,
83     ISO7816_B_ONLY,
84     ISO7816_C_ONLY,
85     ISO7816_AB,
86     ISO7816_AC,
87     ISO7816_BC,
88     ISO7816_ABC,
89 } iso7816_voltage_class_t;
90 
91 typedef struct {
92     iso7816_voltage_class_t    support_voltage_class;
93     int32_t                    proto_t;
94     int32_t                    clk_stop_is_support;
95     int32_t                    history_byte_num;
96     uint8_t                    history_data[15];
97 } iso7816_atr_info_t;
98 
99 typedef enum {
100     EVEN_PARITY,
101     ODD_PARITY,
102 } iso7816_parity_type_t;
103 
104 typedef enum {
105     ISO7816_DRIECT,
106     ISO7816_INVERSE,
107 } iso7816_convention_t;
108 
109 typedef enum {
110     INVCTIVE,
111     ACTIVATEING,
112     PSS_TRF,
113     PSS_RECV,
114     ACTIVATE,
115 } iso7816_card_sta_t;
116 
117 /**
118   \brief       Initialize ISO7816 master interface
119   \param[in]   idx         Master index
120   \param[in]   cb_event    Pointer to \ref iso7816_event_cb_t
121   \param[in]   cb_arg      Event callback arg
122   \return      0 for success, negative for error code
123 */
124 int32_t csi_iso7816_master_init(int idx, iso7816_event_cb_t cb_event, void *cb_arg);
125 
126 /**
127   \brief       Uninit ISO7816 master interface
128   \param[in]   idx    Master index
129   \return      0 for success, negative for error code
130 */
131 int32_t csi_iso7816_master_uninit(int idx);
132 
133 /**
134   \brief       Config ISO7816 master attributes
135   \param[in]   idx       Master index
136   \param[in]   config    master config \ref iso7816_config_t
137   \return      0 for success, negative for error code
138 */
139 int32_t csi_iso7816_master_config(int idx, iso7816_config_t *config);
140 
141 /**
142   \brief       Receiving data from ISO7816 master receiver, used polling mode
143   \param[in]   idx         Master index
144   \param[in]   buf         Pointer to buffer for data to receive from i2s receiver
145   \param[in]   len         Size of receiver data
146   \param[in]   time_out    Receive time out value
147   \return      0 for success, negative for error code
148 */
149 int32_t csi_iso7816_master_receive(int idx, uint8_t *buf, uint32_t len, uint32_t time_out);
150 
151 /**
152   \brief       Receiving data from ISO7816 master receiver, used interrupt mode
153   \param[in]   idx    Master index
154   \param[in]   buf    Pointer to buffer for data to receive from i2s receiver
155   \param[in]   len    Size of receiver data
156   \return      0 for success, negative for error code
157 */
158 int32_t csi_iso7816_master_receive_it(int idx, uint8_t *buf, uint32_t len);
159 
160 /**
161   \brief       Sending data to ISO7816 master transmitter, used polling mode
162   \param[in]   idx         Master index
163   \param[in]   buf         Pointer to buffer for data to send
164   \param[in]   len         Size of tranmitter data
165   \param[in]   time_out    Send time out value
166   \return      0 for success, negative for error code
167 */
168 int32_t csi_iso7816_master_send(int idx, uint8_t *buf, uint32_t len, uint32_t time_out);
169 
170 /**
171   \brief       Sending data to ISO7816 master transmitter, used interrupt mode
172   \param[in]   idx    Master index
173   \param[in]   buf    Pointer to buffer for data to send
174   \param[in]   len    Size of tranmitter data
175   \return      0 for success, negative for error code
176 */
177 int32_t csi_iso7816_master_send_it(int idx, uint8_t *buf, uint32_t len);
178 
179 /**
180   \brief       ISO7816 master performs the activation smart card process, this process
181                is non-blocking,should monitor callback event or read card status to check card is activate
182   \param[in]   idx    Master index
183   \return      0 for success, negative for error code
184 */
185 int32_t csi_iso7816_master_card_activate(int idx);
186 
187 /**
188   \brief       ISO7816 master performs the deactivation smart card process, this process
189                is non-blocking,should monitor callback event or read card status to check card is activate
190   \param[in]   idx    Master index
191   \return      0 for success, negative for error code
192 */
193 int32_t csi_iso7816_master_card_deactivate(int idx);
194 
195 /**
196   \brief       The smard card session status
197   \param[in]   idx    Master index
198   \return      smart card status.
199 */
200 iso7816_card_sta_t csi_iso7816_master_card_status(int idx);
201 
202 /**
203   \brief       ISO7816 master performs the warm reset smart card process
204   \param[in]   idx    Master index
205   \return      0 for success, negative for error code
206 */
207 int32_t csi_iso7816_master_card_warm_reset(int idx);
208 
209 /**
210   \brief       ISO7816 master performs clock stop
211   \param[in]   idx    Master index
212   \param[in]   en     The clk last state when power down
213   \return      0 for success, negative for error code
214 */
215 int32_t csi_iso7816_master_card_clk_stop_enable(int idx, int en);
216 
217 /**
218   \brief       ISO7816 master performs pwoer down
219   \param[in]   idx    Master index
220   \return      0 for success, negative for error code
221 */
222 int32_t csi_iso7816_master_power_down(int idx);
223 
224 /**
225   \brief       Get atr analytical results
226   \param[in]   idx     Master index
227   \param[out]  info    The result of atr information
228   \return      0 for success, negative for error code
229 */
230 int32_t csi_iso7816_master_atr_info(int idx, iso7816_atr_info_t *info);
231 
232 /**
233   \brief       Initialize ISO7816 slave interface
234   \param[in]   idx       Slave index
235   \param[in]   cb        Pointer to \ref iso7816_event_cb_t
236   \param[in]   cb_arg    Event callback arg
237   \return      0 for success, negative for error code
238 */
239 int32_t csi_iso7816_slave_init(int idx, iso7816_event_cb_t cb, void *cb_arg);
240 
241 /**
242   \brief       Uninit ISO7816 slave interface
243   \param[in]   idx    Slave index
244   \return      0 for success, negative for error code
245 */
246 int32_t csi_iso7816_slave_uninit(int idx);
247 
248 /**
249   \brief       Enable ISO7816 slave interface
250   \param[in]   idx    Slave index
251   \param[in]   en     Slave enable
252   \return      0 for success, negative for error code
253 */
254 int32_t csi_iso7816_slave_enable(int idx, int en);
255 
256 /**
257   \brief       Enable ISO7816 slave receive parity
258   \param[in]   idx    Slave index
259   \param[in]   en     Enable receive parity
260   \return      0 for success, negative for error code
261 */
262 int32_t csi_iso7816_slave_receive_parity_enable(int idx, int en);
263 
264 /**
265   \brief       Set ISO7816 slave receive parity attributes
266   \param[in]   idx    Slave index
267   \param[in]   type    Set receiver parity type
268   \return      0 for success, negative for error code
269 */
270 int32_t csi_iso7816_slave_set_receive_parity(int idx, iso7816_parity_type_t type);
271 
272 /**
273   \brief       Enable ISO7816 slave send parity
274   \param[in]   idx    Slave index
275   \param[in]   en     Enable send parity
276   \return      0 for success, negative for error code
277 */
278 int32_t csi_iso7816_slave_send_parity_enable(int idx, int en);
279 
280 /**
281   \brief       Set ISO7816 slave send parity attributes
282   \param[in]   idx     Slave index
283   \param[in]   type    Set send parity attributes
284   \return      0 for success, negative for error code
285 */
286 int32_t csi_iso7816_slave_set_send_parity(int idx, iso7816_parity_type_t type);
287 
288 /**
289   \brief       Set the number of ISO7816 slave receive retry
290   \param[in]   idx    Slave index
291   \param[in]   val    Set the number retry
292   \return      0 for success, negative for error code
293 */
294 int32_t csi_iso7816_slave_set_receive_retry(int idx, uint8_t val);
295 
296 /**
297   \brief       Set the number of ISO7816 send send retry
298   \param[in]   idx    Slave index
299   \param[in]   val    Set the number retry
300   \return      0 for success, negative for error code
301 */
302 int32_t csi_iso7816_slave_set_send_retry(int idx, uint8_t val);
303 
304 /**
305   \brief       Set the ISO7816 slave GT
306   \param[in]   idx    Slave index
307   \param[in]   val    Set the slave GT
308   \return      0 for success, negative for error code
309 */
310 int32_t csi_iso7816_slave_set_gt(int idx, uint8_t val);
311 
312 /**
313   \brief       Set the ISO7816 slave WT
314   \param[in]   idx    Slave index
315   \param[in]   val    Set the slave WT
316   \return      0 for success, negative for error code
317 */
318 int32_t csi_iso7816_slave_set_wt(int idx, uint16_t val);
319 
320 /**
321   \brief       Set the ISO7816 slave baud, baud = F/D
322   \param[in]   idx    Slave index
323   \param[in]   val    Set the slave baud
324   \return      0 for success, negative for error code
325 */
326 int32_t csi_iso7816_slave_set_baud(int idx, uint16_t val);
327 
328 /**
329   \brief       Set the ISO7816 slave convention
330   \param[in]   idx           Slave index
331   \param[in]   convention    Set the slave convention \ref iso7816_convention_t
332   \return      0 for success, negative for error code
333 */
334 int32_t csi_iso7816_slave_set_convention(int idx, iso7816_convention_t convention);
335 
336 /**
337   \brief       Set the ISO7816 slave art response time, val range is 400~40000
338   \param[in]   idx    Slave index
339   \param[in]   val    Set the slave art response time
340   \return      0 for success, negative for error code
341 */
342 int32_t csi_iso7816_slave_set_atr_ack_time(int idx, int val);
343 
344 /**
345   \brief       Set the ISO7816 slave send atr data
346   \param[in]   idx    Slave index
347   \param[in]   buf    Pointer to buffer for data to send
348   \param[in]   len    Size of tranmitter data
349   \return      0 for success, negative for error code
350 */
351 int32_t csi_iso7816_slave_send_atr(int idx, uint8_t *buf, int len);
352 
353 /**
354   \brief       Receiving data from ISO7816 slave receiver, used polling mode
355   \param[in]   idx    Master index
356   \param[in]   buf    Pointer to buffer for data to receive from i2s receiver
357   \param[in]   len    Size of receiver data
358   \param[in]   timer_out  receive time out value
359   \return      0 for success, negative for error code
360 */
361 int32_t csi_iso7816_slave_receive(int idx, uint8_t *buf, uint32_t len, uint32_t time_out);
362 
363 /**
364   \brief       Flushed the ISO7816 slave receive fifo
365   \param[in]   idx    Master index
366   \return      0 for success, negative for error code
367 */
368 int32_t csi_iso7816_slave_flushed_receive_fifo(int idx);
369 
370 /**
371   \brief       Receiving data from ISO7816 slave receiver, used interrupt mode
372   \param[in]   idx    Master index
373   \param[in]   buf    Pointer to buffer for data to receive from i2s receiver
374   \param[in]   len    Size of receiver data
375   \return      0 for success, negative for error code
376 */
377 int32_t csi_iso7816_slave_receive_it(int idx, uint8_t *buf, uint32_t len);
378 
379 /**
380   \brief       Sending data to ISO7816 slave transmitter, used polling mode
381   \param[in]   idx          Slave index
382   \param[in]   buf          Pointer to buffer for data to send
383   \param[in]   len          Size of tranmitter data
384   \param[in]   timer_out    Send time out value
385   \return      0 for success, negative for error code
386 */
387 int32_t csi_iso7816_slave_send(int idx, uint8_t *buf, uint32_t len, uint32_t time_out);
388 
389 /**
390   \brief       Flushed the ISO7816 slave send fifo.
391   \param[in]   idx    Master index
392   \return      0 for success, negative for error code
393 */
394 int32_t csi_iso7816_slave_flushed_send_fifo(int idx);
395 
396 /**
397   \brief       Sending data to ISO7816 slave transmitter, used interrupt mode
398   \param[in]   idx    Slave index
399   \param[in]   buf    Pointer to buffer for data to send
400   \param[in]   len    Size of tranmitter data
401   \return      0 for success, negative for error code
402 */
403 int32_t csi_iso7816_slave_send_it(int idx, uint8_t *buf, uint32_t len);
404 
405 #ifdef __cplusplus
406 }
407 #endif
408 
409 #endif /* _DRV_ISO7816_H_ */
410