blob: 5f0ee7cac45d7d0901df1b0a10e922601ee1096a [file] [log] [blame]
Harald Welte9d3e3822015-11-09 00:50:54 +01001/* ISO7816-3 state machine for the card side */
2/* (C) 2010-2015 by Harald Welte <hwelte@hmw-consulting.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
Harald Welte7abdb512016-03-03 17:48:32 +010020#define TRACE_LEVEL 6
21
Harald Welte4c473da2015-11-14 13:31:11 +010022#include <assert.h>
Harald Welte9d3e3822015-11-09 00:50:54 +010023#include <errno.h>
24#include <string.h>
25#include <stdint.h>
26#include <sys/types.h>
27
28#include "utils.h"
29#include "trace.h"
30#include "iso7816_fidi.h"
31#include "tc_etu.h"
32#include "card_emu.h"
33#include "req_ctx.h"
34#include "cardemu_prot.h"
Harald Welte54cb3d02016-02-29 14:12:40 +010035#include "linuxlist.h"
Harald Welte9d3e3822015-11-09 00:50:54 +010036
37
38#define NUM_SLOTS 2
39
40#define ISO7816_3_INIT_WTIME 9600
41#define ISO7816_3_DEFAULT_WI 10
42#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
43
44#define ISO7816_3_PB_NULL 0x60
45
46enum iso7816_3_card_state {
47 ISO_S_WAIT_POWER, /* waiting for power being applied */
48 ISO_S_WAIT_CLK, /* waiting for clock being applied */
49 ISO_S_WAIT_RST, /* waiting for reset being released */
50 ISO_S_WAIT_ATR, /* waiting for start of ATR */
51 ISO_S_IN_ATR, /* transmitting ATR to reader */
52 ISO_S_IN_PTS, /* transmitting ATR to reader */
53 ISO_S_WAIT_TPDU, /* waiting for data from reader */
54 ISO_S_IN_TPDU, /* inside a TPDU */
55};
56
57/* detailed sub-states of ISO_S_IN_PTS */
58enum pts_state {
59 PTS_S_WAIT_REQ_PTSS,
60 PTS_S_WAIT_REQ_PTS0,
61 PTS_S_WAIT_REQ_PTS1,
62 PTS_S_WAIT_REQ_PTS2,
63 PTS_S_WAIT_REQ_PTS3,
64 PTS_S_WAIT_REQ_PCK,
65 PTS_S_WAIT_RESP_PTSS = PTS_S_WAIT_REQ_PTSS | 0x10,
66 PTS_S_WAIT_RESP_PTS0 = PTS_S_WAIT_REQ_PTS0 | 0x10,
67 PTS_S_WAIT_RESP_PTS1 = PTS_S_WAIT_REQ_PTS1 | 0x10,
68 PTS_S_WAIT_RESP_PTS2 = PTS_S_WAIT_REQ_PTS2 | 0x10,
69 PTS_S_WAIT_RESP_PTS3 = PTS_S_WAIT_REQ_PTS3 | 0x10,
70 PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
71};
72
73#define _PTSS 0
74#define _PTS0 1
75#define _PTS1 2
76#define _PTS2 3
77#define _PTS3 4
78#define _PCK 5
79
Harald Welte16cf4082015-11-11 19:02:48 +010080/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +010081enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +010082 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
83 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
84 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
85 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
86 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +010087 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
88 TPDU_S_WAIT_RX, /* waiitng for more data from reader */
89 TPDU_S_WAIT_TX, /* waiting for more data to reader */
90};
91
92#define _CLA 0
93#define _INS 1
94#define _P1 2
95#define _P2 3
96#define _P3 4
97
98struct card_handle {
99 enum iso7816_3_card_state state;
100
101 /* signal levels */
102 uint8_t vcc_active; /* 1 = on, 0 = off */
103 uint8_t in_reset; /* 1 = RST low, 0 = RST high */
104 uint8_t clocked; /* 1 = active, 0 = inactive */
105
Harald Welte16cf4082015-11-11 19:02:48 +0100106 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100107 uint8_t fi;
108 uint8_t di;
109 uint8_t wi;
110
111 uint8_t tc_chan; /* TC channel number */
112 uint8_t uart_chan; /* UART channel */
113
114 uint32_t waiting_time; /* in clocks */
115
116 /* ATR state machine */
117 struct {
118 uint8_t idx;
119 uint8_t len;
120 //uint8_t hist_len;
121 //uint8_t last_td;
122 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
123 } atr;
124
125 /* PPS / PTS support */
126 struct {
127 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100128 uint8_t req[6]; /* request bytes */
129 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100130 } pts;
131
132 /* TPDU */
133 struct {
134 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100135 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100136 } tpdu;
137
Harald Welte16cf4082015-11-11 19:02:48 +0100138 struct req_ctx *uart_rx_ctx; /* UART RX -> USB TX */
139 struct req_ctx *uart_tx_ctx; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100140
Harald Welte54cb3d02016-02-29 14:12:40 +0100141 struct llist_head usb_tx_queue;
142 struct llist_head uart_tx_queue;
143
Harald Welte9d3e3822015-11-09 00:50:54 +0100144 struct {
145 uint32_t tx_bytes;
146 uint32_t rx_bytes;
147 uint32_t pps;
148 } stats;
149};
150
Harald Welte54cb3d02016-02-29 14:12:40 +0100151struct llist_head *card_emu_get_usb_tx_queue(struct card_handle *ch)
152{
153 return &ch->usb_tx_queue;
154}
155
156struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
157{
158 return &ch->uart_tx_queue;
159}
160
Harald Welte2935b3c2015-11-14 20:00:14 +0100161static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100162static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100163
Harald Welteb5288e82015-11-14 21:15:52 +0100164static void flush_rx_buffer(struct card_handle *ch)
165{
166 struct req_ctx *rctx;
167 struct cardemu_usb_msg_rx_data *rd;
168
169 rctx = ch->uart_rx_ctx;
170 if (!rctx)
171 return;
172
Harald Welte54cb3d02016-02-29 14:12:40 +0100173 ch->uart_rx_ctx = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100174
175 /* store length of data payload fild in header */
Harald Weltefcdd6602016-03-02 10:33:58 +0100176 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
Harald Welted295b922016-03-18 21:01:36 +0100177 rd->data_len = rctx->idx;
178 rd->hdr.msg_len = sizeof(*rd) + rd->data_len;
Harald Welte54cb3d02016-02-29 14:12:40 +0100179
180 llist_add_tail(&rctx->list, &ch->usb_tx_queue);
Harald Welteb5288e82015-11-14 21:15:52 +0100181 req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
Harald Welteb5288e82015-11-14 21:15:52 +0100182
183 /* FIXME: call into USB code to see if this buffer can
184 * be transmitted now */
185}
186
Harald Welte4ba66d02016-02-25 19:38:56 +0100187/* convert a non-contiguous PTS request/responsei into a contiguous
188 * buffer, returning the number of bytes used in the buffer */
189static int serialize_pts(uint8_t *out, const uint8_t *in)
190{
191 int i = 0;
192
193 out[i++] = in[_PTSS];
194 out[i++] = in[_PTS0];
195 if (in[_PTS0] & (1 << 4))
196 out[i++] = in[_PTS1];
197 if (in[_PTS0] & (1 << 5))
198 out[i++] = in[_PTS2];
199 if (in[_PTS0] & (1 << 6))
200 out[i++] = in[_PTS3];
201 out[i++] = in[_PCK];
202
203 return i;
204}
205
Harald Welte17db2f12016-02-26 09:48:57 +0100206static uint8_t csum_pts(const uint8_t *in)
207{
208 uint8_t out[6];
209 int len = serialize_pts(out, in);
210 uint8_t csum = 0;
211 int i;
212
213 /* we don't include the PCK byte in the checksumming process */
214 len -= 1;
215
216 for (i = 0; i < len; i++)
217 csum = csum ^ out[i];
218
219 return csum;
220}
221
Harald Welte4ba66d02016-02-25 19:38:56 +0100222static void flush_pts(struct card_handle *ch)
223{
224 struct req_ctx *rctx;
225 struct cardemu_usb_msg_pts_info *ptsi;
226
227 rctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
228 if (!rctx)
229 return;
230
231 ptsi = (struct cardemu_usb_msg_pts_info *) rctx->data;
232 ptsi->hdr.msg_type = CEMU_USB_MSGT_DO_PTS;
Harald Welted295b922016-03-18 21:01:36 +0100233 ptsi->hdr.msg_len = sizeof(*ptsi);
234 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100235 serialize_pts(ptsi->resp, ch->pts.resp);
236
Harald Welte54cb3d02016-02-29 14:12:40 +0100237 llist_add_tail(&rctx->list, &ch->usb_tx_queue);
Harald Welte4ba66d02016-02-25 19:38:56 +0100238 req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
239
240 /* FIXME: call into USB code to see if this buffer can
241 * be transmitted now */
242}
243
Harald Welte8c496362016-02-27 16:24:09 +0100244static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100245{
246 int rc;
247
248 rc = compute_fidi_ratio(ch->fi, ch->di);
249 if (rc > 0 && rc < 0x400) {
Harald Weltea929f212016-03-20 13:36:42 +0100250 TRACE_INFO("computed Fi(%u) Di(%u) ratio: %d\r\n",
Harald Welte9d3e3822015-11-09 00:50:54 +0100251 ch->fi, ch->di, rc);
252 /* make sure UART uses new F/D ratio */
253 card_emu_uart_update_fidi(ch->uart_chan, rc);
254 /* notify ETU timer about this */
255 tc_etu_set_etu(ch->tc_chan, rc);
256 } else
Harald Weltea929f212016-03-20 13:36:42 +0100257 TRACE_INFO("computed FiDi ration %d unsupported\r\n", rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100258}
259
260/* Update the ISO 7816-3 TPDU receiver state */
261static void card_set_state(struct card_handle *ch,
262 enum iso7816_3_card_state new_state)
263{
264 switch (new_state) {
265 case ISO_S_WAIT_POWER:
266 case ISO_S_WAIT_CLK:
267 case ISO_S_WAIT_RST:
268 /* disable Rx and Tx of UART */
269 card_emu_uart_enable(ch->uart_chan, 0);
270 break;
271 case ISO_S_WAIT_ATR:
Harald Weltee7194ab2015-11-14 21:03:25 +0100272 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100273 /* Reset to initial Fi / Di ratio */
274 ch->fi = 1;
275 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100276 emu_update_fidi(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100277 /* initialize todefault WI, this will be overwritten if we
278 * receive TC2, and it will be programmed into hardware after
279 * ATR is finished */
280 ch->wi = ISO7816_3_DEFAULT_WI;
281 /* update waiting time to initial waiting time */
282 ch->waiting_time = ISO7816_3_INIT_WTIME;
283 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
284 /* Set ATR sub-state to initial state */
285 ch->atr.idx = 0;
286 //set_atr_state(ch, ATR_S_WAIT_TS);
287 /* Notice that we are just coming out of reset */
288 //ch->sh.flags |= SIMTRACE_FLAG_ATR;
289 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
290 break;
291 break;
292 case ISO_S_WAIT_TPDU:
293 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100294 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100295 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
296 break;
297 case ISO_S_IN_ATR:
298 case ISO_S_IN_PTS:
299 case ISO_S_IN_TPDU:
300 /* do nothing */
301 break;
302 }
303
304 if (ch->state == new_state)
305 return;
306
Harald Welte22bf67f2016-02-29 10:18:48 +0100307 TRACE_DEBUG("7816 card state %u -> %u\r\n", ch->state, new_state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100308 ch->state = new_state;
309}
310
311
312/**********************************************************************
313 * PTS / PPS handling
314 **********************************************************************/
315
316/* Update the ATR sub-state */
317static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
318{
Harald Welte22bf67f2016-02-29 10:18:48 +0100319 TRACE_DEBUG("7816 PTS state %u -> %u\r\n", ch->pts.state, new_ptss);
Harald Welte9d3e3822015-11-09 00:50:54 +0100320 ch->pts.state = new_ptss;
321}
322
323/* Determine the next PTS state */
324static enum pts_state next_pts_state(struct card_handle *ch)
325{
326 uint8_t is_resp = ch->pts.state & 0x10;
327 uint8_t sstate = ch->pts.state & 0x0f;
328 uint8_t *pts_ptr;
329
330 if (!is_resp)
331 pts_ptr = ch->pts.req;
332 else
333 pts_ptr = ch->pts.resp;
334
335 switch (sstate) {
336 case PTS_S_WAIT_REQ_PTSS:
337 goto from_ptss;
338 case PTS_S_WAIT_REQ_PTS0:
339 goto from_pts0;
340 case PTS_S_WAIT_REQ_PTS1:
341 goto from_pts1;
342 case PTS_S_WAIT_REQ_PTS2:
343 goto from_pts2;
344 case PTS_S_WAIT_REQ_PTS3:
345 goto from_pts3;
346 }
347
348 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
349 return PTS_S_WAIT_RESP_PTSS;
350
351from_ptss:
352 return PTS_S_WAIT_REQ_PTS0 | is_resp;
353from_pts0:
354 if (pts_ptr[_PTS0] & (1 << 4))
355 return PTS_S_WAIT_REQ_PTS1 | is_resp;
356from_pts1:
357 if (pts_ptr[_PTS0] & (1 << 5))
358 return PTS_S_WAIT_REQ_PTS2 | is_resp;
359from_pts2:
360 if (pts_ptr[_PTS0] & (1 << 6))
361 return PTS_S_WAIT_REQ_PTS3 | is_resp;
362from_pts3:
363 return PTS_S_WAIT_REQ_PCK | is_resp;
364}
365
366
Harald Welteccb8a222016-03-20 13:37:11 +0100367static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100368process_byte_pts(struct card_handle *ch, uint8_t byte)
369{
370 switch (ch->pts.state) {
371 case PTS_S_WAIT_REQ_PTSS:
372 ch->pts.req[_PTSS] = byte;
373 break;
374 case PTS_S_WAIT_REQ_PTS0:
375 ch->pts.req[_PTS0] = byte;
376 break;
377 case PTS_S_WAIT_REQ_PTS1:
378 ch->pts.req[_PTS1] = byte;
379 break;
380 case PTS_S_WAIT_REQ_PTS2:
381 ch->pts.req[_PTS2] = byte;
382 break;
383 case PTS_S_WAIT_REQ_PTS3:
384 ch->pts.req[_PTS3] = byte;
385 break;
386 case PTS_S_WAIT_REQ_PCK:
387 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100388 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltea929f212016-03-20 13:36:42 +0100389 TRACE_ERROR("Error in PTS Checksum!\r\n");
Harald Welte17db2f12016-02-26 09:48:57 +0100390 /* Wait for the next TPDU */
391 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
392 return ISO_S_WAIT_TPDU;
393 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100394 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100395 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
396 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100397 default:
Harald Weltea929f212016-03-20 13:36:42 +0100398 TRACE_ERROR("process_byte_pts() in invalid state %u\r\n",
Harald Welte4c473da2015-11-14 13:31:11 +0100399 ch->pts.state);
400 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100401 }
402 /* calculate the next state and set it */
403 set_pts_state(ch, next_pts_state(ch));
404
Harald Welte4ba66d02016-02-25 19:38:56 +0100405 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
406 flush_pts(ch);
407 /* activate UART TX to transmit PTS response */
408 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welteccb8a222016-03-20 13:37:11 +0100409 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100410 }
411
Harald Welte9d3e3822015-11-09 00:50:54 +0100412 return ISO_S_IN_PTS;
413}
414
415/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100416static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100417{
Harald Welte855ba9e2016-02-24 21:00:46 +0100418 uint8_t byte;
419
420 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100421 switch (ch->pts.state) {
422 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100423 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100424 break;
425 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100426 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100427 break;
428 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100429 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100430 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100431 ch->fi = byte >> 4;
432 ch->di = byte & 0xf;
Harald Welte22bf67f2016-02-29 10:18:48 +0100433 TRACE_DEBUG("found Fi=%u Di=%u\r\n", ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100434 break;
435 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100436 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100437 break;
438 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100439 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100440 break;
441 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100442 byte = ch->pts.resp[_PCK];
Harald Welte9d3e3822015-11-09 00:50:54 +0100443 /* update baud rate generator with Fi/Di */
Harald Welte8c496362016-02-27 16:24:09 +0100444 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100445 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100446 default:
Harald Weltea929f212016-03-20 13:36:42 +0100447 TRACE_ERROR("get_byte_pts() in invalid state %u\r\n",
Harald Welted79dc4f2015-11-14 13:32:21 +0100448 ch->pts.state);
Harald Welte855ba9e2016-02-24 21:00:46 +0100449 return 0;
450 }
451
452 /* 2: Transmit the byte */
453 card_emu_uart_tx(ch->uart_chan, byte);
454
455 /* 3: Update the state */
456
457 switch (ch->pts.state) {
458 case PTS_S_WAIT_RESP_PCK:
459 /* Wait for the next TPDU */
460 card_set_state(ch, ISO_S_WAIT_TPDU);
461 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
462 break;
463 default:
464 /* calculate the next state and set it */
465 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100466 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100467 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100468
Harald Welte855ba9e2016-02-24 21:00:46 +0100469 /* return number of bytes transmitted */
470 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100471}
472
473
474/**********************************************************************
475 * TPDU handling
476 **********************************************************************/
477
Harald Welte4d804672015-11-14 23:02:38 +0100478
479/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
480static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
481{
482 if (reader_to_card) {
483 return p3;
484 } else {
485 if (p3 == 0)
486 return 256;
487 else
488 return p3;
489 }
490}
491
Harald Welte9d3e3822015-11-09 00:50:54 +0100492/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100493static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100494{
495 struct req_ctx *rctx;
496 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100497 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100498
499 /* ensure we have a buffer */
500 if (!ch->uart_rx_ctx) {
Harald Welte4d804672015-11-14 23:02:38 +0100501 rctx = ch->uart_rx_ctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
502 if (!ch->uart_rx_ctx) {
Harald Welte40901a02016-03-03 10:42:45 +0100503 TRACE_ERROR("Received UART byte but ENOMEM\r\n");
Harald Welte9d3e3822015-11-09 00:50:54 +0100504 return;
Harald Welte4d804672015-11-14 23:02:38 +0100505 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100506 rd = (struct cardemu_usb_msg_rx_data *) ch->uart_rx_ctx->data;
507 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
508 rctx->tot_len = sizeof(*rd);
509 rctx->idx = 0;
510 } else
511 rctx = ch->uart_rx_ctx;
512
513 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
514
515 rd->data[rctx->idx++] = byte;
516 rctx->tot_len++;
517
518 /* check if the buffer is full. If so, send it */
Harald Welte4d804672015-11-14 23:02:38 +0100519 if (rctx->tot_len >= sizeof(*rd) + num_data_bytes) {
520 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100521 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100522 /* We need to transmit the SW now, */
523 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte4d804672015-11-14 23:02:38 +0100524 } else if (rctx->tot_len >= rctx->size)
525 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100526}
527
528static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
529{
Harald Welte05b41c62015-11-14 20:58:48 +0100530 if (ch->tpdu.state == new_ts)
531 return;
532
Harald Welte22bf67f2016-02-29 10:18:48 +0100533 TRACE_DEBUG("7816 TPDU state %u -> %u\r\n", ch->tpdu.state, new_ts);
Harald Welte05b41c62015-11-14 20:58:48 +0100534
Harald Welte9d3e3822015-11-09 00:50:54 +0100535 switch (new_ts) {
536 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100537 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100538 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
539 break;
540 case TPDU_S_WAIT_PB:
541 /* we just completed the TPDU header from reader to card
542 * and now need to disable the receiver, enable the
543 * transmitter and transmit the procedure byte */
544 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
545 break;
Harald Weltead434402016-03-02 11:18:29 +0100546 default:
547 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100548 }
Harald Welte05b41c62015-11-14 20:58:48 +0100549
Harald Welte9d3e3822015-11-09 00:50:54 +0100550 ch->tpdu.state = new_ts;
551}
552
553static enum tpdu_state next_tpdu_state(struct card_handle *ch)
554{
555 switch (ch->tpdu.state) {
556 case TPDU_S_WAIT_CLA:
557 return TPDU_S_WAIT_INS;
558 case TPDU_S_WAIT_INS:
559 return TPDU_S_WAIT_P1;
560 case TPDU_S_WAIT_P1:
561 return TPDU_S_WAIT_P2;
562 case TPDU_S_WAIT_P2:
563 return TPDU_S_WAIT_P3;
564 case TPDU_S_WAIT_P3:
565 return TPDU_S_WAIT_PB;
566 /* simply stay in Rx or Tx by default */
567 case TPDU_S_WAIT_PB:
568 return TPDU_S_WAIT_PB;
569 case TPDU_S_WAIT_RX:
570 return TPDU_S_WAIT_RX;
571 case TPDU_S_WAIT_TX:
572 return TPDU_S_WAIT_TX;
573 }
Harald Welte4c473da2015-11-14 13:31:11 +0100574 /* we should never reach here */
575 assert(0);
576 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100577}
578
579static void send_tpdu_header(struct card_handle *ch)
580{
581 struct req_ctx *rctx;
582 struct cardemu_usb_msg_rx_data *rd;
583
Harald Weltea929f212016-03-20 13:36:42 +0100584 TRACE_INFO("%s: %02x %02x %02x %02x %02x\r\n", __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100585 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
586 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
587 ch->tpdu.hdr[4]);
588
Harald Welte9d3e3822015-11-09 00:50:54 +0100589 /* if we already/still have a context, send it off */
Harald Weltef1697e22016-03-02 10:28:54 +0100590 if (ch->uart_rx_ctx) {
591 TRACE_DEBUG("have old buffer\r\n");
592 if (ch->uart_rx_ctx->idx) {
593 TRACE_DEBUG("flushing old buffer\r\n");
594 flush_rx_buffer(ch);
595 }
596 } else {
597 TRACE_DEBUG("allocating new buffer\r\n");
598 /* ensure we have a new buffer */
599 ch->uart_rx_ctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
600 if (!ch->uart_rx_ctx) {
601 TRACE_ERROR("%s: ENOMEM\r\n", __func__);
602 return;
603 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100604 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100605 rctx = ch->uart_rx_ctx;
606 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
607
608 /* initializ header */
609 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
610 rd->flags = CEMU_DATA_F_TPDU_HDR;
611 rctx->tot_len = sizeof(*rd) + sizeof(ch->tpdu.hdr);
Harald Welte0ef96d52016-02-25 00:09:17 +0100612 rctx->idx = sizeof(ch->tpdu.hdr);
Harald Welte9d3e3822015-11-09 00:50:54 +0100613
614 /* copy TPDU header to data field */
615 memcpy(rd->data, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100616 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100617
Harald Welteb5288e82015-11-14 21:15:52 +0100618 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100619}
620
621static enum iso7816_3_card_state
622process_byte_tpdu(struct card_handle *ch, uint8_t byte)
623{
624 switch (ch->tpdu.state) {
625 case TPDU_S_WAIT_CLA:
626 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100627 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100628 break;
629 case TPDU_S_WAIT_INS:
630 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100631 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100632 break;
633 case TPDU_S_WAIT_P1:
634 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100635 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100636 break;
637 case TPDU_S_WAIT_P2:
638 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100639 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100640 break;
641 case TPDU_S_WAIT_P3:
642 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100643 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100644 /* FIXME: start timer to transmit further 0x60 */
645 /* send the TPDU header as part of a procedure byte
646 * request to the USB host */
647 send_tpdu_header(ch);
648 break;
649 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100650 add_tpdu_byte(ch, byte);
651 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100652 default:
Harald Weltea929f212016-03-20 13:36:42 +0100653 TRACE_ERROR("process_byte_tpdu() in invalid state %u\r\n",
Harald Welte9d3e3822015-11-09 00:50:54 +0100654 ch->tpdu.state);
655 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100656
657 /* ensure we stay in TPDU ISO state */
658 return ISO_S_IN_TPDU;
659}
660
Harald Welte855ba9e2016-02-24 21:00:46 +0100661/* tx a single byte to be transmitted to the reader */
662static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100663{
664 struct req_ctx *rctx;
665 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100666 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100667
668 /* ensure we are aware of any data that might be pending for
669 * transmit */
670 if (!ch->uart_tx_ctx) {
Harald Welte54cb3d02016-02-29 14:12:40 +0100671 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100672 return 0;
673
Harald Welte54cb3d02016-02-29 14:12:40 +0100674 /* dequeue first at head */
675 ch->uart_tx_ctx = llist_entry(ch->uart_tx_queue.next,
676 struct req_ctx, list);
677 llist_del(&ch->uart_tx_ctx->list);
678 req_ctx_set_state(ch->uart_tx_ctx, RCTX_S_UART_TX_BUSY);
679
Harald Welte9d3e3822015-11-09 00:50:54 +0100680 /* start with index zero */
681 ch->uart_tx_ctx->idx = 0;
682
683 }
684 rctx = ch->uart_tx_ctx;
685 td = (struct cardemu_usb_msg_tx_data *) rctx->data;
686
Harald Welte9d3e3822015-11-09 00:50:54 +0100687 /* take the next pending byte out of the rctx */
Harald Welte855ba9e2016-02-24 21:00:46 +0100688 byte = td->data[rctx->idx++];
689
690 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100691
Harald Weltef16b6182016-02-24 22:18:46 +0100692 /* this must happen _after_ the byte has been transmittd */
693 switch (ch->tpdu.state) {
694 case TPDU_S_WAIT_PB:
695 /* if we just transmitted the procedure byte, we need to decide
696 * if we want to continue to receive or transmit */
697 if (td->flags & CEMU_DATA_F_PB_AND_TX)
698 set_tpdu_state(ch, TPDU_S_WAIT_TX);
699 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
700 set_tpdu_state(ch, TPDU_S_WAIT_RX);
701 break;
Harald Weltead434402016-03-02 11:18:29 +0100702 default:
703 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100704 }
705
Harald Welte9d3e3822015-11-09 00:50:54 +0100706 /* check if the buffer has now been fully transmitted */
Harald Welted295b922016-03-18 21:01:36 +0100707 if ((rctx->idx >= td->data_len) ||
Harald Weltef16b6182016-02-24 22:18:46 +0100708 (td->data + rctx->idx >= rctx->data + rctx->tot_len)) {
Harald Welte52922ff2015-11-14 20:59:56 +0100709 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
710 /* we have just sent the procedure byte and now
711 * need to continue receiving */
712 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100713 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100714 /* we have transmitted all bytes */
715 if (td->flags & CEMU_DATA_F_FINAL) {
716 /* this was the final part of the APDU, go
717 * back to state one*/
718 card_set_state(ch, ISO_S_WAIT_TPDU);
719 } else {
720 /* FIXME: call into USB code to chec if we need
721 * to submit a free buffer to accept
722 * further data on bulk out endpoint */
723 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100724 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100725 req_ctx_set_state(rctx, RCTX_S_FREE);
726 ch->uart_tx_ctx = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100727 }
728
729 return 1;
730}
731
732/**********************************************************************
733 * Public API
734 **********************************************************************/
735
736/* process a single byte received from the reader */
737void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
738{
739 int new_state = -1;
740
741 ch->stats.rx_bytes++;
742
743 switch (ch->state) {
744 case ISO_S_WAIT_POWER:
745 case ISO_S_WAIT_CLK:
746 case ISO_S_WAIT_RST:
747 case ISO_S_WAIT_ATR:
Harald Welte22bf67f2016-02-29 10:18:48 +0100748 TRACE_DEBUG("Received UART char in 7816 state %u\r\n",
Harald Welte4d804672015-11-14 23:02:38 +0100749 ch->state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100750 /* we shouldn't receive any data from the reader yet! */
751 break;
752 case ISO_S_WAIT_TPDU:
753 if (byte == 0xff) {
754 new_state = process_byte_pts(ch, byte);
755 ch->stats.pps++;
756 goto out_silent;
757 }
758 /* fall-through */
759 case ISO_S_IN_TPDU:
760 new_state = process_byte_tpdu(ch, byte);
761 break;
762 case ISO_S_IN_PTS:
763 new_state = process_byte_pts(ch, byte);
764 goto out_silent;
765 }
766
767out_silent:
768 if (new_state != -1)
769 card_set_state(ch, new_state);
770}
771
Harald Welte855ba9e2016-02-24 21:00:46 +0100772/* transmit a single byte to the reader */
773int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100774{
775 int rc = 0;
776
777 switch (ch->state) {
778 case ISO_S_IN_ATR:
779 if (ch->atr.idx < ch->atr.len) {
Harald Welte855ba9e2016-02-24 21:00:46 +0100780 uint8_t byte;
781 byte = ch->atr.atr[ch->atr.idx++];
Harald Welte9d3e3822015-11-09 00:50:54 +0100782 rc = 1;
Harald Welte855ba9e2016-02-24 21:00:46 +0100783
784 card_emu_uart_tx(ch->uart_chan, byte);
785
Harald Welte9d3e3822015-11-09 00:50:54 +0100786 /* detect end of ATR */
787 if (ch->atr.idx >= ch->atr.len)
788 card_set_state(ch, ISO_S_WAIT_TPDU);
789 }
790 break;
791 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100792 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100793 break;
794 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +0100795 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100796 break;
Harald Weltead434402016-03-02 11:18:29 +0100797 default:
798 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100799 }
800
801 if (rc)
802 ch->stats.tx_bytes++;
803
Harald Welte4d804672015-11-14 23:02:38 +0100804 /* if we return 0 here, the UART needs to disable transmit-ready
805 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +0100806 return rc;
807}
808
Harald Welteacae4122016-03-02 10:27:58 +0100809void card_emu_have_new_uart_tx(struct card_handle *ch)
810{
811 switch (ch->state) {
812 case ISO_S_IN_TPDU:
813 switch (ch->tpdu.state) {
814 case TPDU_S_WAIT_TX:
815 case TPDU_S_WAIT_PB:
816 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
817 break;
818 default:
819 break;
820 }
821 default:
822 break;
823 }
824}
825
Harald Welteff160652016-03-19 21:59:06 +0100826void card_emu_report_status(struct card_handle *ch)
827{
828 struct req_ctx *rctx;
829 struct cardemu_usb_msg_status *sts;
830
831 rctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
832 if (!rctx)
833 return;
834
835 rctx->tot_len = sizeof(*sts);
836 sts = (struct cardemu_usb_msg_status *)rctx->data;
837 sts->hdr.msg_type = CEMU_USB_MSGT_DO_STATUS;
838 sts->hdr.msg_len = sizeof(*sts);
839 sts->flags = 0;
840 if (ch->vcc_active)
841 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
842 if (ch->clocked)
843 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
844 if (ch->in_reset)
845 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
846 /* FIXME: voltage + card insert */
847 sts->fi = ch->fi;
848 sts->di = ch->di;
849 sts->wi = ch->wi;
850 sts->waiting_time = ch->waiting_time;
851
852 llist_add_tail(&rctx->list, &ch->usb_tx_queue);
853 req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
854}
855
Harald Welte9d3e3822015-11-09 00:50:54 +0100856/* hardware driver informs us that a card I/O signal has changed */
857void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
858{
859 switch (io) {
860 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +0100861 if (active == 0 && ch->vcc_active == 1) {
Harald Weltea929f212016-03-20 13:36:42 +0100862 TRACE_INFO("VCC deactivated\r\n");
Harald Welte22cdf2a2016-02-24 22:18:11 +0100863 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100864 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +0100865 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltea929f212016-03-20 13:36:42 +0100866 TRACE_INFO("VCC activated\r\n");
Harald Welte9d3e3822015-11-09 00:50:54 +0100867 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +0100868 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100869 ch->vcc_active = active;
870 break;
871 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +0100872 if (active == 1 && ch->clocked == 0) {
Harald Weltea929f212016-03-20 13:36:42 +0100873 TRACE_INFO("CLK activated\r\n");
Harald Welte47ee2832016-02-29 10:09:46 +0100874 if (ch->state == ISO_S_WAIT_CLK)
875 card_set_state(ch, ISO_S_WAIT_RST);
876 } else if (active == 0 && ch->clocked == 1) {
Harald Weltea929f212016-03-20 13:36:42 +0100877 TRACE_INFO("CLK deactivated\r\n");
Harald Welte47ee2832016-02-29 10:09:46 +0100878 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100879 ch->clocked = active;
880 break;
881 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +0100882 if (active == 0 && ch->in_reset) {
Harald Welte40901a02016-03-03 10:42:45 +0100883 TRACE_INFO("RST released\r\n");
Harald Welte47ee2832016-02-29 10:09:46 +0100884 if (ch->vcc_active && ch->clocked) {
885 /* enable the TC/ETU counter once reset has been released */
886 tc_etu_enable(ch->tc_chan);
887 card_set_state(ch, ISO_S_WAIT_ATR);
888 /* FIXME: wait 400 to 40k clock cycles before sending ATR */
889 card_set_state(ch, ISO_S_IN_ATR);
890 }
891 } else if (active && !ch->in_reset) {
Harald Welte40901a02016-03-03 10:42:45 +0100892 TRACE_INFO("RST asserted\r\n");
Harald Welte22cdf2a2016-02-24 22:18:11 +0100893 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100894 }
895 ch->in_reset = active;
896 break;
897 }
898}
899
900/* User sets a new ATR to be returned during next card reset */
901int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
902{
903 if (len > sizeof(ch->atr.atr))
904 return -1;
905
906 memcpy(ch->atr.atr, atr, len);
907 ch->atr.len = len;
908 ch->atr.idx = 0;
909
910 /* FIXME: race condition with trasmitting ATR to reader? */
911
912 return 0;
913}
914
915/* hardware driver informs us that one (more) ETU has expired */
916void tc_etu_wtime_half_expired(void *handle)
917{
918 struct card_handle *ch = handle;
919 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +0100920 switch (ch->state) {
921 case ISO_S_IN_TPDU:
922 switch (ch->tpdu.state) {
923 case TPDU_S_WAIT_PB:
924 case TPDU_S_WAIT_TX:
925 putchar('N');
926 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
927 break;
928 default:
929 break;
930 }
931 break;
932 default:
933 break;
934 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100935}
936
937/* hardware driver informs us that one (more) ETU has expired */
938void tc_etu_wtime_expired(void *handle)
939{
Harald Welte40901a02016-03-03 10:42:45 +0100940 TRACE_ERROR("wtime_exp\r\n");
Harald Welte9d3e3822015-11-09 00:50:54 +0100941}
942
943/* shortest ATR found in smartcard_list.txt */
944static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
945
946static struct card_handle card_handles[NUM_SLOTS];
947
948struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan)
949{
950 struct card_handle *ch;
951
952 if (slot_num >= ARRAY_SIZE(card_handles))
953 return NULL;
954
955 ch = &card_handles[slot_num];
956
957 memset(ch, 0, sizeof(*ch));
958
Harald Welte54cb3d02016-02-29 14:12:40 +0100959 INIT_LLIST_HEAD(&ch->usb_tx_queue);
960 INIT_LLIST_HEAD(&ch->uart_tx_queue);
961
Harald Welte9d3e3822015-11-09 00:50:54 +0100962 /* initialize the card_handle with reasonabe defaults */
963 ch->state = ISO_S_WAIT_POWER;
964 ch->vcc_active = 0;
965 ch->in_reset = 1;
966 ch->clocked = 0;
967
968 ch->fi = 0;
969 ch->di = 1;
970 ch->wi = ISO7816_3_DEFAULT_WI;
971
972 ch->tc_chan = tc_chan;
973 ch->uart_chan = uart_chan;
974 ch->waiting_time = ISO7816_3_INIT_WTIME;
975
976 ch->atr.idx = 0;
977 ch->atr.len = sizeof(default_atr);
978 memcpy(ch->atr.atr, default_atr, ch->atr.len);
979
980 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
981 ch->tpdu.state = TPDU_S_WAIT_CLA;
982
983 tc_etu_init(ch->tc_chan, ch);
984
985 return ch;
986}