blob: 99c8c21020753bd5e5b0151ec5bbe8f1d4dd5efb [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
4#include <unistd.h>
5#include <errno.h>
Harald Welte6def1cf2019-10-10 15:40:02 +02006#include <string.h>
Harald Welte727d6752019-09-30 21:46:44 +02007
8#include <osmocom/core/msgb.h>
9#include <osmocom/core/timer.h>
10#include <osmocom/core/logging.h>
11#include <osmocom/core/fsm.h>
12
13#include "ccid_device.h"
14#include "cuart.h"
15#include "iso7816_fsm.h"
Eric Wildad1edce2019-11-27 16:51:08 +010016#include "iso7816_3.h"
Harald Welte727d6752019-09-30 21:46:44 +020017
18struct iso_fsm_slot {
19 /* CCID slot above us */
20 struct ccid_slot *cs;
21 /* main ISO7816-3 FSM instance beneath us */
22 struct osmo_fsm_inst *fi;
23 /* UART beneath the ISO7816-3 FSM */
24 struct card_uart *cuart;
25 /* bSeq of the operation currently in progress */
26 uint8_t seq;
27};
28
29struct iso_fsm_slot_instance {
30 struct iso_fsm_slot slot[NR_SLOTS];
31};
32
33static struct iso_fsm_slot_instance g_si;
34
Harald Welte03d6ebb2019-09-28 23:19:31 +020035static struct iso_fsm_slot *ccid_slot2iso_fsm_slot(struct ccid_slot *cs)
Harald Welte727d6752019-09-30 21:46:44 +020036{
37 OSMO_ASSERT(cs->slot_nr < ARRAY_SIZE(g_si.slot));
38 return &g_si.slot[cs->slot_nr];
39}
40
Harald Welte03d6ebb2019-09-28 23:19:31 +020041struct card_uart *cuart4slot_nr(uint8_t slot_nr)
42{
43 OSMO_ASSERT(slot_nr < ARRAY_SIZE(g_si.slot));
44 return g_si.slot[slot_nr].cuart;
45}
46
Harald Welte727d6752019-09-30 21:46:44 +020047static const uint8_t sysmousim_sjs1_atr[] = {
48 0x3B, 0x9F, 0x96, 0x80, 0x1F, 0xC7, 0x80, 0x31,
49 0xA0, 0x73, 0xBE, 0x21, 0x13, 0x67, 0x43, 0x20,
50 0x07, 0x18, 0x00, 0x00, 0x01, 0xA5 };
51
52static const struct ccid_pars_decoded iso_fsm_def_pars = {
53 .fi = 372,
54 .di = 1,
55 .clock_stop = CCID_CLOCK_STOP_NOTALLOWED,
56 .inverse_convention = false,
57 .t0 = {
58 .guard_time_etu = 0,
59 .waiting_integer = 0,
60 },
61 /* FIXME: T=1 */
62};
63
64static void iso_fsm_slot_pre_proc_cb(struct ccid_slot *cs, struct msgb *msg)
65{
66 /* do nothing; real hardware would update the slot related state here */
67}
68
Eric Wild9e622dc2019-11-27 14:43:16 +010069static void iso_fsm_slot_icc_set_insertion_status(struct ccid_slot *cs, bool present) {
70 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
71
72 if(present == cs->icc_present)
73 return;
74
75 cs->icc_present = present;
76
77 if (!present) {
78 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_CARD_REMOVAL, NULL);
79 card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);
Eric Wild70f36912020-04-03 22:29:02 +020080 card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, false);
Eric Wild9e622dc2019-11-27 14:43:16 +010081 cs->icc_powered = false;
82 cs->cmd_busy = false;
83 }
84}
85
Harald Welte727d6752019-09-30 21:46:44 +020086static void iso_fsm_slot_icc_power_on_async(struct ccid_slot *cs, struct msgb *msg,
87 const struct ccid_pc_to_rdr_icc_power_on *ipo)
88{
89 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
Eric Wild70f36912020-04-03 22:29:02 +020090 enum ccid_power_select pwrsel = ipo->bPowerSelect;
91 enum card_uart_ctl cctl;
Harald Welte727d6752019-09-30 21:46:44 +020092
93 ss->seq = ipo->hdr.bSeq;
94 LOGPCS(cs, LOGL_DEBUG, "scheduling power-up\n");
95
Eric Wild70f36912020-04-03 22:29:02 +020096 switch (pwrsel) {
97 case CCID_PWRSEL_5V0: cctl = CUART_CTL_POWER_5V0; break;
98 case CCID_PWRSEL_3V0: cctl = CUART_CTL_POWER_3V0; break;
99 case CCID_PWRSEL_1V8: cctl = CUART_CTL_POWER_1V8; break;
100 default: cctl = CUART_CTL_POWER_5V0;
101 }
102
Eric Wildaed26cc2020-03-30 04:22:36 +0200103 if (! cs->icc_powered) {
104 /* FIXME: do this via a FSM? */
105 card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);
106 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_ACT_IND, NULL);
Eric Wild70f36912020-04-03 22:29:02 +0200107 card_uart_ctrl(ss->cuart, cctl, true);
Eric Wildaed26cc2020-03-30 04:22:36 +0200108 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_POWER_UP_IND, NULL);
109 cs->icc_powered = true;
110 card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, true);
111 #ifdef OCTSIMFWBUILD
112 delay_us(10000);
113 #else
114 usleep(10000);
115 #endif
Harald Welte03d6ebb2019-09-28 23:19:31 +0200116
Eric Wildaed26cc2020-03-30 04:22:36 +0200117 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_REL_IND, NULL);
118 card_uart_ctrl(ss->cuart, CUART_CTL_RST, false);
119 } else { /* warm reset */
120 card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);
121 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_ACT_IND, NULL);
122 #ifdef OCTSIMFWBUILD
123 delay_us(10000);
124 #else
125 usleep(10000);
126 #endif
127 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_REL_IND, NULL);
128 card_uart_ctrl(ss->cuart, CUART_CTL_RST, false);
129 }
Harald Welte727d6752019-09-30 21:46:44 +0200130 msgb_free(msg);
131 /* continues in iso_fsm_clot_user_cb once ATR is received */
132}
133static void iso_fsm_clot_user_cb(struct osmo_fsm_inst *fi, int event, int cause, void *data)
134{
135 struct iso_fsm_slot *ss = iso7816_fsm_get_user_priv(fi);
136 struct ccid_slot *cs = ss->cs;
Eric Wild759a6462019-11-11 14:22:52 +0100137
138 switch (event) {
139 case ISO7816_E_ATR_DONE_IND:
140 case ISO7816_E_ATR_ERR_IND:
141 case ISO7816_E_TPDU_DONE_IND:
142 case ISO7816_E_TPDU_FAILED_IND:
143 case ISO7816_E_PPS_DONE_IND:
144 case ISO7816_E_PPS_FAILED_IND:
Eric Wild91f75ce2020-03-30 04:10:31 +0200145 case ISO7816_E_WTIME_EXP:
Eric Wild759a6462019-11-11 14:22:52 +0100146 cs->event_data = data;
Eric Wilde84a5712019-11-28 17:30:30 +0100147#ifdef OCTSIMFWBUILD
Eric Wild759a6462019-11-11 14:22:52 +0100148 asm volatile("dmb st": : :"memory");
Eric Wilde84a5712019-11-28 17:30:30 +0100149#endif
Eric Wild759a6462019-11-11 14:22:52 +0100150 cs->event = event;
151 break;
152 default:
153 LOGPCS(cs, LOGL_NOTICE, "%s(event=%d, cause=%d, data=%p) unhandled\n",
154 __func__, event, cause, data);
155 break;
156 }
157}
158
159static int iso_handle_fsm_events(struct ccid_slot *cs, bool enable){
160 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
Harald Welte727d6752019-09-30 21:46:44 +0200161 struct msgb *tpdu, *resp;
Eric Wild759a6462019-11-11 14:22:52 +0100162 volatile uint32_t event = cs->event;
163 volatile void * volatile data = cs->event_data;
164
165 if(!event)
166 return 0;
Eric Wild91f75ce2020-03-30 04:10:31 +0200167// if(event && !data)
168// return 0;
Harald Welte727d6752019-09-30 21:46:44 +0200169
Harald Welte727d6752019-09-30 21:46:44 +0200170 switch (event) {
Eric Wild91f75ce2020-03-30 04:10:31 +0200171 case ISO7816_E_WTIME_EXP:
172 tpdu = data;
173 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=0)\n", __func__, event);
174
175
176 /* perform deactivation */
177 card_uart_ctrl(ss->cuart, CUART_CTL_RST, true);
Eric Wild70f36912020-04-03 22:29:02 +0200178 card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, false);
Eric Wild91f75ce2020-03-30 04:10:31 +0200179 cs->icc_powered = false;
180
181
182 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_FAILED, CCID_ERR_ICC_MUTE, 0, 0);
183 ccid_slot_send_unbusy(cs, resp);
184 cs->event = 0;
185 break;
Harald Welte727d6752019-09-30 21:46:44 +0200186 case ISO7816_E_ATR_DONE_IND:
187 tpdu = data;
Eric Wild759a6462019-11-11 14:22:52 +0100188 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,
Harald Welte22dd1ff2019-10-10 15:40:53 +0200189 msgb_hexdump(tpdu));
Harald Welte727d6752019-09-30 21:46:44 +0200190 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0,
191 msgb_data(tpdu), msgb_length(tpdu));
192 ccid_slot_send_unbusy(cs, resp);
Harald Weltebbb50092019-10-10 14:55:25 +0200193 /* Don't free "TPDU" here, as the ATR should survive */
Eric Wild759a6462019-11-11 14:22:52 +0100194 cs->event = 0;
195 break;
196 case ISO7816_E_ATR_ERR_IND:
197 tpdu = data;
198 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,
199 msgb_hexdump(tpdu));
200 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_FAILED, CCID_ERR_ICC_MUTE,
201 msgb_data(tpdu), msgb_length(tpdu));
202 ccid_slot_send_unbusy(cs, resp);
203 /* Don't free "TPDU" here, as the ATR should survive */
204 cs->event = 0;
205 break;
Harald Welte727d6752019-09-30 21:46:44 +0200206 break;
207 case ISO7816_E_TPDU_DONE_IND:
208 tpdu = data;
Eric Wild759a6462019-11-11 14:22:52 +0100209 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,
Harald Welte22dd1ff2019-10-10 15:40:53 +0200210 msgb_hexdump(tpdu));
Harald Welte43281fe2020-07-30 20:29:02 +0200211 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 +0200212 ccid_slot_send_unbusy(cs, resp);
213 msgb_free(tpdu);
Eric Wild759a6462019-11-11 14:22:52 +0100214 cs->event = 0;
Harald Welte727d6752019-09-30 21:46:44 +0200215 break;
Eric Wild9e622dc2019-11-27 14:43:16 +0100216 case ISO7816_E_TPDU_FAILED_IND:
217 tpdu = data;
Eric Wild759a6462019-11-11 14:22:52 +0100218 LOGPCS(cs, LOGL_DEBUG, "%s(event=%d, data=%s)\n", __func__, event,
Eric Wild9e622dc2019-11-27 14:43:16 +0100219 msgb_hexdump(tpdu));
220 /* FIXME: other error causes than card removal?*/
221 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_FAILED, CCID_ERR_ICC_MUTE, msgb_l2(tpdu), 0);
222 ccid_slot_send_unbusy(cs, resp);
223 msgb_free(tpdu);
Eric Wild759a6462019-11-11 14:22:52 +0100224 cs->event = 0;
Eric Wild9e622dc2019-11-27 14:43:16 +0100225 break;
Eric Wildad1edce2019-11-27 16:51:08 +0100226 case ISO7816_E_PPS_DONE_IND:
227 tpdu = data;
228 /* pps was successful, so we know these values are fine */
229 uint16_t F = iso7816_3_fi_table[cs->proposed_pars.fi];
230 uint8_t D = iso7816_3_di_table[cs->proposed_pars.di];
231 uint32_t fmax = iso7816_3_fmax_table[cs->proposed_pars.fi];
232
Eric Wilda0574572019-11-21 15:28:59 +0100233 /* 7816-3 5.2.3
234 * No information shall be exchanged when switching the
235 * frequency value. Two different times are recommended
236 * for switching the frequency value, either
237 * - after ATR while card is idle
238 * - after PPS while card is idle
239 */
Eric Wild587d4fb2019-11-27 18:59:43 +0100240 card_uart_ctrl(ss->cuart, CUART_CTL_SET_CLOCK_FREQ, fmax);
241 card_uart_ctrl(ss->cuart, CUART_CTL_SET_FD, F/D);
Eric Wildad1edce2019-11-27 16:51:08 +0100242 card_uart_ctrl(ss->cuart, CUART_CTL_WTIME, cs->proposed_pars.t0.waiting_integer);
243
244 cs->pars = cs->proposed_pars;
245 resp = ccid_gen_parameters_t0(cs, ss->seq, CCID_CMD_STATUS_OK, 0);
246
247 ccid_slot_send_unbusy(cs, resp);
248
249 /* this frees the pps req from the host, pps resp buffer stays with the pps fsm */
250 msgb_free(tpdu);
Eric Wild759a6462019-11-11 14:22:52 +0100251 cs->event = 0;
Eric Wildad1edce2019-11-27 16:51:08 +0100252 break;
253 case ISO7816_E_PPS_FAILED_IND:
254 tpdu = data;
255 /* failed fi/di */
256 resp = ccid_gen_parameters_t0(cs, ss->seq, CCID_CMD_STATUS_FAILED, 10);
257 ccid_slot_send_unbusy(cs, resp);
258 /* this frees the pps req from the host, pps resp buffer stays with the pps fsm */
259 msgb_free(tpdu);
Eric Wild759a6462019-11-11 14:22:52 +0100260 cs->event = 0;
261 break;
262 case 0:
Eric Wildad1edce2019-11-27 16:51:08 +0100263 break;
Harald Welte22dd1ff2019-10-10 15:40:53 +0200264 default:
Eric Wild759a6462019-11-11 14:22:52 +0100265 LOGPCS(cs, LOGL_NOTICE, "%s(event=%d, data=%p) unhandled\n",
266 __func__, event, data);
Harald Welte22dd1ff2019-10-10 15:40:53 +0200267 break;
Harald Welte727d6752019-09-30 21:46:44 +0200268 }
269}
270
Eric Wild9e622dc2019-11-27 14:43:16 +0100271static int iso_fsm_slot_xfr_block_async(struct ccid_slot *cs, struct msgb *msg,
Harald Welte727d6752019-09-30 21:46:44 +0200272 const struct ccid_pc_to_rdr_xfr_block *xfb)
273{
274 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
Eric Wild759a6462019-11-11 14:22:52 +0100275
Harald Welte727d6752019-09-30 21:46:44 +0200276
Harald Welte727d6752019-09-30 21:46:44 +0200277 ss->seq = xfb->hdr.bSeq;
Harald Welte6def1cf2019-10-10 15:40:02 +0200278
279 /* must be '0' for TPDU level exchanges or for short APDU */
280 OSMO_ASSERT(xfb->wLevelParameter == 0x0000);
281 OSMO_ASSERT(msgb_length(msg) > xfb->hdr.dwLength);
282
Eric Wild759a6462019-11-11 14:22:52 +0100283 msgb_pull(msg, 10);
Harald Welte6def1cf2019-10-10 15:40:02 +0200284
Eric Wild759a6462019-11-11 14:22:52 +0100285 LOGPCS(cs, LOGL_DEBUG, "scheduling TPDU transfer: %s\n", msgb_hexdump(msg));
286 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_XCEIVE_TPDU_CMD, msg);
Harald Welte727d6752019-09-30 21:46:44 +0200287 /* continues in iso_fsm_clot_user_cb once response/error/timeout is received */
Eric Wild9e622dc2019-11-27 14:43:16 +0100288 return 0;
Harald Welte727d6752019-09-30 21:46:44 +0200289}
290
291
292static void iso_fsm_slot_set_power(struct ccid_slot *cs, bool enable)
293{
294 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
295
296 if (enable) {
Eric Wild70f36912020-04-03 22:29:02 +0200297 card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, true);
Harald Welte03d6ebb2019-09-28 23:19:31 +0200298 cs->icc_powered = true;
Harald Welte727d6752019-09-30 21:46:44 +0200299 } else {
Eric Wild70f36912020-04-03 22:29:02 +0200300 card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, false);
Harald Welte03d6ebb2019-09-28 23:19:31 +0200301 cs->icc_powered = false;
Harald Welte727d6752019-09-30 21:46:44 +0200302 }
303}
304
305static void iso_fsm_slot_set_clock(struct ccid_slot *cs, enum ccid_clock_command cmd)
306{
307 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
308
309 switch (cmd) {
310 case CCID_CLOCK_CMD_STOP:
311 card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, false);
312 break;
313 case CCID_CLOCK_CMD_RESTART:
314 card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, true);
315 break;
316 default:
317 OSMO_ASSERT(0);
318 }
319}
320
Eric Wildad1edce2019-11-27 16:51:08 +0100321static 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 +0200322 const struct ccid_pars_decoded *pars_dec)
323{
Eric Wildad1edce2019-11-27 16:51:08 +0100324 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
325 struct msgb *tpdu;
326
327 /* see 6.1.7 for error offsets */
328 if(proto != CCID_PROTOCOL_NUM_T0)
329 return -7;
330
331 if(pars_dec->t0.guard_time_etu != 0)
332 return -12;
333
334 if(pars_dec->clock_stop != CCID_CLOCK_STOP_NOTALLOWED)
335 return -14;
336
337 ss->seq = seq;
338
Eric Wild45e930d2019-11-21 14:38:16 +0100339 /* FIXME:
340 When using D=64, the interface device shall ensure a delay
341 of at least 16 etu between the leading edge of the last
342 received character and the leading edge of the character transmitted
343 for initiating a command.
344 -> we can't really do 4 stop bits?!
345 */
346
Eric Wildad1edce2019-11-27 16:51:08 +0100347 /* Hardware does not support SPU, so no PPS2, and PPS3 is reserved anyway */
348 tpdu = msgb_alloc(6, "PPSRQ");
349 OSMO_ASSERT(tpdu);
350 msgb_put_u8(tpdu, 0xff);
351 msgb_put_u8(tpdu, (1 << 4)); /* only PPS1, T=0 */
352 msgb_put_u8(tpdu, (pars_dec->fi << 4 | pars_dec->di));
353 msgb_put_u8(tpdu, 0xff ^ (1 << 4) ^ (pars_dec->fi << 4 | pars_dec->di));
354
355
356 LOGPCS(cs, LOGL_DEBUG, "scheduling PPS transfer: %s\n", msgb_hexdump(tpdu));
357 osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_XCEIVE_PPS_CMD, tpdu);
358 /* continues in iso_fsm_clot_user_cb once response/error/timeout is received */
Harald Welte727d6752019-09-30 21:46:44 +0200359 return 0;
360}
361
Eric Wild56a50552020-01-28 16:07:23 +0100362static 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 +0200363{
Eric Wild56a50552020-01-28 16:07:23 +0100364 /* we return the currently used values, since we support automatic features */
365 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
366
367 *rate_bps = card_uart_ctrl(ss->cuart, CUART_CTL_GET_BAUDRATE, false);
368 *freq_hz = card_uart_ctrl(ss->cuart, CUART_CTL_GET_CLOCK_FREQ, false)/1000;
369
Harald Welte727d6752019-09-30 21:46:44 +0200370 return 0;
371}
372
Harald Welte03d6ebb2019-09-28 23:19:31 +0200373extern void *g_tall_ctx;
Harald Welte727d6752019-09-30 21:46:44 +0200374static int iso_fsm_slot_init(struct ccid_slot *cs)
375{
Harald Welte03d6ebb2019-09-28 23:19:31 +0200376 void *ctx = g_tall_ctx; /* FIXME */
Harald Welte727d6752019-09-30 21:46:44 +0200377 struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs);
378 struct card_uart *cuart = talloc_zero(ctx, struct card_uart);
Eric Wilde84a5712019-11-28 17:30:30 +0100379 char id_buf[3+3+1];
380 char devname[2+1];
381 char *devnamep = 0;
382 char *drivername = "asf4";
Harald Welte727d6752019-09-30 21:46:44 +0200383 int rc;
384
385 LOGPCS(cs, LOGL_DEBUG, "%s\n", __func__);
386
Eric Wilde84a5712019-11-28 17:30:30 +0100387 snprintf(id_buf, sizeof(id_buf), "SIM%d", cs->slot_nr);
388#ifdef OCTSIMFWBUILD
389 snprintf(devname, sizeof(devname), "%d", cs->slot_nr);
390 devnamep = devname;
391#else
392 if (cs->slot_nr == 0) {
393 cs->icc_present = true;
394 devnamep = "/dev/ttyUSB5";
395 }
396 drivername = "tty";
397#endif
Harald Welte727d6752019-09-30 21:46:44 +0200398
399 if (!cuart)
400 return -ENOMEM;
401
Eric Wilde84a5712019-11-28 17:30:30 +0100402 if (devnamep) {
403 rc = card_uart_open(cuart, drivername, devnamep);
Harald Welte515d5b22019-10-10 13:46:13 +0200404 if (rc < 0) {
405 LOGPCS(cs, LOGL_ERROR, "Cannot open UART %s: %d\n", devname, rc);
406 talloc_free(cuart);
407 return rc;
408 }
Harald Welte727d6752019-09-30 21:46:44 +0200409 }
Eric Wilde84a5712019-11-28 17:30:30 +0100410
Harald Welte727d6752019-09-30 21:46:44 +0200411 ss->fi = iso7816_fsm_alloc(ctx, LOGL_DEBUG, id_buf, cuart, iso_fsm_clot_user_cb, ss);
412 if (!ss->fi) {
Harald Welte515d5b22019-10-10 13:46:13 +0200413 LOGPCS(cs, LOGL_ERROR, "Cannot allocate ISO FSM\n");
Harald Welte727d6752019-09-30 21:46:44 +0200414 talloc_free(cuart);
415 return -1;
416 }
417
418 cs->default_pars = &iso_fsm_def_pars;
419 ss->cuart = cuart;
420 ss->cs = cs;
421
422
423 return 0;
424}
425
426const struct ccid_slot_ops iso_fsm_slot_ops = {
427 .init = iso_fsm_slot_init,
428 .pre_proc_cb = iso_fsm_slot_pre_proc_cb,
429 .icc_power_on_async = iso_fsm_slot_icc_power_on_async,
Eric Wild9e622dc2019-11-27 14:43:16 +0100430 .icc_set_insertion_status = iso_fsm_slot_icc_set_insertion_status,
Harald Welte727d6752019-09-30 21:46:44 +0200431 .xfr_block_async = iso_fsm_slot_xfr_block_async,
432 .set_power = iso_fsm_slot_set_power,
433 .set_clock = iso_fsm_slot_set_clock,
434 .set_params = iso_fsm_slot_set_params,
435 .set_rate_and_clock = iso_fsm_slot_set_rate_and_clock,
Eric Wild759a6462019-11-11 14:22:52 +0100436 .handle_fsm_events = iso_handle_fsm_events,
Harald Welte727d6752019-09-30 21:46:44 +0200437};