blob: 216ffe3d4d680f62dc29179082011d41b00aff21 [file] [log] [blame]
Kévin Redon9a12d682018-07-08 13:21:16 +02001/* ISO7816-3 state machine for the card side
Harald Welte9d3e3822015-11-09 00:50:54 +01002 *
Harald Welte79f0ea72021-04-05 17:55:54 +02003 * (C) 2010-2021 by Harald Welte <laforge@gnumonks.org>
Kévin Redonebe672e2018-07-29 00:18:12 +02004 * (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
Harald Welte9d3e3822015-11-09 00:50:54 +01005 *
Kévin Redon9a12d682018-07-08 13:21:16 +02006 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
Harald Welte9d3e3822015-11-09 00:50:54 +010010 *
Kévin Redon9a12d682018-07-08 13:21:16 +020011 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Harald Welte9d3e3822015-11-09 00:50:54 +010015 *
Kévin Redon9a12d682018-07-08 13:21:16 +020016 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
Harald Welte9d3e3822015-11-09 00:50:54 +010019 */
Harald Weltec430ac12017-02-28 01:25:12 +010020#include <stdio.h>
Harald Welte4c473da2015-11-14 13:31:11 +010021#include <assert.h>
Harald Welte9d3e3822015-11-09 00:50:54 +010022#include <errno.h>
23#include <string.h>
24#include <stdint.h>
25#include <sys/types.h>
26
27#include "utils.h"
28#include "trace.h"
29#include "iso7816_fidi.h"
30#include "tc_etu.h"
31#include "card_emu.h"
Harald Welte25a9a802017-05-08 13:30:09 +020032#include "simtrace_prot.h"
Harald Welte8e7fca32017-05-07 16:14:33 +020033#include "usb_buf.h"
Harald Welte9d90d282018-06-29 22:25:42 +020034#include <osmocom/core/linuxlist.h>
35#include <osmocom/core/msgb.h>
Harald Welte9d3e3822015-11-09 00:50:54 +010036
37
38#define NUM_SLOTS 2
39
Harald Weltea5bbe782019-12-16 10:39:55 +010040/* bit-mask of supported CEMU_FEAT_F_ flags */
Harald Weltee213cc42019-12-16 10:53:22 +010041#define SUPPORTED_FEATURES (CEMU_FEAT_F_STATUS_IRQ)
Harald Weltea5bbe782019-12-16 10:39:55 +010042
Harald Welte9d3e3822015-11-09 00:50:54 +010043#define ISO7816_3_INIT_WTIME 9600
44#define ISO7816_3_DEFAULT_WI 10
45#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
46
47#define ISO7816_3_PB_NULL 0x60
48
49enum iso7816_3_card_state {
50 ISO_S_WAIT_POWER, /* waiting for power being applied */
51 ISO_S_WAIT_CLK, /* waiting for clock being applied */
52 ISO_S_WAIT_RST, /* waiting for reset being released */
53 ISO_S_WAIT_ATR, /* waiting for start of ATR */
54 ISO_S_IN_ATR, /* transmitting ATR to reader */
55 ISO_S_IN_PTS, /* transmitting ATR to reader */
56 ISO_S_WAIT_TPDU, /* waiting for data from reader */
57 ISO_S_IN_TPDU, /* inside a TPDU */
58};
59
Kévin Redon8a4fba52018-08-02 17:44:16 +020060const struct value_string iso7816_3_card_state_names[] = {
Harald Weltebfd27af2019-12-17 12:53:59 +010061 { ISO_S_WAIT_POWER, "WAIT_POWER" },
62 { ISO_S_WAIT_CLK, "WAIT_CLK" },
63 { ISO_S_WAIT_RST, "WAIT_RST" },
64 { ISO_S_WAIT_ATR, "WAIT_ATR" },
65 { ISO_S_IN_ATR, "IN_ATR" },
66 { ISO_S_IN_PTS, "IN_PTS" },
67 { ISO_S_WAIT_TPDU, "WAIT_TPDU" },
68 { ISO_S_IN_TPDU, "IN_TPDU" },
69 { 0, NULL }
Kévin Redon8a4fba52018-08-02 17:44:16 +020070};
71
72
Harald Welte9d3e3822015-11-09 00:50:54 +010073/* detailed sub-states of ISO_S_IN_PTS */
74enum pts_state {
75 PTS_S_WAIT_REQ_PTSS,
76 PTS_S_WAIT_REQ_PTS0,
77 PTS_S_WAIT_REQ_PTS1,
78 PTS_S_WAIT_REQ_PTS2,
79 PTS_S_WAIT_REQ_PTS3,
80 PTS_S_WAIT_REQ_PCK,
81 PTS_S_WAIT_RESP_PTSS = PTS_S_WAIT_REQ_PTSS | 0x10,
82 PTS_S_WAIT_RESP_PTS0 = PTS_S_WAIT_REQ_PTS0 | 0x10,
83 PTS_S_WAIT_RESP_PTS1 = PTS_S_WAIT_REQ_PTS1 | 0x10,
84 PTS_S_WAIT_RESP_PTS2 = PTS_S_WAIT_REQ_PTS2 | 0x10,
85 PTS_S_WAIT_RESP_PTS3 = PTS_S_WAIT_REQ_PTS3 | 0x10,
86 PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
87};
88
Harald Welte6a3a7142019-12-16 14:23:02 +010089const struct value_string pts_state_names[] = {
90 { PTS_S_WAIT_REQ_PTSS, "WAIT_REQ_PTSS" },
91 { PTS_S_WAIT_REQ_PTS0, "WAIT_REQ_PTS0" },
92 { PTS_S_WAIT_REQ_PTS1, "WAIT_REQ_PTS1" },
93 { PTS_S_WAIT_REQ_PTS2, "WAIT_REQ_PTS2" },
94 { PTS_S_WAIT_REQ_PTS3, "WAIT_REQ_PTS3" },
95 { PTS_S_WAIT_REQ_PCK, "WAIT_REQ_PCK" },
96 { PTS_S_WAIT_RESP_PTSS, "WAIT_RESP_PTSS" },
97 { PTS_S_WAIT_RESP_PTS0, "WAIT_RESP_PTS0" },
98 { PTS_S_WAIT_RESP_PTS1, "WAIT_RESP_PTS1" },
99 { PTS_S_WAIT_RESP_PTS2, "WAIT_RESP_PTS2" },
100 { PTS_S_WAIT_RESP_PTS3, "WAIT_RESP_PTS3" },
101 { PTS_S_WAIT_RESP_PCK, "WAIT_RESP_PCK" },
102 { 0, NULL }
103};
104
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200105/* PTS field byte index */
Harald Welte9d3e3822015-11-09 00:50:54 +0100106#define _PTSS 0
107#define _PTS0 1
108#define _PTS1 2
109#define _PTS2 3
110#define _PTS3 4
111#define _PCK 5
112
Harald Welte16cf4082015-11-11 19:02:48 +0100113/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +0100114enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +0100115 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
116 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
117 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
118 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
119 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100120 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
Kévin Redon0f4abf52018-08-02 17:42:48 +0200121 TPDU_S_WAIT_RX, /* waiting for more data from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100122 TPDU_S_WAIT_TX, /* waiting for more data to reader */
123};
124
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200125const struct value_string tpdu_state_names[] = {
Harald Weltebfd27af2019-12-17 12:53:59 +0100126 { TPDU_S_WAIT_CLA, "WAIT_CLA" },
127 { TPDU_S_WAIT_INS, "WAIT_INS" },
128 { TPDU_S_WAIT_P1, "WAIT_P1" },
129 { TPDU_S_WAIT_P2, "WAIT_P2" },
130 { TPDU_S_WAIT_P3, "WAIT_P3" },
131 { TPDU_S_WAIT_PB, "WAIT_PB" },
132 { TPDU_S_WAIT_RX, "WAIT_RX" },
133 { TPDU_S_WAIT_TX, "WAIT_TX" },
134 { 0, NULL }
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200135};
136
137/* TPDU field byte index */
Harald Welte9d3e3822015-11-09 00:50:54 +0100138#define _CLA 0
139#define _INS 1
140#define _P1 2
141#define _P2 3
142#define _P3 4
143
144struct card_handle {
Harald Weltec3941092018-08-26 09:53:13 +0200145 unsigned int num;
Harald Weltedde112e2016-03-20 16:42:11 +0100146
Harald Weltea5bbe782019-12-16 10:39:55 +0100147 /* bit-mask of enabled optional features (CEMU_FEAT_F_*) */
148 uint32_t features;
149
Harald Welte9d3e3822015-11-09 00:50:54 +0100150 enum iso7816_3_card_state state;
151
152 /* signal levels */
Kévin Redon7233cf82019-11-14 19:37:32 +0100153 bool vcc_active; /*< if VCC is active (true = active/ON) */
154 bool in_reset; /*< if card is in reset (true = RST low/asserted, false = RST high/ released) */
155 bool clocked; /*< if clock is active ( true = active, false = inactive) */
Harald Welte9d3e3822015-11-09 00:50:54 +0100156
Harald Welte79f0ea72021-04-05 17:55:54 +0200157 /* All below variables with _index suffix are indexes from 0..15 into Tables 7 + 8
158 * of ISO7816-3. */
159
160 /*! Index to clock rate conversion integer Fi (ISO7816-3 Table 7).
161 * \note this represents the maximum value supported by the card, and can be indicated in TA1 */
162 uint8_t Fi_index;
163 /*! Current value of index to clock rate conversion integer F (ISO 7816-3 Section 7.1). */
164 uint8_t F_index;
165
166 /*! Index to baud rate adjustment factor Di (ISO7816-3 Table 8).
167 * \note this represents the maximum value supported by the card, and can be indicated in TA1 */
168 uint8_t Di_index;
169 /*! Current value of index to baud rate adjustment factor D (ISO 7816-3 Section 7.1). */
170 uint8_t D_index;
171
172 /*! Waiting Integer (ISO7816-3 Section 10.2).
173 * \note this value can be set in TA2 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100174 uint8_t wi;
175
Harald Welte79f0ea72021-04-05 17:55:54 +0200176 /*! Waiting Time, in ETU (ISO7816-3 Section 8.1).
177 * \note this depends on Fi, Di, and WI if T=0 is used */
178 uint32_t waiting_time; /* in etu */
179
Harald Welte9d3e3822015-11-09 00:50:54 +0100180 uint8_t tc_chan; /* TC channel number */
181 uint8_t uart_chan; /* UART channel */
182
Harald Welte8e7fca32017-05-07 16:14:33 +0200183 uint8_t in_ep; /* USB IN EP */
184 uint8_t irq_ep; /* USB IN EP */
185
Harald Welte9d3e3822015-11-09 00:50:54 +0100186 /* ATR state machine */
187 struct {
188 uint8_t idx;
189 uint8_t len;
190 //uint8_t hist_len;
191 //uint8_t last_td;
192 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
193 } atr;
194
195 /* PPS / PTS support */
196 struct {
197 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100198 uint8_t req[6]; /* request bytes */
199 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100200 } pts;
201
202 /* TPDU */
203 struct {
204 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100205 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100206 } tpdu;
207
Harald Welte8e7fca32017-05-07 16:14:33 +0200208 struct msgb *uart_rx_msg; /* UART RX -> USB TX */
209 struct msgb *uart_tx_msg; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100210
Harald Welte54cb3d02016-02-29 14:12:40 +0100211 struct llist_head uart_tx_queue;
212
Harald Welte9d3e3822015-11-09 00:50:54 +0100213 struct {
214 uint32_t tx_bytes;
215 uint32_t rx_bytes;
216 uint32_t pps;
217 } stats;
218};
219
Harald Weltee92cb502019-12-14 21:48:45 +0100220/* reset all the 'dynamic' state of the card handle to the initial/default values */
221static void card_handle_reset(struct card_handle *ch)
222{
Harald Welte81f4ef72019-12-14 22:20:00 +0100223 struct msgb *msg;
224
225 tc_etu_disable(ch->tc_chan);
226
Harald Welte81f4ef72019-12-14 22:20:00 +0100227 /* release any buffers we may still own */
228 if (ch->uart_tx_msg) {
229 usb_buf_free(ch->uart_tx_msg);
230 ch->uart_tx_msg = NULL;
231 }
232 if (ch->uart_rx_msg) {
233 usb_buf_free(ch->uart_rx_msg);
234 ch->uart_rx_msg = NULL;
235 }
236 while ((msg = msgb_dequeue(&ch->uart_tx_queue))) {
237 usb_buf_free(msg);
238 }
Harald Weltee92cb502019-12-14 21:48:45 +0100239}
240
Harald Welte54cb3d02016-02-29 14:12:40 +0100241struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
242{
243 return &ch->uart_tx_queue;
244}
245
Harald Welte2935b3c2015-11-14 20:00:14 +0100246static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100247static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100248
Harald Welte25a9a802017-05-08 13:30:09 +0200249/* update simtrace header msg_len and submit USB buffer */
250void usb_buf_upd_len_and_submit(struct msgb *msg)
251{
Harald Welteb91f6ad2017-05-10 22:51:30 +0200252 struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
Harald Welte25a9a802017-05-08 13:30:09 +0200253
254 sh->msg_len = msgb_length(msg);
255
256 usb_buf_submit(msg);
257}
258
259/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
260struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
261{
Kévin Redonc90de692019-11-18 22:32:58 +0100262 struct msgb *msg = NULL;
Harald Welte25a9a802017-05-08 13:30:09 +0200263 struct simtrace_msg_hdr *sh;
264
Kévin Redonc90de692019-11-18 22:32:58 +0100265 while (!msg) {
266 msg = usb_buf_alloc(ep); // try to allocate some memory
267 if (!msg) { // allocation failed, we might be out of memory
Harald Weltef4a625b2019-12-14 19:07:57 +0100268 struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
269 if (!bep) {
Kévin Redonc90de692019-11-18 22:32:58 +0100270 TRACE_ERROR("ep %u: %s queue does not exist\n\r",
271 ep, __func__);
272 return NULL;
273 }
Harald Weltef4a625b2019-12-14 19:07:57 +0100274 if (llist_empty(&bep->queue)) {
Kévin Redonc90de692019-11-18 22:32:58 +0100275 TRACE_ERROR("ep %u: %s EOMEM (queue already empty)\n\r",
276 ep, __func__);
277 return NULL;
278 }
Harald Weltef4a625b2019-12-14 19:07:57 +0100279 msg = msgb_dequeue_count(&bep->queue, &bep->queue_len);
Kévin Redonc90de692019-11-18 22:32:58 +0100280 if (!msg) {
281 TRACE_ERROR("ep %u: %s no msg in non-empty queue\n\r",
282 ep, __func__);
283 return NULL;
284 }
285 usb_buf_free(msg);
286 msg = NULL;
287 TRACE_DEBUG("ep %u: %s queue msg dropped\n\r",
288 ep, __func__);
289 }
290 }
Harald Welte25a9a802017-05-08 13:30:09 +0200291
292 msg->l1h = msgb_put(msg, sizeof(*sh));
293 sh = (struct simtrace_msg_hdr *) msg->l1h;
294 memset(sh, 0, sizeof(*sh));
295 sh->msg_class = msg_class;
296 sh->msg_type = msg_type;
297 msg->l2h = msg->l1h + sizeof(*sh);
298
299 return msg;
300}
301
Kévin Redon680bdab2018-07-18 14:00:57 +0200302/* Update cardemu_usb_msg_rx_data length + submit buffer */
Harald Welteb5288e82015-11-14 21:15:52 +0100303static void flush_rx_buffer(struct card_handle *ch)
304{
Harald Welte8e7fca32017-05-07 16:14:33 +0200305 struct msgb *msg;
Harald Welteb5288e82015-11-14 21:15:52 +0100306 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200307 uint32_t data_len;
Harald Welteb5288e82015-11-14 21:15:52 +0100308
Harald Welte8e7fca32017-05-07 16:14:33 +0200309 msg = ch->uart_rx_msg;
310 if (!msg)
Harald Welteb5288e82015-11-14 21:15:52 +0100311 return;
312
Harald Welte8e7fca32017-05-07 16:14:33 +0200313 ch->uart_rx_msg = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100314
Kévin Redon680bdab2018-07-18 14:00:57 +0200315 /* store length of data payload field in header */
Harald Welte25a9a802017-05-08 13:30:09 +0200316 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
317 rd->data_len = msgb_l2len(msg) - sizeof(*rd);
Harald Welte54cb3d02016-02-29 14:12:40 +0100318
Kévin Redon910e6832018-08-02 17:47:57 +0200319 TRACE_INFO("%u: %s (%u)\n\r",
320 ch->num, __func__, rd->data_len);
321
Harald Welte25a9a802017-05-08 13:30:09 +0200322 usb_buf_upd_len_and_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100323}
324
Kévin Redon680bdab2018-07-18 14:00:57 +0200325/* convert a non-contiguous PTS request/response into a contiguous
Harald Welte4ba66d02016-02-25 19:38:56 +0100326 * buffer, returning the number of bytes used in the buffer */
327static int serialize_pts(uint8_t *out, const uint8_t *in)
328{
329 int i = 0;
330
331 out[i++] = in[_PTSS];
332 out[i++] = in[_PTS0];
333 if (in[_PTS0] & (1 << 4))
334 out[i++] = in[_PTS1];
335 if (in[_PTS0] & (1 << 5))
336 out[i++] = in[_PTS2];
337 if (in[_PTS0] & (1 << 6))
338 out[i++] = in[_PTS3];
339 out[i++] = in[_PCK];
340
341 return i;
342}
343
Harald Welte17db2f12016-02-26 09:48:57 +0100344static uint8_t csum_pts(const uint8_t *in)
345{
346 uint8_t out[6];
347 int len = serialize_pts(out, in);
348 uint8_t csum = 0;
349 int i;
350
351 /* we don't include the PCK byte in the checksumming process */
352 len -= 1;
353
354 for (i = 0; i < len; i++)
355 csum = csum ^ out[i];
356
357 return csum;
358}
359
Harald Welte4ba66d02016-02-25 19:38:56 +0100360static void flush_pts(struct card_handle *ch)
361{
Harald Welte8e7fca32017-05-07 16:14:33 +0200362 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100363 struct cardemu_usb_msg_pts_info *ptsi;
364
Harald Welte25a9a802017-05-08 13:30:09 +0200365 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200366 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100367 return;
368
Harald Welte25a9a802017-05-08 13:30:09 +0200369 ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
Harald Welted295b922016-03-18 21:01:36 +0100370 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100371 serialize_pts(ptsi->resp, ch->pts.resp);
372
Harald Welte25a9a802017-05-08 13:30:09 +0200373 usb_buf_upd_len_and_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100374}
375
Harald Welte8c496362016-02-27 16:24:09 +0100376static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100377{
378 int rc;
379
Harald Weltec1ffc8a2021-04-05 18:08:49 +0200380 rc = iso7816_3_compute_fd_ratio(ch->F_index, ch->D_index);
Harald Welte9d3e3822015-11-09 00:50:54 +0100381 if (rc > 0 && rc < 0x400) {
Harald Welte79f0ea72021-04-05 17:55:54 +0200382 TRACE_INFO("%u: computed F(%u)/D(%u) ratio: %d\r\n", ch->num,
383 ch->F_index, ch->D_index, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100384 /* make sure UART uses new F/D ratio */
385 card_emu_uart_update_fidi(ch->uart_chan, rc);
386 /* notify ETU timer about this */
387 tc_etu_set_etu(ch->tc_chan, rc);
388 } else
Harald Welte79f0ea72021-04-05 17:55:54 +0200389 TRACE_INFO("%u: computed F/D ratio %d unsupported\r\n",
Harald Weltedde112e2016-03-20 16:42:11 +0100390 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100391}
392
393/* Update the ISO 7816-3 TPDU receiver state */
394static void card_set_state(struct card_handle *ch,
395 enum iso7816_3_card_state new_state)
396{
Harald Welte903d63a2016-03-20 13:38:39 +0100397 if (ch->state == new_state)
398 return;
399
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200400 TRACE_DEBUG("%u: 7816 card state %s -> %s\r\n", ch->num,
401 get_value_string(iso7816_3_card_state_names, ch->state),
402 get_value_string(iso7816_3_card_state_names, new_state));
Harald Welte903d63a2016-03-20 13:38:39 +0100403 ch->state = new_state;
404
Harald Welte9d3e3822015-11-09 00:50:54 +0100405 switch (new_state) {
406 case ISO_S_WAIT_POWER:
407 case ISO_S_WAIT_CLK:
408 case ISO_S_WAIT_RST:
409 /* disable Rx and Tx of UART */
410 card_emu_uart_enable(ch->uart_chan, 0);
411 break;
412 case ISO_S_WAIT_ATR:
413 /* Reset to initial Fi / Di ratio */
Harald Welte79f0ea72021-04-05 17:55:54 +0200414 ch->Fi_index = ch->F_index = 1;
415 ch->Di_index = ch->D_index = 1;
416 ch->wi = ISO7816_3_DEFAULT_WI;
417 ch->waiting_time = ISO7816_3_INIT_WTIME;
Harald Welte8c496362016-02-27 16:24:09 +0100418 emu_update_fidi(ch);
Kévin Redonebe672e2018-07-29 00:18:12 +0200419 /* the ATR should only be sent 400 to 40k clock cycles after the RESET.
420 * we use the tc_etu mechanism to wait this time.
421 * since the initial ETU is Fd=372/Dd=1 clock cycles long, we have to wait 2-107 ETU.
422 */
423 tc_etu_set_wtime(ch->tc_chan, 2);
Harald Welte4d4405f2019-12-15 13:23:51 +0100424 /* enable the TC/ETU counter once reset has been released */
Kévin Redonebe672e2018-07-29 00:18:12 +0200425 tc_etu_enable(ch->tc_chan);
426 break;
427 case ISO_S_IN_ATR:
Kévin Redon680bdab2018-07-18 14:00:57 +0200428 /* initialize to default WI, this will be overwritten if we
Kévin Redonebe672e2018-07-29 00:18:12 +0200429 * send TC2, and it will be programmed into hardware after
Harald Welte9d3e3822015-11-09 00:50:54 +0100430 * ATR is finished */
431 ch->wi = ISO7816_3_DEFAULT_WI;
432 /* update waiting time to initial waiting time */
433 ch->waiting_time = ISO7816_3_INIT_WTIME;
Kévin Redonebe672e2018-07-29 00:18:12 +0200434 /* set initial waiting time */
Harald Welte9d3e3822015-11-09 00:50:54 +0100435 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
436 /* Set ATR sub-state to initial state */
437 ch->atr.idx = 0;
Kévin Redonebe672e2018-07-29 00:18:12 +0200438 /* enable USART transmission to reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100439 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Kévin Redonebe672e2018-07-29 00:18:12 +0200440 /* trigger USART TX IRQ to sent first ATR byte TS */
441 card_emu_uart_interrupt(ch->uart_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100442 break;
443 case ISO_S_WAIT_TPDU:
444 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100445 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100446 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
447 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100448 case ISO_S_IN_PTS:
449 case ISO_S_IN_TPDU:
450 /* do nothing */
451 break;
452 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100453}
454
Kévin Redonebe672e2018-07-29 00:18:12 +0200455/**********************************************************************
456 * ATR handling
457 **********************************************************************/
458
459/*! Transmit ATR data to reader
460 * @param[in] ch card interface connected to reader
461 * @return numbers of bytes transmitted
462 */
463static int tx_byte_atr(struct card_handle *ch)
464{
465 if (NULL == ch) {
466 TRACE_ERROR("ATR TX: no card handle provided\n\r");
467 return 0;
468 }
469 if (ISO_S_IN_ATR != ch->state) {
470 TRACE_ERROR("%u: ATR TX: no in ATR state\n\r", ch->num);
471 return 0;
472 }
473
474 /* Transmit ATR */
475 if (ch->atr.idx < ch->atr.len) {
476 uint8_t byte = ch->atr.atr[ch->atr.idx++];
477 card_emu_uart_tx(ch->uart_chan, byte);
Kévin Redonebe672e2018-07-29 00:18:12 +0200478 return 1;
479 } else { /* The ATR has been completely transmitted */
Kévin Redon8b8e58b2018-07-30 18:19:11 +0200480 /* search for TC2 to updated WI */
481 ch->wi = ISO7816_3_DEFAULT_WI;
482 if (ch->atr.len >= 2 && ch->atr.atr[1] & 0xf0) { /* Y1 has some data */
483 uint8_t atr_td1 = 2;
484 if (ch->atr.atr[1] & 0x10) { /* TA1 is present */
485 atr_td1++;
486 }
487 if (ch->atr.atr[1] & 0x20) { /* TB1 is present */
488 atr_td1++;
489 }
490 if (ch->atr.atr[1] & 0x40) { /* TC1 is present */
491 atr_td1++;
492 }
493 if (ch->atr.atr[1] & 0x80) { /* TD1 is present */
494 if (ch->atr.len > atr_td1 && ch->atr.atr[atr_td1] & 0xf0) { /* Y2 has some data */
495 uint8_t atr_tc2 = atr_td1+1;
496 if (ch->atr.atr[atr_td1] & 0x10) { /* TA2 is present */
497 atr_tc2++;
498 }
499 if (ch->atr.atr[atr_td1] & 0x20) { /* TB2 is present */
500 atr_tc2++;
501 }
502 if (ch->atr.atr[atr_td1] & 0x40) { /* TC2 is present */
503 if (ch->atr.len > atr_tc2 && ch->atr.atr[atr_tc2]) { /* TC2 encodes WI */
504 ch->wi = ch->atr.atr[atr_tc2]; /* set WI */
505 }
506 }
507 }
508 }
509 }
510 /* update waiting time (see ISO 7816-3 10.2) */
Harald Weltec1ffc8a2021-04-05 18:08:49 +0200511 ch->waiting_time = ch->wi * 960 * iso7816_3_fi_table[ch->F_index];
Kévin Redon8b8e58b2018-07-30 18:19:11 +0200512 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
Kévin Redonebe672e2018-07-29 00:18:12 +0200513 /* go to next state */
514 card_set_state(ch, ISO_S_WAIT_TPDU);
515 return 0;
516 }
517
518 /* return number of bytes transmitted */
519 return 1;
520}
Harald Welte9d3e3822015-11-09 00:50:54 +0100521
522/**********************************************************************
523 * PTS / PPS handling
524 **********************************************************************/
525
Kévin Redon680bdab2018-07-18 14:00:57 +0200526/* Update the PTS sub-state */
Harald Welte9d3e3822015-11-09 00:50:54 +0100527static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
528{
Harald Welte6a3a7142019-12-16 14:23:02 +0100529 TRACE_DEBUG("%u: 7816 PTS state %s -> %s\r\n", ch->num,
530 get_value_string(pts_state_names, ch->pts.state),
531 get_value_string(pts_state_names, new_ptss));
Harald Welte9d3e3822015-11-09 00:50:54 +0100532 ch->pts.state = new_ptss;
533}
534
535/* Determine the next PTS state */
536static enum pts_state next_pts_state(struct card_handle *ch)
537{
538 uint8_t is_resp = ch->pts.state & 0x10;
539 uint8_t sstate = ch->pts.state & 0x0f;
540 uint8_t *pts_ptr;
541
542 if (!is_resp)
543 pts_ptr = ch->pts.req;
544 else
545 pts_ptr = ch->pts.resp;
546
547 switch (sstate) {
548 case PTS_S_WAIT_REQ_PTSS:
549 goto from_ptss;
550 case PTS_S_WAIT_REQ_PTS0:
551 goto from_pts0;
552 case PTS_S_WAIT_REQ_PTS1:
553 goto from_pts1;
554 case PTS_S_WAIT_REQ_PTS2:
555 goto from_pts2;
556 case PTS_S_WAIT_REQ_PTS3:
557 goto from_pts3;
558 }
559
560 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
561 return PTS_S_WAIT_RESP_PTSS;
562
563from_ptss:
564 return PTS_S_WAIT_REQ_PTS0 | is_resp;
565from_pts0:
566 if (pts_ptr[_PTS0] & (1 << 4))
567 return PTS_S_WAIT_REQ_PTS1 | is_resp;
568from_pts1:
569 if (pts_ptr[_PTS0] & (1 << 5))
570 return PTS_S_WAIT_REQ_PTS2 | is_resp;
571from_pts2:
572 if (pts_ptr[_PTS0] & (1 << 6))
573 return PTS_S_WAIT_REQ_PTS3 | is_resp;
574from_pts3:
575 return PTS_S_WAIT_REQ_PCK | is_resp;
576}
577
578
Harald Welteccb8a222016-03-20 13:37:11 +0100579static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100580process_byte_pts(struct card_handle *ch, uint8_t byte)
581{
582 switch (ch->pts.state) {
583 case PTS_S_WAIT_REQ_PTSS:
584 ch->pts.req[_PTSS] = byte;
585 break;
586 case PTS_S_WAIT_REQ_PTS0:
587 ch->pts.req[_PTS0] = byte;
588 break;
589 case PTS_S_WAIT_REQ_PTS1:
590 ch->pts.req[_PTS1] = byte;
591 break;
592 case PTS_S_WAIT_REQ_PTS2:
593 ch->pts.req[_PTS2] = byte;
594 break;
595 case PTS_S_WAIT_REQ_PTS3:
596 ch->pts.req[_PTS3] = byte;
597 break;
598 case PTS_S_WAIT_REQ_PCK:
599 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100600 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100601 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
602 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100603 /* Wait for the next TPDU */
604 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
605 return ISO_S_WAIT_TPDU;
606 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100607 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100608 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
609 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100610 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100611 TRACE_ERROR("%u: process_byte_pts() in invalid PTS state %s\r\n", ch->num,
612 get_value_string(pts_state_names, ch->pts.state));
Harald Welte4c473da2015-11-14 13:31:11 +0100613 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100614 }
615 /* calculate the next state and set it */
616 set_pts_state(ch, next_pts_state(ch));
617
Harald Welte4ba66d02016-02-25 19:38:56 +0100618 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
619 flush_pts(ch);
620 /* activate UART TX to transmit PTS response */
621 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100622 /* don't fall-through to the 'return ISO_S_IN_PTS'
623 * below, rather keep ISO7816 state as-is, it will be
624 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100625 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100626 }
627
Harald Welte9d3e3822015-11-09 00:50:54 +0100628 return ISO_S_IN_PTS;
629}
630
631/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100632static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100633{
Harald Welte855ba9e2016-02-24 21:00:46 +0100634 uint8_t byte;
635
636 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100637 switch (ch->pts.state) {
638 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100639 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100640 break;
641 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100642 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100643 break;
644 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100645 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100646 /* This must be TA1 */
Harald Welte79f0ea72021-04-05 17:55:54 +0200647 ch->F_index = byte >> 4;
648 ch->D_index = byte & 0xf;
649 TRACE_DEBUG("%u: found F=%u D=%u\r\n", ch->num,
Harald Weltec1ffc8a2021-04-05 18:08:49 +0200650 iso7816_3_fi_table[ch->F_index], iso7816_3_di_table[ch->D_index]);
Harald Welte79f0ea72021-04-05 17:55:54 +0200651 /* FIXME: if F or D are 0, become unresponsive to signal error condition */
Harald Welte9d3e3822015-11-09 00:50:54 +0100652 break;
653 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100654 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100655 break;
656 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100657 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100658 break;
659 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100660 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100661 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100662 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100663 TRACE_ERROR("%u: get_byte_pts() in invalid PTS state %s\r\n", ch->num,
664 get_value_string(pts_state_names, ch->pts.state));
Harald Welte855ba9e2016-02-24 21:00:46 +0100665 return 0;
666 }
667
668 /* 2: Transmit the byte */
669 card_emu_uart_tx(ch->uart_chan, byte);
670
671 /* 3: Update the state */
672
673 switch (ch->pts.state) {
674 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100675 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte79f0ea72021-04-05 17:55:54 +0200676 /* update baud rate generator with F/D */
Harald Welte52d55462016-03-20 13:38:05 +0100677 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100678 /* Wait for the next TPDU */
679 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte855ba9e2016-02-24 21:00:46 +0100680 break;
681 default:
682 /* calculate the next state and set it */
683 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100684 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100685 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100686
Harald Welte855ba9e2016-02-24 21:00:46 +0100687 /* return number of bytes transmitted */
688 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100689}
690
691
692/**********************************************************************
693 * TPDU handling
694 **********************************************************************/
695
Harald Welte4d804672015-11-14 23:02:38 +0100696
697/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
698static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
699{
700 if (reader_to_card) {
701 return p3;
702 } else {
703 if (p3 == 0)
704 return 256;
705 else
706 return p3;
707 }
708}
709
Harald Welte9d3e3822015-11-09 00:50:54 +0100710/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100711static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100712{
Harald Welte8e7fca32017-05-07 16:14:33 +0200713 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100714 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100715 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100716
717 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200718 if (!ch->uart_rx_msg) {
Harald Welte25a9a802017-05-08 13:30:09 +0200719 msg = ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
720 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200721 if (!ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100722 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
723 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100724 return;
Harald Welte4d804672015-11-14 23:02:38 +0100725 }
Harald Welte25a9a802017-05-08 13:30:09 +0200726 msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100727 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200728 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100729
Harald Welte25a9a802017-05-08 13:30:09 +0200730 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
Harald Welte8e7fca32017-05-07 16:14:33 +0200731 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100732
733 /* check if the buffer is full. If so, send it */
Harald Welte25a9a802017-05-08 13:30:09 +0200734 if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100735 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100736 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100737 /* We need to transmit the SW now, */
738 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200739 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100740 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100741}
742
743static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
744{
Harald Welte05b41c62015-11-14 20:58:48 +0100745 if (ch->tpdu.state == new_ts)
746 return;
747
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200748 TRACE_DEBUG("%u: 7816 TPDU state %s -> %s\r\n", ch->num,
749 get_value_string(tpdu_state_names, ch->tpdu.state),
750 get_value_string(tpdu_state_names, new_ts));
Harald Welte903d63a2016-03-20 13:38:39 +0100751 ch->tpdu.state = new_ts;
752
Harald Welte9d3e3822015-11-09 00:50:54 +0100753 switch (new_ts) {
754 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100755 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100756 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
757 break;
758 case TPDU_S_WAIT_PB:
759 /* we just completed the TPDU header from reader to card
760 * and now need to disable the receiver, enable the
761 * transmitter and transmit the procedure byte */
762 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
763 break;
Harald Weltead434402016-03-02 11:18:29 +0100764 default:
765 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100766 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100767}
768
769static enum tpdu_state next_tpdu_state(struct card_handle *ch)
770{
771 switch (ch->tpdu.state) {
772 case TPDU_S_WAIT_CLA:
773 return TPDU_S_WAIT_INS;
774 case TPDU_S_WAIT_INS:
775 return TPDU_S_WAIT_P1;
776 case TPDU_S_WAIT_P1:
777 return TPDU_S_WAIT_P2;
778 case TPDU_S_WAIT_P2:
779 return TPDU_S_WAIT_P3;
780 case TPDU_S_WAIT_P3:
781 return TPDU_S_WAIT_PB;
782 /* simply stay in Rx or Tx by default */
783 case TPDU_S_WAIT_PB:
784 return TPDU_S_WAIT_PB;
785 case TPDU_S_WAIT_RX:
786 return TPDU_S_WAIT_RX;
787 case TPDU_S_WAIT_TX:
788 return TPDU_S_WAIT_TX;
789 }
Harald Welte4c473da2015-11-14 13:31:11 +0100790 /* we should never reach here */
791 assert(0);
792 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100793}
794
795static void send_tpdu_header(struct card_handle *ch)
796{
Harald Welte8e7fca32017-05-07 16:14:33 +0200797 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100798 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200799 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100800
Harald Weltedde112e2016-03-20 16:42:11 +0100801 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
802 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100803 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
804 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
805 ch->tpdu.hdr[4]);
806
Harald Welte9d3e3822015-11-09 00:50:54 +0100807 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200808 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100809 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200810 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100811 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100812 flush_rx_buffer(ch);
813 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100814 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200815 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
816 /* ensure we have a new buffer */
Harald Welte25a9a802017-05-08 13:30:09 +0200817 ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
818 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200819 if (!ch->uart_rx_msg) {
820 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
821 return;
822 }
823 msg = ch->uart_rx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200824 rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100825
Harald Welte8e7fca32017-05-07 16:14:33 +0200826 /* initialize header */
Harald Welte9d3e3822015-11-09 00:50:54 +0100827 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100828
829 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200830 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
831 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100832 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100833
Harald Welteb5288e82015-11-14 21:15:52 +0100834 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100835}
836
837static enum iso7816_3_card_state
838process_byte_tpdu(struct card_handle *ch, uint8_t byte)
839{
840 switch (ch->tpdu.state) {
841 case TPDU_S_WAIT_CLA:
842 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100843 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100844 break;
845 case TPDU_S_WAIT_INS:
846 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100847 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100848 break;
849 case TPDU_S_WAIT_P1:
850 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100851 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100852 break;
853 case TPDU_S_WAIT_P2:
854 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100855 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100856 break;
857 case TPDU_S_WAIT_P3:
858 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100859 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100860 /* FIXME: start timer to transmit further 0x60 */
861 /* send the TPDU header as part of a procedure byte
862 * request to the USB host */
863 send_tpdu_header(ch);
864 break;
865 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100866 add_tpdu_byte(ch, byte);
867 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100868 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100869 TRACE_ERROR("%u: process_byte_tpdu() in invalid TPDU state %s\r\n", ch->num,
870 get_value_string(tpdu_state_names, ch->tpdu.state));
Harald Welte9d3e3822015-11-09 00:50:54 +0100871 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100872
873 /* ensure we stay in TPDU ISO state */
874 return ISO_S_IN_TPDU;
875}
876
Harald Welte855ba9e2016-02-24 21:00:46 +0100877/* tx a single byte to be transmitted to the reader */
878static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100879{
Harald Welte8e7fca32017-05-07 16:14:33 +0200880 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100881 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100882 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100883
884 /* ensure we are aware of any data that might be pending for
885 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200886 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100887 /* uart_tx_queue is filled from main loop, so no need
888 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100889 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100890 return 0;
891
Harald Welte54cb3d02016-02-29 14:12:40 +0100892 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200893 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
Harald Welte25a9a802017-05-08 13:30:09 +0200894 ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
895 ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
Harald Welte8e7fca32017-05-07 16:14:33 +0200896 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200897 /* remove the header */
898 msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100899 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200900 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200901 td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100902
Harald Welte8e7fca32017-05-07 16:14:33 +0200903 /* take the next pending byte out of the msgb */
904 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100905
906 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100907
Kévin Redon0f4abf52018-08-02 17:42:48 +0200908 /* this must happen _after_ the byte has been transmitted */
Harald Weltef16b6182016-02-24 22:18:46 +0100909 switch (ch->tpdu.state) {
910 case TPDU_S_WAIT_PB:
911 /* if we just transmitted the procedure byte, we need to decide
912 * if we want to continue to receive or transmit */
913 if (td->flags & CEMU_DATA_F_PB_AND_TX)
914 set_tpdu_state(ch, TPDU_S_WAIT_TX);
915 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
916 set_tpdu_state(ch, TPDU_S_WAIT_RX);
917 break;
Harald Weltead434402016-03-02 11:18:29 +0100918 default:
919 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100920 }
921
Harald Welte9d3e3822015-11-09 00:50:54 +0100922 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200923 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100924 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
925 /* we have just sent the procedure byte and now
926 * need to continue receiving */
927 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100928 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100929 /* we have transmitted all bytes */
930 if (td->flags & CEMU_DATA_F_FINAL) {
931 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100932 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100933 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100934 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100935 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200936 usb_buf_free(msg);
937 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100938 }
939
940 return 1;
941}
942
943/**********************************************************************
944 * Public API
945 **********************************************************************/
946
947/* process a single byte received from the reader */
948void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
949{
950 int new_state = -1;
951
952 ch->stats.rx_bytes++;
953
954 switch (ch->state) {
Harald Welte9d3e3822015-11-09 00:50:54 +0100955 case ISO_S_WAIT_TPDU:
956 if (byte == 0xff) {
Harald Welte02d0d732019-12-15 13:19:24 +0100957 /* reset PTS to initial state */
958 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100959 new_state = process_byte_pts(ch, byte);
960 ch->stats.pps++;
961 goto out_silent;
962 }
963 /* fall-through */
964 case ISO_S_IN_TPDU:
965 new_state = process_byte_tpdu(ch, byte);
966 break;
967 case ISO_S_IN_PTS:
968 new_state = process_byte_pts(ch, byte);
969 goto out_silent;
Kévin Redon5f6b8712018-07-11 09:49:06 +0200970 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100971 TRACE_ERROR("%u: Received UART char in invalid 7816 state %s\r\n", ch->num,
972 get_value_string(iso7816_3_card_state_names, ch->state));
Kévin Redon5f6b8712018-07-11 09:49:06 +0200973 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100974 }
975
976out_silent:
977 if (new_state != -1)
978 card_set_state(ch, new_state);
979}
980
Harald Welte855ba9e2016-02-24 21:00:46 +0100981/* transmit a single byte to the reader */
982int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100983{
984 int rc = 0;
985
986 switch (ch->state) {
987 case ISO_S_IN_ATR:
Kévin Redonebe672e2018-07-29 00:18:12 +0200988 rc = tx_byte_atr(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100989 break;
990 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100991 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100992 break;
993 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +0100994 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100995 break;
Harald Weltead434402016-03-02 11:18:29 +0100996 default:
997 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100998 }
999
1000 if (rc)
1001 ch->stats.tx_bytes++;
1002
Harald Welte4d804672015-11-14 23:02:38 +01001003 /* if we return 0 here, the UART needs to disable transmit-ready
1004 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +01001005 return rc;
1006}
1007
Harald Welteacae4122016-03-02 10:27:58 +01001008void card_emu_have_new_uart_tx(struct card_handle *ch)
1009{
1010 switch (ch->state) {
1011 case ISO_S_IN_TPDU:
1012 switch (ch->tpdu.state) {
1013 case TPDU_S_WAIT_TX:
1014 case TPDU_S_WAIT_PB:
1015 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
1016 break;
1017 default:
1018 break;
1019 }
1020 default:
1021 break;
1022 }
1023}
1024
Harald Welte140f0072019-12-16 10:23:32 +01001025void card_emu_report_status(struct card_handle *ch, bool report_on_irq)
Harald Welteff160652016-03-19 21:59:06 +01001026{
Harald Welte8e7fca32017-05-07 16:14:33 +02001027 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +01001028 struct cardemu_usb_msg_status *sts;
Harald Welte140f0072019-12-16 10:23:32 +01001029 uint8_t ep = ch->in_ep;
Harald Welteff160652016-03-19 21:59:06 +01001030
Harald Welte140f0072019-12-16 10:23:32 +01001031 if (report_on_irq)
1032 ep = ch->irq_ep;
1033
1034 msg = usb_buf_alloc_st(ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_BD_CEMU_STATUS);
Harald Welte8e7fca32017-05-07 16:14:33 +02001035 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +01001036 return;
Harald Welte8e7fca32017-05-07 16:14:33 +02001037
Harald Welte25a9a802017-05-08 13:30:09 +02001038 sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
Harald Welteff160652016-03-19 21:59:06 +01001039 sts->flags = 0;
1040 if (ch->vcc_active)
1041 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
1042 if (ch->clocked)
1043 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
1044 if (ch->in_reset)
1045 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
1046 /* FIXME: voltage + card insert */
Harald Welte79f0ea72021-04-05 17:55:54 +02001047 sts->F_index = ch->F_index;
1048 sts->D_index = ch->D_index;
Harald Welteff160652016-03-19 21:59:06 +01001049 sts->wi = ch->wi;
1050 sts->waiting_time = ch->waiting_time;
1051
Harald Welte25a9a802017-05-08 13:30:09 +02001052 usb_buf_upd_len_and_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +01001053}
1054
Harald Weltea5bbe782019-12-16 10:39:55 +01001055static void card_emu_report_config(struct card_handle *ch)
1056{
1057 struct msgb *msg;
1058 struct cardemu_usb_msg_config *cfg;
1059 uint8_t ep = ch->in_ep;
1060
1061 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_BD_CEMU_CONFIG);
1062 if (!msg)
1063 return;
1064
1065 cfg = (struct cardemu_usb_msg_config *) msgb_put(msg, sizeof(*cfg));
1066 cfg->features = ch->features;
1067
1068 usb_buf_upd_len_and_submit(msg);
1069}
1070
Harald Welte9d3e3822015-11-09 00:50:54 +01001071/* hardware driver informs us that a card I/O signal has changed */
1072void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
1073{
Harald Weltee213cc42019-12-16 10:53:22 +01001074 uint32_t chg_mask = 0;
1075
Harald Welte9d3e3822015-11-09 00:50:54 +01001076 switch (io) {
1077 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +01001078 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001079 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte81f4ef72019-12-14 22:20:00 +01001080 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001081 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Weltee213cc42019-12-16 10:53:22 +01001082 chg_mask |= CEMU_STATUS_F_VCC_PRESENT;
Harald Welte47ee2832016-02-29 10:09:46 +01001083 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001084 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +01001085 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Weltee213cc42019-12-16 10:53:22 +01001086 chg_mask |= CEMU_STATUS_F_VCC_PRESENT;
Harald Welte47ee2832016-02-29 10:09:46 +01001087 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001088 ch->vcc_active = active;
1089 break;
1090 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +01001091 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001092 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001093 if (ch->state == ISO_S_WAIT_CLK)
1094 card_set_state(ch, ISO_S_WAIT_RST);
Harald Weltee213cc42019-12-16 10:53:22 +01001095 chg_mask |= CEMU_STATUS_F_CLK_ACTIVE;
Harald Welte47ee2832016-02-29 10:09:46 +01001096 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001097 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Weltee213cc42019-12-16 10:53:22 +01001098 chg_mask |= CEMU_STATUS_F_CLK_ACTIVE;
Harald Welte47ee2832016-02-29 10:09:46 +01001099 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001100 ch->clocked = active;
1101 break;
1102 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +01001103 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001104 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Weltea708ea12021-04-05 18:16:14 +02001105 if (ch->vcc_active && ch->clocked && ch->state == ISO_S_WAIT_RST) {
Harald Welte47ee2832016-02-29 10:09:46 +01001106 /* enable the TC/ETU counter once reset has been released */
1107 tc_etu_enable(ch->tc_chan);
Kévin Redonebe672e2018-07-29 00:18:12 +02001108 /* prepare to send the ATR */
Harald Welte47ee2832016-02-29 10:09:46 +01001109 card_set_state(ch, ISO_S_WAIT_ATR);
Harald Welte47ee2832016-02-29 10:09:46 +01001110 }
Harald Weltee213cc42019-12-16 10:53:22 +01001111 chg_mask |= CEMU_STATUS_F_RESET_ACTIVE;
Harald Welte47ee2832016-02-29 10:09:46 +01001112 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001113 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte81f4ef72019-12-14 22:20:00 +01001114 card_handle_reset(ch);
Harald Weltee213cc42019-12-16 10:53:22 +01001115 chg_mask |= CEMU_STATUS_F_RESET_ACTIVE;
Harald Weltea708ea12021-04-05 18:16:14 +02001116 card_set_state(ch, ISO_S_WAIT_RST);
Harald Welte9d3e3822015-11-09 00:50:54 +01001117 }
1118 ch->in_reset = active;
1119 break;
1120 }
Harald Weltee9f429d2019-12-15 13:21:17 +01001121
1122 switch (ch->state) {
1123 case ISO_S_WAIT_POWER:
1124 case ISO_S_WAIT_CLK:
1125 case ISO_S_WAIT_RST:
1126 /* check end activation state (even if the reader does
1127 * not respect the activation sequence) */
1128 if (ch->vcc_active && ch->clocked && !ch->in_reset) {
Harald Weltee9f429d2019-12-15 13:21:17 +01001129 /* prepare to send the ATR */
1130 card_set_state(ch, ISO_S_WAIT_ATR);
1131 }
1132 break;
1133 default:
1134 break;
1135 }
Harald Weltee213cc42019-12-16 10:53:22 +01001136
1137 /* notify the host about the state change */
1138 if ((ch->features & CEMU_FEAT_F_STATUS_IRQ) && chg_mask)
1139 card_emu_report_status(ch, true);
Harald Welte9d3e3822015-11-09 00:50:54 +01001140}
1141
1142/* User sets a new ATR to be returned during next card reset */
1143int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
1144{
1145 if (len > sizeof(ch->atr.atr))
1146 return -1;
1147
1148 memcpy(ch->atr.atr, atr, len);
1149 ch->atr.len = len;
1150 ch->atr.idx = 0;
1151
Kévin Redonebe672e2018-07-29 00:18:12 +02001152#if TRACE_LEVEL >= TRACE_LEVEL_INFO
1153 uint8_t i;
1154 TRACE_INFO("%u: ATR set: ", ch->num);
1155 for (i = 0; i < ch->atr.len; i++) {
1156 TRACE_INFO_WP("%02x ", atr[i]);
1157 }
1158 TRACE_INFO_WP("\n\r");
1159#endif
1160 /* FIXME: race condition with transmitting ATR to reader? */
Harald Welte9d3e3822015-11-09 00:50:54 +01001161
1162 return 0;
1163}
1164
1165/* hardware driver informs us that one (more) ETU has expired */
1166void tc_etu_wtime_half_expired(void *handle)
1167{
1168 struct card_handle *ch = handle;
1169 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +01001170 switch (ch->state) {
1171 case ISO_S_IN_TPDU:
1172 switch (ch->tpdu.state) {
1173 case TPDU_S_WAIT_PB:
1174 case TPDU_S_WAIT_TX:
1175 putchar('N');
1176 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
1177 break;
1178 default:
1179 break;
1180 }
1181 break;
1182 default:
1183 break;
1184 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001185}
1186
1187/* hardware driver informs us that one (more) ETU has expired */
1188void tc_etu_wtime_expired(void *handle)
1189{
Harald Weltedde112e2016-03-20 16:42:11 +01001190 struct card_handle *ch = handle;
Kévin Redonebe672e2018-07-29 00:18:12 +02001191 switch (ch->state) {
1192 case ISO_S_WAIT_ATR:
1193 /* ISO 7816-3 6.2.1 time tc has passed, we can now send the ATR */
1194 card_set_state(ch, ISO_S_IN_ATR);
1195 break;
1196 default:
1197 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
1198 break;
1199 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001200}
1201
Eric Wild0b1a3b42020-04-03 21:21:27 +02001202/* reasonable ATR offering all protocols and voltages
1203 * smartphones might not care, but other readers do
1204 *
1205 * TS = 0x3B Direct Convention
1206 * T0 = 0x80 Y(1): b1000, K: 0 (historical bytes)
1207 * TD(1) = 0x80 Y(i+1) = b1000, Protocol T=0
1208 * ----
1209 * TD(2) = 0x81 Y(i+1) = b1000, Protocol T=1
1210 * ----
1211 * TD(3) = 0x1F Y(i+1) = b0001, Protocol T=15
1212 * ----
1213 * TA(4) = 0xC7 Clock stop: no preference - Class accepted by the card: (3G) A 5V B 3V C 1.8V
1214 * ----
1215 * Historical bytes
1216 * TCK = 0x59 correct checksum
1217 */
1218static const uint8_t default_atr[] = { 0x3B, 0x80, 0x80, 0x81 , 0x1F, 0xC7, 0x59 };
Harald Welte9d3e3822015-11-09 00:50:54 +01001219
1220static struct card_handle card_handles[NUM_SLOTS];
1221
Harald Weltea5bbe782019-12-16 10:39:55 +01001222int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_config *scfg,
1223 unsigned int scfg_len)
1224{
1225 if (scfg_len >= sizeof(uint32_t))
1226 ch->features = (scfg->features & SUPPORTED_FEATURES);
1227
1228 /* send back a report of our current configuration */
1229 card_emu_report_config(ch);
1230
1231 return 0;
1232}
1233
Kévin Redon7233cf82019-11-14 19:37:32 +01001234struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked)
Harald Welte9d3e3822015-11-09 00:50:54 +01001235{
1236 struct card_handle *ch;
1237
1238 if (slot_num >= ARRAY_SIZE(card_handles))
1239 return NULL;
1240
1241 ch = &card_handles[slot_num];
1242
1243 memset(ch, 0, sizeof(*ch));
1244
Harald Welte54cb3d02016-02-29 14:12:40 +01001245 INIT_LLIST_HEAD(&ch->uart_tx_queue);
1246
Harald Weltedde112e2016-03-20 16:42:11 +01001247 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +02001248 ch->irq_ep = irq_ep;
1249 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +01001250 ch->state = ISO_S_WAIT_POWER;
Kévin Redon7233cf82019-11-14 19:37:32 +01001251 ch->vcc_active = vcc_active;
1252 ch->in_reset = in_reset;
1253 ch->clocked = clocked;
Harald Welte9d3e3822015-11-09 00:50:54 +01001254
Harald Welte79f0ea72021-04-05 17:55:54 +02001255 ch->Fi_index = ch->F_index = 1;
1256 ch->Di_index = ch->D_index = 1;
Harald Welte9d3e3822015-11-09 00:50:54 +01001257 ch->wi = ISO7816_3_DEFAULT_WI;
1258
1259 ch->tc_chan = tc_chan;
1260 ch->uart_chan = uart_chan;
1261 ch->waiting_time = ISO7816_3_INIT_WTIME;
1262
1263 ch->atr.idx = 0;
1264 ch->atr.len = sizeof(default_atr);
1265 memcpy(ch->atr.atr, default_atr, ch->atr.len);
1266
Harald Weltee92cb502019-12-14 21:48:45 +01001267 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001268
1269 tc_etu_init(ch->tc_chan, ch);
1270
1271 return ch;
1272}