blob: 72e79046d3e6c3d458d6dbf6fc82e1f9d14f95da [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file sim.h
2 * Routines for helping with SIM (ISO/IEC 7816-4 more generally) communication.
3 */
4
Harald Welted54c2ee2012-01-17 18:25:50 +01005#ifndef _OSMOCOM_SIM_H
6#define _OSMOCOM_SIM_H
7
8#include <osmocom/core/msgb.h>
9#include <osmocom/core/linuxlist.h>
10
11#define APDU_HDR_LEN 5
Harald Welte429adec2020-03-20 13:05:40 +010012#define MAX_AID_LEN 16 /* Table 13.2 of TS 102 221 */
Harald Welted54c2ee2012-01-17 18:25:50 +010013
Neels Hofmeyr87e45502017-06-20 00:17:59 +020014/*! command-response pairs cases
Kevin Redon43eabee2012-09-16 18:40:02 +020015 *
16 * Enumeration used to identify the APDU structure based on command-response pair case , as specified in ISO/IEC 7816-3:2006(E) §12.1.
17 */
Harald Welted54c2ee2012-01-17 18:25:50 +010018enum osim_apdu_case {
Kevin Redon43eabee2012-09-16 18:40:02 +020019 APDU_CASE_1, /*!< command header, no command data field, no response data field */
20 APDU_CASE_2S, /*!< command header, no command data field, response data field (short) */
21 APDU_CASE_2E, /*!< command header, no command data field, response data field (extended) */
22 APDU_CASE_3S, /*!< command header, command data field (short), no response data field */
23 APDU_CASE_3E, /*!< command header, command data field (extended), no response data field */
24 APDU_CASE_4S, /*!< command header, command data field (short), response data field (short) */
25 APDU_CASE_4E /*!< command header, command data field (extended), response data field (extended) */
Harald Welted54c2ee2012-01-17 18:25:50 +010026};
27
Neels Hofmeyr87e45502017-06-20 00:17:59 +020028/*! APDU/TPDU command header
Kevin Redon43eabee2012-09-16 18:40:02 +020029 *
30 * This structure encode an APDU/TPDU command header, as specified in ISO/IEC 7816-3:2006(E) §12.2 and §12.3.
31 * The APDU (application layer) can be encoded as different TPDUs (transport layer), depending on the transport protocol used.
32 * The TPDU encoding by T=1 of the APDU command header is identical to the APDU.
33 * The TPDU encoding by T=0 of the APDU command header adds a Parameter 3 field, generally used instead of Lc/Le.
34 *
35 * @todo have different structures for APDU, TPDU by T=0, and TPDU by T=1.
36 */
Harald Welted54c2ee2012-01-17 18:25:50 +010037struct osim_apdu_cmd_hdr {
Kevin Redon43eabee2012-09-16 18:40:02 +020038 uint8_t cla; /*!< CLASS byte */
39 uint8_t ins; /*!< INSTRUCTION byte */
40 uint8_t p1; /*!< Parameter 1 byte */
41 uint8_t p2; /*!< Parameter 2 byte */
42 uint8_t p3; /*!< Parameter 3 byte, used for TPDU by T=0 */
Harald Welted54c2ee2012-01-17 18:25:50 +010043} __attribute__ ((packed));
44
45#define msgb_apdu_dr(__x)
46
Neels Hofmeyr87e45502017-06-20 00:17:59 +020047/*! APDU command body
Kevin Redon43eabee2012-09-16 18:40:02 +020048 *
49 * This structure encode a command body, as specified in ISO/IEC 7816-3:2006(E) §12.1.
50 * The data and response contents should be provided along with this structure.
51 */
Harald Welted54c2ee2012-01-17 18:25:50 +010052struct osim_msgb_cb {
Kevin Redon43eabee2012-09-16 18:40:02 +020053 enum osim_apdu_case apduc; /*!< command-response pair case, defining the encoding of Lc and Le */
54 uint16_t lc; /*!< number of bytes in the command data field Nc, which will encoded in 0, 1 or 3 bytes into Lc, depending on the case */
55 uint16_t le; /*!< maximum number of bytes expected in the response data field, which will encoded in 0, 1, 2 or 3 bytes into Le, depending on the case */
56 uint16_t sw; /*!< status word, composed of SW1 and SW2 bytes */
Harald Weltee8dd2bd2014-05-04 13:42:38 +020057} __attribute__((__may_alias__));
Harald Welted54c2ee2012-01-17 18:25:50 +010058#define OSIM_MSGB_CB(__msgb) ((struct osim_msgb_cb *)&((__msgb)->cb[0]))
Neels Hofmeyr87e45502017-06-20 00:17:59 +020059/*! status word from msgb->cb */
Harald Welted54c2ee2012-01-17 18:25:50 +010060#define msgb_apdu_case(__x) OSIM_MSGB_CB(__x)->apduc
61#define msgb_apdu_lc(__x) OSIM_MSGB_CB(__x)->lc
62#define msgb_apdu_le(__x) OSIM_MSGB_CB(__x)->le
63#define msgb_apdu_sw(__x) OSIM_MSGB_CB(__x)->sw
Neels Hofmeyr87e45502017-06-20 00:17:59 +020064/*! pointer to the command header of the APDU */
Harald Welted54c2ee2012-01-17 18:25:50 +010065#define msgb_apdu_h(__x) ((struct osim_apdu_cmd_hdr *)(__x)->l2h)
66
67#define msgb_apdu_dc(__x) ((__x)->l2h + sizeof(struct osim_apdu_cmd_hdr))
68#define msgb_apdu_de(__x) ((__x)->l2h + sizeof(struct osim_apdu_cmd_hdr) + msgb_apdu_lc(__x))
69
Harald Welte429adec2020-03-20 13:05:40 +010070int osim_init(void *ctx);
71
Harald Welte586d7102014-05-04 17:01:16 +020072/* FILES */
73
Harald Welted54c2ee2012-01-17 18:25:50 +010074struct osim_file;
75struct osim_file_desc;
76struct osim_decoded_data;
77
Neels Hofmeyr87e45502017-06-20 00:17:59 +020078/*! Operations for a given File */
Harald Welted54c2ee2012-01-17 18:25:50 +010079struct osim_file_ops {
Harald Welte586d7102014-05-04 17:01:16 +020080 /*! Parse binary file data into osim_decoded_data */
Harald Welted54c2ee2012-01-17 18:25:50 +010081 int (*parse)(struct osim_decoded_data *dd,
82 const struct osim_file_desc *desc,
83 int len, uint8_t *data);
Harald Welte586d7102014-05-04 17:01:16 +020084 /*! Encode osim_decoded_data into binary file */
Harald Welte6729a972014-10-26 19:04:56 +010085 struct msgb * (*encode)(const struct osim_file_desc *desc,
Harald Welted54c2ee2012-01-17 18:25:50 +010086 const struct osim_decoded_data *decoded);
87};
88
89enum osim_element_type {
90 ELEM_T_NONE,
91 ELEM_T_BOOL, /*!< a boolean flag */
92 ELEM_T_UINT8, /*!< unsigned integer */
93 ELEM_T_UINT16, /*!< unsigned integer */
94 ELEM_T_UINT32, /*!< unsigned integer */
95 ELEM_T_STRING, /*!< generic string */
96 ELEM_T_BCD, /*!< BCD encoded digits */
97 ELEM_T_BYTES, /*!< BCD encoded digits */
98 ELEM_T_GROUP, /*!< group container, has siblings */
99};
100
101enum osim_element_repr {
102 ELEM_REPR_NONE,
103 ELEM_REPR_DEC,
104 ELEM_REPR_HEX,
105};
106
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200107/*! A single decoded element inside a file */
Harald Welted54c2ee2012-01-17 18:25:50 +0100108struct osim_decoded_element {
109 struct llist_head list;
110
111 enum osim_element_type type;
112 enum osim_element_repr representation;
113 const char *name;
114
115 unsigned int length;
116 union {
117 uint8_t u8;
118 uint16_t u16;
119 uint32_t u32;
120 uint8_t *buf;
Harald Welte586d7102014-05-04 17:01:16 +0200121 /*! A list of sibling decoded_items */
Harald Welted54c2ee2012-01-17 18:25:50 +0100122 struct llist_head siblings;
123 } u;
124};
125
Harald Welte586d7102014-05-04 17:01:16 +0200126/*! Decoded data for a single file, consisting of all decoded elements */
Harald Welted54c2ee2012-01-17 18:25:50 +0100127struct osim_decoded_data {
128 /*! file to which we belong */
129 const struct osim_file *file;
130 /*! list of 'struct decoded_element' */
131 struct llist_head decoded_elements;
132};
133
134
135enum osim_file_type {
136 TYPE_NONE,
Harald Welte586d7102014-05-04 17:01:16 +0200137 TYPE_DF, /*!< Dedicated File */
138 TYPE_ADF, /*!< Application Dedicated File */
139 TYPE_EF, /*!< Entry File */
140 TYPE_EF_INT, /*!< Internal Entry File */
Harald Welte053bebc2020-02-15 18:58:16 +0100141 TYPE_MF, /*!< Master File */
Harald Welted54c2ee2012-01-17 18:25:50 +0100142};
143
144enum osim_ef_type {
Harald Welte586d7102014-05-04 17:01:16 +0200145 EF_TYPE_TRANSP, /*!< Transparent EF */
146 EF_TYPE_RECORD_FIXED, /*!< Fixed-Size Record EF */
147 EF_TYPE_RECORD_CYCLIC, /*!< Cyclic Record EF */
148 EF_TYPE_KEY, /*!< Key file as used in TETRA */
Harald Welted54c2ee2012-01-17 18:25:50 +0100149};
150
151#define F_OPTIONAL 0x0001
152
Harald Welte2656e652014-05-03 14:23:44 +0200153#define SFI_NONE 0xFF
154
Harald Welted54c2ee2012-01-17 18:25:50 +0100155struct osim_file_desc {
156 struct llist_head list; /*!< local element in list */
157 struct llist_head child_list; /*!< list of children EF in DF */
158 struct osim_file_desc *parent; /*!< parent DF */
159
Harald Welte586d7102014-05-04 17:01:16 +0200160 enum osim_file_type type; /*!< Type of the file (EF, DF, ...) */
161 enum osim_ef_type ef_type; /*!< Type of the EF, if type == TYPE_EF */
Harald Welted54c2ee2012-01-17 18:25:50 +0100162
163 uint16_t fid; /*!< File Identifier */
164 uint8_t sfid; /*!< Short File IDentifier */
Harald Welte6729a972014-10-26 19:04:56 +0100165 const uint8_t *df_name;
Harald Welted54c2ee2012-01-17 18:25:50 +0100166 uint8_t df_name_len;
167
168 const char *short_name; /*!< Short Name (like EF.ICCID) */
169 const char *long_name; /*!< Long / description */
170 unsigned int flags;
171
Harald Welte586d7102014-05-04 17:01:16 +0200172 struct osim_file_ops ops; /*!< Operations (parse/encode */
Harald Welte1e0dfda2014-05-03 14:22:12 +0200173
174 struct {
175 size_t min; /*!< Minimum size of the file
176 (transparent) or record in
177 cyclic / linear file */
178 size_t rec; /*!< Recommended size */
179 } size;
Harald Welted54c2ee2012-01-17 18:25:50 +0100180};
181
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200182/*! A single instance of a file: Descriptor and contents */
Harald Welted54c2ee2012-01-17 18:25:50 +0100183struct osim_file {
Harald Welte586d7102014-05-04 17:01:16 +0200184 /*! Descriptor for the file */
Harald Welted54c2ee2012-01-17 18:25:50 +0100185 const struct osim_file_desc *desc;
186
Harald Welte586d7102014-05-04 17:01:16 +0200187 /*! Encoded file contents */
Harald Welted54c2ee2012-01-17 18:25:50 +0100188 struct msgb *encoded_data;
Harald Welte586d7102014-05-04 17:01:16 +0200189 /*! Parsed/Decoded file contents */
Harald Welted54c2ee2012-01-17 18:25:50 +0100190 struct osim_decoded_data *decoded_data;
191};
192
Harald Welte586d7102014-05-04 17:01:16 +0200193/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200194#define EF(pfid, sfi, pns, pflags, pnl, ptype, smin, srec, pdec, penc) \
Harald Welted54c2ee2012-01-17 18:25:50 +0100195 { \
196 .fid = pfid, \
Harald Welte2656e652014-05-03 14:23:44 +0200197 .sfid = sfi, \
Harald Welted54c2ee2012-01-17 18:25:50 +0100198 .type = TYPE_EF, \
199 .ef_type = ptype, \
200 .short_name = pns, \
201 .long_name = pnl, \
202 .flags = pflags, \
203 .ops = { .encode = penc, .parse = pdec }, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200204 .size = { .min = smin, .rec = srec}, \
Harald Welted54c2ee2012-01-17 18:25:50 +0100205 }
206
207
Harald Welte586d7102014-05-04 17:01:16 +0200208/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200209#define EF_TRANSP(fid, sfi, ns, flags, smin, srec, nl, dec, enc) \
210 EF(fid, sfi, ns, flags, nl, EF_TYPE_TRANSP, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200211 smin, srec, dec, enc)
Harald Welte586d7102014-05-04 17:01:16 +0200212/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200213#define EF_TRANSP_N(fid, sfi, ns, flags, smin, srec, nl) \
214 EF_TRANSP(fid, sfi, ns, flags, smin, srec, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200215 nl, &default_decode, NULL)
Harald Welted54c2ee2012-01-17 18:25:50 +0100216
Harald Welte586d7102014-05-04 17:01:16 +0200217/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200218#define EF_CYCLIC(fid, sfi, ns, flags, smin, srec, nl, dec, enc) \
219 EF(fid, sfi, ns, flags, nl, EF_TYPE_RECORD_CYCLIC, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200220 smin, srec, dec, enc)
Harald Welte586d7102014-05-04 17:01:16 +0200221/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200222#define EF_CYCLIC_N(fid, sfi, ns, flags, smin, srec, nl) \
223 EF_CYCLIC(fid, sfi, ns, flags, smin, srec, nl, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200224 &default_decode, NULL)
Harald Welted54c2ee2012-01-17 18:25:50 +0100225
Harald Welte586d7102014-05-04 17:01:16 +0200226/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200227#define EF_LIN_FIX(fid, sfi, ns, flags, smin, srec, nl, dec, enc) \
228 EF(fid, sfi, ns, flags, nl, EF_TYPE_RECORD_FIXED, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200229 smin, srec, dec, enc)
Harald Welte586d7102014-05-04 17:01:16 +0200230/*! Convenience macros for defining EF */
Harald Welte1e0dfda2014-05-03 14:22:12 +0200231#define EF_LIN_FIX_N(fid, sfi, ns, flags, smin, srec, nl) \
232 EF_LIN_FIX(fid, sfi, ns, flags, smin, srec, nl, \
233 &default_decode, NULL)
Harald Welted54c2ee2012-01-17 18:25:50 +0100234
Harald Welte586d7102014-05-04 17:01:16 +0200235/*! Convenience macros for defining EF */
Harald Welteaad7e062014-05-04 16:31:24 +0200236#define EF_KEY(fid, sfi, ns, flags, smin, srec, nl, dec, enc) \
237 EF(fid, sfi, ns, flags, nl, EF_TYPE_KEY, \
238 smin, srec, dec, enc)
Harald Welte586d7102014-05-04 17:01:16 +0200239/*! Convenience macros for defining EF */
Harald Welteaad7e062014-05-04 16:31:24 +0200240#define EF_KEY_N(fid, sfi, ns, flags, smin, srec, nl) \
241 EF_KEY(fid, sfi, ns, flags, smin, srec, nl, \
242 &default_decode, NULL)
243
244
Harald Welted54c2ee2012-01-17 18:25:50 +0100245struct osim_file_desc *
Harald Welte5ffb5032016-03-11 09:40:56 +0700246osim_file_desc_find_name(struct osim_file_desc *parent, const char *name);
Harald Welted54c2ee2012-01-17 18:25:50 +0100247
Harald Weltec28f4cd2016-03-11 09:35:07 +0700248struct osim_file_desc *
Harald Weltebf90d742020-03-20 12:11:03 +0100249osim_file_desc_find_aid(struct osim_file_desc *parent, const uint8_t *aid, uint8_t aid_len);
250
251struct osim_file_desc *
Harald Welte5ffb5032016-03-11 09:40:56 +0700252osim_file_desc_find_fid(struct osim_file_desc *parent, uint16_t fid);
Harald Weltec28f4cd2016-03-11 09:35:07 +0700253
254struct osim_file_desc *
Harald Welte5ffb5032016-03-11 09:40:56 +0700255osim_file_desc_find_sfid(struct osim_file_desc *parent, uint8_t sfid);
Harald Weltec28f4cd2016-03-11 09:35:07 +0700256
Harald Welte586d7102014-05-04 17:01:16 +0200257/* STATUS WORDS */
258
Harald Welted54c2ee2012-01-17 18:25:50 +0100259enum osim_card_sw_type {
260 SW_TYPE_NONE,
261 SW_TYPE_STR,
262};
263
264enum osim_card_sw_class {
265 SW_CLS_NONE,
266 SW_CLS_OK,
267 SW_CLS_POSTP,
268 SW_CLS_WARN,
269 SW_CLS_ERROR,
270};
271
Harald Welte586d7102014-05-04 17:01:16 +0200272/*! A card status word (SW) */
Harald Welted54c2ee2012-01-17 18:25:50 +0100273struct osim_card_sw {
Harald Welte586d7102014-05-04 17:01:16 +0200274 /*! status word code (2 bytes) */
Harald Welted54c2ee2012-01-17 18:25:50 +0100275 uint16_t code;
Harald Welte586d7102014-05-04 17:01:16 +0200276 /*! status word mask (2 bytes), to match range/prefix of SW */
Harald Welted54c2ee2012-01-17 18:25:50 +0100277 uint16_t mask;
278 enum osim_card_sw_type type;
279 enum osim_card_sw_class class;
280 union {
Harald Welte586d7102014-05-04 17:01:16 +0200281 /*! Human-readable meaning of SW */
Harald Welted54c2ee2012-01-17 18:25:50 +0100282 const char *str;
283 } u;
284};
285
Oliver Smithaf916f12021-02-01 09:25:34 +0100286#define OSIM_CARD_SW_LAST { \
Harald Welted54c2ee2012-01-17 18:25:50 +0100287 .code = 0, .mask = 0, .type = SW_TYPE_NONE, \
288 .class = SW_CLS_NONE, .u.str = NULL \
289}
290
Harald Welte429adec2020-03-20 13:05:40 +0100291/*! A card application (e.g. USIM, ISIM, HPSIM) */
292struct osim_card_app_profile {
293 /*! entry in the global list of card application profiles */
294 struct llist_head list;
295 /*! human-readable name */
296 const char *name;
297 /*! AID of this application, as used in EF.DIR */
298 uint8_t aid[MAX_AID_LEN];
299 uint8_t aid_len;
300 /*! file system description */
301 struct osim_file_desc *adf;
302 /*! Status words defined by application */
303 const struct osim_card_sw *sw;
304};
305
306const struct osim_card_app_profile *
307osim_app_profile_find_by_name(const char *name);
308
309const struct osim_card_app_profile *
310osim_app_profile_find_by_aid(const uint8_t *aid, uint8_t aid_len);
311
Harald Welte3a6bedf2020-03-22 10:30:10 +0100312const struct osim_card_sw *osim_app_profile_find_sw(const struct osim_card_app_profile *ap, uint16_t sw_in);
Harald Welte429adec2020-03-20 13:05:40 +0100313
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200314/*! A card profile (e.g. SIM card */
Harald Welted54c2ee2012-01-17 18:25:50 +0100315struct osim_card_profile {
316 const char *name;
Harald Welte586d7102014-05-04 17:01:16 +0200317 /*! Descriptor for the MF (root directory */
Harald Welted54c2ee2012-01-17 18:25:50 +0100318 struct osim_file_desc *mf;
Harald Welte586d7102014-05-04 17:01:16 +0200319 /*! Array of pointers to status words */
Harald Welte76749602012-09-19 20:55:54 +0200320 const struct osim_card_sw **sws;
Harald Welted54c2ee2012-01-17 18:25:50 +0100321};
322
Harald Welte3a6bedf2020-03-22 10:30:10 +0100323const struct osim_card_sw *osim_cprof_find_sw(const struct osim_card_profile *cp, uint16_t sw_in);
Harald Welte76749602012-09-19 20:55:54 +0200324
Harald Welte3a6bedf2020-03-22 10:30:10 +0100325struct osim_chan_hdl;
326enum osim_card_sw_class osim_sw_class(const struct osim_chan_hdl *ch, uint16_t sw_in);
327char *osim_print_sw_buf(char *buf, size_t buf_len, const struct osim_chan_hdl *ch, uint16_t sw_in);
328char *osim_print_sw(const struct osim_chan_hdl *ch, uint16_t sw_in);
329char *osim_print_sw_c(const void *ctx, const struct osim_chan_hdl *ch, uint16_t sw_in);
Harald Welte76749602012-09-19 20:55:54 +0200330
Harald Welted54c2ee2012-01-17 18:25:50 +0100331extern const struct tlv_definition ts102221_fcp_tlv_def;
Holger Hans Peter Freytherc2b44582015-04-11 19:31:03 +0200332extern const struct value_string ts102221_fcp_vals[14];
Harald Welted54c2ee2012-01-17 18:25:50 +0100333
334/* 11.1.1.3 */
335enum ts102221_fcp_tag {
336 UICC_FCP_T_FCP = 0x62,
337 UICC_FCP_T_FILE_SIZE = 0x80,
338 UICC_FCP_T_TOT_F_SIZE = 0x81,
339 UICC_FCP_T_FILE_DESC = 0x82,
340 UICC_FCP_T_FILE_ID = 0x83,
341 UICC_FCP_T_DF_NAME = 0x84,
342 UICC_FCP_T_SFID = 0x88,
343 UICC_FCP_T_LIFEC_STS = 0x8A,
344 UICC_FCP_T_SEC_ATTR_REFEXP= 0x8B,
345 UICC_FCP_T_SEC_ATTR_COMP= 0x8C,
346 UICC_FCP_T_PROPRIETARY = 0xA5,
347 UICC_FCP_T_SEC_ATTR_EXP = 0xAB,
348 UICC_FCP_T_PIN_STS_DO = 0xC6,
349};
350
351struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
352 uint8_t p2, uint16_t lc, uint16_t le);
353
Harald Welte586d7102014-05-04 17:01:16 +0200354/* CARD READERS */
355
Harald Welte55790aa2014-10-26 18:46:50 +0100356enum osim_proto {
357 OSIM_PROTO_T0 = 0,
358 OSIM_PROTO_T1 = 1,
359};
360
361enum osim_reader_driver {
362 OSIM_READER_DRV_PCSC = 0,
363 OSIM_READER_DRV_OPENCT = 1,
364 OSIM_READER_DRV_SERIAL = 2,
365};
366
Harald Welte932d2d42016-03-19 21:18:40 +0100367struct osim_reader_ops {
368 const char *name;
369 struct osim_reader_hdl *(*reader_open)(int idx, const char *name, void *ctx);
370 struct osim_card_hdl *(*card_open)(struct osim_reader_hdl *rh, enum osim_proto proto);
371 int (*transceive)(struct osim_reader_hdl *rh, struct msgb *msg);
372};
373
Harald Welted54c2ee2012-01-17 18:25:50 +0100374struct osim_reader_hdl {
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200375 /*! member in global list of readers */
Harald Welted54c2ee2012-01-17 18:25:50 +0100376 struct llist_head list;
Harald Welte67354b12014-10-26 18:47:30 +0100377 const struct osim_reader_ops *ops;
Harald Welte55790aa2014-10-26 18:46:50 +0100378 uint32_t proto_supported;
Harald Welted54c2ee2012-01-17 18:25:50 +0100379 void *priv;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200380 /*! current card, if any */
Harald Welted54c2ee2012-01-17 18:25:50 +0100381 struct osim_card_hdl *card;
382};
383
Harald Welte429adec2020-03-20 13:05:40 +0100384/*! descriptor for a given application present on a card */
385struct osim_card_app_hdl {
386 /*! member in card list of applications */
387 struct llist_head list;
388 /*! AID of the application */
389 uint8_t aid[MAX_AID_LEN];
390 uint8_t aid_len;
391 /*! application label from EF_DIR */
392 char *label;
393 /*! application profile (if any known) */
394 const struct osim_card_app_profile *prof;
395};
396
Harald Welted54c2ee2012-01-17 18:25:50 +0100397struct osim_card_hdl {
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200398 /*! member in global list of cards */
Harald Welted54c2ee2012-01-17 18:25:50 +0100399 struct llist_head list;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200400 /*! reader through which card is accessed */
Harald Welted54c2ee2012-01-17 18:25:50 +0100401 struct osim_reader_hdl *reader;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200402 /*! card profile */
Harald Welted54c2ee2012-01-17 18:25:50 +0100403 struct osim_card_profile *prof;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200404 /*! card protocol */
Harald Welte55790aa2014-10-26 18:46:50 +0100405 enum osim_proto proto;
Harald Welted54c2ee2012-01-17 18:25:50 +0100406
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200407 /*! list of channels for this card */
Harald Welted54c2ee2012-01-17 18:25:50 +0100408 struct llist_head channels;
Harald Welte429adec2020-03-20 13:05:40 +0100409
410 /*! list of applications found on card */
411 struct llist_head apps;
Harald Welted54c2ee2012-01-17 18:25:50 +0100412};
413
414struct osim_chan_hdl {
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200415 /*! linked to card->channels */
Harald Welted54c2ee2012-01-17 18:25:50 +0100416 struct llist_head list;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200417 /*! card to which this channel belongs */
Harald Welted54c2ee2012-01-17 18:25:50 +0100418 struct osim_card_hdl *card;
Harald Welte429adec2020-03-20 13:05:40 +0100419 /*! current working directory */
Harald Welted54c2ee2012-01-17 18:25:50 +0100420 const struct osim_file_desc *cwd;
Harald Welte429adec2020-03-20 13:05:40 +0100421 /*! currently selected application (if any) */
422 struct osim_card_app_hdl *cur_app;
Harald Welted54c2ee2012-01-17 18:25:50 +0100423};
424
Harald Welte429adec2020-03-20 13:05:40 +0100425int osim_card_hdl_add_app(struct osim_card_hdl *ch, const uint8_t *aid, uint8_t aid_len,
426 const char *label);
427
Harald Welted54c2ee2012-01-17 18:25:50 +0100428/* reader.c */
429int osim_transceive_apdu(struct osim_chan_hdl *st, struct msgb *amsg);
Harald Welte55790aa2014-10-26 18:46:50 +0100430struct osim_reader_hdl *osim_reader_open(enum osim_reader_driver drv, int idx,
431 const char *name, void *ctx);
432struct osim_card_hdl *osim_card_open(struct osim_reader_hdl *rh, enum osim_proto proto);
Harald Welted54c2ee2012-01-17 18:25:50 +0100433#endif /* _OSMOCOM_SIM_H */