blob: 18aa61f5d7588b1816f87df7b5cfa1e01efebfff [file] [log] [blame]
Harald Welte727d6752019-09-30 21:46:44 +02001/* Code providing a ccid_slot_ops implementation based on iso7716_fsm,
2 * (which in turn sits on top of card_uart) */
3
Harald Weltea67be5f2020-09-03 10:04:36 +02004/* (C) 2019-2020 by Harald Welte <laforge@gnumonks.org>
5 *
6 * 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.
10 *
11 * 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.
15 *
16 * 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
19 */
20
Harald Welte727d6752019-09-30 21:46:44 +020021#include <unistd.h>
22#include <errno.h>
Harald Welte6def1cf2019-10-10 15:40:02 +020023#include <string.h>
Harald Welte727d6752019-09-30 21:46:44 +020024
25#include <osmocom/core/msgb.h>
26#include <osmocom/core/timer.h>
27#include <osmocom/core/logging.h>
28#include <osmocom/core/fsm.h>
29
30#include "ccid_device.h"
31#include "cuart.h"
32#include "iso7816_fsm.h"
Eric Wildad1edce2019-11-27 16:51:08 +010033#include "iso7816_3.h"
Harald Welte727d6752019-09-30 21:46:44 +020034
35struct iso_fsm_slot {
36 /* CCID slot above us */
37 struct ccid_slot *cs;
38 /* main ISO7816-3 FSM instance beneath us */
39 struct osmo_fsm_inst *fi;
40 /* UART beneath the ISO7816-3 FSM */
41 struct card_uart *cuart;
42 /* bSeq of the operation currently in progress */
43 uint8_t seq;
44};
45
46struct iso_fsm_slot_instance {
47 struct iso_fsm_slot slot[NR_SLOTS];
48};
49
50static struct iso_fsm_slot_instance g_si;
51
Harald Welte03d6ebb2019-09-28 23:19:31 +020052static struct iso_fsm_slot *ccid_slot2iso_fsm_slot(struct ccid_slot *cs)
Harald Welte727d6752019-09-30 21:46:44 +020053{
54 OSMO_ASSERT(cs->slot_nr < ARRAY_SIZE(g_si.slot));
55 return &g_si.slot[cs->slot_nr];
56}
57
Harald Welte03d6ebb2019-09-28 23:19:31 +020058struct card_uart *cuart4slot_nr(uint8_t slot_nr)
59{
60 OSMO_ASSERT(slot_nr < ARRAY_SIZE(g_si.slot));
61 return g_si.slot[slot_nr].cuart;
62}
63
Harald Welte727d6752019-09-30 21:46:44 +020064static const uint8_t sysmousim_sjs1_atr[] = {
65 0x3B, 0x9F, 0x96, 0x80, 0x1F, 0xC7, 0x80, 0x31,
66 0xA0, 0x73, 0xBE, 0x21, 0x13, 0x67, 0x43, 0x20,
67 0x07, 0x18, 0x00, 0x00, 0x01, 0xA5 };
68
69static const struct ccid_pars_decoded iso_fsm_def_pars = {
70 .fi = 372,
71 .di = 1,
72 .clock_stop = CCID_CLOCK_STOP_NOTALLOWED,
73 .inverse_convention = false,
74 .t0 = {
75 .guard_time_etu = 0,
76 .waiting_integer = 0,
77 },
78 /* FIXME: T=1 */
79};
80
81static void iso_fsm_slot_pre_proc_cb(struct ccid_slot *cs, struct msgb *msg)
82{
83 /* do nothing; real hardware would update the slot related state here */
84}
85
Eric Wild9e622dc2019-11-27 14:43:16 +010086static void iso_fsm_slot_icc_set_insertion_status(struct ccid_slot *cs, bool present) {
87 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
88
89 if(present == cs->icc_present)
90 return;
91
92 cs->icc_present = present;
93
94 if (!present) {
95 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_CARD_REMOVAL, NULL);
96 card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);
Eric Wild70f36912020-04-03 22:29:02 +020097 card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, false);
Eric Wild9e622dc2019-11-27 14:43:16 +010098 cs->icc_powered = false;
99 cs->cmd_busy = false;
100 }
101}
102
Harald Welte727d6752019-09-30 21:46:44 +0200103static void iso_fsm_slot_icc_power_on_async(struct ccid_slot *cs, struct msgb *msg,
104 const struct ccid_pc_to_rdr_icc_power_on *ipo)
105{
106 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
Eric Wild70f36912020-04-03 22:29:02 +0200107 enum ccid_power_select pwrsel = ipo->bPowerSelect;
108 enum card_uart_ctl cctl;
Harald Welte727d6752019-09-30 21:46:44 +0200109
110 ss->seq = ipo->hdr.bSeq;
111 LOGPCS(cs, LOGL_DEBUG, "scheduling power-up\n");
112
Eric Wild70f36912020-04-03 22:29:02 +0200113 switch (pwrsel) {
114 case CCID_PWRSEL_5V0: cctl = CUART_CTL_POWER_5V0; break;
115 case CCID_PWRSEL_3V0: cctl = CUART_CTL_POWER_3V0; break;
116 case CCID_PWRSEL_1V8: cctl = CUART_CTL_POWER_1V8; break;
117 default: cctl = CUART_CTL_POWER_5V0;
118 }
119
Eric Wildaed26cc2020-03-30 04:22:36 +0200120 if (! cs->icc_powered) {
121 /* FIXME: do this via a FSM? */
122 card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);
123 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_ACT_IND, NULL);
Eric Wild70f36912020-04-03 22:29:02 +0200124 card_uart_ctrl(ss->cuart, cctl, true);
Eric Wildaed26cc2020-03-30 04:22:36 +0200125 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_POWER_UP_IND, NULL);
126 cs->icc_powered = true;
127 card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, true);
128 #ifdef OCTSIMFWBUILD
129 delay_us(10000);
130 #else
131 usleep(10000);
132 #endif
Harald Welte03d6ebb2019-09-28 23:19:31 +0200133
Eric Wildaed26cc2020-03-30 04:22:36 +0200134 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_REL_IND, NULL);
135 card_uart_ctrl(ss->cuart, CUART_CTL_RST, false);
136 } else { /* warm reset */
137 card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);
138 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_ACT_IND, NULL);
139 #ifdef OCTSIMFWBUILD
140 delay_us(10000);
141 #else
142 usleep(10000);
143 #endif
144 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_REL_IND, NULL);
145 card_uart_ctrl(ss->cuart, CUART_CTL_RST, false);
146 }
Harald Welte727d6752019-09-30 21:46:44 +0200147 msgb_free(msg);
148 /* continues in iso_fsm_clot_user_cb once ATR is received */
149}
150static void iso_fsm_clot_user_cb(struct osmo_fsm_inst *fi, int event, int cause, void *data)
151{
152 struct iso_fsm_slot *ss = iso7816_fsm_get_user_priv(fi);
153 struct ccid_slot *cs = ss->cs;
Eric Wild759a6462019-11-11 14:22:52 +0100154
155 switch (event) {
156 case ISO7816_E_ATR_DONE_IND:
157 case ISO7816_E_ATR_ERR_IND:
158 case ISO7816_E_TPDU_DONE_IND:
159 case ISO7816_E_TPDU_FAILED_IND:
160 case ISO7816_E_PPS_DONE_IND:
161 case ISO7816_E_PPS_FAILED_IND:
Eric Wild91f75ce2020-03-30 04:10:31 +0200162 case ISO7816_E_WTIME_EXP:
Eric Wild759a6462019-11-11 14:22:52 +0100163 cs->event_data = data;
Eric Wilde84a5712019-11-28 17:30:30 +0100164#ifdef OCTSIMFWBUILD
Eric Wild759a6462019-11-11 14:22:52 +0100165 asm volatile("dmb st": : :"memory");
Eric Wilde84a5712019-11-28 17:30:30 +0100166#endif
Eric Wild759a6462019-11-11 14:22:52 +0100167 cs->event = event;
168 break;
169 default:
170 LOGPCS(cs, LOGL_NOTICE, "%s(event=%d, cause=%d, data=%p) unhandled\n",
171 __func__, event, cause, data);
172 break;
173 }
174}
175
176static int iso_handle_fsm_events(struct ccid_slot *cs, bool enable){
177 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
Harald Welte727d6752019-09-30 21:46:44 +0200178 struct msgb *tpdu, *resp;
Eric Wild759a6462019-11-11 14:22:52 +0100179 volatile uint32_t event = cs->event;
180 volatile void * volatile data = cs->event_data;
181
182 if(!event)
183 return 0;
Eric Wild91f75ce2020-03-30 04:10:31 +0200184// if(event && !data)
185// return 0;
Harald Welte727d6752019-09-30 21:46:44 +0200186
Harald Welte727d6752019-09-30 21:46:44 +0200187 switch (event) {
Eric Wild91f75ce2020-03-30 04:10:31 +0200188 case ISO7816_E_WTIME_EXP:
189 tpdu = data;
190 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=0)\n", __func__, event);
191
192
193 /* perform deactivation */
194 card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);
Eric Wild70f36912020-04-03 22:29:02 +0200195 card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, false);
Eric Wild91f75ce2020-03-30 04:10:31 +0200196 cs->icc_powered = false;
197
198
199 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_FAILED, CCID_ERR_ICC_MUTE, 0, 0);
200 ccid_slot_send_unbusy(cs, resp);
201 cs->event = 0;
202 break;
Harald Welte727d6752019-09-30 21:46:44 +0200203 case ISO7816_E_ATR_DONE_IND:
204 tpdu = data;
Eric Wild759a6462019-11-11 14:22:52 +0100205 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,
Harald Welte22dd1ff2019-10-10 15:40:53 +0200206 msgb_hexdump(tpdu));
Harald Welte727d6752019-09-30 21:46:44 +0200207 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0,
208 msgb_data(tpdu), msgb_length(tpdu));
209 ccid_slot_send_unbusy(cs, resp);
Harald Weltebbb50092019-10-10 14:55:25 +0200210 /* Don't free "TPDU" here, as the ATR should survive */
Eric Wild759a6462019-11-11 14:22:52 +0100211 cs->event = 0;
212 break;
213 case ISO7816_E_ATR_ERR_IND:
214 tpdu = data;
215 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,
216 msgb_hexdump(tpdu));
217 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_FAILED, CCID_ERR_ICC_MUTE,
218 msgb_data(tpdu), msgb_length(tpdu));
219 ccid_slot_send_unbusy(cs, resp);
220 /* Don't free "TPDU" here, as the ATR should survive */
221 cs->event = 0;
222 break;
Harald Welte727d6752019-09-30 21:46:44 +0200223 break;
224 case ISO7816_E_TPDU_DONE_IND:
225 tpdu = data;
Eric Wild759a6462019-11-11 14:22:52 +0100226 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,
Harald Welte22dd1ff2019-10-10 15:40:53 +0200227 msgb_hexdump(tpdu));
Harald Welte43281fe2020-07-30 20:29:02 +0200228 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0, msgb_l4(tpdu), msgb_l4len(tpdu));
Harald Welte727d6752019-09-30 21:46:44 +0200229 ccid_slot_send_unbusy(cs, resp);
230 msgb_free(tpdu);
Eric Wild759a6462019-11-11 14:22:52 +0100231 cs->event = 0;
Harald Welte727d6752019-09-30 21:46:44 +0200232 break;
Eric Wild9e622dc2019-11-27 14:43:16 +0100233 case ISO7816_E_TPDU_FAILED_IND:
234 tpdu = data;
Eric Wild759a6462019-11-11 14:22:52 +0100235 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,
Eric Wild9e622dc2019-11-27 14:43:16 +0100236 msgb_hexdump(tpdu));
237 /* FIXME: other error causes than card removal?*/
238 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_FAILED, CCID_ERR_ICC_MUTE, msgb_l2(tpdu), 0);
239 ccid_slot_send_unbusy(cs, resp);
240 msgb_free(tpdu);
Eric Wild759a6462019-11-11 14:22:52 +0100241 cs->event = 0;
Eric Wild9e622dc2019-11-27 14:43:16 +0100242 break;
Eric Wildad1edce2019-11-27 16:51:08 +0100243 case ISO7816_E_PPS_DONE_IND:
244 tpdu = data;
245 /* pps was successful, so we know these values are fine */
246 uint16_t F = iso7816_3_fi_table[cs->proposed_pars.fi];
247 uint8_t D = iso7816_3_di_table[cs->proposed_pars.di];
248 uint32_t fmax = iso7816_3_fmax_table[cs->proposed_pars.fi];
Eric Wild066489d2020-10-17 01:36:26 +0200249 uint8_t D_or_one = D > 0 ? D : 1;
Eric Wildad1edce2019-11-27 16:51:08 +0100250
Eric Wilda0574572019-11-21 15:28:59 +0100251 /* 7816-3 5.2.3
252 * No information shall be exchanged when switching the
253 * frequency value. Two different times are recommended
254 * for switching the frequency value, either
255 * - after ATR while card is idle
256 * - after PPS while card is idle
257 */
Eric Wild587d4fb2019-11-27 18:59:43 +0100258 card_uart_ctrl(ss->cuart, CUART_CTL_SET_CLOCK_FREQ, fmax);
259 card_uart_ctrl(ss->cuart, CUART_CTL_SET_FD, F/D);
Eric Wild066489d2020-10-17 01:36:26 +0200260 card_uart_ctrl(ss->cuart, CUART_CTL_WTIME, cs->proposed_pars.t0.waiting_integer * 960 * D_or_one);
Eric Wildad1edce2019-11-27 16:51:08 +0100261
262 cs->pars = cs->proposed_pars;
263 resp = ccid_gen_parameters_t0(cs, ss->seq, CCID_CMD_STATUS_OK, 0);
264
265 ccid_slot_send_unbusy(cs, resp);
266
267 /* this frees the pps req from the host, pps resp buffer stays with the pps fsm */
268 msgb_free(tpdu);
Eric Wild759a6462019-11-11 14:22:52 +0100269 cs->event = 0;
Eric Wildad1edce2019-11-27 16:51:08 +0100270 break;
271 case ISO7816_E_PPS_FAILED_IND:
272 tpdu = data;
273 /* failed fi/di */
274 resp = ccid_gen_parameters_t0(cs, ss->seq, CCID_CMD_STATUS_FAILED, 10);
275 ccid_slot_send_unbusy(cs, resp);
276 /* this frees the pps req from the host, pps resp buffer stays with the pps fsm */
277 msgb_free(tpdu);
Eric Wild759a6462019-11-11 14:22:52 +0100278 cs->event = 0;
279 break;
280 case 0:
Eric Wildad1edce2019-11-27 16:51:08 +0100281 break;
Harald Welte22dd1ff2019-10-10 15:40:53 +0200282 default:
Eric Wild759a6462019-11-11 14:22:52 +0100283 LOGPCS(cs, LOGL_NOTICE, "%s(event=%d, data=%p) unhandled\n",
284 __func__, event, data);
Harald Welte22dd1ff2019-10-10 15:40:53 +0200285 break;
Harald Welte727d6752019-09-30 21:46:44 +0200286 }
287}
288
Eric Wild9e622dc2019-11-27 14:43:16 +0100289static int iso_fsm_slot_xfr_block_async(struct ccid_slot *cs, struct msgb *msg,
Harald Welte727d6752019-09-30 21:46:44 +0200290 const struct ccid_pc_to_rdr_xfr_block *xfb)
291{
292 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
Eric Wild759a6462019-11-11 14:22:52 +0100293
Harald Welte727d6752019-09-30 21:46:44 +0200294
Harald Welte727d6752019-09-30 21:46:44 +0200295 ss->seq = xfb->hdr.bSeq;
Harald Welte6def1cf2019-10-10 15:40:02 +0200296
297 /* must be '0' for TPDU level exchanges or for short APDU */
Eric Wild672a9602020-10-17 01:02:39 +0200298 if (xfb->wLevelParameter != 0x0000)
299 return -8;
300
301 if (msgb_length(msg) != xfb->hdr.dwLength)
302 return -1;
Harald Welte6def1cf2019-10-10 15:40:02 +0200303
Eric Wild759a6462019-11-11 14:22:52 +0100304 msgb_pull(msg, 10);
Harald Welte6def1cf2019-10-10 15:40:02 +0200305
Eric Wild759a6462019-11-11 14:22:52 +0100306 LOGPCS(cs, LOGL_DEBUG, "scheduling TPDU transfer: %s\n", msgb_hexdump(msg));
307 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_XCEIVE_TPDU_CMD, msg);
Harald Welte727d6752019-09-30 21:46:44 +0200308 /* continues in iso_fsm_clot_user_cb once response/error/timeout is received */
Eric Wild9e622dc2019-11-27 14:43:16 +0100309 return 0;
Harald Welte727d6752019-09-30 21:46:44 +0200310}
311
312
313static void iso_fsm_slot_set_power(struct ccid_slot *cs, bool enable)
314{
315 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
316
317 if (enable) {
Eric Wild70f36912020-04-03 22:29:02 +0200318 card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, true);
Harald Welte03d6ebb2019-09-28 23:19:31 +0200319 cs->icc_powered = true;
Harald Welte727d6752019-09-30 21:46:44 +0200320 } else {
Eric Wild70f36912020-04-03 22:29:02 +0200321 card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, false);
Harald Welte03d6ebb2019-09-28 23:19:31 +0200322 cs->icc_powered = false;
Harald Welte727d6752019-09-30 21:46:44 +0200323 }
324}
325
326static void iso_fsm_slot_set_clock(struct ccid_slot *cs, enum ccid_clock_command cmd)
327{
328 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
329
330 switch (cmd) {
331 case CCID_CLOCK_CMD_STOP:
332 card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, false);
333 break;
334 case CCID_CLOCK_CMD_RESTART:
335 card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, true);
336 break;
337 default:
338 OSMO_ASSERT(0);
339 }
340}
341
Eric Wildad1edce2019-11-27 16:51:08 +0100342static int iso_fsm_slot_set_params(struct ccid_slot *cs, uint8_t seq, enum ccid_protocol_num proto,
Harald Welte727d6752019-09-30 21:46:44 +0200343 const struct ccid_pars_decoded *pars_dec)
344{
Eric Wildad1edce2019-11-27 16:51:08 +0100345 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
346 struct msgb *tpdu;
347
348 /* see 6.1.7 for error offsets */
349 if(proto != CCID_PROTOCOL_NUM_T0)
350 return -7;
351
352 if(pars_dec->t0.guard_time_etu != 0)
353 return -12;
354
355 if(pars_dec->clock_stop != CCID_CLOCK_STOP_NOTALLOWED)
356 return -14;
357
358 ss->seq = seq;
359
Eric Wild45e930d2019-11-21 14:38:16 +0100360 /* FIXME:
361 When using D=64, the interface device shall ensure a delay
362 of at least 16 etu between the leading edge of the last
363 received character and the leading edge of the character transmitted
364 for initiating a command.
365 -> we can't really do 4 stop bits?!
366 */
367
Eric Wildad1edce2019-11-27 16:51:08 +0100368 /* Hardware does not support SPU, so no PPS2, and PPS3 is reserved anyway */
369 tpdu = msgb_alloc(6, "PPSRQ");
370 OSMO_ASSERT(tpdu);
371 msgb_put_u8(tpdu, 0xff);
372 msgb_put_u8(tpdu, (1 << 4)); /* only PPS1, T=0 */
373 msgb_put_u8(tpdu, (pars_dec->fi << 4 | pars_dec->di));
374 msgb_put_u8(tpdu, 0xff ^ (1 << 4) ^ (pars_dec->fi << 4 | pars_dec->di));
375
376
377 LOGPCS(cs, LOGL_DEBUG, "scheduling PPS transfer: %s\n", msgb_hexdump(tpdu));
378 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_XCEIVE_PPS_CMD, tpdu);
379 /* continues in iso_fsm_clot_user_cb once response/error/timeout is received */
Harald Welte727d6752019-09-30 21:46:44 +0200380 return 0;
381}
382
Eric Wild56a50552020-01-28 16:07:23 +0100383static int iso_fsm_slot_set_rate_and_clock(struct ccid_slot *cs, uint32_t* freq_hz, uint32_t* rate_bps)
Harald Welte727d6752019-09-30 21:46:44 +0200384{
Eric Wild56a50552020-01-28 16:07:23 +0100385 /* we return the currently used values, since we support automatic features */
386 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
387
388 *rate_bps = card_uart_ctrl(ss->cuart, CUART_CTL_GET_BAUDRATE, false);
389 *freq_hz = card_uart_ctrl(ss->cuart, CUART_CTL_GET_CLOCK_FREQ, false)/1000;
390
Harald Welte727d6752019-09-30 21:46:44 +0200391 return 0;
392}
393
Harald Welte03d6ebb2019-09-28 23:19:31 +0200394extern void *g_tall_ctx;
Harald Welte727d6752019-09-30 21:46:44 +0200395static int iso_fsm_slot_init(struct ccid_slot *cs)
396{
Harald Welte03d6ebb2019-09-28 23:19:31 +0200397 void *ctx = g_tall_ctx; /* FIXME */
Harald Welte727d6752019-09-30 21:46:44 +0200398 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
399 struct card_uart *cuart = talloc_zero(ctx, struct card_uart);
Eric Wilde84a5712019-11-28 17:30:30 +0100400 char id_buf[3+3+1];
401 char devname[2+1];
402 char *devnamep = 0;
403 char *drivername = "asf4";
Harald Welte727d6752019-09-30 21:46:44 +0200404 int rc;
405
406 LOGPCS(cs, LOGL_DEBUG, "%s\n", __func__);
407
Eric Wilde84a5712019-11-28 17:30:30 +0100408 snprintf(id_buf, sizeof(id_buf), "SIM%d", cs->slot_nr);
409#ifdef OCTSIMFWBUILD
410 snprintf(devname, sizeof(devname), "%d", cs->slot_nr);
411 devnamep = devname;
412#else
413 if (cs->slot_nr == 0) {
414 cs->icc_present = true;
415 devnamep = "/dev/ttyUSB5";
416 }
417 drivername = "tty";
418#endif
Harald Welte727d6752019-09-30 21:46:44 +0200419
420 if (!cuart)
421 return -ENOMEM;
422
Eric Wilde84a5712019-11-28 17:30:30 +0100423 if (devnamep) {
424 rc = card_uart_open(cuart, drivername, devnamep);
Harald Welte515d5b22019-10-10 13:46:13 +0200425 if (rc < 0) {
426 LOGPCS(cs, LOGL_ERROR, "Cannot open UART %s: %d\n", devname, rc);
427 talloc_free(cuart);
428 return rc;
429 }
Harald Welte727d6752019-09-30 21:46:44 +0200430 }
Eric Wilde84a5712019-11-28 17:30:30 +0100431
Harald Welte727d6752019-09-30 21:46:44 +0200432 ss->fi = iso7816_fsm_alloc(ctx, LOGL_DEBUG, id_buf, cuart, iso_fsm_clot_user_cb, ss);
433 if (!ss->fi) {
Harald Welte515d5b22019-10-10 13:46:13 +0200434 LOGPCS(cs, LOGL_ERROR, "Cannot allocate ISO FSM\n");
Harald Welte727d6752019-09-30 21:46:44 +0200435 talloc_free(cuart);
436 return -1;
437 }
438
439 cs->default_pars = &iso_fsm_def_pars;
440 ss->cuart = cuart;
441 ss->cs = cs;
442
443
444 return 0;
445}
446
447const struct ccid_slot_ops iso_fsm_slot_ops = {
448 .init = iso_fsm_slot_init,
449 .pre_proc_cb = iso_fsm_slot_pre_proc_cb,
450 .icc_power_on_async = iso_fsm_slot_icc_power_on_async,
Eric Wild9e622dc2019-11-27 14:43:16 +0100451 .icc_set_insertion_status = iso_fsm_slot_icc_set_insertion_status,
Harald Welte727d6752019-09-30 21:46:44 +0200452 .xfr_block_async = iso_fsm_slot_xfr_block_async,
453 .set_power = iso_fsm_slot_set_power,
454 .set_clock = iso_fsm_slot_set_clock,
455 .set_params = iso_fsm_slot_set_params,
456 .set_rate_and_clock = iso_fsm_slot_set_rate_and_clock,
Eric Wild759a6462019-11-11 14:22:52 +0100457 .handle_fsm_events = iso_handle_fsm_events,
Harald Welte727d6752019-09-30 21:46:44 +0200458};