blob: 57fe3cf3af93ed36637b6edd5d00fd8ad72d0b60 [file] [log] [blame]
Harald Weltecab5d152019-05-16 13:31:16 +02001/* Simulated CCID card slot. This is used in absence of a real hardware back-end
2 * in order to test the CCID firmware codebase in a virtual environment */
3
Harald Welte505d4412019-05-16 17:26:09 +02004#include <osmocom/core/msgb.h>
5#include <osmocom/core/timer.h>
6
Harald Weltecab5d152019-05-16 13:31:16 +02007#include "ccid_device.h"
8
Harald Welte505d4412019-05-16 17:26:09 +02009struct slotsim_slot {
10 struct osmo_timer_list pwron_timer;
11 struct osmo_timer_list xfr_timer;
12 /* bSeq of the operation currently in progress */
13 uint8_t seq;
14};
15
16struct slotsim_instance {
17 struct slotsim_slot slot[NR_SLOTS];
18};
19
20static struct slotsim_instance g_si;
21
22struct slotsim_slot *ccid_slot2slotsim_slot(struct ccid_slot *cs)
23{
24 OSMO_ASSERT(cs->slot_nr < ARRAY_SIZE(g_si.slot));
25 return &g_si.slot[cs->slot_nr];
26}
27
Harald Weltecab5d152019-05-16 13:31:16 +020028static const struct ccid_pars_decoded slotsim_def_pars = {
29 .fi = 0,
30 .di = 0,
31 .clock_stop = CCID_CLOCK_STOP_NOTALLOWED,
32 .inverse_convention = false,
33 .t0 = {
34 .guard_time_etu = 0,
35 .waiting_integer = 0,
36 },
37 /* FIXME: T=1 */
38};
39
40static void slotsim_pre_proc_cb(struct ccid_slot *cs, struct msgb *msg)
41{
42 /* do nothing; real hardware would update the slot related state here */
43}
44
Harald Welte505d4412019-05-16 17:26:09 +020045static void slotsim_icc_power_on_async(struct ccid_slot *cs, struct msgb *msg,
46 const struct ccid_pc_to_rdr_icc_power_on *ipo)
47{
48 struct slotsim_slot *ss = ccid_slot2slotsim_slot(cs);
49
50 ss->seq = ipo->hdr.bSeq;
51 osmo_timer_schedule(&ss->pwron_timer, 1, 0);
52 msgb_free(msg);
53 /* continues in timer call-back below */
54}
55static void slotsim_pwron_timer_cb(void *data)
56{
57 struct ccid_slot *cs = data;
58 struct slotsim_slot *ss = ccid_slot2slotsim_slot(cs);
59 struct msgb *resp;
60
61 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0, NULL, 0);
62 ccid_slot_send_unbusy(cs, resp);
63}
64
65static void slotsim_xfr_block_async(struct ccid_slot *cs, struct msgb *msg,
66 const struct ccid_pc_to_rdr_xfr_block *xfb)
67{
68 struct slotsim_slot *ss = ccid_slot2slotsim_slot(cs);
69
70 ss->seq = xfb->hdr.bSeq;
71 osmo_timer_schedule(&ss->xfr_timer, 0, 50000);
72 msgb_free(msg);
73 /* continues in timer call-back below */
74}
75static void slotsim_xfr_timer_cb(void *data)
76{
77 struct ccid_slot *cs = data;
78 struct slotsim_slot *ss = ccid_slot2slotsim_slot(cs);
79 struct msgb *resp;
80
81 resp = ccid_gen_data_block(cs, ss->seq, CCID_CMD_STATUS_OK, 0, NULL, 0);
82 ccid_slot_send_unbusy(cs, resp);
83}
84
85
Harald Weltecab5d152019-05-16 13:31:16 +020086static void slotsim_set_power(struct ccid_slot *cs, bool enable)
87{
88 if (enable) {
89 cs->icc_powered = true;
90 /* FIXME: What to do about ATR? */
91 } else {
92 cs->icc_powered = false;
93 }
94}
95
96static void slotsim_set_clock(struct ccid_slot *cs, enum ccid_clock_command cmd)
97{
98 /* FIXME */
99 switch (cmd) {
100 case CCID_CLOCK_CMD_STOP:
101 break;
102 case CCID_CLOCK_CMD_RESTART:
103 break;
104 default:
105 OSMO_ASSERT(0);
106 }
107}
108
109static int slotsim_set_params(struct ccid_slot *cs, enum ccid_protocol_num proto,
110 const struct ccid_pars_decoded *pars_dec)
111{
112 /* we always acknowledge all parameters */
113 return 0;
114}
115
116static int slotsim_set_rate_and_clock(struct ccid_slot *cs, uint32_t freq_hz, uint32_t rate_bps)
117{
118 /* we always acknowledge all rates/clocks */
119 return 0;
120}
121
Harald Welte505d4412019-05-16 17:26:09 +0200122
Harald Weltecab5d152019-05-16 13:31:16 +0200123static int slotsim_init(struct ccid_slot *cs)
124{
Harald Welte505d4412019-05-16 17:26:09 +0200125 struct slotsim_slot *ss = ccid_slot2slotsim_slot(cs);
126 osmo_timer_setup(&ss->pwron_timer, slotsim_pwron_timer_cb, cs);
127 osmo_timer_setup(&ss->xfr_timer, slotsim_xfr_timer_cb, cs);
Harald Weltecab5d152019-05-16 13:31:16 +0200128 cs->default_pars = &slotsim_def_pars;
129 return 0;
130}
131
132const struct ccid_slot_ops slotsim_slot_ops = {
133 .init = slotsim_init,
134 .pre_proc_cb = slotsim_pre_proc_cb,
Harald Welte505d4412019-05-16 17:26:09 +0200135 .icc_power_on_async = slotsim_icc_power_on_async,
136 .xfr_block_async = slotsim_xfr_block_async,
Harald Weltecab5d152019-05-16 13:31:16 +0200137 .set_power = slotsim_set_power,
138 .set_clock = slotsim_set_clock,
139 .set_params = slotsim_set_params,
140 .set_rate_and_clock = slotsim_set_rate_and_clock,
141};