blob: 929106493e420a37d9e7fecf9f1273cb87c6530d [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 *
Kévin Redon9a12d682018-07-08 13:21:16 +02003 * (C) 2010-2017 by Harald Welte <laforge@gnumonks.org>
Harald Welte9d3e3822015-11-09 00:50:54 +01004 *
Kévin Redon9a12d682018-07-08 13:21:16 +02005 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
Harald Welte9d3e3822015-11-09 00:50:54 +01009 *
Kévin Redon9a12d682018-07-08 13:21:16 +020010 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Harald Welte9d3e3822015-11-09 00:50:54 +010014 *
Kévin Redon9a12d682018-07-08 13:21:16 +020015 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
Harald Welte9d3e3822015-11-09 00:50:54 +010018 */
Harald Weltec430ac12017-02-28 01:25:12 +010019#include <stdio.h>
Harald Welte4c473da2015-11-14 13:31:11 +010020#include <assert.h>
Harald Welte9d3e3822015-11-09 00:50:54 +010021#include <errno.h>
22#include <string.h>
23#include <stdint.h>
24#include <sys/types.h>
25
26#include "utils.h"
27#include "trace.h"
28#include "iso7816_fidi.h"
29#include "tc_etu.h"
30#include "card_emu.h"
Harald Welte25a9a802017-05-08 13:30:09 +020031#include "simtrace_prot.h"
Harald Welte8e7fca32017-05-07 16:14:33 +020032#include "usb_buf.h"
Harald Welte9d90d282018-06-29 22:25:42 +020033#include <osmocom/core/linuxlist.h>
34#include <osmocom/core/msgb.h>
Harald Welte9d3e3822015-11-09 00:50:54 +010035
36
37#define NUM_SLOTS 2
38
39#define ISO7816_3_INIT_WTIME 9600
40#define ISO7816_3_DEFAULT_WI 10
41#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
42
43#define ISO7816_3_PB_NULL 0x60
44
45enum iso7816_3_card_state {
46 ISO_S_WAIT_POWER, /* waiting for power being applied */
47 ISO_S_WAIT_CLK, /* waiting for clock being applied */
48 ISO_S_WAIT_RST, /* waiting for reset being released */
49 ISO_S_WAIT_ATR, /* waiting for start of ATR */
50 ISO_S_IN_ATR, /* transmitting ATR to reader */
51 ISO_S_IN_PTS, /* transmitting ATR to reader */
52 ISO_S_WAIT_TPDU, /* waiting for data from reader */
53 ISO_S_IN_TPDU, /* inside a TPDU */
54};
55
56/* detailed sub-states of ISO_S_IN_PTS */
57enum pts_state {
58 PTS_S_WAIT_REQ_PTSS,
59 PTS_S_WAIT_REQ_PTS0,
60 PTS_S_WAIT_REQ_PTS1,
61 PTS_S_WAIT_REQ_PTS2,
62 PTS_S_WAIT_REQ_PTS3,
63 PTS_S_WAIT_REQ_PCK,
64 PTS_S_WAIT_RESP_PTSS = PTS_S_WAIT_REQ_PTSS | 0x10,
65 PTS_S_WAIT_RESP_PTS0 = PTS_S_WAIT_REQ_PTS0 | 0x10,
66 PTS_S_WAIT_RESP_PTS1 = PTS_S_WAIT_REQ_PTS1 | 0x10,
67 PTS_S_WAIT_RESP_PTS2 = PTS_S_WAIT_REQ_PTS2 | 0x10,
68 PTS_S_WAIT_RESP_PTS3 = PTS_S_WAIT_REQ_PTS3 | 0x10,
69 PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
70};
71
72#define _PTSS 0
73#define _PTS0 1
74#define _PTS1 2
75#define _PTS2 3
76#define _PTS3 4
77#define _PCK 5
78
Harald Welte16cf4082015-11-11 19:02:48 +010079/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +010080enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +010081 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
82 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
83 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
84 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
85 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +010086 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
87 TPDU_S_WAIT_RX, /* waiitng for more data from reader */
88 TPDU_S_WAIT_TX, /* waiting for more data to reader */
89};
90
91#define _CLA 0
92#define _INS 1
93#define _P1 2
94#define _P2 3
95#define _P3 4
96
97struct card_handle {
Harald Weltedde112e2016-03-20 16:42:11 +010098 uint32_t num;
99
Harald Welte9d3e3822015-11-09 00:50:54 +0100100 enum iso7816_3_card_state state;
101
102 /* signal levels */
103 uint8_t vcc_active; /* 1 = on, 0 = off */
104 uint8_t in_reset; /* 1 = RST low, 0 = RST high */
105 uint8_t clocked; /* 1 = active, 0 = inactive */
106
Harald Welte16cf4082015-11-11 19:02:48 +0100107 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100108 uint8_t fi;
109 uint8_t di;
110 uint8_t wi;
111
112 uint8_t tc_chan; /* TC channel number */
113 uint8_t uart_chan; /* UART channel */
114
Harald Welte8e7fca32017-05-07 16:14:33 +0200115 uint8_t in_ep; /* USB IN EP */
116 uint8_t irq_ep; /* USB IN EP */
117
Harald Welte9d3e3822015-11-09 00:50:54 +0100118 uint32_t waiting_time; /* in clocks */
119
120 /* ATR state machine */
121 struct {
122 uint8_t idx;
123 uint8_t len;
124 //uint8_t hist_len;
125 //uint8_t last_td;
126 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
127 } atr;
128
129 /* PPS / PTS support */
130 struct {
131 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100132 uint8_t req[6]; /* request bytes */
133 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100134 } pts;
135
136 /* TPDU */
137 struct {
138 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100139 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100140 } tpdu;
141
Harald Welte8e7fca32017-05-07 16:14:33 +0200142 struct msgb *uart_rx_msg; /* UART RX -> USB TX */
143 struct msgb *uart_tx_msg; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100144
Harald Welte54cb3d02016-02-29 14:12:40 +0100145 struct llist_head uart_tx_queue;
146
Harald Welte9d3e3822015-11-09 00:50:54 +0100147 struct {
148 uint32_t tx_bytes;
149 uint32_t rx_bytes;
150 uint32_t pps;
151 } stats;
152};
153
Harald Welte54cb3d02016-02-29 14:12:40 +0100154struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
155{
156 return &ch->uart_tx_queue;
157}
158
Harald Welte2935b3c2015-11-14 20:00:14 +0100159static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100160static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100161
Harald Welte25a9a802017-05-08 13:30:09 +0200162/* update simtrace header msg_len and submit USB buffer */
163void usb_buf_upd_len_and_submit(struct msgb *msg)
164{
Harald Welteb91f6ad2017-05-10 22:51:30 +0200165 struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
Harald Welte25a9a802017-05-08 13:30:09 +0200166
167 sh->msg_len = msgb_length(msg);
168
169 usb_buf_submit(msg);
170}
171
172/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
173struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
174{
175 struct msgb *msg;
176 struct simtrace_msg_hdr *sh;
177
178 msg = usb_buf_alloc(ep);
179 if (!msg)
180 return NULL;
181
182 msg->l1h = msgb_put(msg, sizeof(*sh));
183 sh = (struct simtrace_msg_hdr *) msg->l1h;
184 memset(sh, 0, sizeof(*sh));
185 sh->msg_class = msg_class;
186 sh->msg_type = msg_type;
187 msg->l2h = msg->l1h + sizeof(*sh);
188
189 return msg;
190}
191
192/* Update cardemu_usb_msg_rx_data length + submit bufffer */
Harald Welteb5288e82015-11-14 21:15:52 +0100193static void flush_rx_buffer(struct card_handle *ch)
194{
Harald Welte8e7fca32017-05-07 16:14:33 +0200195 struct msgb *msg;
Harald Welteb5288e82015-11-14 21:15:52 +0100196 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200197 uint32_t data_len;
Harald Welteb5288e82015-11-14 21:15:52 +0100198
Harald Welte8e7fca32017-05-07 16:14:33 +0200199 msg = ch->uart_rx_msg;
200 if (!msg)
Harald Welteb5288e82015-11-14 21:15:52 +0100201 return;
202
Harald Welte8e7fca32017-05-07 16:14:33 +0200203 ch->uart_rx_msg = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100204
205 /* store length of data payload fild in header */
Harald Welte25a9a802017-05-08 13:30:09 +0200206 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
207 rd->data_len = msgb_l2len(msg) - sizeof(*rd);
Harald Welte54cb3d02016-02-29 14:12:40 +0100208
Harald Welte25a9a802017-05-08 13:30:09 +0200209 usb_buf_upd_len_and_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100210}
211
Harald Welte4ba66d02016-02-25 19:38:56 +0100212/* convert a non-contiguous PTS request/responsei into a contiguous
213 * buffer, returning the number of bytes used in the buffer */
214static int serialize_pts(uint8_t *out, const uint8_t *in)
215{
216 int i = 0;
217
218 out[i++] = in[_PTSS];
219 out[i++] = in[_PTS0];
220 if (in[_PTS0] & (1 << 4))
221 out[i++] = in[_PTS1];
222 if (in[_PTS0] & (1 << 5))
223 out[i++] = in[_PTS2];
224 if (in[_PTS0] & (1 << 6))
225 out[i++] = in[_PTS3];
226 out[i++] = in[_PCK];
227
228 return i;
229}
230
Harald Welte17db2f12016-02-26 09:48:57 +0100231static uint8_t csum_pts(const uint8_t *in)
232{
233 uint8_t out[6];
234 int len = serialize_pts(out, in);
235 uint8_t csum = 0;
236 int i;
237
238 /* we don't include the PCK byte in the checksumming process */
239 len -= 1;
240
241 for (i = 0; i < len; i++)
242 csum = csum ^ out[i];
243
244 return csum;
245}
246
Harald Welte4ba66d02016-02-25 19:38:56 +0100247static void flush_pts(struct card_handle *ch)
248{
Harald Welte8e7fca32017-05-07 16:14:33 +0200249 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100250 struct cardemu_usb_msg_pts_info *ptsi;
251
Harald Welte25a9a802017-05-08 13:30:09 +0200252 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200253 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100254 return;
255
Harald Welte25a9a802017-05-08 13:30:09 +0200256 ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
Harald Welted295b922016-03-18 21:01:36 +0100257 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100258 serialize_pts(ptsi->resp, ch->pts.resp);
259
Harald Welte25a9a802017-05-08 13:30:09 +0200260 usb_buf_upd_len_and_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100261}
262
Harald Welte8c496362016-02-27 16:24:09 +0100263static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100264{
265 int rc;
266
267 rc = compute_fidi_ratio(ch->fi, ch->di);
268 if (rc > 0 && rc < 0x400) {
Harald Weltedde112e2016-03-20 16:42:11 +0100269 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
270 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100271 /* make sure UART uses new F/D ratio */
272 card_emu_uart_update_fidi(ch->uart_chan, rc);
273 /* notify ETU timer about this */
274 tc_etu_set_etu(ch->tc_chan, rc);
275 } else
Harald Weltedde112e2016-03-20 16:42:11 +0100276 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
277 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100278}
279
280/* Update the ISO 7816-3 TPDU receiver state */
281static void card_set_state(struct card_handle *ch,
282 enum iso7816_3_card_state new_state)
283{
Harald Welte903d63a2016-03-20 13:38:39 +0100284 if (ch->state == new_state)
285 return;
286
Harald Weltedde112e2016-03-20 16:42:11 +0100287 TRACE_DEBUG("%u: 7816 card state %u -> %u\r\n", ch->num,
288 ch->state, new_state);
Harald Welte903d63a2016-03-20 13:38:39 +0100289 ch->state = new_state;
290
Harald Welte9d3e3822015-11-09 00:50:54 +0100291 switch (new_state) {
292 case ISO_S_WAIT_POWER:
293 case ISO_S_WAIT_CLK:
294 case ISO_S_WAIT_RST:
295 /* disable Rx and Tx of UART */
296 card_emu_uart_enable(ch->uart_chan, 0);
297 break;
298 case ISO_S_WAIT_ATR:
Harald Weltee7194ab2015-11-14 21:03:25 +0100299 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100300 /* Reset to initial Fi / Di ratio */
301 ch->fi = 1;
302 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100303 emu_update_fidi(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100304 /* initialize todefault WI, this will be overwritten if we
305 * receive TC2, and it will be programmed into hardware after
306 * ATR is finished */
307 ch->wi = ISO7816_3_DEFAULT_WI;
308 /* update waiting time to initial waiting time */
309 ch->waiting_time = ISO7816_3_INIT_WTIME;
310 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
311 /* Set ATR sub-state to initial state */
312 ch->atr.idx = 0;
313 //set_atr_state(ch, ATR_S_WAIT_TS);
314 /* Notice that we are just coming out of reset */
315 //ch->sh.flags |= SIMTRACE_FLAG_ATR;
316 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
317 break;
318 break;
319 case ISO_S_WAIT_TPDU:
320 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100321 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100322 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
323 break;
324 case ISO_S_IN_ATR:
325 case ISO_S_IN_PTS:
326 case ISO_S_IN_TPDU:
327 /* do nothing */
328 break;
329 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100330}
331
332
333/**********************************************************************
334 * PTS / PPS handling
335 **********************************************************************/
336
337/* Update the ATR sub-state */
338static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
339{
Harald Weltedde112e2016-03-20 16:42:11 +0100340 TRACE_DEBUG("%u: 7816 PTS state %u -> %u\r\n",
341 ch->num, ch->pts.state, new_ptss);
Harald Welte9d3e3822015-11-09 00:50:54 +0100342 ch->pts.state = new_ptss;
343}
344
345/* Determine the next PTS state */
346static enum pts_state next_pts_state(struct card_handle *ch)
347{
348 uint8_t is_resp = ch->pts.state & 0x10;
349 uint8_t sstate = ch->pts.state & 0x0f;
350 uint8_t *pts_ptr;
351
352 if (!is_resp)
353 pts_ptr = ch->pts.req;
354 else
355 pts_ptr = ch->pts.resp;
356
357 switch (sstate) {
358 case PTS_S_WAIT_REQ_PTSS:
359 goto from_ptss;
360 case PTS_S_WAIT_REQ_PTS0:
361 goto from_pts0;
362 case PTS_S_WAIT_REQ_PTS1:
363 goto from_pts1;
364 case PTS_S_WAIT_REQ_PTS2:
365 goto from_pts2;
366 case PTS_S_WAIT_REQ_PTS3:
367 goto from_pts3;
368 }
369
370 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
371 return PTS_S_WAIT_RESP_PTSS;
372
373from_ptss:
374 return PTS_S_WAIT_REQ_PTS0 | is_resp;
375from_pts0:
376 if (pts_ptr[_PTS0] & (1 << 4))
377 return PTS_S_WAIT_REQ_PTS1 | is_resp;
378from_pts1:
379 if (pts_ptr[_PTS0] & (1 << 5))
380 return PTS_S_WAIT_REQ_PTS2 | is_resp;
381from_pts2:
382 if (pts_ptr[_PTS0] & (1 << 6))
383 return PTS_S_WAIT_REQ_PTS3 | is_resp;
384from_pts3:
385 return PTS_S_WAIT_REQ_PCK | is_resp;
386}
387
388
Harald Welteccb8a222016-03-20 13:37:11 +0100389static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100390process_byte_pts(struct card_handle *ch, uint8_t byte)
391{
392 switch (ch->pts.state) {
393 case PTS_S_WAIT_REQ_PTSS:
394 ch->pts.req[_PTSS] = byte;
395 break;
396 case PTS_S_WAIT_REQ_PTS0:
397 ch->pts.req[_PTS0] = byte;
398 break;
399 case PTS_S_WAIT_REQ_PTS1:
400 ch->pts.req[_PTS1] = byte;
401 break;
402 case PTS_S_WAIT_REQ_PTS2:
403 ch->pts.req[_PTS2] = byte;
404 break;
405 case PTS_S_WAIT_REQ_PTS3:
406 ch->pts.req[_PTS3] = byte;
407 break;
408 case PTS_S_WAIT_REQ_PCK:
409 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100410 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100411 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
412 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100413 /* Wait for the next TPDU */
414 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
415 return ISO_S_WAIT_TPDU;
416 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100417 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100418 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
419 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100420 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100421 TRACE_ERROR("%u: process_byte_pts() in invalid state %u\r\n",
422 ch->num, ch->pts.state);
Harald Welte4c473da2015-11-14 13:31:11 +0100423 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100424 }
425 /* calculate the next state and set it */
426 set_pts_state(ch, next_pts_state(ch));
427
Harald Welte4ba66d02016-02-25 19:38:56 +0100428 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
429 flush_pts(ch);
430 /* activate UART TX to transmit PTS response */
431 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100432 /* don't fall-through to the 'return ISO_S_IN_PTS'
433 * below, rather keep ISO7816 state as-is, it will be
434 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100435 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100436 }
437
Harald Welte9d3e3822015-11-09 00:50:54 +0100438 return ISO_S_IN_PTS;
439}
440
441/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100442static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100443{
Harald Welte855ba9e2016-02-24 21:00:46 +0100444 uint8_t byte;
445
446 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100447 switch (ch->pts.state) {
448 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100449 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100450 break;
451 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100452 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100453 break;
454 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100455 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100456 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100457 ch->fi = byte >> 4;
458 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100459 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
460 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100461 break;
462 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100463 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100464 break;
465 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100466 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100467 break;
468 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100469 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100470 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100471 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100472 TRACE_ERROR("%u: get_byte_pts() in invalid state %u\r\n",
473 ch->num, ch->pts.state);
Harald Welte855ba9e2016-02-24 21:00:46 +0100474 return 0;
475 }
476
477 /* 2: Transmit the byte */
478 card_emu_uart_tx(ch->uart_chan, byte);
479
480 /* 3: Update the state */
481
482 switch (ch->pts.state) {
483 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100484 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100485 /* update baud rate generator with Fi/Di */
486 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100487 /* Wait for the next TPDU */
488 card_set_state(ch, ISO_S_WAIT_TPDU);
489 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
490 break;
491 default:
492 /* calculate the next state and set it */
493 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100494 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100495 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100496
Harald Welte855ba9e2016-02-24 21:00:46 +0100497 /* return number of bytes transmitted */
498 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100499}
500
501
502/**********************************************************************
503 * TPDU handling
504 **********************************************************************/
505
Harald Welte4d804672015-11-14 23:02:38 +0100506
507/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
508static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
509{
510 if (reader_to_card) {
511 return p3;
512 } else {
513 if (p3 == 0)
514 return 256;
515 else
516 return p3;
517 }
518}
519
Harald Welte9d3e3822015-11-09 00:50:54 +0100520/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100521static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100522{
Harald Welte8e7fca32017-05-07 16:14:33 +0200523 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100524 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100525 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100526
527 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200528 if (!ch->uart_rx_msg) {
Harald Welte25a9a802017-05-08 13:30:09 +0200529 msg = ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
530 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200531 if (!ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100532 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
533 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100534 return;
Harald Welte4d804672015-11-14 23:02:38 +0100535 }
Harald Welte25a9a802017-05-08 13:30:09 +0200536 msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100537 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200538 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100539
Harald Welte25a9a802017-05-08 13:30:09 +0200540 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
Harald Welte8e7fca32017-05-07 16:14:33 +0200541 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100542
543 /* check if the buffer is full. If so, send it */
Harald Welte25a9a802017-05-08 13:30:09 +0200544 if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100545 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100546 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100547 /* We need to transmit the SW now, */
548 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200549 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100550 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100551}
552
553static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
554{
Harald Welte05b41c62015-11-14 20:58:48 +0100555 if (ch->tpdu.state == new_ts)
556 return;
557
Harald Weltedde112e2016-03-20 16:42:11 +0100558 TRACE_DEBUG("%u: 7816 TPDU state %u -> %u\r\n", ch->num,
559 ch->tpdu.state, new_ts);
Harald Welte05b41c62015-11-14 20:58:48 +0100560
Harald Welte903d63a2016-03-20 13:38:39 +0100561 ch->tpdu.state = new_ts;
562
Harald Welte9d3e3822015-11-09 00:50:54 +0100563 switch (new_ts) {
564 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100565 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100566 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
567 break;
568 case TPDU_S_WAIT_PB:
569 /* we just completed the TPDU header from reader to card
570 * and now need to disable the receiver, enable the
571 * transmitter and transmit the procedure byte */
572 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
573 break;
Harald Weltead434402016-03-02 11:18:29 +0100574 default:
575 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100576 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100577}
578
579static enum tpdu_state next_tpdu_state(struct card_handle *ch)
580{
581 switch (ch->tpdu.state) {
582 case TPDU_S_WAIT_CLA:
583 return TPDU_S_WAIT_INS;
584 case TPDU_S_WAIT_INS:
585 return TPDU_S_WAIT_P1;
586 case TPDU_S_WAIT_P1:
587 return TPDU_S_WAIT_P2;
588 case TPDU_S_WAIT_P2:
589 return TPDU_S_WAIT_P3;
590 case TPDU_S_WAIT_P3:
591 return TPDU_S_WAIT_PB;
592 /* simply stay in Rx or Tx by default */
593 case TPDU_S_WAIT_PB:
594 return TPDU_S_WAIT_PB;
595 case TPDU_S_WAIT_RX:
596 return TPDU_S_WAIT_RX;
597 case TPDU_S_WAIT_TX:
598 return TPDU_S_WAIT_TX;
599 }
Harald Welte4c473da2015-11-14 13:31:11 +0100600 /* we should never reach here */
601 assert(0);
602 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100603}
604
605static void send_tpdu_header(struct card_handle *ch)
606{
Harald Welte8e7fca32017-05-07 16:14:33 +0200607 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100608 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200609 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100610
Harald Weltedde112e2016-03-20 16:42:11 +0100611 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
612 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100613 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
614 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
615 ch->tpdu.hdr[4]);
616
Harald Welte9d3e3822015-11-09 00:50:54 +0100617 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200618 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100619 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200620 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100621 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100622 flush_rx_buffer(ch);
623 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100624 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200625 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
626 /* ensure we have a new buffer */
Harald Welte25a9a802017-05-08 13:30:09 +0200627 ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
628 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200629 if (!ch->uart_rx_msg) {
630 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
631 return;
632 }
633 msg = ch->uart_rx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200634 rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100635
Harald Welte8e7fca32017-05-07 16:14:33 +0200636 /* initialize header */
Harald Welte9d3e3822015-11-09 00:50:54 +0100637 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100638
639 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200640 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
641 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100642 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100643
Harald Welteb5288e82015-11-14 21:15:52 +0100644 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100645}
646
647static enum iso7816_3_card_state
648process_byte_tpdu(struct card_handle *ch, uint8_t byte)
649{
650 switch (ch->tpdu.state) {
651 case TPDU_S_WAIT_CLA:
652 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100653 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100654 break;
655 case TPDU_S_WAIT_INS:
656 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100657 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100658 break;
659 case TPDU_S_WAIT_P1:
660 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100661 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100662 break;
663 case TPDU_S_WAIT_P2:
664 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100665 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100666 break;
667 case TPDU_S_WAIT_P3:
668 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100669 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100670 /* FIXME: start timer to transmit further 0x60 */
671 /* send the TPDU header as part of a procedure byte
672 * request to the USB host */
673 send_tpdu_header(ch);
674 break;
675 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100676 add_tpdu_byte(ch, byte);
677 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100678 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100679 TRACE_ERROR("%u: process_byte_tpdu() in invalid state %u\r\n",
680 ch->num, ch->tpdu.state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100681 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100682
683 /* ensure we stay in TPDU ISO state */
684 return ISO_S_IN_TPDU;
685}
686
Harald Welte855ba9e2016-02-24 21:00:46 +0100687/* tx a single byte to be transmitted to the reader */
688static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100689{
Harald Welte8e7fca32017-05-07 16:14:33 +0200690 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100691 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100692 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100693
694 /* ensure we are aware of any data that might be pending for
695 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200696 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100697 /* uart_tx_queue is filled from main loop, so no need
698 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100699 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100700 return 0;
701
Harald Welte54cb3d02016-02-29 14:12:40 +0100702 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200703 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
Harald Welte25a9a802017-05-08 13:30:09 +0200704 ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
705 ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
Harald Welte8e7fca32017-05-07 16:14:33 +0200706 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200707 /* remove the header */
708 msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100709 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200710 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200711 td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100712
Harald Welte8e7fca32017-05-07 16:14:33 +0200713 /* take the next pending byte out of the msgb */
714 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100715
716 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100717
Harald Weltef16b6182016-02-24 22:18:46 +0100718 /* this must happen _after_ the byte has been transmittd */
719 switch (ch->tpdu.state) {
720 case TPDU_S_WAIT_PB:
721 /* if we just transmitted the procedure byte, we need to decide
722 * if we want to continue to receive or transmit */
723 if (td->flags & CEMU_DATA_F_PB_AND_TX)
724 set_tpdu_state(ch, TPDU_S_WAIT_TX);
725 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
726 set_tpdu_state(ch, TPDU_S_WAIT_RX);
727 break;
Harald Weltead434402016-03-02 11:18:29 +0100728 default:
729 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100730 }
731
Harald Welte9d3e3822015-11-09 00:50:54 +0100732 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200733 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100734 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
735 /* we have just sent the procedure byte and now
736 * need to continue receiving */
737 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100738 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100739 /* we have transmitted all bytes */
740 if (td->flags & CEMU_DATA_F_FINAL) {
741 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100742 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100743 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100744 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100745 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200746 usb_buf_free(msg);
747 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100748 }
749
750 return 1;
751}
752
753/**********************************************************************
754 * Public API
755 **********************************************************************/
756
757/* process a single byte received from the reader */
758void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
759{
760 int new_state = -1;
761
762 ch->stats.rx_bytes++;
763
764 switch (ch->state) {
765 case ISO_S_WAIT_POWER:
766 case ISO_S_WAIT_CLK:
767 case ISO_S_WAIT_RST:
768 case ISO_S_WAIT_ATR:
Harald Weltedde112e2016-03-20 16:42:11 +0100769 TRACE_ERROR("%u: Received UART char in invalid 7816 state "
770 "%u\r\n", ch->num, ch->state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100771 /* we shouldn't receive any data from the reader yet! */
772 break;
773 case ISO_S_WAIT_TPDU:
774 if (byte == 0xff) {
775 new_state = process_byte_pts(ch, byte);
776 ch->stats.pps++;
777 goto out_silent;
778 }
779 /* fall-through */
780 case ISO_S_IN_TPDU:
781 new_state = process_byte_tpdu(ch, byte);
782 break;
783 case ISO_S_IN_PTS:
784 new_state = process_byte_pts(ch, byte);
785 goto out_silent;
786 }
787
788out_silent:
789 if (new_state != -1)
790 card_set_state(ch, new_state);
791}
792
Harald Welte855ba9e2016-02-24 21:00:46 +0100793/* transmit a single byte to the reader */
794int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100795{
796 int rc = 0;
797
798 switch (ch->state) {
799 case ISO_S_IN_ATR:
800 if (ch->atr.idx < ch->atr.len) {
Harald Welte855ba9e2016-02-24 21:00:46 +0100801 uint8_t byte;
802 byte = ch->atr.atr[ch->atr.idx++];
Harald Welte9d3e3822015-11-09 00:50:54 +0100803 rc = 1;
Harald Welte855ba9e2016-02-24 21:00:46 +0100804
805 card_emu_uart_tx(ch->uart_chan, byte);
806
Harald Welte9d3e3822015-11-09 00:50:54 +0100807 /* detect end of ATR */
808 if (ch->atr.idx >= ch->atr.len)
809 card_set_state(ch, ISO_S_WAIT_TPDU);
810 }
811 break;
812 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100813 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100814 break;
815 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +0100816 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100817 break;
Harald Weltead434402016-03-02 11:18:29 +0100818 default:
819 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100820 }
821
822 if (rc)
823 ch->stats.tx_bytes++;
824
Harald Welte4d804672015-11-14 23:02:38 +0100825 /* if we return 0 here, the UART needs to disable transmit-ready
826 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +0100827 return rc;
828}
829
Harald Welteacae4122016-03-02 10:27:58 +0100830void card_emu_have_new_uart_tx(struct card_handle *ch)
831{
832 switch (ch->state) {
833 case ISO_S_IN_TPDU:
834 switch (ch->tpdu.state) {
835 case TPDU_S_WAIT_TX:
836 case TPDU_S_WAIT_PB:
837 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
838 break;
839 default:
840 break;
841 }
842 default:
843 break;
844 }
845}
846
Harald Welteff160652016-03-19 21:59:06 +0100847void card_emu_report_status(struct card_handle *ch)
848{
Harald Welte8e7fca32017-05-07 16:14:33 +0200849 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +0100850 struct cardemu_usb_msg_status *sts;
851
Harald Welte25a9a802017-05-08 13:30:09 +0200852 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
853 SIMTRACE_MSGT_BD_CEMU_STATUS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200854 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +0100855 return;
Harald Welte8e7fca32017-05-07 16:14:33 +0200856
Harald Welte25a9a802017-05-08 13:30:09 +0200857 sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
Harald Welteff160652016-03-19 21:59:06 +0100858 sts->flags = 0;
859 if (ch->vcc_active)
860 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
861 if (ch->clocked)
862 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
863 if (ch->in_reset)
864 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
865 /* FIXME: voltage + card insert */
866 sts->fi = ch->fi;
867 sts->di = ch->di;
868 sts->wi = ch->wi;
869 sts->waiting_time = ch->waiting_time;
870
Harald Welte25a9a802017-05-08 13:30:09 +0200871 usb_buf_upd_len_and_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +0100872}
873
Harald Welte9d3e3822015-11-09 00:50:54 +0100874/* hardware driver informs us that a card I/O signal has changed */
875void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
876{
877 switch (io) {
878 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +0100879 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100880 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100881 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100882 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +0100883 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100884 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100885 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +0100886 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100887 ch->vcc_active = active;
888 break;
889 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +0100890 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100891 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100892 if (ch->state == ISO_S_WAIT_CLK)
893 card_set_state(ch, ISO_S_WAIT_RST);
894 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100895 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100896 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100897 ch->clocked = active;
898 break;
899 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +0100900 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100901 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100902 if (ch->vcc_active && ch->clocked) {
903 /* enable the TC/ETU counter once reset has been released */
904 tc_etu_enable(ch->tc_chan);
905 card_set_state(ch, ISO_S_WAIT_ATR);
906 /* FIXME: wait 400 to 40k clock cycles before sending ATR */
907 card_set_state(ch, ISO_S_IN_ATR);
908 }
909 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100910 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100911 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100912 }
913 ch->in_reset = active;
914 break;
915 }
916}
917
918/* User sets a new ATR to be returned during next card reset */
919int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
920{
921 if (len > sizeof(ch->atr.atr))
922 return -1;
923
924 memcpy(ch->atr.atr, atr, len);
925 ch->atr.len = len;
926 ch->atr.idx = 0;
927
928 /* FIXME: race condition with trasmitting ATR to reader? */
929
930 return 0;
931}
932
933/* hardware driver informs us that one (more) ETU has expired */
934void tc_etu_wtime_half_expired(void *handle)
935{
936 struct card_handle *ch = handle;
937 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +0100938 switch (ch->state) {
939 case ISO_S_IN_TPDU:
940 switch (ch->tpdu.state) {
941 case TPDU_S_WAIT_PB:
942 case TPDU_S_WAIT_TX:
943 putchar('N');
944 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
945 break;
946 default:
947 break;
948 }
949 break;
950 default:
951 break;
952 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100953}
954
955/* hardware driver informs us that one (more) ETU has expired */
956void tc_etu_wtime_expired(void *handle)
957{
Harald Weltedde112e2016-03-20 16:42:11 +0100958 struct card_handle *ch = handle;
959 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100960}
961
962/* shortest ATR found in smartcard_list.txt */
963static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
964
965static struct card_handle card_handles[NUM_SLOTS];
966
Harald Welte8e7fca32017-05-07 16:14:33 +0200967struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan,
968 uint8_t in_ep, uint8_t irq_ep)
Harald Welte9d3e3822015-11-09 00:50:54 +0100969{
970 struct card_handle *ch;
971
972 if (slot_num >= ARRAY_SIZE(card_handles))
973 return NULL;
974
975 ch = &card_handles[slot_num];
976
977 memset(ch, 0, sizeof(*ch));
978
Harald Welte54cb3d02016-02-29 14:12:40 +0100979 INIT_LLIST_HEAD(&ch->uart_tx_queue);
980
Harald Welte9d3e3822015-11-09 00:50:54 +0100981 /* initialize the card_handle with reasonabe defaults */
Harald Weltedde112e2016-03-20 16:42:11 +0100982 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +0200983 ch->irq_ep = irq_ep;
984 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +0100985 ch->state = ISO_S_WAIT_POWER;
986 ch->vcc_active = 0;
987 ch->in_reset = 1;
988 ch->clocked = 0;
989
990 ch->fi = 0;
991 ch->di = 1;
992 ch->wi = ISO7816_3_DEFAULT_WI;
993
994 ch->tc_chan = tc_chan;
995 ch->uart_chan = uart_chan;
996 ch->waiting_time = ISO7816_3_INIT_WTIME;
997
998 ch->atr.idx = 0;
999 ch->atr.len = sizeof(default_atr);
1000 memcpy(ch->atr.atr, default_atr, ch->atr.len);
1001
1002 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
1003 ch->tpdu.state = TPDU_S_WAIT_CLA;
1004
1005 tc_etu_init(ch->tc_chan, ch);
1006
1007 return ch;
1008}