blob: 1da453af1a435e5cdbd4046d2464225ef4224659 [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
20#include <errno.h>
21#include <string.h>
22#include <stdint.h>
23#include <sys/types.h>
24
25#include "utils.h"
26#include "trace.h"
27#include "iso7816_fidi.h"
28#include "tc_etu.h"
29#include "card_emu.h"
30#include "req_ctx.h"
31#include "cardemu_prot.h"
32
33
34#define NUM_SLOTS 2
35
36#define ISO7816_3_INIT_WTIME 9600
37#define ISO7816_3_DEFAULT_WI 10
38#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
39
40#define ISO7816_3_PB_NULL 0x60
41
42enum iso7816_3_card_state {
43 ISO_S_WAIT_POWER, /* waiting for power being applied */
44 ISO_S_WAIT_CLK, /* waiting for clock being applied */
45 ISO_S_WAIT_RST, /* waiting for reset being released */
46 ISO_S_WAIT_ATR, /* waiting for start of ATR */
47 ISO_S_IN_ATR, /* transmitting ATR to reader */
48 ISO_S_IN_PTS, /* transmitting ATR to reader */
49 ISO_S_WAIT_TPDU, /* waiting for data from reader */
50 ISO_S_IN_TPDU, /* inside a TPDU */
51};
52
53/* detailed sub-states of ISO_S_IN_PTS */
54enum pts_state {
55 PTS_S_WAIT_REQ_PTSS,
56 PTS_S_WAIT_REQ_PTS0,
57 PTS_S_WAIT_REQ_PTS1,
58 PTS_S_WAIT_REQ_PTS2,
59 PTS_S_WAIT_REQ_PTS3,
60 PTS_S_WAIT_REQ_PCK,
61 PTS_S_WAIT_RESP_PTSS = PTS_S_WAIT_REQ_PTSS | 0x10,
62 PTS_S_WAIT_RESP_PTS0 = PTS_S_WAIT_REQ_PTS0 | 0x10,
63 PTS_S_WAIT_RESP_PTS1 = PTS_S_WAIT_REQ_PTS1 | 0x10,
64 PTS_S_WAIT_RESP_PTS2 = PTS_S_WAIT_REQ_PTS2 | 0x10,
65 PTS_S_WAIT_RESP_PTS3 = PTS_S_WAIT_REQ_PTS3 | 0x10,
66 PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
67};
68
69#define _PTSS 0
70#define _PTS0 1
71#define _PTS1 2
72#define _PTS2 3
73#define _PTS3 4
74#define _PCK 5
75
Harald Welte16cf4082015-11-11 19:02:48 +010076/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +010077enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +010078 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
79 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
80 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
81 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
82 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +010083 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
84 TPDU_S_WAIT_RX, /* waiitng for more data from reader */
85 TPDU_S_WAIT_TX, /* waiting for more data to reader */
86};
87
88#define _CLA 0
89#define _INS 1
90#define _P1 2
91#define _P2 3
92#define _P3 4
93
94struct card_handle {
95 enum iso7816_3_card_state state;
96
97 /* signal levels */
98 uint8_t vcc_active; /* 1 = on, 0 = off */
99 uint8_t in_reset; /* 1 = RST low, 0 = RST high */
100 uint8_t clocked; /* 1 = active, 0 = inactive */
101
Harald Welte16cf4082015-11-11 19:02:48 +0100102 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100103 uint8_t fi;
104 uint8_t di;
105 uint8_t wi;
106
107 uint8_t tc_chan; /* TC channel number */
108 uint8_t uart_chan; /* UART channel */
109
110 uint32_t waiting_time; /* in clocks */
111
112 /* ATR state machine */
113 struct {
114 uint8_t idx;
115 uint8_t len;
116 //uint8_t hist_len;
117 //uint8_t last_td;
118 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
119 } atr;
120
121 /* PPS / PTS support */
122 struct {
123 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100124 uint8_t req[6]; /* request bytes */
125 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100126 } pts;
127
128 /* TPDU */
129 struct {
130 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100131 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100132 } tpdu;
133
Harald Welte16cf4082015-11-11 19:02:48 +0100134 struct req_ctx *uart_rx_ctx; /* UART RX -> USB TX */
135 struct req_ctx *uart_tx_ctx; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100136
137 struct {
138 uint32_t tx_bytes;
139 uint32_t rx_bytes;
140 uint32_t pps;
141 } stats;
142};
143
144static int update_fidi(struct card_handle *ch)
145{
146 int rc;
147
148 rc = compute_fidi_ratio(ch->fi, ch->di);
149 if (rc > 0 && rc < 0x400) {
150 TRACE_DEBUG("computed Fi(%u) Di(%u) ratio: %d\n",
151 ch->fi, ch->di, rc);
152 /* make sure UART uses new F/D ratio */
153 card_emu_uart_update_fidi(ch->uart_chan, rc);
154 /* notify ETU timer about this */
155 tc_etu_set_etu(ch->tc_chan, rc);
156 } else
157 TRACE_DEBUG("computed FiDi ration %d unsupported\n", rc);
158}
159
160/* Update the ISO 7816-3 TPDU receiver state */
161static void card_set_state(struct card_handle *ch,
162 enum iso7816_3_card_state new_state)
163{
164 switch (new_state) {
165 case ISO_S_WAIT_POWER:
166 case ISO_S_WAIT_CLK:
167 case ISO_S_WAIT_RST:
168 /* disable Rx and Tx of UART */
169 card_emu_uart_enable(ch->uart_chan, 0);
170 break;
171 case ISO_S_WAIT_ATR:
172 /* Reset to initial Fi / Di ratio */
173 ch->fi = 1;
174 ch->di = 1;
175 update_fidi(ch);
176 /* initialize todefault WI, this will be overwritten if we
177 * receive TC2, and it will be programmed into hardware after
178 * ATR is finished */
179 ch->wi = ISO7816_3_DEFAULT_WI;
180 /* update waiting time to initial waiting time */
181 ch->waiting_time = ISO7816_3_INIT_WTIME;
182 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
183 /* Set ATR sub-state to initial state */
184 ch->atr.idx = 0;
185 //set_atr_state(ch, ATR_S_WAIT_TS);
186 /* Notice that we are just coming out of reset */
187 //ch->sh.flags |= SIMTRACE_FLAG_ATR;
188 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
189 break;
190 break;
191 case ISO_S_WAIT_TPDU:
192 /* enable the receiver, disable transmitter */
193 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
194 break;
195 case ISO_S_IN_ATR:
196 case ISO_S_IN_PTS:
197 case ISO_S_IN_TPDU:
198 /* do nothing */
199 break;
200 }
201
202 if (ch->state == new_state)
203 return;
204
205 TRACE_DEBUG("7816 card state %u -> %u\n", ch->state, new_state);
206 ch->state = new_state;
207}
208
209
210/**********************************************************************
211 * PTS / PPS handling
212 **********************************************************************/
213
214/* Update the ATR sub-state */
215static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
216{
217 TRACE_DEBUG("7816 PTS state %u -> %u\n", ch->pts.state, new_ptss);
218 ch->pts.state = new_ptss;
219}
220
221/* Determine the next PTS state */
222static enum pts_state next_pts_state(struct card_handle *ch)
223{
224 uint8_t is_resp = ch->pts.state & 0x10;
225 uint8_t sstate = ch->pts.state & 0x0f;
226 uint8_t *pts_ptr;
227
228 if (!is_resp)
229 pts_ptr = ch->pts.req;
230 else
231 pts_ptr = ch->pts.resp;
232
233 switch (sstate) {
234 case PTS_S_WAIT_REQ_PTSS:
235 goto from_ptss;
236 case PTS_S_WAIT_REQ_PTS0:
237 goto from_pts0;
238 case PTS_S_WAIT_REQ_PTS1:
239 goto from_pts1;
240 case PTS_S_WAIT_REQ_PTS2:
241 goto from_pts2;
242 case PTS_S_WAIT_REQ_PTS3:
243 goto from_pts3;
244 }
245
246 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
247 return PTS_S_WAIT_RESP_PTSS;
248
249from_ptss:
250 return PTS_S_WAIT_REQ_PTS0 | is_resp;
251from_pts0:
252 if (pts_ptr[_PTS0] & (1 << 4))
253 return PTS_S_WAIT_REQ_PTS1 | is_resp;
254from_pts1:
255 if (pts_ptr[_PTS0] & (1 << 5))
256 return PTS_S_WAIT_REQ_PTS2 | is_resp;
257from_pts2:
258 if (pts_ptr[_PTS0] & (1 << 6))
259 return PTS_S_WAIT_REQ_PTS3 | is_resp;
260from_pts3:
261 return PTS_S_WAIT_REQ_PCK | is_resp;
262}
263
264
265static enum iso7816_3_card_state
266process_byte_pts(struct card_handle *ch, uint8_t byte)
267{
268 switch (ch->pts.state) {
269 case PTS_S_WAIT_REQ_PTSS:
270 ch->pts.req[_PTSS] = byte;
271 break;
272 case PTS_S_WAIT_REQ_PTS0:
273 ch->pts.req[_PTS0] = byte;
274 break;
275 case PTS_S_WAIT_REQ_PTS1:
276 ch->pts.req[_PTS1] = byte;
277 break;
278 case PTS_S_WAIT_REQ_PTS2:
279 ch->pts.req[_PTS2] = byte;
280 break;
281 case PTS_S_WAIT_REQ_PTS3:
282 ch->pts.req[_PTS3] = byte;
283 break;
284 case PTS_S_WAIT_REQ_PCK:
285 ch->pts.req[_PCK] = byte;
286 /* FIXME: check PCK */
287 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
288 break;
289 }
290 /* calculate the next state and set it */
291 set_pts_state(ch, next_pts_state(ch));
292
293 return ISO_S_IN_PTS;
294}
295
296/* return a single byte to be transmitted to the reader */
297static int get_byte_pps(struct card_handle *ch, uint8_t *byte)
298{
299 /* FIXME */
300#if 0
301 switch (ch->pts.state) {
302 case PTS_S_WAIT_RESP_PTSS:
303 ch->pts.resp[_PTSS] = byte;
304 break;
305 case PTS_S_WAIT_RESP_PTS0:
306 ch->pts.resp[_PTS0] = byte;
307 break;
308 case PTS_S_WAIT_RESP_PTS1:
309 /* This must be TA1 */
310 ch->fi = byte >> 4;
311 ch->di = byte & 0xf;
312 TRACE_DEBUG("found Fi=%u Di=%u\n", ch->fi, ch->di);
313 ch->sh.flags |= SIMTRACE_FLAG_PPS_FIDI;
314 ch->pts.resp[_PTS1] = byte;
315 break;
316 case PTS_S_WAIT_RESP_PTS2:
317 ch->pts.resp[_PTS2] = byte;
318 break;
319 case PTS_S_WAIT_RESP_PTS3:
320 ch->pts.resp[_PTS3] = byte;
321 break;
322 case PTS_S_WAIT_RESP_PCK:
323 ch->pts.resp[_PCK] = byte;
324 /* FIXME: check PCK */
325 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
326 /* update baud rate generator with Fi/Di */
327 update_fidi(ch);
328 /* Wait for the next TPDU */
329 card_set_state(ch, ISO_S_WAIT_TPDU);
330 }
331#endif
332 /* calculate the next state and set it */
333 set_pts_state(ch, next_pts_state(ch));
334
335 return 0;
336}
337
338
339/**********************************************************************
340 * TPDU handling
341 **********************************************************************/
342
343/* add a just-received TPDU byte (from reader) to USB buffer */
344static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
345{
346 struct req_ctx *rctx;
347 struct cardemu_usb_msg_rx_data *rd;
348
349 /* ensure we have a buffer */
350 if (!ch->uart_rx_ctx) {
351 ch->uart_rx_ctx = req_ctx_find_get(1, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
352 if (!ch->uart_rx_ctx)
353 return;
354 rd = (struct cardemu_usb_msg_rx_data *) ch->uart_rx_ctx->data;
355 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
356 rctx->tot_len = sizeof(*rd);
357 rctx->idx = 0;
358 } else
359 rctx = ch->uart_rx_ctx;
360
361 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
362
363 rd->data[rctx->idx++] = byte;
364 rctx->tot_len++;
365
366 /* check if the buffer is full. If so, send it */
367 if (rctx->tot_len >= rctx->size) {
368 /* store length of data payload fild in header */
369 rd->hdr.data_len = rctx->idx;
370 req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
371 ch->uart_rx_ctx = NULL;
372 /* FIXME: call into USB code to see if this buffer can
373 * be transmitted now */
374 }
375}
376
377static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
378{
379 TRACE_DEBUG("7816 TPDU state %u -> %u\n", ch->tpdu.state, new_ts);
380 switch (new_ts) {
381 case TPDU_S_WAIT_CLA:
382 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
383 break;
384 case TPDU_S_WAIT_PB:
385 /* we just completed the TPDU header from reader to card
386 * and now need to disable the receiver, enable the
387 * transmitter and transmit the procedure byte */
388 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
389 break;
390 }
391 ch->tpdu.state = new_ts;
392}
393
394static enum tpdu_state next_tpdu_state(struct card_handle *ch)
395{
396 switch (ch->tpdu.state) {
397 case TPDU_S_WAIT_CLA:
398 return TPDU_S_WAIT_INS;
399 case TPDU_S_WAIT_INS:
400 return TPDU_S_WAIT_P1;
401 case TPDU_S_WAIT_P1:
402 return TPDU_S_WAIT_P2;
403 case TPDU_S_WAIT_P2:
404 return TPDU_S_WAIT_P3;
405 case TPDU_S_WAIT_P3:
406 return TPDU_S_WAIT_PB;
407 /* simply stay in Rx or Tx by default */
408 case TPDU_S_WAIT_PB:
409 return TPDU_S_WAIT_PB;
410 case TPDU_S_WAIT_RX:
411 return TPDU_S_WAIT_RX;
412 case TPDU_S_WAIT_TX:
413 return TPDU_S_WAIT_TX;
414 }
415}
416
417static void send_tpdu_header(struct card_handle *ch)
418{
419 struct req_ctx *rctx;
420 struct cardemu_usb_msg_rx_data *rd;
421
422 /* if we already/still have a context, send it off */
423 if (ch->uart_rx_ctx && rctx->idx) {
424 ch->uart_rx_ctx = NULL;
425 }
426
427 /* ensure we have a new buffer */
428 ch->uart_rx_ctx = req_ctx_find_get(1, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
429 if (!ch->uart_rx_ctx)
430 return;
431 rctx = ch->uart_rx_ctx;
432 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
433
434 /* initializ header */
435 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
436 rd->flags = CEMU_DATA_F_TPDU_HDR;
437 rctx->tot_len = sizeof(*rd) + sizeof(ch->tpdu.hdr);
438 rctx->idx = 0;
439
440 /* copy TPDU header to data field */
441 memcpy(rd->data, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
442 rd->hdr.data_len = sizeof(ch->tpdu.hdr);
443
444 req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
445}
446
447static enum iso7816_3_card_state
448process_byte_tpdu(struct card_handle *ch, uint8_t byte)
449{
450 switch (ch->tpdu.state) {
451 case TPDU_S_WAIT_CLA:
452 ch->tpdu.hdr[_CLA] = byte;
453 break;
454 case TPDU_S_WAIT_INS:
455 ch->tpdu.hdr[_INS] = byte;
456 break;
457 case TPDU_S_WAIT_P1:
458 ch->tpdu.hdr[_P1] = byte;
459 break;
460 case TPDU_S_WAIT_P2:
461 ch->tpdu.hdr[_P2] = byte;
462 break;
463 case TPDU_S_WAIT_P3:
464 ch->tpdu.hdr[_P3] = byte;
465 /* FIXME: start timer to transmit further 0x60 */
466 /* send the TPDU header as part of a procedure byte
467 * request to the USB host */
468 send_tpdu_header(ch);
469 break;
470 case TPDU_S_WAIT_RX:
471 add_tpdu_byte(ch, byte);
472 break;
473 default:
474 TRACE_DEBUG("process_byte_tpdu() in invalid state %u\n",
475 ch->tpdu.state);
476 }
477 set_tpdu_state(ch, next_tpdu_state(ch));
478
479 /* ensure we stay in TPDU ISO state */
480 return ISO_S_IN_TPDU;
481}
482
483/* return a single byte to be transmitted to the reader */
484static int get_byte_tpdu(struct card_handle *ch, uint8_t *byte)
485{
486 struct req_ctx *rctx;
487 struct cardemu_usb_msg_tx_data *td;
488
489 /* ensure we are aware of any data that might be pending for
490 * transmit */
491 if (!ch->uart_tx_ctx) {
492 ch->uart_tx_ctx = req_ctx_find_get(1, RCTX_S_UART_TX_PENDING,
493 RCTX_S_UART_TX_BUSY);
494 if (!ch->uart_tx_ctx)
495 return 0;
496
497 /* start with index zero */
498 ch->uart_tx_ctx->idx = 0;
499
500 }
501 rctx = ch->uart_tx_ctx;
502 td = (struct cardemu_usb_msg_tx_data *) rctx->data;
503
504#if 0
505 /* this must happen _after_ the byte has been transmittd */
506 switch (ch->tpdu.state) {
507 case TPDU_S_WAIT_PB:
508 if (td->flags & CEMU_DATA_F_PB_AND_TX)
509 set_tpdu_state(ch, TPDU_S_WAIT_TX);
510 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
511 set_tpdu_state(ch, TPDU_S_WAIT_RX);
512 break;
513 }
514#endif
515
516 /* take the next pending byte out of the rctx */
517 *byte = td->data[rctx->idx++];
518
519 /* check if the buffer has now been fully transmitted */
520 if ((rctx->idx >= td->hdr.data_len) ||
521 (rctx->idx + sizeof(*td) - sizeof(td->hdr) >= rctx->tot_len)) {
522 req_ctx_set_state(rctx, RCTX_S_FREE);
523 ch->uart_tx_ctx = NULL;
524 /* FIXME: call into USB code to chec if we need to
525 * submit a free buffer to accept furthe data on bulk
526 * out endpoint */
527 }
528
529 return 1;
530}
531
532/**********************************************************************
533 * Public API
534 **********************************************************************/
535
536/* process a single byte received from the reader */
537void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
538{
539 int new_state = -1;
540
541 ch->stats.rx_bytes++;
542
543 switch (ch->state) {
544 case ISO_S_WAIT_POWER:
545 case ISO_S_WAIT_CLK:
546 case ISO_S_WAIT_RST:
547 case ISO_S_WAIT_ATR:
548 /* we shouldn't receive any data from the reader yet! */
549 break;
550 case ISO_S_WAIT_TPDU:
551 if (byte == 0xff) {
552 new_state = process_byte_pts(ch, byte);
553 ch->stats.pps++;
554 goto out_silent;
555 }
556 /* fall-through */
557 case ISO_S_IN_TPDU:
558 new_state = process_byte_tpdu(ch, byte);
559 break;
560 case ISO_S_IN_PTS:
561 new_state = process_byte_pts(ch, byte);
562 goto out_silent;
563 }
564
565out_silent:
566 if (new_state != -1)
567 card_set_state(ch, new_state);
568}
569
570/* return a single byte to be transmitted to the reader */
571int card_emu_get_tx_byte(struct card_handle *ch, uint8_t *byte)
572{
573 int rc = 0;
574
575 switch (ch->state) {
576 case ISO_S_IN_ATR:
577 if (ch->atr.idx < ch->atr.len) {
578 *byte = ch->atr.atr[ch->atr.idx++];
579 rc = 1;
580 /* detect end of ATR */
581 if (ch->atr.idx >= ch->atr.len)
582 card_set_state(ch, ISO_S_WAIT_TPDU);
583 }
584 break;
585 case ISO_S_IN_PTS:
586 rc = get_byte_pps(ch, byte);
587 break;
588 case ISO_S_IN_TPDU:
589 rc = get_byte_tpdu(ch, byte);
590 break;
591 }
592
593 if (rc)
594 ch->stats.tx_bytes++;
595
596 return rc;
597}
598
599/* hardware driver informs us that a card I/O signal has changed */
600void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
601{
602 switch (io) {
603 case CARD_IO_VCC:
604 if (active == 0)
605 card_set_state(ch, ISO_S_WAIT_POWER);
606 else if (active == 1 && ch->vcc_active == 0)
607 card_set_state(ch, ISO_S_WAIT_CLK);
608 ch->vcc_active = active;
609 break;
610 case CARD_IO_CLK:
611 if (active == 1 && ch->state == ISO_S_WAIT_CLK)
612 card_set_state(ch, ISO_S_WAIT_RST);
613 ch->clocked = active;
614 break;
615 case CARD_IO_RST:
616 if (active == 0 && ch->in_reset &&
617 ch->vcc_active && ch->clocked) {
618 /* FIXME: wait 400 clocks */
619 //card_set_state(ch, ISO_S_WAIT_ATR);
620 card_set_state(ch, ISO_S_IN_ATR);
621 }
622 ch->in_reset = active;
623 break;
624 }
625}
626
627/* User sets a new ATR to be returned during next card reset */
628int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
629{
630 if (len > sizeof(ch->atr.atr))
631 return -1;
632
633 memcpy(ch->atr.atr, atr, len);
634 ch->atr.len = len;
635 ch->atr.idx = 0;
636
637 /* FIXME: race condition with trasmitting ATR to reader? */
638
639 return 0;
640}
641
642/* hardware driver informs us that one (more) ETU has expired */
643void tc_etu_wtime_half_expired(void *handle)
644{
645 struct card_handle *ch = handle;
646 /* transmit NULL procedure byte well before waiting time expires */
647 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
648}
649
650/* hardware driver informs us that one (more) ETU has expired */
651void tc_etu_wtime_expired(void *handle)
652{
653}
654
655/* shortest ATR found in smartcard_list.txt */
656static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
657
658static struct card_handle card_handles[NUM_SLOTS];
659
660struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan)
661{
662 struct card_handle *ch;
663
664 if (slot_num >= ARRAY_SIZE(card_handles))
665 return NULL;
666
667 ch = &card_handles[slot_num];
668
669 memset(ch, 0, sizeof(*ch));
670
671 /* initialize the card_handle with reasonabe defaults */
672 ch->state = ISO_S_WAIT_POWER;
673 ch->vcc_active = 0;
674 ch->in_reset = 1;
675 ch->clocked = 0;
676
677 ch->fi = 0;
678 ch->di = 1;
679 ch->wi = ISO7816_3_DEFAULT_WI;
680
681 ch->tc_chan = tc_chan;
682 ch->uart_chan = uart_chan;
683 ch->waiting_time = ISO7816_3_INIT_WTIME;
684
685 ch->atr.idx = 0;
686 ch->atr.len = sizeof(default_atr);
687 memcpy(ch->atr.atr, default_atr, ch->atr.len);
688
689 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
690 ch->tpdu.state = TPDU_S_WAIT_CLA;
691
692 tc_etu_init(ch->tc_chan, ch);
693
694 return ch;
695}