blob: 5b3a5bc395bc4d046636acd7f4c1ff5b057fdf0c [file] [log] [blame]
Harald Welte8d186ad2019-05-15 19:40:29 +02001#pragma once
2#include <stdbool.h>
3#include <stdint.h>
4
Harald Weltecab5d152019-05-16 13:31:16 +02005#include "ccid_proto.h"
6
Harald Weltee73a1df2019-05-15 22:27:02 +02007enum {
8 DCCID,
9 DUSB,
10};
Harald Welte8d186ad2019-05-15 19:40:29 +020011
12#define NR_SLOTS 8
13
14#define LOGPCI(ci, lvl, fmt, args ...) LOGP(DCCID, lvl, "%s: " fmt, (ci)->name, ## args)
15#define LOGPCS(cs, lvl, fmt, args ...) \
Harald Weltee73a1df2019-05-15 22:27:02 +020016 LOGP(DCCID, lvl, "%s(%u): " fmt, (cs)->ci->name, (cs)->slot_nr, ## args)
Harald Welte8d186ad2019-05-15 19:40:29 +020017
18struct msgb;
19
20struct ccid_pars_decoded {
21 /* global for T0/T1 */
22 uint8_t fi;
23 uint8_t di;
24 enum ccid_clock_stop clock_stop;
25 bool inverse_convention;
26
27 struct {
28 uint8_t guard_time_etu;
29 uint8_t waiting_integer;
30 } t0;
31
32 struct {
33 enum ccid_t1_csum_type csum_type;
34 uint8_t guard_time_t1;
35 uint8_t bwi;
36 uint8_t cwi;
37 uint8_t ifsc;
38 uint8_t nad;
39 } t1;
40};
41
42struct ccid_slot {
43 /* back-pointer to the ccid_instance */
44 struct ccid_instance *ci;
45 /* number of this slot (0 = first) */
46 uint8_t slot_nr;
47 /* is there an ICC physically present (card detect)? */
48 bool icc_present;
49 /* was there an ICC present during the last NotifSlotStatus?
50 * should be set to zero every USB resume and setConfig != 0 */
51 bool icc_present_last;
52 /* is the ICC physically powered? */
53 bool icc_powered;
54 /* is the ICC currently in reset? */
55 bool icc_in_reset;
56 /* is this slot currently busy with processing a CCID command? */
57 bool cmd_busy;
58 /* decided CCID parameters */
59 struct ccid_pars_decoded pars;
Harald Weltecab5d152019-05-16 13:31:16 +020060 /* default parameters; applied on ResetParameters */
61 const struct ccid_pars_decoded *default_pars;
Harald Welte8d186ad2019-05-15 19:40:29 +020062};
63
Harald Weltecab5d152019-05-16 13:31:16 +020064/* CCID operations provided by USB transport layer */
Harald Welte8d186ad2019-05-15 19:40:29 +020065struct ccid_ops {
Harald Weltee6ac4162019-05-16 11:18:00 +020066 /* msgb ownership in below functions is transferred, i.e. whoever
67 * provides the callback function must make sure to msgb_free() them
68 * once transmission on IN or INT EP has completed. */
Harald Welte8d186ad2019-05-15 19:40:29 +020069 int (*send_in)(struct ccid_instance *ci, struct msgb *msg);
Harald Weltea7da5042019-05-16 11:08:35 +020070 int (*send_int)(struct ccid_instance *ci, struct msgb *msg);
Harald Welte8d186ad2019-05-15 19:40:29 +020071};
72
Harald Weltecab5d152019-05-16 13:31:16 +020073/* CCID operations provided by actual slot hardware */
74struct ccid_slot_ops {
75 /* called once on start-up for initialization */
76 int (*init)(struct ccid_slot *cs);
77 /* called before processing any command for a slot; used e.g. to
78 * update the (power/clock/...) status from the hardware */
79 void (*pre_proc_cb)(struct ccid_slot *cs, struct msgb *msg);
80
81 void (*set_power)(struct ccid_slot *cs, bool enable);
82 void (*set_clock)(struct ccid_slot *cs, enum ccid_clock_command cmd);
83 int (*set_params)(struct ccid_slot *cs, enum ccid_protocol_num proto,
84 const struct ccid_pars_decoded *pars_dec);
85 int (*set_rate_and_clock)(struct ccid_slot *cs, uint32_t freq_hz, uint32_t rate_bps);
86};
87
Harald Welte8d186ad2019-05-15 19:40:29 +020088/* An instance of CCID (i.e. a card reader device) */
89struct ccid_instance {
90 /* slots within the reader */
91 struct ccid_slot slot[NR_SLOTS];
92 /* set of function pointers implementing specific operations */
Harald Weltebcbc1972019-05-15 21:57:32 +020093 const struct ccid_ops *ops;
Harald Weltecab5d152019-05-16 13:31:16 +020094 const struct ccid_slot_ops *slot_ops;
Harald Welte8d186ad2019-05-15 19:40:29 +020095 const char *name;
Harald Weltebcbc1972019-05-15 21:57:32 +020096 /* user-supplied opaque data */
97 void *priv;
Harald Welte8d186ad2019-05-15 19:40:29 +020098};
99
Harald Welte005b09d2019-05-16 17:24:29 +0200100int ccid_slot_send(struct ccid_slot *cs, struct msgb *msg);
101int ccid_slot_send_unbusy(struct ccid_slot *cs, struct msgb *msg);
102struct msgb *ccid_gen_slot_status(struct ccid_slot *cs, uint8_t seq, uint8_t cmd_sts,
103 enum ccid_error_code err);
104
105struct msgb *ccid_gen_data_block(struct ccid_slot *cs, uint8_t seq, uint8_t cmd_sts,
106 enum ccid_error_code err, const uint8_t *data,
107 uint32_t data_len);
108
Harald Weltecab5d152019-05-16 13:31:16 +0200109void ccid_instance_init(struct ccid_instance *ci, const struct ccid_ops *ops,
110 const struct ccid_slot_ops *slot_ops, const char *name, void *priv);
Harald Welte8d186ad2019-05-15 19:40:29 +0200111int ccid_handle_out(struct ccid_instance *ci, struct msgb *msg);