blob: 7aa3fc0be28d5878add30206ad16609192515707 [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 Welte25a9a802017-05-08 13:30:09 +020034#include "simtrace_prot.h"
Harald Welte8e7fca32017-05-07 16:14:33 +020035#include "usb_buf.h"
Harald Welte9d90d282018-06-29 22:25:42 +020036#include <osmocom/core/linuxlist.h>
37#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 Welte25a9a802017-05-08 13:30:09 +0200165/* update simtrace header msg_len and submit USB buffer */
166void usb_buf_upd_len_and_submit(struct msgb *msg)
167{
Harald Welteb91f6ad2017-05-10 22:51:30 +0200168 struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
Harald Welte25a9a802017-05-08 13:30:09 +0200169
170 sh->msg_len = msgb_length(msg);
171
172 usb_buf_submit(msg);
173}
174
175/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
176struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
177{
178 struct msgb *msg;
179 struct simtrace_msg_hdr *sh;
180
181 msg = usb_buf_alloc(ep);
182 if (!msg)
183 return NULL;
184
185 msg->l1h = msgb_put(msg, sizeof(*sh));
186 sh = (struct simtrace_msg_hdr *) msg->l1h;
187 memset(sh, 0, sizeof(*sh));
188 sh->msg_class = msg_class;
189 sh->msg_type = msg_type;
190 msg->l2h = msg->l1h + sizeof(*sh);
191
192 return msg;
193}
194
195/* Update cardemu_usb_msg_rx_data length + submit bufffer */
Harald Welteb5288e82015-11-14 21:15:52 +0100196static void flush_rx_buffer(struct card_handle *ch)
197{
Harald Welte8e7fca32017-05-07 16:14:33 +0200198 struct msgb *msg;
Harald Welteb5288e82015-11-14 21:15:52 +0100199 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200200 uint32_t data_len;
Harald Welteb5288e82015-11-14 21:15:52 +0100201
Harald Welte8e7fca32017-05-07 16:14:33 +0200202 msg = ch->uart_rx_msg;
203 if (!msg)
Harald Welteb5288e82015-11-14 21:15:52 +0100204 return;
205
Harald Welte8e7fca32017-05-07 16:14:33 +0200206 ch->uart_rx_msg = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100207
208 /* store length of data payload fild in header */
Harald Welte25a9a802017-05-08 13:30:09 +0200209 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
210 rd->data_len = msgb_l2len(msg) - sizeof(*rd);
Harald Welte54cb3d02016-02-29 14:12:40 +0100211
Harald Welte25a9a802017-05-08 13:30:09 +0200212 usb_buf_upd_len_and_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100213}
214
Harald Welte4ba66d02016-02-25 19:38:56 +0100215/* convert a non-contiguous PTS request/responsei into a contiguous
216 * buffer, returning the number of bytes used in the buffer */
217static int serialize_pts(uint8_t *out, const uint8_t *in)
218{
219 int i = 0;
220
221 out[i++] = in[_PTSS];
222 out[i++] = in[_PTS0];
223 if (in[_PTS0] & (1 << 4))
224 out[i++] = in[_PTS1];
225 if (in[_PTS0] & (1 << 5))
226 out[i++] = in[_PTS2];
227 if (in[_PTS0] & (1 << 6))
228 out[i++] = in[_PTS3];
229 out[i++] = in[_PCK];
230
231 return i;
232}
233
Harald Welte17db2f12016-02-26 09:48:57 +0100234static uint8_t csum_pts(const uint8_t *in)
235{
236 uint8_t out[6];
237 int len = serialize_pts(out, in);
238 uint8_t csum = 0;
239 int i;
240
241 /* we don't include the PCK byte in the checksumming process */
242 len -= 1;
243
244 for (i = 0; i < len; i++)
245 csum = csum ^ out[i];
246
247 return csum;
248}
249
Harald Welte4ba66d02016-02-25 19:38:56 +0100250static void flush_pts(struct card_handle *ch)
251{
Harald Welte8e7fca32017-05-07 16:14:33 +0200252 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100253 struct cardemu_usb_msg_pts_info *ptsi;
254
Harald Welte25a9a802017-05-08 13:30:09 +0200255 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200256 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100257 return;
258
Harald Welte25a9a802017-05-08 13:30:09 +0200259 ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
Harald Welted295b922016-03-18 21:01:36 +0100260 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100261 serialize_pts(ptsi->resp, ch->pts.resp);
262
Harald Welte25a9a802017-05-08 13:30:09 +0200263 usb_buf_upd_len_and_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100264}
265
Harald Welte8c496362016-02-27 16:24:09 +0100266static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100267{
268 int rc;
269
270 rc = compute_fidi_ratio(ch->fi, ch->di);
271 if (rc > 0 && rc < 0x400) {
Harald Weltedde112e2016-03-20 16:42:11 +0100272 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
273 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100274 /* make sure UART uses new F/D ratio */
275 card_emu_uart_update_fidi(ch->uart_chan, rc);
276 /* notify ETU timer about this */
277 tc_etu_set_etu(ch->tc_chan, rc);
278 } else
Harald Weltedde112e2016-03-20 16:42:11 +0100279 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
280 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100281}
282
283/* Update the ISO 7816-3 TPDU receiver state */
284static void card_set_state(struct card_handle *ch,
285 enum iso7816_3_card_state new_state)
286{
Harald Welte903d63a2016-03-20 13:38:39 +0100287 if (ch->state == new_state)
288 return;
289
Harald Weltedde112e2016-03-20 16:42:11 +0100290 TRACE_DEBUG("%u: 7816 card state %u -> %u\r\n", ch->num,
291 ch->state, new_state);
Harald Welte903d63a2016-03-20 13:38:39 +0100292 ch->state = new_state;
293
Harald Welte9d3e3822015-11-09 00:50:54 +0100294 switch (new_state) {
295 case ISO_S_WAIT_POWER:
296 case ISO_S_WAIT_CLK:
297 case ISO_S_WAIT_RST:
298 /* disable Rx and Tx of UART */
299 card_emu_uart_enable(ch->uart_chan, 0);
300 break;
301 case ISO_S_WAIT_ATR:
Harald Weltee7194ab2015-11-14 21:03:25 +0100302 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100303 /* Reset to initial Fi / Di ratio */
304 ch->fi = 1;
305 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100306 emu_update_fidi(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100307 /* initialize todefault WI, this will be overwritten if we
308 * receive TC2, and it will be programmed into hardware after
309 * ATR is finished */
310 ch->wi = ISO7816_3_DEFAULT_WI;
311 /* update waiting time to initial waiting time */
312 ch->waiting_time = ISO7816_3_INIT_WTIME;
313 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
314 /* Set ATR sub-state to initial state */
315 ch->atr.idx = 0;
316 //set_atr_state(ch, ATR_S_WAIT_TS);
317 /* Notice that we are just coming out of reset */
318 //ch->sh.flags |= SIMTRACE_FLAG_ATR;
319 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
320 break;
321 break;
322 case ISO_S_WAIT_TPDU:
323 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100324 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100325 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
326 break;
327 case ISO_S_IN_ATR:
328 case ISO_S_IN_PTS:
329 case ISO_S_IN_TPDU:
330 /* do nothing */
331 break;
332 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100333}
334
335
336/**********************************************************************
337 * PTS / PPS handling
338 **********************************************************************/
339
340/* Update the ATR sub-state */
341static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
342{
Harald Weltedde112e2016-03-20 16:42:11 +0100343 TRACE_DEBUG("%u: 7816 PTS state %u -> %u\r\n",
344 ch->num, ch->pts.state, new_ptss);
Harald Welte9d3e3822015-11-09 00:50:54 +0100345 ch->pts.state = new_ptss;
346}
347
348/* Determine the next PTS state */
349static enum pts_state next_pts_state(struct card_handle *ch)
350{
351 uint8_t is_resp = ch->pts.state & 0x10;
352 uint8_t sstate = ch->pts.state & 0x0f;
353 uint8_t *pts_ptr;
354
355 if (!is_resp)
356 pts_ptr = ch->pts.req;
357 else
358 pts_ptr = ch->pts.resp;
359
360 switch (sstate) {
361 case PTS_S_WAIT_REQ_PTSS:
362 goto from_ptss;
363 case PTS_S_WAIT_REQ_PTS0:
364 goto from_pts0;
365 case PTS_S_WAIT_REQ_PTS1:
366 goto from_pts1;
367 case PTS_S_WAIT_REQ_PTS2:
368 goto from_pts2;
369 case PTS_S_WAIT_REQ_PTS3:
370 goto from_pts3;
371 }
372
373 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
374 return PTS_S_WAIT_RESP_PTSS;
375
376from_ptss:
377 return PTS_S_WAIT_REQ_PTS0 | is_resp;
378from_pts0:
379 if (pts_ptr[_PTS0] & (1 << 4))
380 return PTS_S_WAIT_REQ_PTS1 | is_resp;
381from_pts1:
382 if (pts_ptr[_PTS0] & (1 << 5))
383 return PTS_S_WAIT_REQ_PTS2 | is_resp;
384from_pts2:
385 if (pts_ptr[_PTS0] & (1 << 6))
386 return PTS_S_WAIT_REQ_PTS3 | is_resp;
387from_pts3:
388 return PTS_S_WAIT_REQ_PCK | is_resp;
389}
390
391
Harald Welteccb8a222016-03-20 13:37:11 +0100392static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100393process_byte_pts(struct card_handle *ch, uint8_t byte)
394{
395 switch (ch->pts.state) {
396 case PTS_S_WAIT_REQ_PTSS:
397 ch->pts.req[_PTSS] = byte;
398 break;
399 case PTS_S_WAIT_REQ_PTS0:
400 ch->pts.req[_PTS0] = byte;
401 break;
402 case PTS_S_WAIT_REQ_PTS1:
403 ch->pts.req[_PTS1] = byte;
404 break;
405 case PTS_S_WAIT_REQ_PTS2:
406 ch->pts.req[_PTS2] = byte;
407 break;
408 case PTS_S_WAIT_REQ_PTS3:
409 ch->pts.req[_PTS3] = byte;
410 break;
411 case PTS_S_WAIT_REQ_PCK:
412 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100413 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100414 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
415 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100416 /* Wait for the next TPDU */
417 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
418 return ISO_S_WAIT_TPDU;
419 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100420 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100421 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
422 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100423 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100424 TRACE_ERROR("%u: process_byte_pts() in invalid state %u\r\n",
425 ch->num, ch->pts.state);
Harald Welte4c473da2015-11-14 13:31:11 +0100426 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100427 }
428 /* calculate the next state and set it */
429 set_pts_state(ch, next_pts_state(ch));
430
Harald Welte4ba66d02016-02-25 19:38:56 +0100431 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
432 flush_pts(ch);
433 /* activate UART TX to transmit PTS response */
434 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100435 /* don't fall-through to the 'return ISO_S_IN_PTS'
436 * below, rather keep ISO7816 state as-is, it will be
437 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100438 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100439 }
440
Harald Welte9d3e3822015-11-09 00:50:54 +0100441 return ISO_S_IN_PTS;
442}
443
444/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100445static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100446{
Harald Welte855ba9e2016-02-24 21:00:46 +0100447 uint8_t byte;
448
449 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100450 switch (ch->pts.state) {
451 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100452 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100453 break;
454 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100455 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100456 break;
457 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100458 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100459 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100460 ch->fi = byte >> 4;
461 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100462 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
463 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100464 break;
465 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100466 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100467 break;
468 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100469 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100470 break;
471 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100472 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100473 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100474 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100475 TRACE_ERROR("%u: get_byte_pts() in invalid state %u\r\n",
476 ch->num, ch->pts.state);
Harald Welte855ba9e2016-02-24 21:00:46 +0100477 return 0;
478 }
479
480 /* 2: Transmit the byte */
481 card_emu_uart_tx(ch->uart_chan, byte);
482
483 /* 3: Update the state */
484
485 switch (ch->pts.state) {
486 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100487 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100488 /* update baud rate generator with Fi/Di */
489 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100490 /* Wait for the next TPDU */
491 card_set_state(ch, ISO_S_WAIT_TPDU);
492 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
493 break;
494 default:
495 /* calculate the next state and set it */
496 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100497 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100498 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100499
Harald Welte855ba9e2016-02-24 21:00:46 +0100500 /* return number of bytes transmitted */
501 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100502}
503
504
505/**********************************************************************
506 * TPDU handling
507 **********************************************************************/
508
Harald Welte4d804672015-11-14 23:02:38 +0100509
510/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
511static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
512{
513 if (reader_to_card) {
514 return p3;
515 } else {
516 if (p3 == 0)
517 return 256;
518 else
519 return p3;
520 }
521}
522
Harald Welte9d3e3822015-11-09 00:50:54 +0100523/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100524static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100525{
Harald Welte8e7fca32017-05-07 16:14:33 +0200526 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100527 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100528 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100529
530 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200531 if (!ch->uart_rx_msg) {
Harald Welte25a9a802017-05-08 13:30:09 +0200532 msg = ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
533 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200534 if (!ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100535 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
536 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100537 return;
Harald Welte4d804672015-11-14 23:02:38 +0100538 }
Harald Welte25a9a802017-05-08 13:30:09 +0200539 msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100540 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200541 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100542
Harald Welte25a9a802017-05-08 13:30:09 +0200543 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
Harald Welte8e7fca32017-05-07 16:14:33 +0200544 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100545
546 /* check if the buffer is full. If so, send it */
Harald Welte25a9a802017-05-08 13:30:09 +0200547 if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100548 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100549 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100550 /* We need to transmit the SW now, */
551 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200552 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100553 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100554}
555
556static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
557{
Harald Welte05b41c62015-11-14 20:58:48 +0100558 if (ch->tpdu.state == new_ts)
559 return;
560
Harald Weltedde112e2016-03-20 16:42:11 +0100561 TRACE_DEBUG("%u: 7816 TPDU state %u -> %u\r\n", ch->num,
562 ch->tpdu.state, new_ts);
Harald Welte05b41c62015-11-14 20:58:48 +0100563
Harald Welte903d63a2016-03-20 13:38:39 +0100564 ch->tpdu.state = new_ts;
565
Harald Welte9d3e3822015-11-09 00:50:54 +0100566 switch (new_ts) {
567 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100568 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100569 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
570 break;
571 case TPDU_S_WAIT_PB:
572 /* we just completed the TPDU header from reader to card
573 * and now need to disable the receiver, enable the
574 * transmitter and transmit the procedure byte */
575 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
576 break;
Harald Weltead434402016-03-02 11:18:29 +0100577 default:
578 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100579 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100580}
581
582static enum tpdu_state next_tpdu_state(struct card_handle *ch)
583{
584 switch (ch->tpdu.state) {
585 case TPDU_S_WAIT_CLA:
586 return TPDU_S_WAIT_INS;
587 case TPDU_S_WAIT_INS:
588 return TPDU_S_WAIT_P1;
589 case TPDU_S_WAIT_P1:
590 return TPDU_S_WAIT_P2;
591 case TPDU_S_WAIT_P2:
592 return TPDU_S_WAIT_P3;
593 case TPDU_S_WAIT_P3:
594 return TPDU_S_WAIT_PB;
595 /* simply stay in Rx or Tx by default */
596 case TPDU_S_WAIT_PB:
597 return TPDU_S_WAIT_PB;
598 case TPDU_S_WAIT_RX:
599 return TPDU_S_WAIT_RX;
600 case TPDU_S_WAIT_TX:
601 return TPDU_S_WAIT_TX;
602 }
Harald Welte4c473da2015-11-14 13:31:11 +0100603 /* we should never reach here */
604 assert(0);
605 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100606}
607
608static void send_tpdu_header(struct card_handle *ch)
609{
Harald Welte8e7fca32017-05-07 16:14:33 +0200610 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100611 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200612 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100613
Harald Weltedde112e2016-03-20 16:42:11 +0100614 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
615 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100616 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
617 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
618 ch->tpdu.hdr[4]);
619
Harald Welte9d3e3822015-11-09 00:50:54 +0100620 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200621 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100622 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200623 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100624 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100625 flush_rx_buffer(ch);
626 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100627 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200628 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
629 /* ensure we have a new buffer */
Harald Welte25a9a802017-05-08 13:30:09 +0200630 ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
631 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200632 if (!ch->uart_rx_msg) {
633 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
634 return;
635 }
636 msg = ch->uart_rx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200637 rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100638
Harald Welte8e7fca32017-05-07 16:14:33 +0200639 /* initialize header */
Harald Welte9d3e3822015-11-09 00:50:54 +0100640 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100641
642 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200643 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
644 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100645 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100646
Harald Welteb5288e82015-11-14 21:15:52 +0100647 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100648}
649
650static enum iso7816_3_card_state
651process_byte_tpdu(struct card_handle *ch, uint8_t byte)
652{
653 switch (ch->tpdu.state) {
654 case TPDU_S_WAIT_CLA:
655 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100656 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100657 break;
658 case TPDU_S_WAIT_INS:
659 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100660 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100661 break;
662 case TPDU_S_WAIT_P1:
663 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100664 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100665 break;
666 case TPDU_S_WAIT_P2:
667 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100668 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100669 break;
670 case TPDU_S_WAIT_P3:
671 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100672 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100673 /* FIXME: start timer to transmit further 0x60 */
674 /* send the TPDU header as part of a procedure byte
675 * request to the USB host */
676 send_tpdu_header(ch);
677 break;
678 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100679 add_tpdu_byte(ch, byte);
680 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100681 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100682 TRACE_ERROR("%u: process_byte_tpdu() in invalid state %u\r\n",
683 ch->num, ch->tpdu.state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100684 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100685
686 /* ensure we stay in TPDU ISO state */
687 return ISO_S_IN_TPDU;
688}
689
Harald Welte855ba9e2016-02-24 21:00:46 +0100690/* tx a single byte to be transmitted to the reader */
691static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100692{
Harald Welte8e7fca32017-05-07 16:14:33 +0200693 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100694 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100695 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100696
697 /* ensure we are aware of any data that might be pending for
698 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200699 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100700 /* uart_tx_queue is filled from main loop, so no need
701 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100702 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100703 return 0;
704
Harald Welte54cb3d02016-02-29 14:12:40 +0100705 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200706 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
Harald Welte25a9a802017-05-08 13:30:09 +0200707 ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
708 ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
Harald Welte8e7fca32017-05-07 16:14:33 +0200709 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200710 /* remove the header */
711 msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100712 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200713 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200714 td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100715
Harald Welte8e7fca32017-05-07 16:14:33 +0200716 /* take the next pending byte out of the msgb */
717 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100718
719 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100720
Harald Weltef16b6182016-02-24 22:18:46 +0100721 /* this must happen _after_ the byte has been transmittd */
722 switch (ch->tpdu.state) {
723 case TPDU_S_WAIT_PB:
724 /* if we just transmitted the procedure byte, we need to decide
725 * if we want to continue to receive or transmit */
726 if (td->flags & CEMU_DATA_F_PB_AND_TX)
727 set_tpdu_state(ch, TPDU_S_WAIT_TX);
728 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
729 set_tpdu_state(ch, TPDU_S_WAIT_RX);
730 break;
Harald Weltead434402016-03-02 11:18:29 +0100731 default:
732 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100733 }
734
Harald Welte9d3e3822015-11-09 00:50:54 +0100735 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200736 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100737 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
738 /* we have just sent the procedure byte and now
739 * need to continue receiving */
740 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100741 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100742 /* we have transmitted all bytes */
743 if (td->flags & CEMU_DATA_F_FINAL) {
744 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100745 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100746 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100747 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100748 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200749 usb_buf_free(msg);
750 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100751 }
752
753 return 1;
754}
755
756/**********************************************************************
757 * Public API
758 **********************************************************************/
759
760/* process a single byte received from the reader */
761void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
762{
763 int new_state = -1;
764
765 ch->stats.rx_bytes++;
766
767 switch (ch->state) {
768 case ISO_S_WAIT_POWER:
769 case ISO_S_WAIT_CLK:
770 case ISO_S_WAIT_RST:
771 case ISO_S_WAIT_ATR:
Harald Weltedde112e2016-03-20 16:42:11 +0100772 TRACE_ERROR("%u: Received UART char in invalid 7816 state "
773 "%u\r\n", ch->num, ch->state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100774 /* we shouldn't receive any data from the reader yet! */
775 break;
776 case ISO_S_WAIT_TPDU:
777 if (byte == 0xff) {
778 new_state = process_byte_pts(ch, byte);
779 ch->stats.pps++;
780 goto out_silent;
781 }
782 /* fall-through */
783 case ISO_S_IN_TPDU:
784 new_state = process_byte_tpdu(ch, byte);
785 break;
786 case ISO_S_IN_PTS:
787 new_state = process_byte_pts(ch, byte);
788 goto out_silent;
789 }
790
791out_silent:
792 if (new_state != -1)
793 card_set_state(ch, new_state);
794}
795
Harald Welte855ba9e2016-02-24 21:00:46 +0100796/* transmit a single byte to the reader */
797int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100798{
799 int rc = 0;
800
801 switch (ch->state) {
802 case ISO_S_IN_ATR:
803 if (ch->atr.idx < ch->atr.len) {
Harald Welte855ba9e2016-02-24 21:00:46 +0100804 uint8_t byte;
805 byte = ch->atr.atr[ch->atr.idx++];
Harald Welte9d3e3822015-11-09 00:50:54 +0100806 rc = 1;
Harald Welte855ba9e2016-02-24 21:00:46 +0100807
808 card_emu_uart_tx(ch->uart_chan, byte);
809
Harald Welte9d3e3822015-11-09 00:50:54 +0100810 /* detect end of ATR */
811 if (ch->atr.idx >= ch->atr.len)
812 card_set_state(ch, ISO_S_WAIT_TPDU);
813 }
814 break;
815 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100816 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100817 break;
818 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +0100819 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100820 break;
Harald Weltead434402016-03-02 11:18:29 +0100821 default:
822 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100823 }
824
825 if (rc)
826 ch->stats.tx_bytes++;
827
Harald Welte4d804672015-11-14 23:02:38 +0100828 /* if we return 0 here, the UART needs to disable transmit-ready
829 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +0100830 return rc;
831}
832
Harald Welteacae4122016-03-02 10:27:58 +0100833void card_emu_have_new_uart_tx(struct card_handle *ch)
834{
835 switch (ch->state) {
836 case ISO_S_IN_TPDU:
837 switch (ch->tpdu.state) {
838 case TPDU_S_WAIT_TX:
839 case TPDU_S_WAIT_PB:
840 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
841 break;
842 default:
843 break;
844 }
845 default:
846 break;
847 }
848}
849
Harald Welteff160652016-03-19 21:59:06 +0100850void card_emu_report_status(struct card_handle *ch)
851{
Harald Welte8e7fca32017-05-07 16:14:33 +0200852 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +0100853 struct cardemu_usb_msg_status *sts;
854
Harald Welte25a9a802017-05-08 13:30:09 +0200855 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
856 SIMTRACE_MSGT_BD_CEMU_STATUS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200857 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +0100858 return;
Harald Welte8e7fca32017-05-07 16:14:33 +0200859
Harald Welte25a9a802017-05-08 13:30:09 +0200860 sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
Harald Welteff160652016-03-19 21:59:06 +0100861 sts->flags = 0;
862 if (ch->vcc_active)
863 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
864 if (ch->clocked)
865 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
866 if (ch->in_reset)
867 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
868 /* FIXME: voltage + card insert */
869 sts->fi = ch->fi;
870 sts->di = ch->di;
871 sts->wi = ch->wi;
872 sts->waiting_time = ch->waiting_time;
873
Harald Welte25a9a802017-05-08 13:30:09 +0200874 usb_buf_upd_len_and_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +0100875}
876
Harald Welte9d3e3822015-11-09 00:50:54 +0100877/* hardware driver informs us that a card I/O signal has changed */
878void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
879{
880 switch (io) {
881 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +0100882 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100883 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100884 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100885 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +0100886 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100887 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100888 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +0100889 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100890 ch->vcc_active = active;
891 break;
892 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +0100893 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100894 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100895 if (ch->state == ISO_S_WAIT_CLK)
896 card_set_state(ch, ISO_S_WAIT_RST);
897 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100898 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100899 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100900 ch->clocked = active;
901 break;
902 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +0100903 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100904 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100905 if (ch->vcc_active && ch->clocked) {
906 /* enable the TC/ETU counter once reset has been released */
907 tc_etu_enable(ch->tc_chan);
908 card_set_state(ch, ISO_S_WAIT_ATR);
909 /* FIXME: wait 400 to 40k clock cycles before sending ATR */
910 card_set_state(ch, ISO_S_IN_ATR);
911 }
912 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100913 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100914 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100915 }
916 ch->in_reset = active;
917 break;
918 }
919}
920
921/* User sets a new ATR to be returned during next card reset */
922int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
923{
924 if (len > sizeof(ch->atr.atr))
925 return -1;
926
927 memcpy(ch->atr.atr, atr, len);
928 ch->atr.len = len;
929 ch->atr.idx = 0;
930
931 /* FIXME: race condition with trasmitting ATR to reader? */
932
933 return 0;
934}
935
936/* hardware driver informs us that one (more) ETU has expired */
937void tc_etu_wtime_half_expired(void *handle)
938{
939 struct card_handle *ch = handle;
940 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +0100941 switch (ch->state) {
942 case ISO_S_IN_TPDU:
943 switch (ch->tpdu.state) {
944 case TPDU_S_WAIT_PB:
945 case TPDU_S_WAIT_TX:
946 putchar('N');
947 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
948 break;
949 default:
950 break;
951 }
952 break;
953 default:
954 break;
955 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100956}
957
958/* hardware driver informs us that one (more) ETU has expired */
959void tc_etu_wtime_expired(void *handle)
960{
Harald Weltedde112e2016-03-20 16:42:11 +0100961 struct card_handle *ch = handle;
962 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100963}
964
965/* shortest ATR found in smartcard_list.txt */
966static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
967
968static struct card_handle card_handles[NUM_SLOTS];
969
Harald Welte8e7fca32017-05-07 16:14:33 +0200970struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan,
971 uint8_t in_ep, uint8_t irq_ep)
Harald Welte9d3e3822015-11-09 00:50:54 +0100972{
973 struct card_handle *ch;
974
975 if (slot_num >= ARRAY_SIZE(card_handles))
976 return NULL;
977
978 ch = &card_handles[slot_num];
979
980 memset(ch, 0, sizeof(*ch));
981
Harald Welte54cb3d02016-02-29 14:12:40 +0100982 INIT_LLIST_HEAD(&ch->uart_tx_queue);
983
Harald Welte9d3e3822015-11-09 00:50:54 +0100984 /* initialize the card_handle with reasonabe defaults */
Harald Weltedde112e2016-03-20 16:42:11 +0100985 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +0200986 ch->irq_ep = irq_ep;
987 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +0100988 ch->state = ISO_S_WAIT_POWER;
989 ch->vcc_active = 0;
990 ch->in_reset = 1;
991 ch->clocked = 0;
992
993 ch->fi = 0;
994 ch->di = 1;
995 ch->wi = ISO7816_3_DEFAULT_WI;
996
997 ch->tc_chan = tc_chan;
998 ch->uart_chan = uart_chan;
999 ch->waiting_time = ISO7816_3_INIT_WTIME;
1000
1001 ch->atr.idx = 0;
1002 ch->atr.len = sizeof(default_atr);
1003 memcpy(ch->atr.atr, default_atr, ch->atr.len);
1004
1005 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
1006 ch->tpdu.state = TPDU_S_WAIT_CLA;
1007
1008 tc_etu_init(ch->tc_chan, ch);
1009
1010 return ch;
1011}