blob: 6edf05e1f1db15511b628123ddc214b9091edfa0 [file] [log] [blame]
Harald Welte9d3e3822015-11-09 00:50:54 +01001/* ISO7816-3 state machine for the card side */
Harald Welte8e7fca32017-05-07 16:14:33 +02002/* (C) 2010-2017 by Harald Welte <hwelte@hmw-consulting.de>
Harald Welte9d3e3822015-11-09 00:50:54 +01003 *
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 Weltec430ac12017-02-28 01:25:12 +010022#include <stdio.h>
Harald Welte4c473da2015-11-14 13:31:11 +010023#include <assert.h>
Harald Welte9d3e3822015-11-09 00:50:54 +010024#include <errno.h>
25#include <string.h>
26#include <stdint.h>
27#include <sys/types.h>
28
29#include "utils.h"
30#include "trace.h"
31#include "iso7816_fidi.h"
32#include "tc_etu.h"
33#include "card_emu.h"
Harald Welte9d3e3822015-11-09 00:50:54 +010034#include "cardemu_prot.h"
Harald Welte8e7fca32017-05-07 16:14:33 +020035#include "usb_buf.h"
Harald Welteb41598b2017-02-04 12:15:58 +010036#include "osmocom/core/linuxlist.h"
Harald Welte8e7fca32017-05-07 16:14:33 +020037#include "osmocom/core/msgb.h"
Harald Welte9d3e3822015-11-09 00:50:54 +010038
39
40#define NUM_SLOTS 2
41
42#define ISO7816_3_INIT_WTIME 9600
43#define ISO7816_3_DEFAULT_WI 10
44#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
45
46#define ISO7816_3_PB_NULL 0x60
47
48enum iso7816_3_card_state {
49 ISO_S_WAIT_POWER, /* waiting for power being applied */
50 ISO_S_WAIT_CLK, /* waiting for clock being applied */
51 ISO_S_WAIT_RST, /* waiting for reset being released */
52 ISO_S_WAIT_ATR, /* waiting for start of ATR */
53 ISO_S_IN_ATR, /* transmitting ATR to reader */
54 ISO_S_IN_PTS, /* transmitting ATR to reader */
55 ISO_S_WAIT_TPDU, /* waiting for data from reader */
56 ISO_S_IN_TPDU, /* inside a TPDU */
57};
58
59/* detailed sub-states of ISO_S_IN_PTS */
60enum pts_state {
61 PTS_S_WAIT_REQ_PTSS,
62 PTS_S_WAIT_REQ_PTS0,
63 PTS_S_WAIT_REQ_PTS1,
64 PTS_S_WAIT_REQ_PTS2,
65 PTS_S_WAIT_REQ_PTS3,
66 PTS_S_WAIT_REQ_PCK,
67 PTS_S_WAIT_RESP_PTSS = PTS_S_WAIT_REQ_PTSS | 0x10,
68 PTS_S_WAIT_RESP_PTS0 = PTS_S_WAIT_REQ_PTS0 | 0x10,
69 PTS_S_WAIT_RESP_PTS1 = PTS_S_WAIT_REQ_PTS1 | 0x10,
70 PTS_S_WAIT_RESP_PTS2 = PTS_S_WAIT_REQ_PTS2 | 0x10,
71 PTS_S_WAIT_RESP_PTS3 = PTS_S_WAIT_REQ_PTS3 | 0x10,
72 PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
73};
74
75#define _PTSS 0
76#define _PTS0 1
77#define _PTS1 2
78#define _PTS2 3
79#define _PTS3 4
80#define _PCK 5
81
Harald Welte16cf4082015-11-11 19:02:48 +010082/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +010083enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +010084 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
85 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
86 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
87 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
88 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +010089 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
90 TPDU_S_WAIT_RX, /* waiitng for more data from reader */
91 TPDU_S_WAIT_TX, /* waiting for more data to reader */
92};
93
94#define _CLA 0
95#define _INS 1
96#define _P1 2
97#define _P2 3
98#define _P3 4
99
100struct card_handle {
Harald Weltedde112e2016-03-20 16:42:11 +0100101 uint32_t num;
102
Harald Welte9d3e3822015-11-09 00:50:54 +0100103 enum iso7816_3_card_state state;
104
105 /* signal levels */
106 uint8_t vcc_active; /* 1 = on, 0 = off */
107 uint8_t in_reset; /* 1 = RST low, 0 = RST high */
108 uint8_t clocked; /* 1 = active, 0 = inactive */
109
Harald Welte16cf4082015-11-11 19:02:48 +0100110 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100111 uint8_t fi;
112 uint8_t di;
113 uint8_t wi;
114
115 uint8_t tc_chan; /* TC channel number */
116 uint8_t uart_chan; /* UART channel */
117
Harald Welte8e7fca32017-05-07 16:14:33 +0200118 uint8_t in_ep; /* USB IN EP */
119 uint8_t irq_ep; /* USB IN EP */
120
Harald Welte9d3e3822015-11-09 00:50:54 +0100121 uint32_t waiting_time; /* in clocks */
122
123 /* ATR state machine */
124 struct {
125 uint8_t idx;
126 uint8_t len;
127 //uint8_t hist_len;
128 //uint8_t last_td;
129 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
130 } atr;
131
132 /* PPS / PTS support */
133 struct {
134 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100135 uint8_t req[6]; /* request bytes */
136 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100137 } pts;
138
139 /* TPDU */
140 struct {
141 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100142 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100143 } tpdu;
144
Harald Welte8e7fca32017-05-07 16:14:33 +0200145 struct msgb *uart_rx_msg; /* UART RX -> USB TX */
146 struct msgb *uart_tx_msg; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100147
Harald Welte54cb3d02016-02-29 14:12:40 +0100148 struct llist_head uart_tx_queue;
149
Harald Welte9d3e3822015-11-09 00:50:54 +0100150 struct {
151 uint32_t tx_bytes;
152 uint32_t rx_bytes;
153 uint32_t pps;
154 } stats;
155};
156
Harald Welte54cb3d02016-02-29 14:12:40 +0100157struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
158{
159 return &ch->uart_tx_queue;
160}
161
Harald Welte2935b3c2015-11-14 20:00:14 +0100162static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100163static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100164
Harald Welteb5288e82015-11-14 21:15:52 +0100165static void flush_rx_buffer(struct card_handle *ch)
166{
Harald Welte8e7fca32017-05-07 16:14:33 +0200167 struct msgb *msg;
Harald Welteb5288e82015-11-14 21:15:52 +0100168 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200169 uint32_t data_len;
Harald Welteb5288e82015-11-14 21:15:52 +0100170
Harald Welte8e7fca32017-05-07 16:14:33 +0200171 msg = ch->uart_rx_msg;
172 if (!msg)
Harald Welteb5288e82015-11-14 21:15:52 +0100173 return;
174
Harald Welte8e7fca32017-05-07 16:14:33 +0200175 ch->uart_rx_msg = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100176
177 /* store length of data payload fild in header */
Harald Welte8e7fca32017-05-07 16:14:33 +0200178 rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
179 msg->l2h = &rd->data;
180 rd->data_len = msgb_l2len(msg);
181 rd->hdr.msg_len = msgb_length(msg);
Harald Welte54cb3d02016-02-29 14:12:40 +0100182
Harald Welte8e7fca32017-05-07 16:14:33 +0200183 usb_buf_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100184}
185
Harald Welte4ba66d02016-02-25 19:38:56 +0100186/* convert a non-contiguous PTS request/responsei into a contiguous
187 * buffer, returning the number of bytes used in the buffer */
188static int serialize_pts(uint8_t *out, const uint8_t *in)
189{
190 int i = 0;
191
192 out[i++] = in[_PTSS];
193 out[i++] = in[_PTS0];
194 if (in[_PTS0] & (1 << 4))
195 out[i++] = in[_PTS1];
196 if (in[_PTS0] & (1 << 5))
197 out[i++] = in[_PTS2];
198 if (in[_PTS0] & (1 << 6))
199 out[i++] = in[_PTS3];
200 out[i++] = in[_PCK];
201
202 return i;
203}
204
Harald Welte17db2f12016-02-26 09:48:57 +0100205static uint8_t csum_pts(const uint8_t *in)
206{
207 uint8_t out[6];
208 int len = serialize_pts(out, in);
209 uint8_t csum = 0;
210 int i;
211
212 /* we don't include the PCK byte in the checksumming process */
213 len -= 1;
214
215 for (i = 0; i < len; i++)
216 csum = csum ^ out[i];
217
218 return csum;
219}
220
Harald Welte4ba66d02016-02-25 19:38:56 +0100221static void flush_pts(struct card_handle *ch)
222{
Harald Welte8e7fca32017-05-07 16:14:33 +0200223 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100224 struct cardemu_usb_msg_pts_info *ptsi;
225
Harald Welte8e7fca32017-05-07 16:14:33 +0200226 msg = usb_buf_alloc(ch->in_ep);
227 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100228 return;
229
Harald Welte8e7fca32017-05-07 16:14:33 +0200230 msg->l1h = msgb_put(msg, sizeof(*ptsi));
231 msg->l2h = msg->l1h + sizeof(ptsi->hdr);
232 ptsi = (struct cardemu_usb_msg_pts_info *) msg->l1h;
Harald Welte4ba66d02016-02-25 19:38:56 +0100233 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
Harald Welte8e7fca32017-05-07 16:14:33 +0200238 usb_buf_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100239}
240
Harald Welte8c496362016-02-27 16:24:09 +0100241static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100242{
243 int rc;
244
245 rc = compute_fidi_ratio(ch->fi, ch->di);
246 if (rc > 0 && rc < 0x400) {
Harald Weltedde112e2016-03-20 16:42:11 +0100247 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
248 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100249 /* make sure UART uses new F/D ratio */
250 card_emu_uart_update_fidi(ch->uart_chan, rc);
251 /* notify ETU timer about this */
252 tc_etu_set_etu(ch->tc_chan, rc);
253 } else
Harald Weltedde112e2016-03-20 16:42:11 +0100254 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
255 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100256}
257
258/* Update the ISO 7816-3 TPDU receiver state */
259static void card_set_state(struct card_handle *ch,
260 enum iso7816_3_card_state new_state)
261{
Harald Welte903d63a2016-03-20 13:38:39 +0100262 if (ch->state == new_state)
263 return;
264
Harald Weltedde112e2016-03-20 16:42:11 +0100265 TRACE_DEBUG("%u: 7816 card state %u -> %u\r\n", ch->num,
266 ch->state, new_state);
Harald Welte903d63a2016-03-20 13:38:39 +0100267 ch->state = new_state;
268
Harald Welte9d3e3822015-11-09 00:50:54 +0100269 switch (new_state) {
270 case ISO_S_WAIT_POWER:
271 case ISO_S_WAIT_CLK:
272 case ISO_S_WAIT_RST:
273 /* disable Rx and Tx of UART */
274 card_emu_uart_enable(ch->uart_chan, 0);
275 break;
276 case ISO_S_WAIT_ATR:
Harald Weltee7194ab2015-11-14 21:03:25 +0100277 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100278 /* Reset to initial Fi / Di ratio */
279 ch->fi = 1;
280 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100281 emu_update_fidi(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100282 /* initialize todefault WI, this will be overwritten if we
283 * receive TC2, and it will be programmed into hardware after
284 * ATR is finished */
285 ch->wi = ISO7816_3_DEFAULT_WI;
286 /* update waiting time to initial waiting time */
287 ch->waiting_time = ISO7816_3_INIT_WTIME;
288 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
289 /* Set ATR sub-state to initial state */
290 ch->atr.idx = 0;
291 //set_atr_state(ch, ATR_S_WAIT_TS);
292 /* Notice that we are just coming out of reset */
293 //ch->sh.flags |= SIMTRACE_FLAG_ATR;
294 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
295 break;
296 break;
297 case ISO_S_WAIT_TPDU:
298 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100299 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100300 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
301 break;
302 case ISO_S_IN_ATR:
303 case ISO_S_IN_PTS:
304 case ISO_S_IN_TPDU:
305 /* do nothing */
306 break;
307 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100308}
309
310
311/**********************************************************************
312 * PTS / PPS handling
313 **********************************************************************/
314
315/* Update the ATR sub-state */
316static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
317{
Harald Weltedde112e2016-03-20 16:42:11 +0100318 TRACE_DEBUG("%u: 7816 PTS state %u -> %u\r\n",
319 ch->num, 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 Weltedde112e2016-03-20 16:42:11 +0100389 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
390 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100391 /* Wait for the next TPDU */
392 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
393 return ISO_S_WAIT_TPDU;
394 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100395 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100396 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
397 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100398 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100399 TRACE_ERROR("%u: process_byte_pts() in invalid state %u\r\n",
400 ch->num, ch->pts.state);
Harald Welte4c473da2015-11-14 13:31:11 +0100401 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100402 }
403 /* calculate the next state and set it */
404 set_pts_state(ch, next_pts_state(ch));
405
Harald Welte4ba66d02016-02-25 19:38:56 +0100406 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
407 flush_pts(ch);
408 /* activate UART TX to transmit PTS response */
409 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100410 /* don't fall-through to the 'return ISO_S_IN_PTS'
411 * below, rather keep ISO7816 state as-is, it will be
412 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100413 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100414 }
415
Harald Welte9d3e3822015-11-09 00:50:54 +0100416 return ISO_S_IN_PTS;
417}
418
419/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100420static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100421{
Harald Welte855ba9e2016-02-24 21:00:46 +0100422 uint8_t byte;
423
424 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100425 switch (ch->pts.state) {
426 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100427 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100428 break;
429 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100430 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100431 break;
432 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100433 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100434 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100435 ch->fi = byte >> 4;
436 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100437 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
438 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100439 break;
440 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100441 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100442 break;
443 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100444 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100445 break;
446 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100447 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100448 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100449 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100450 TRACE_ERROR("%u: get_byte_pts() in invalid state %u\r\n",
451 ch->num, ch->pts.state);
Harald Welte855ba9e2016-02-24 21:00:46 +0100452 return 0;
453 }
454
455 /* 2: Transmit the byte */
456 card_emu_uart_tx(ch->uart_chan, byte);
457
458 /* 3: Update the state */
459
460 switch (ch->pts.state) {
461 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100462 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100463 /* update baud rate generator with Fi/Di */
464 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100465 /* Wait for the next TPDU */
466 card_set_state(ch, ISO_S_WAIT_TPDU);
467 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
468 break;
469 default:
470 /* calculate the next state and set it */
471 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100472 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100473 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100474
Harald Welte855ba9e2016-02-24 21:00:46 +0100475 /* return number of bytes transmitted */
476 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100477}
478
479
480/**********************************************************************
481 * TPDU handling
482 **********************************************************************/
483
Harald Welte4d804672015-11-14 23:02:38 +0100484
485/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
486static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
487{
488 if (reader_to_card) {
489 return p3;
490 } else {
491 if (p3 == 0)
492 return 256;
493 else
494 return p3;
495 }
496}
497
Harald Welte9d3e3822015-11-09 00:50:54 +0100498/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100499static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100500{
Harald Welte8e7fca32017-05-07 16:14:33 +0200501 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100502 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100503 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100504
505 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200506 if (!ch->uart_rx_msg) {
507 msg = ch->uart_rx_msg = usb_buf_alloc(ch->in_ep);
508 if (!ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100509 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
510 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100511 return;
Harald Welte4d804672015-11-14 23:02:38 +0100512 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200513 msg->l1h = msgb_put(msg, sizeof(*rd));
514 rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
515 msg->l2h = msg->l1h + sizeof(rd->hdr);
Harald Welte9d3e3822015-11-09 00:50:54 +0100516 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100517 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200518 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100519
Harald Welte8e7fca32017-05-07 16:14:33 +0200520 rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
521 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100522
523 /* check if the buffer is full. If so, send it */
Harald Welte8e7fca32017-05-07 16:14:33 +0200524 if (msgb_length(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100525 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100526 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100527 /* We need to transmit the SW now, */
528 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200529 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100530 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100531}
532
533static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
534{
Harald Welte05b41c62015-11-14 20:58:48 +0100535 if (ch->tpdu.state == new_ts)
536 return;
537
Harald Weltedde112e2016-03-20 16:42:11 +0100538 TRACE_DEBUG("%u: 7816 TPDU state %u -> %u\r\n", ch->num,
539 ch->tpdu.state, new_ts);
Harald Welte05b41c62015-11-14 20:58:48 +0100540
Harald Welte903d63a2016-03-20 13:38:39 +0100541 ch->tpdu.state = new_ts;
542
Harald Welte9d3e3822015-11-09 00:50:54 +0100543 switch (new_ts) {
544 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100545 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100546 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
547 break;
548 case TPDU_S_WAIT_PB:
549 /* we just completed the TPDU header from reader to card
550 * and now need to disable the receiver, enable the
551 * transmitter and transmit the procedure byte */
552 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
553 break;
Harald Weltead434402016-03-02 11:18:29 +0100554 default:
555 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100556 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100557}
558
559static enum tpdu_state next_tpdu_state(struct card_handle *ch)
560{
561 switch (ch->tpdu.state) {
562 case TPDU_S_WAIT_CLA:
563 return TPDU_S_WAIT_INS;
564 case TPDU_S_WAIT_INS:
565 return TPDU_S_WAIT_P1;
566 case TPDU_S_WAIT_P1:
567 return TPDU_S_WAIT_P2;
568 case TPDU_S_WAIT_P2:
569 return TPDU_S_WAIT_P3;
570 case TPDU_S_WAIT_P3:
571 return TPDU_S_WAIT_PB;
572 /* simply stay in Rx or Tx by default */
573 case TPDU_S_WAIT_PB:
574 return TPDU_S_WAIT_PB;
575 case TPDU_S_WAIT_RX:
576 return TPDU_S_WAIT_RX;
577 case TPDU_S_WAIT_TX:
578 return TPDU_S_WAIT_TX;
579 }
Harald Welte4c473da2015-11-14 13:31:11 +0100580 /* we should never reach here */
581 assert(0);
582 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100583}
584
585static void send_tpdu_header(struct card_handle *ch)
586{
Harald Welte8e7fca32017-05-07 16:14:33 +0200587 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100588 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200589 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100590
Harald Weltedde112e2016-03-20 16:42:11 +0100591 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
592 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100593 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
594 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
595 ch->tpdu.hdr[4]);
596
Harald Welte9d3e3822015-11-09 00:50:54 +0100597 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200598 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100599 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200600 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100601 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100602 flush_rx_buffer(ch);
603 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100604 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200605 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
606 /* ensure we have a new buffer */
607 ch->uart_rx_msg = usb_buf_alloc(ch->in_ep);
608 if (!ch->uart_rx_msg) {
609 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
610 return;
611 }
612 msg = ch->uart_rx_msg;
613 msg->l1h = msgb_put(msg, sizeof(*rd));
614 rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100615
Harald Welte8e7fca32017-05-07 16:14:33 +0200616 /* initialize header */
617 msg->l2h = msg->l1h + sizeof(rd->hdr);
Harald Welte9d3e3822015-11-09 00:50:54 +0100618 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
619 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100620
621 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200622 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
623 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100624 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100625
Harald Welteb5288e82015-11-14 21:15:52 +0100626 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100627}
628
629static enum iso7816_3_card_state
630process_byte_tpdu(struct card_handle *ch, uint8_t byte)
631{
632 switch (ch->tpdu.state) {
633 case TPDU_S_WAIT_CLA:
634 ch->tpdu.hdr[_CLA] = 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_INS:
638 ch->tpdu.hdr[_INS] = 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_P1:
642 ch->tpdu.hdr[_P1] = 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_P2:
646 ch->tpdu.hdr[_P2] = 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_P3:
650 ch->tpdu.hdr[_P3] = 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 /* FIXME: start timer to transmit further 0x60 */
653 /* send the TPDU header as part of a procedure byte
654 * request to the USB host */
655 send_tpdu_header(ch);
656 break;
657 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100658 add_tpdu_byte(ch, byte);
659 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100660 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100661 TRACE_ERROR("%u: process_byte_tpdu() in invalid state %u\r\n",
662 ch->num, ch->tpdu.state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100663 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100664
665 /* ensure we stay in TPDU ISO state */
666 return ISO_S_IN_TPDU;
667}
668
Harald Welte855ba9e2016-02-24 21:00:46 +0100669/* tx a single byte to be transmitted to the reader */
670static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100671{
Harald Welte8e7fca32017-05-07 16:14:33 +0200672 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100673 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100674 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100675
676 /* ensure we are aware of any data that might be pending for
677 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200678 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100679 /* uart_tx_queue is filled from main loop, so no need
680 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100681 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100682 return 0;
683
Harald Welte54cb3d02016-02-29 14:12:40 +0100684 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200685 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
686 ch->uart_tx_msg->l1h = ch->uart_tx_msg->data;
687 msg = ch->uart_tx_msg;
688 msgb_pull(msg, sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100689 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200690 msg = ch->uart_tx_msg;
691 td = (struct cardemu_usb_msg_tx_data *) msg->l1h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100692
Harald Welte8e7fca32017-05-07 16:14:33 +0200693 /* take the next pending byte out of the msgb */
694 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100695
696 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100697
Harald Weltef16b6182016-02-24 22:18:46 +0100698 /* this must happen _after_ the byte has been transmittd */
699 switch (ch->tpdu.state) {
700 case TPDU_S_WAIT_PB:
701 /* if we just transmitted the procedure byte, we need to decide
702 * if we want to continue to receive or transmit */
703 if (td->flags & CEMU_DATA_F_PB_AND_TX)
704 set_tpdu_state(ch, TPDU_S_WAIT_TX);
705 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
706 set_tpdu_state(ch, TPDU_S_WAIT_RX);
707 break;
Harald Weltead434402016-03-02 11:18:29 +0100708 default:
709 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100710 }
711
Harald Welte9d3e3822015-11-09 00:50:54 +0100712 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200713 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100714 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
715 /* we have just sent the procedure byte and now
716 * need to continue receiving */
717 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100718 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100719 /* we have transmitted all bytes */
720 if (td->flags & CEMU_DATA_F_FINAL) {
721 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100722 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100723 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100724 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100725 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200726 usb_buf_free(msg);
727 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100728 }
729
730 return 1;
731}
732
733/**********************************************************************
734 * Public API
735 **********************************************************************/
736
737/* process a single byte received from the reader */
738void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
739{
740 int new_state = -1;
741
742 ch->stats.rx_bytes++;
743
744 switch (ch->state) {
745 case ISO_S_WAIT_POWER:
746 case ISO_S_WAIT_CLK:
747 case ISO_S_WAIT_RST:
748 case ISO_S_WAIT_ATR:
Harald Weltedde112e2016-03-20 16:42:11 +0100749 TRACE_ERROR("%u: Received UART char in invalid 7816 state "
750 "%u\r\n", ch->num, ch->state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100751 /* we shouldn't receive any data from the reader yet! */
752 break;
753 case ISO_S_WAIT_TPDU:
754 if (byte == 0xff) {
755 new_state = process_byte_pts(ch, byte);
756 ch->stats.pps++;
757 goto out_silent;
758 }
759 /* fall-through */
760 case ISO_S_IN_TPDU:
761 new_state = process_byte_tpdu(ch, byte);
762 break;
763 case ISO_S_IN_PTS:
764 new_state = process_byte_pts(ch, byte);
765 goto out_silent;
766 }
767
768out_silent:
769 if (new_state != -1)
770 card_set_state(ch, new_state);
771}
772
Harald Welte855ba9e2016-02-24 21:00:46 +0100773/* transmit a single byte to the reader */
774int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100775{
776 int rc = 0;
777
778 switch (ch->state) {
779 case ISO_S_IN_ATR:
780 if (ch->atr.idx < ch->atr.len) {
Harald Welte855ba9e2016-02-24 21:00:46 +0100781 uint8_t byte;
782 byte = ch->atr.atr[ch->atr.idx++];
Harald Welte9d3e3822015-11-09 00:50:54 +0100783 rc = 1;
Harald Welte855ba9e2016-02-24 21:00:46 +0100784
785 card_emu_uart_tx(ch->uart_chan, byte);
786
Harald Welte9d3e3822015-11-09 00:50:54 +0100787 /* detect end of ATR */
788 if (ch->atr.idx >= ch->atr.len)
789 card_set_state(ch, ISO_S_WAIT_TPDU);
790 }
791 break;
792 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100793 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100794 break;
795 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +0100796 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100797 break;
Harald Weltead434402016-03-02 11:18:29 +0100798 default:
799 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100800 }
801
802 if (rc)
803 ch->stats.tx_bytes++;
804
Harald Welte4d804672015-11-14 23:02:38 +0100805 /* if we return 0 here, the UART needs to disable transmit-ready
806 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +0100807 return rc;
808}
809
Harald Welteacae4122016-03-02 10:27:58 +0100810void card_emu_have_new_uart_tx(struct card_handle *ch)
811{
812 switch (ch->state) {
813 case ISO_S_IN_TPDU:
814 switch (ch->tpdu.state) {
815 case TPDU_S_WAIT_TX:
816 case TPDU_S_WAIT_PB:
817 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
818 break;
819 default:
820 break;
821 }
822 default:
823 break;
824 }
825}
826
Harald Welteff160652016-03-19 21:59:06 +0100827void card_emu_report_status(struct card_handle *ch)
828{
Harald Welte8e7fca32017-05-07 16:14:33 +0200829 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +0100830 struct cardemu_usb_msg_status *sts;
831
Harald Welte8e7fca32017-05-07 16:14:33 +0200832 msg = usb_buf_alloc(ch->in_ep);
833 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +0100834 return;
Harald Welte8e7fca32017-05-07 16:14:33 +0200835
836 msg->l1h = msgb_put(msg, sizeof(*sts));
837 msg->l2h = msg->l1h + sizeof(sts->hdr);
838 sts = (struct cardemu_usb_msg_status *) msg->l1h;
Harald Welteff160652016-03-19 21:59:06 +0100839 sts->hdr.msg_type = CEMU_USB_MSGT_DO_STATUS;
840 sts->hdr.msg_len = sizeof(*sts);
841 sts->flags = 0;
842 if (ch->vcc_active)
843 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
844 if (ch->clocked)
845 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
846 if (ch->in_reset)
847 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
848 /* FIXME: voltage + card insert */
849 sts->fi = ch->fi;
850 sts->di = ch->di;
851 sts->wi = ch->wi;
852 sts->waiting_time = ch->waiting_time;
853
Harald Welte8e7fca32017-05-07 16:14:33 +0200854 usb_buf_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +0100855}
856
Harald Welte9d3e3822015-11-09 00:50:54 +0100857/* hardware driver informs us that a card I/O signal has changed */
858void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
859{
860 switch (io) {
861 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +0100862 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100863 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100864 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100865 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +0100866 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100867 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100868 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +0100869 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100870 ch->vcc_active = active;
871 break;
872 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +0100873 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100874 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100875 if (ch->state == ISO_S_WAIT_CLK)
876 card_set_state(ch, ISO_S_WAIT_RST);
877 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100878 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100879 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100880 ch->clocked = active;
881 break;
882 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +0100883 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100884 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100885 if (ch->vcc_active && ch->clocked) {
886 /* enable the TC/ETU counter once reset has been released */
887 tc_etu_enable(ch->tc_chan);
888 card_set_state(ch, ISO_S_WAIT_ATR);
889 /* FIXME: wait 400 to 40k clock cycles before sending ATR */
890 card_set_state(ch, ISO_S_IN_ATR);
891 }
892 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100893 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100894 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100895 }
896 ch->in_reset = active;
897 break;
898 }
899}
900
901/* User sets a new ATR to be returned during next card reset */
902int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
903{
904 if (len > sizeof(ch->atr.atr))
905 return -1;
906
907 memcpy(ch->atr.atr, atr, len);
908 ch->atr.len = len;
909 ch->atr.idx = 0;
910
911 /* FIXME: race condition with trasmitting ATR to reader? */
912
913 return 0;
914}
915
916/* hardware driver informs us that one (more) ETU has expired */
917void tc_etu_wtime_half_expired(void *handle)
918{
919 struct card_handle *ch = handle;
920 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +0100921 switch (ch->state) {
922 case ISO_S_IN_TPDU:
923 switch (ch->tpdu.state) {
924 case TPDU_S_WAIT_PB:
925 case TPDU_S_WAIT_TX:
926 putchar('N');
927 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
928 break;
929 default:
930 break;
931 }
932 break;
933 default:
934 break;
935 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100936}
937
938/* hardware driver informs us that one (more) ETU has expired */
939void tc_etu_wtime_expired(void *handle)
940{
Harald Weltedde112e2016-03-20 16:42:11 +0100941 struct card_handle *ch = handle;
942 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100943}
944
945/* shortest ATR found in smartcard_list.txt */
946static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
947
948static struct card_handle card_handles[NUM_SLOTS];
949
Harald Welte8e7fca32017-05-07 16:14:33 +0200950struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan,
951 uint8_t in_ep, uint8_t irq_ep)
Harald Welte9d3e3822015-11-09 00:50:54 +0100952{
953 struct card_handle *ch;
954
955 if (slot_num >= ARRAY_SIZE(card_handles))
956 return NULL;
957
958 ch = &card_handles[slot_num];
959
960 memset(ch, 0, sizeof(*ch));
961
Harald Welte54cb3d02016-02-29 14:12:40 +0100962 INIT_LLIST_HEAD(&ch->uart_tx_queue);
963
Harald Welte9d3e3822015-11-09 00:50:54 +0100964 /* initialize the card_handle with reasonabe defaults */
Harald Weltedde112e2016-03-20 16:42:11 +0100965 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +0200966 ch->irq_ep = irq_ep;
967 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +0100968 ch->state = ISO_S_WAIT_POWER;
969 ch->vcc_active = 0;
970 ch->in_reset = 1;
971 ch->clocked = 0;
972
973 ch->fi = 0;
974 ch->di = 1;
975 ch->wi = ISO7816_3_DEFAULT_WI;
976
977 ch->tc_chan = tc_chan;
978 ch->uart_chan = uart_chan;
979 ch->waiting_time = ISO7816_3_INIT_WTIME;
980
981 ch->atr.idx = 0;
982 ch->atr.len = sizeof(default_atr);
983 memcpy(ch->atr.atr, default_atr, ch->atr.len);
984
985 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
986 ch->tpdu.state = TPDU_S_WAIT_CLA;
987
988 tc_etu_init(ch->tc_chan, ch);
989
990 return ch;
991}