blob: 6b61e46ef16efdd9d7ca24efdb5a09433666c080 [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 Welte53079bb2016-03-20 14:58:35 +010020//#define TRACE_LEVEL 6
Harald Welte7abdb512016-03-03 17:48:32 +010021
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 Welteb41598b2017-02-04 12:15:58 +010035#include "osmocom/core/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 {
Harald Weltedde112e2016-03-20 16:42:11 +010099 uint32_t num;
100
Harald Welte9d3e3822015-11-09 00:50:54 +0100101 enum iso7816_3_card_state state;
102
103 /* signal levels */
104 uint8_t vcc_active; /* 1 = on, 0 = off */
105 uint8_t in_reset; /* 1 = RST low, 0 = RST high */
106 uint8_t clocked; /* 1 = active, 0 = inactive */
107
Harald Welte16cf4082015-11-11 19:02:48 +0100108 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100109 uint8_t fi;
110 uint8_t di;
111 uint8_t wi;
112
113 uint8_t tc_chan; /* TC channel number */
114 uint8_t uart_chan; /* UART channel */
115
116 uint32_t waiting_time; /* in clocks */
117
118 /* ATR state machine */
119 struct {
120 uint8_t idx;
121 uint8_t len;
122 //uint8_t hist_len;
123 //uint8_t last_td;
124 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
125 } atr;
126
127 /* PPS / PTS support */
128 struct {
129 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100130 uint8_t req[6]; /* request bytes */
131 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100132 } pts;
133
134 /* TPDU */
135 struct {
136 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100137 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100138 } tpdu;
139
Harald Welte16cf4082015-11-11 19:02:48 +0100140 struct req_ctx *uart_rx_ctx; /* UART RX -> USB TX */
141 struct req_ctx *uart_tx_ctx; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100142
Harald Welte54cb3d02016-02-29 14:12:40 +0100143 struct llist_head usb_tx_queue;
144 struct llist_head uart_tx_queue;
145
Harald Welte9d3e3822015-11-09 00:50:54 +0100146 struct {
147 uint32_t tx_bytes;
148 uint32_t rx_bytes;
149 uint32_t pps;
150 } stats;
151};
152
Harald Welte54cb3d02016-02-29 14:12:40 +0100153struct llist_head *card_emu_get_usb_tx_queue(struct card_handle *ch)
154{
155 return &ch->usb_tx_queue;
156}
157
158struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
159{
160 return &ch->uart_tx_queue;
161}
162
Harald Welte2935b3c2015-11-14 20:00:14 +0100163static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100164static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100165
Harald Welteb5288e82015-11-14 21:15:52 +0100166static void flush_rx_buffer(struct card_handle *ch)
167{
168 struct req_ctx *rctx;
169 struct cardemu_usb_msg_rx_data *rd;
170
171 rctx = ch->uart_rx_ctx;
172 if (!rctx)
173 return;
174
Harald Welte54cb3d02016-02-29 14:12:40 +0100175 ch->uart_rx_ctx = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100176
177 /* store length of data payload fild in header */
Harald Weltefcdd6602016-03-02 10:33:58 +0100178 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
Harald Welted295b922016-03-18 21:01:36 +0100179 rd->data_len = rctx->idx;
180 rd->hdr.msg_len = sizeof(*rd) + rd->data_len;
Harald Welte54cb3d02016-02-29 14:12:40 +0100181
Harald Welteb5288e82015-11-14 21:15:52 +0100182 req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
Harald Welte53079bb2016-03-20 14:58:35 +0100183 /* no need for irqsafe operation, as the usb_tx_queue is
184 * processed only by the main loop context */
185 llist_add_tail(&rctx->list, &ch->usb_tx_queue);
Harald Welteb5288e82015-11-14 21:15:52 +0100186}
187
Harald Welte4ba66d02016-02-25 19:38:56 +0100188/* convert a non-contiguous PTS request/responsei into a contiguous
189 * buffer, returning the number of bytes used in the buffer */
190static int serialize_pts(uint8_t *out, const uint8_t *in)
191{
192 int i = 0;
193
194 out[i++] = in[_PTSS];
195 out[i++] = in[_PTS0];
196 if (in[_PTS0] & (1 << 4))
197 out[i++] = in[_PTS1];
198 if (in[_PTS0] & (1 << 5))
199 out[i++] = in[_PTS2];
200 if (in[_PTS0] & (1 << 6))
201 out[i++] = in[_PTS3];
202 out[i++] = in[_PCK];
203
204 return i;
205}
206
Harald Welte17db2f12016-02-26 09:48:57 +0100207static uint8_t csum_pts(const uint8_t *in)
208{
209 uint8_t out[6];
210 int len = serialize_pts(out, in);
211 uint8_t csum = 0;
212 int i;
213
214 /* we don't include the PCK byte in the checksumming process */
215 len -= 1;
216
217 for (i = 0; i < len; i++)
218 csum = csum ^ out[i];
219
220 return csum;
221}
222
Harald Welte4ba66d02016-02-25 19:38:56 +0100223static void flush_pts(struct card_handle *ch)
224{
225 struct req_ctx *rctx;
226 struct cardemu_usb_msg_pts_info *ptsi;
227
228 rctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
229 if (!rctx)
230 return;
231
232 ptsi = (struct cardemu_usb_msg_pts_info *) rctx->data;
233 ptsi->hdr.msg_type = CEMU_USB_MSGT_DO_PTS;
Harald Welted295b922016-03-18 21:01:36 +0100234 ptsi->hdr.msg_len = sizeof(*ptsi);
235 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100236 serialize_pts(ptsi->resp, ch->pts.resp);
237
238 req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
Harald Welte53079bb2016-03-20 14:58:35 +0100239 /* no need for irqsafe operation, as the usb_tx_queue is
240 * processed only by the main loop context */
241 llist_add_tail(&rctx->list, &ch->usb_tx_queue);
Harald Welte4ba66d02016-02-25 19:38:56 +0100242}
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 Weltedde112e2016-03-20 16:42:11 +0100250 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
251 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100252 /* 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 Weltedde112e2016-03-20 16:42:11 +0100257 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
258 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100259}
260
261/* Update the ISO 7816-3 TPDU receiver state */
262static void card_set_state(struct card_handle *ch,
263 enum iso7816_3_card_state new_state)
264{
Harald Welte903d63a2016-03-20 13:38:39 +0100265 if (ch->state == new_state)
266 return;
267
Harald Weltedde112e2016-03-20 16:42:11 +0100268 TRACE_DEBUG("%u: 7816 card state %u -> %u\r\n", ch->num,
269 ch->state, new_state);
Harald Welte903d63a2016-03-20 13:38:39 +0100270 ch->state = new_state;
271
Harald Welte9d3e3822015-11-09 00:50:54 +0100272 switch (new_state) {
273 case ISO_S_WAIT_POWER:
274 case ISO_S_WAIT_CLK:
275 case ISO_S_WAIT_RST:
276 /* disable Rx and Tx of UART */
277 card_emu_uart_enable(ch->uart_chan, 0);
278 break;
279 case ISO_S_WAIT_ATR:
Harald Weltee7194ab2015-11-14 21:03:25 +0100280 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100281 /* Reset to initial Fi / Di ratio */
282 ch->fi = 1;
283 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100284 emu_update_fidi(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100285 /* initialize todefault WI, this will be overwritten if we
286 * receive TC2, and it will be programmed into hardware after
287 * ATR is finished */
288 ch->wi = ISO7816_3_DEFAULT_WI;
289 /* update waiting time to initial waiting time */
290 ch->waiting_time = ISO7816_3_INIT_WTIME;
291 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
292 /* Set ATR sub-state to initial state */
293 ch->atr.idx = 0;
294 //set_atr_state(ch, ATR_S_WAIT_TS);
295 /* Notice that we are just coming out of reset */
296 //ch->sh.flags |= SIMTRACE_FLAG_ATR;
297 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
298 break;
299 break;
300 case ISO_S_WAIT_TPDU:
301 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100302 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100303 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
304 break;
305 case ISO_S_IN_ATR:
306 case ISO_S_IN_PTS:
307 case ISO_S_IN_TPDU:
308 /* do nothing */
309 break;
310 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100311}
312
313
314/**********************************************************************
315 * PTS / PPS handling
316 **********************************************************************/
317
318/* Update the ATR sub-state */
319static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
320{
Harald Weltedde112e2016-03-20 16:42:11 +0100321 TRACE_DEBUG("%u: 7816 PTS state %u -> %u\r\n",
322 ch->num, ch->pts.state, new_ptss);
Harald Welte9d3e3822015-11-09 00:50:54 +0100323 ch->pts.state = new_ptss;
324}
325
326/* Determine the next PTS state */
327static enum pts_state next_pts_state(struct card_handle *ch)
328{
329 uint8_t is_resp = ch->pts.state & 0x10;
330 uint8_t sstate = ch->pts.state & 0x0f;
331 uint8_t *pts_ptr;
332
333 if (!is_resp)
334 pts_ptr = ch->pts.req;
335 else
336 pts_ptr = ch->pts.resp;
337
338 switch (sstate) {
339 case PTS_S_WAIT_REQ_PTSS:
340 goto from_ptss;
341 case PTS_S_WAIT_REQ_PTS0:
342 goto from_pts0;
343 case PTS_S_WAIT_REQ_PTS1:
344 goto from_pts1;
345 case PTS_S_WAIT_REQ_PTS2:
346 goto from_pts2;
347 case PTS_S_WAIT_REQ_PTS3:
348 goto from_pts3;
349 }
350
351 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
352 return PTS_S_WAIT_RESP_PTSS;
353
354from_ptss:
355 return PTS_S_WAIT_REQ_PTS0 | is_resp;
356from_pts0:
357 if (pts_ptr[_PTS0] & (1 << 4))
358 return PTS_S_WAIT_REQ_PTS1 | is_resp;
359from_pts1:
360 if (pts_ptr[_PTS0] & (1 << 5))
361 return PTS_S_WAIT_REQ_PTS2 | is_resp;
362from_pts2:
363 if (pts_ptr[_PTS0] & (1 << 6))
364 return PTS_S_WAIT_REQ_PTS3 | is_resp;
365from_pts3:
366 return PTS_S_WAIT_REQ_PCK | is_resp;
367}
368
369
Harald Welteccb8a222016-03-20 13:37:11 +0100370static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100371process_byte_pts(struct card_handle *ch, uint8_t byte)
372{
373 switch (ch->pts.state) {
374 case PTS_S_WAIT_REQ_PTSS:
375 ch->pts.req[_PTSS] = byte;
376 break;
377 case PTS_S_WAIT_REQ_PTS0:
378 ch->pts.req[_PTS0] = byte;
379 break;
380 case PTS_S_WAIT_REQ_PTS1:
381 ch->pts.req[_PTS1] = byte;
382 break;
383 case PTS_S_WAIT_REQ_PTS2:
384 ch->pts.req[_PTS2] = byte;
385 break;
386 case PTS_S_WAIT_REQ_PTS3:
387 ch->pts.req[_PTS3] = byte;
388 break;
389 case PTS_S_WAIT_REQ_PCK:
390 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100391 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100392 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
393 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100394 /* Wait for the next TPDU */
395 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
396 return ISO_S_WAIT_TPDU;
397 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100398 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100399 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
400 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100401 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100402 TRACE_ERROR("%u: process_byte_pts() in invalid state %u\r\n",
403 ch->num, ch->pts.state);
Harald Welte4c473da2015-11-14 13:31:11 +0100404 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100405 }
406 /* calculate the next state and set it */
407 set_pts_state(ch, next_pts_state(ch));
408
Harald Welte4ba66d02016-02-25 19:38:56 +0100409 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
410 flush_pts(ch);
411 /* activate UART TX to transmit PTS response */
412 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100413 /* don't fall-through to the 'return ISO_S_IN_PTS'
414 * below, rather keep ISO7816 state as-is, it will be
415 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100416 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100417 }
418
Harald Welte9d3e3822015-11-09 00:50:54 +0100419 return ISO_S_IN_PTS;
420}
421
422/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100423static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100424{
Harald Welte855ba9e2016-02-24 21:00:46 +0100425 uint8_t byte;
426
427 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100428 switch (ch->pts.state) {
429 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100430 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100431 break;
432 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100433 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100434 break;
435 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100436 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100437 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100438 ch->fi = byte >> 4;
439 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100440 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
441 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100442 break;
443 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100444 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100445 break;
446 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100447 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100448 break;
449 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100450 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100451 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100452 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100453 TRACE_ERROR("%u: get_byte_pts() in invalid state %u\r\n",
454 ch->num, ch->pts.state);
Harald Welte855ba9e2016-02-24 21:00:46 +0100455 return 0;
456 }
457
458 /* 2: Transmit the byte */
459 card_emu_uart_tx(ch->uart_chan, byte);
460
461 /* 3: Update the state */
462
463 switch (ch->pts.state) {
464 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100465 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100466 /* update baud rate generator with Fi/Di */
467 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100468 /* Wait for the next TPDU */
469 card_set_state(ch, ISO_S_WAIT_TPDU);
470 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
471 break;
472 default:
473 /* calculate the next state and set it */
474 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100475 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100476 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100477
Harald Welte855ba9e2016-02-24 21:00:46 +0100478 /* return number of bytes transmitted */
479 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100480}
481
482
483/**********************************************************************
484 * TPDU handling
485 **********************************************************************/
486
Harald Welte4d804672015-11-14 23:02:38 +0100487
488/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
489static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
490{
491 if (reader_to_card) {
492 return p3;
493 } else {
494 if (p3 == 0)
495 return 256;
496 else
497 return p3;
498 }
499}
500
Harald Welte9d3e3822015-11-09 00:50:54 +0100501/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100502static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100503{
504 struct req_ctx *rctx;
505 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100506 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100507
508 /* ensure we have a buffer */
509 if (!ch->uart_rx_ctx) {
Harald Welte4d804672015-11-14 23:02:38 +0100510 rctx = ch->uart_rx_ctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
511 if (!ch->uart_rx_ctx) {
Harald Weltedde112e2016-03-20 16:42:11 +0100512 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
513 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100514 return;
Harald Welte4d804672015-11-14 23:02:38 +0100515 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100516 rd = (struct cardemu_usb_msg_rx_data *) ch->uart_rx_ctx->data;
517 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
518 rctx->tot_len = sizeof(*rd);
519 rctx->idx = 0;
520 } else
521 rctx = ch->uart_rx_ctx;
522
523 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
524
525 rd->data[rctx->idx++] = byte;
526 rctx->tot_len++;
527
528 /* check if the buffer is full. If so, send it */
Harald Welte4d804672015-11-14 23:02:38 +0100529 if (rctx->tot_len >= sizeof(*rd) + num_data_bytes) {
530 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100531 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100532 /* We need to transmit the SW now, */
533 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte4d804672015-11-14 23:02:38 +0100534 } else if (rctx->tot_len >= rctx->size)
535 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100536}
537
538static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
539{
Harald Welte05b41c62015-11-14 20:58:48 +0100540 if (ch->tpdu.state == new_ts)
541 return;
542
Harald Weltedde112e2016-03-20 16:42:11 +0100543 TRACE_DEBUG("%u: 7816 TPDU state %u -> %u\r\n", ch->num,
544 ch->tpdu.state, new_ts);
Harald Welte05b41c62015-11-14 20:58:48 +0100545
Harald Welte903d63a2016-03-20 13:38:39 +0100546 ch->tpdu.state = new_ts;
547
Harald Welte9d3e3822015-11-09 00:50:54 +0100548 switch (new_ts) {
549 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100550 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100551 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
552 break;
553 case TPDU_S_WAIT_PB:
554 /* we just completed the TPDU header from reader to card
555 * and now need to disable the receiver, enable the
556 * transmitter and transmit the procedure byte */
557 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
558 break;
Harald Weltead434402016-03-02 11:18:29 +0100559 default:
560 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100561 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100562}
563
564static enum tpdu_state next_tpdu_state(struct card_handle *ch)
565{
566 switch (ch->tpdu.state) {
567 case TPDU_S_WAIT_CLA:
568 return TPDU_S_WAIT_INS;
569 case TPDU_S_WAIT_INS:
570 return TPDU_S_WAIT_P1;
571 case TPDU_S_WAIT_P1:
572 return TPDU_S_WAIT_P2;
573 case TPDU_S_WAIT_P2:
574 return TPDU_S_WAIT_P3;
575 case TPDU_S_WAIT_P3:
576 return TPDU_S_WAIT_PB;
577 /* simply stay in Rx or Tx by default */
578 case TPDU_S_WAIT_PB:
579 return TPDU_S_WAIT_PB;
580 case TPDU_S_WAIT_RX:
581 return TPDU_S_WAIT_RX;
582 case TPDU_S_WAIT_TX:
583 return TPDU_S_WAIT_TX;
584 }
Harald Welte4c473da2015-11-14 13:31:11 +0100585 /* we should never reach here */
586 assert(0);
587 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100588}
589
590static void send_tpdu_header(struct card_handle *ch)
591{
592 struct req_ctx *rctx;
593 struct cardemu_usb_msg_rx_data *rd;
594
Harald Weltedde112e2016-03-20 16:42:11 +0100595 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
596 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100597 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
598 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
599 ch->tpdu.hdr[4]);
600
Harald Welte9d3e3822015-11-09 00:50:54 +0100601 /* if we already/still have a context, send it off */
Harald Weltef1697e22016-03-02 10:28:54 +0100602 if (ch->uart_rx_ctx) {
Harald Weltedde112e2016-03-20 16:42:11 +0100603 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100604 if (ch->uart_rx_ctx->idx) {
Harald Weltedde112e2016-03-20 16:42:11 +0100605 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100606 flush_rx_buffer(ch);
607 }
608 } else {
Harald Weltedde112e2016-03-20 16:42:11 +0100609 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100610 /* ensure we have a new buffer */
611 ch->uart_rx_ctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
612 if (!ch->uart_rx_ctx) {
Harald Weltedde112e2016-03-20 16:42:11 +0100613 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
Harald Weltef1697e22016-03-02 10:28:54 +0100614 return;
615 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100616 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100617 rctx = ch->uart_rx_ctx;
618 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
619
620 /* initializ header */
621 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
622 rd->flags = CEMU_DATA_F_TPDU_HDR;
623 rctx->tot_len = sizeof(*rd) + sizeof(ch->tpdu.hdr);
Harald Welte0ef96d52016-02-25 00:09:17 +0100624 rctx->idx = sizeof(ch->tpdu.hdr);
Harald Welte9d3e3822015-11-09 00:50:54 +0100625
626 /* copy TPDU header to data field */
627 memcpy(rd->data, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100628 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100629
Harald Welteb5288e82015-11-14 21:15:52 +0100630 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100631}
632
633static enum iso7816_3_card_state
634process_byte_tpdu(struct card_handle *ch, uint8_t byte)
635{
636 switch (ch->tpdu.state) {
637 case TPDU_S_WAIT_CLA:
638 ch->tpdu.hdr[_CLA] = 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_INS:
642 ch->tpdu.hdr[_INS] = 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 break;
645 case TPDU_S_WAIT_P1:
646 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100647 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100648 break;
649 case TPDU_S_WAIT_P2:
650 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100651 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100652 break;
653 case TPDU_S_WAIT_P3:
654 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100655 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100656 /* FIXME: start timer to transmit further 0x60 */
657 /* send the TPDU header as part of a procedure byte
658 * request to the USB host */
659 send_tpdu_header(ch);
660 break;
661 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100662 add_tpdu_byte(ch, byte);
663 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100664 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100665 TRACE_ERROR("%u: process_byte_tpdu() in invalid state %u\r\n",
666 ch->num, ch->tpdu.state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100667 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100668
669 /* ensure we stay in TPDU ISO state */
670 return ISO_S_IN_TPDU;
671}
672
Harald Welte855ba9e2016-02-24 21:00:46 +0100673/* tx a single byte to be transmitted to the reader */
674static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100675{
676 struct req_ctx *rctx;
677 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100678 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100679
680 /* ensure we are aware of any data that might be pending for
681 * transmit */
682 if (!ch->uart_tx_ctx) {
Harald Welte53079bb2016-03-20 14:58:35 +0100683 /* uart_tx_queue is filled from main loop, so no need
684 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100685 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100686 return 0;
687
Harald Welte54cb3d02016-02-29 14:12:40 +0100688 /* dequeue first at head */
689 ch->uart_tx_ctx = llist_entry(ch->uart_tx_queue.next,
690 struct req_ctx, list);
691 llist_del(&ch->uart_tx_ctx->list);
692 req_ctx_set_state(ch->uart_tx_ctx, RCTX_S_UART_TX_BUSY);
693
Harald Welte9d3e3822015-11-09 00:50:54 +0100694 /* start with index zero */
695 ch->uart_tx_ctx->idx = 0;
696
697 }
698 rctx = ch->uart_tx_ctx;
699 td = (struct cardemu_usb_msg_tx_data *) rctx->data;
700
Harald Welte9d3e3822015-11-09 00:50:54 +0100701 /* take the next pending byte out of the rctx */
Harald Welte855ba9e2016-02-24 21:00:46 +0100702 byte = td->data[rctx->idx++];
703
704 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100705
Harald Weltef16b6182016-02-24 22:18:46 +0100706 /* this must happen _after_ the byte has been transmittd */
707 switch (ch->tpdu.state) {
708 case TPDU_S_WAIT_PB:
709 /* if we just transmitted the procedure byte, we need to decide
710 * if we want to continue to receive or transmit */
711 if (td->flags & CEMU_DATA_F_PB_AND_TX)
712 set_tpdu_state(ch, TPDU_S_WAIT_TX);
713 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
714 set_tpdu_state(ch, TPDU_S_WAIT_RX);
715 break;
Harald Weltead434402016-03-02 11:18:29 +0100716 default:
717 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100718 }
719
Harald Welte9d3e3822015-11-09 00:50:54 +0100720 /* check if the buffer has now been fully transmitted */
Harald Welted295b922016-03-18 21:01:36 +0100721 if ((rctx->idx >= td->data_len) ||
Harald Weltef16b6182016-02-24 22:18:46 +0100722 (td->data + rctx->idx >= rctx->data + rctx->tot_len)) {
Harald Welte52922ff2015-11-14 20:59:56 +0100723 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
724 /* we have just sent the procedure byte and now
725 * need to continue receiving */
726 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100727 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100728 /* we have transmitted all bytes */
729 if (td->flags & CEMU_DATA_F_FINAL) {
730 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100731 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100732 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100733 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100734 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100735 req_ctx_set_state(rctx, RCTX_S_FREE);
736 ch->uart_tx_ctx = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100737 }
738
739 return 1;
740}
741
742/**********************************************************************
743 * Public API
744 **********************************************************************/
745
746/* process a single byte received from the reader */
747void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
748{
749 int new_state = -1;
750
751 ch->stats.rx_bytes++;
752
753 switch (ch->state) {
754 case ISO_S_WAIT_POWER:
755 case ISO_S_WAIT_CLK:
756 case ISO_S_WAIT_RST:
757 case ISO_S_WAIT_ATR:
Harald Weltedde112e2016-03-20 16:42:11 +0100758 TRACE_ERROR("%u: Received UART char in invalid 7816 state "
759 "%u\r\n", ch->num, ch->state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100760 /* we shouldn't receive any data from the reader yet! */
761 break;
762 case ISO_S_WAIT_TPDU:
763 if (byte == 0xff) {
764 new_state = process_byte_pts(ch, byte);
765 ch->stats.pps++;
766 goto out_silent;
767 }
768 /* fall-through */
769 case ISO_S_IN_TPDU:
770 new_state = process_byte_tpdu(ch, byte);
771 break;
772 case ISO_S_IN_PTS:
773 new_state = process_byte_pts(ch, byte);
774 goto out_silent;
775 }
776
777out_silent:
778 if (new_state != -1)
779 card_set_state(ch, new_state);
780}
781
Harald Welte855ba9e2016-02-24 21:00:46 +0100782/* transmit a single byte to the reader */
783int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100784{
785 int rc = 0;
786
787 switch (ch->state) {
788 case ISO_S_IN_ATR:
789 if (ch->atr.idx < ch->atr.len) {
Harald Welte855ba9e2016-02-24 21:00:46 +0100790 uint8_t byte;
791 byte = ch->atr.atr[ch->atr.idx++];
Harald Welte9d3e3822015-11-09 00:50:54 +0100792 rc = 1;
Harald Welte855ba9e2016-02-24 21:00:46 +0100793
794 card_emu_uart_tx(ch->uart_chan, byte);
795
Harald Welte9d3e3822015-11-09 00:50:54 +0100796 /* detect end of ATR */
797 if (ch->atr.idx >= ch->atr.len)
798 card_set_state(ch, ISO_S_WAIT_TPDU);
799 }
800 break;
801 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100802 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100803 break;
804 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +0100805 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100806 break;
Harald Weltead434402016-03-02 11:18:29 +0100807 default:
808 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100809 }
810
811 if (rc)
812 ch->stats.tx_bytes++;
813
Harald Welte4d804672015-11-14 23:02:38 +0100814 /* if we return 0 here, the UART needs to disable transmit-ready
815 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +0100816 return rc;
817}
818
Harald Welteacae4122016-03-02 10:27:58 +0100819void card_emu_have_new_uart_tx(struct card_handle *ch)
820{
821 switch (ch->state) {
822 case ISO_S_IN_TPDU:
823 switch (ch->tpdu.state) {
824 case TPDU_S_WAIT_TX:
825 case TPDU_S_WAIT_PB:
826 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
827 break;
828 default:
829 break;
830 }
831 default:
832 break;
833 }
834}
835
Harald Welteff160652016-03-19 21:59:06 +0100836void card_emu_report_status(struct card_handle *ch)
837{
838 struct req_ctx *rctx;
839 struct cardemu_usb_msg_status *sts;
840
841 rctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
842 if (!rctx)
843 return;
844
845 rctx->tot_len = sizeof(*sts);
846 sts = (struct cardemu_usb_msg_status *)rctx->data;
847 sts->hdr.msg_type = CEMU_USB_MSGT_DO_STATUS;
848 sts->hdr.msg_len = sizeof(*sts);
849 sts->flags = 0;
850 if (ch->vcc_active)
851 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
852 if (ch->clocked)
853 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
854 if (ch->in_reset)
855 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
856 /* FIXME: voltage + card insert */
857 sts->fi = ch->fi;
858 sts->di = ch->di;
859 sts->wi = ch->wi;
860 sts->waiting_time = ch->waiting_time;
861
862 llist_add_tail(&rctx->list, &ch->usb_tx_queue);
863 req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
864}
865
Harald Welte9d3e3822015-11-09 00:50:54 +0100866/* hardware driver informs us that a card I/O signal has changed */
867void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
868{
869 switch (io) {
870 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +0100871 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100872 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100873 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100874 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +0100875 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100876 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100877 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +0100878 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100879 ch->vcc_active = active;
880 break;
881 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +0100882 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100883 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100884 if (ch->state == ISO_S_WAIT_CLK)
885 card_set_state(ch, ISO_S_WAIT_RST);
886 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100887 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100888 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100889 ch->clocked = active;
890 break;
891 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +0100892 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100893 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100894 if (ch->vcc_active && ch->clocked) {
895 /* enable the TC/ETU counter once reset has been released */
896 tc_etu_enable(ch->tc_chan);
897 card_set_state(ch, ISO_S_WAIT_ATR);
898 /* FIXME: wait 400 to 40k clock cycles before sending ATR */
899 card_set_state(ch, ISO_S_IN_ATR);
900 }
901 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100902 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100903 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100904 }
905 ch->in_reset = active;
906 break;
907 }
908}
909
910/* User sets a new ATR to be returned during next card reset */
911int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
912{
913 if (len > sizeof(ch->atr.atr))
914 return -1;
915
916 memcpy(ch->atr.atr, atr, len);
917 ch->atr.len = len;
918 ch->atr.idx = 0;
919
920 /* FIXME: race condition with trasmitting ATR to reader? */
921
922 return 0;
923}
924
925/* hardware driver informs us that one (more) ETU has expired */
926void tc_etu_wtime_half_expired(void *handle)
927{
928 struct card_handle *ch = handle;
929 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +0100930 switch (ch->state) {
931 case ISO_S_IN_TPDU:
932 switch (ch->tpdu.state) {
933 case TPDU_S_WAIT_PB:
934 case TPDU_S_WAIT_TX:
935 putchar('N');
936 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
937 break;
938 default:
939 break;
940 }
941 break;
942 default:
943 break;
944 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100945}
946
947/* hardware driver informs us that one (more) ETU has expired */
948void tc_etu_wtime_expired(void *handle)
949{
Harald Weltedde112e2016-03-20 16:42:11 +0100950 struct card_handle *ch = handle;
951 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100952}
953
954/* shortest ATR found in smartcard_list.txt */
955static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
956
957static struct card_handle card_handles[NUM_SLOTS];
958
959struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan)
960{
961 struct card_handle *ch;
962
963 if (slot_num >= ARRAY_SIZE(card_handles))
964 return NULL;
965
966 ch = &card_handles[slot_num];
967
968 memset(ch, 0, sizeof(*ch));
969
Harald Welte54cb3d02016-02-29 14:12:40 +0100970 INIT_LLIST_HEAD(&ch->usb_tx_queue);
971 INIT_LLIST_HEAD(&ch->uart_tx_queue);
972
Harald Welte9d3e3822015-11-09 00:50:54 +0100973 /* initialize the card_handle with reasonabe defaults */
Harald Weltedde112e2016-03-20 16:42:11 +0100974 ch->num = slot_num;
Harald Welte9d3e3822015-11-09 00:50:54 +0100975 ch->state = ISO_S_WAIT_POWER;
976 ch->vcc_active = 0;
977 ch->in_reset = 1;
978 ch->clocked = 0;
979
980 ch->fi = 0;
981 ch->di = 1;
982 ch->wi = ISO7816_3_DEFAULT_WI;
983
984 ch->tc_chan = tc_chan;
985 ch->uart_chan = uart_chan;
986 ch->waiting_time = ISO7816_3_INIT_WTIME;
987
988 ch->atr.idx = 0;
989 ch->atr.len = sizeof(default_atr);
990 memcpy(ch->atr.atr, default_atr, ch->atr.len);
991
992 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
993 ch->tpdu.state = TPDU_S_WAIT_CLA;
994
995 tc_etu_init(ch->tc_chan, ch);
996
997 return ch;
998}