blob: 5440d855145bcb5d92f12352b43c87426970926e [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
12
Neels Hofmeyr87e45502017-06-20 00:17:59 +020013/*! command-response pairs cases
Kevin Redon43eabee2012-09-16 18:40:02 +020014 *
15 * Enumeration used to identify the APDU structure based on command-response pair case , as specified in ISO/IEC 7816-3:2006(E) §12.1.
16 */
Harald Welted54c2ee2012-01-17 18:25:50 +010017enum osim_apdu_case {
Kevin Redon43eabee2012-09-16 18:40:02 +020018 APDU_CASE_1, /*!< command header, no command data field, no response data field */
19 APDU_CASE_2S, /*!< command header, no command data field, response data field (short) */
20 APDU_CASE_2E, /*!< command header, no command data field, response data field (extended) */
21 APDU_CASE_3S, /*!< command header, command data field (short), no response data field */
22 APDU_CASE_3E, /*!< command header, command data field (extended), no response data field */
23 APDU_CASE_4S, /*!< command header, command data field (short), response data field (short) */
24 APDU_CASE_4E /*!< command header, command data field (extended), response data field (extended) */
Harald Welted54c2ee2012-01-17 18:25:50 +010025};
26
Neels Hofmeyr87e45502017-06-20 00:17:59 +020027/*! APDU/TPDU command header
Kevin Redon43eabee2012-09-16 18:40:02 +020028 *
29 * This structure encode an APDU/TPDU command header, as specified in ISO/IEC 7816-3:2006(E) §12.2 and §12.3.
30 * The APDU (application layer) can be encoded as different TPDUs (transport layer), depending on the transport protocol used.
31 * The TPDU encoding by T=1 of the APDU command header is identical to the APDU.
32 * The TPDU encoding by T=0 of the APDU command header adds a Parameter 3 field, generally used instead of Lc/Le.
33 *
34 * @todo have different structures for APDU, TPDU by T=0, and TPDU by T=1.
35 */
Harald Welted54c2ee2012-01-17 18:25:50 +010036struct osim_apdu_cmd_hdr {
Kevin Redon43eabee2012-09-16 18:40:02 +020037 uint8_t cla; /*!< CLASS byte */
38 uint8_t ins; /*!< INSTRUCTION byte */
39 uint8_t p1; /*!< Parameter 1 byte */
40 uint8_t p2; /*!< Parameter 2 byte */
41 uint8_t p3; /*!< Parameter 3 byte, used for TPDU by T=0 */
Harald Welted54c2ee2012-01-17 18:25:50 +010042} __attribute__ ((packed));
43
44#define msgb_apdu_dr(__x)
45
Neels Hofmeyr87e45502017-06-20 00:17:59 +020046/*! APDU command body
Kevin Redon43eabee2012-09-16 18:40:02 +020047 *
48 * This structure encode a command body, as specified in ISO/IEC 7816-3:2006(E) §12.1.
49 * The data and response contents should be provided along with this structure.
50 */
Harald Welted54c2ee2012-01-17 18:25:50 +010051struct osim_msgb_cb {
Kevin Redon43eabee2012-09-16 18:40:02 +020052 enum osim_apdu_case apduc; /*!< command-response pair case, defining the encoding of Lc and Le */
53 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 */
54 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 */
55 uint16_t sw; /*!< status word, composed of SW1 and SW2 bytes */
Harald Weltee8dd2bd2014-05-04 13:42:38 +020056} __attribute__((__may_alias__));
Harald Welted54c2ee2012-01-17 18:25:50 +010057#define OSIM_MSGB_CB(__msgb) ((struct osim_msgb_cb *)&((__msgb)->cb[0]))
Neels Hofmeyr87e45502017-06-20 00:17:59 +020058/*! status word from msgb->cb */
Harald Welted54c2ee2012-01-17 18:25:50 +010059#define msgb_apdu_case(__x) OSIM_MSGB_CB(__x)->apduc
60#define msgb_apdu_lc(__x) OSIM_MSGB_CB(__x)->lc
61#define msgb_apdu_le(__x) OSIM_MSGB_CB(__x)->le
62#define msgb_apdu_sw(__x) OSIM_MSGB_CB(__x)->sw
Neels Hofmeyr87e45502017-06-20 00:17:59 +020063/*! pointer to the command header of the APDU */
Harald Welted54c2ee2012-01-17 18:25:50 +010064#define msgb_apdu_h(__x) ((struct osim_apdu_cmd_hdr *)(__x)->l2h)
65
66#define msgb_apdu_dc(__x) ((__x)->l2h + sizeof(struct osim_apdu_cmd_hdr))
67#define msgb_apdu_de(__x) ((__x)->l2h + sizeof(struct osim_apdu_cmd_hdr) + msgb_apdu_lc(__x))
68
Harald Welte586d7102014-05-04 17:01:16 +020069/* FILES */
70
Harald Welted54c2ee2012-01-17 18:25:50 +010071struct osim_file;
72struct osim_file_desc;
73struct osim_decoded_data;
74
Neels Hofmeyr87e45502017-06-20 00:17:59 +020075/*! Operations for a given File */
Harald Welted54c2ee2012-01-17 18:25:50 +010076struct osim_file_ops {
Harald Welte586d7102014-05-04 17:01:16 +020077 /*! Parse binary file data into osim_decoded_data */
Harald Welted54c2ee2012-01-17 18:25:50 +010078 int (*parse)(struct osim_decoded_data *dd,
79 const struct osim_file_desc *desc,
80 int len, uint8_t *data);
Harald Welte586d7102014-05-04 17:01:16 +020081 /*! Encode osim_decoded_data into binary file */
Harald Welte6729a972014-10-26 19:04:56 +010082 struct msgb * (*encode)(const struct osim_file_desc *desc,
Harald Welted54c2ee2012-01-17 18:25:50 +010083 const struct osim_decoded_data *decoded);
84};
85
86enum osim_element_type {
87 ELEM_T_NONE,
88 ELEM_T_BOOL, /*!< a boolean flag */
89 ELEM_T_UINT8, /*!< unsigned integer */
90 ELEM_T_UINT16, /*!< unsigned integer */
91 ELEM_T_UINT32, /*!< unsigned integer */
92 ELEM_T_STRING, /*!< generic string */
93 ELEM_T_BCD, /*!< BCD encoded digits */
94 ELEM_T_BYTES, /*!< BCD encoded digits */
95 ELEM_T_GROUP, /*!< group container, has siblings */
96};
97
98enum osim_element_repr {
99 ELEM_REPR_NONE,
100 ELEM_REPR_DEC,
101 ELEM_REPR_HEX,
102};
103
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200104/*! A single decoded element inside a file */
Harald Welted54c2ee2012-01-17 18:25:50 +0100105struct osim_decoded_element {
106 struct llist_head list;
107
108 enum osim_element_type type;
109 enum osim_element_repr representation;
110 const char *name;
111
112 unsigned int length;
113 union {
114 uint8_t u8;
115 uint16_t u16;
116 uint32_t u32;
117 uint8_t *buf;
Harald Welte586d7102014-05-04 17:01:16 +0200118 /*! A list of sibling decoded_items */
Harald Welted54c2ee2012-01-17 18:25:50 +0100119 struct llist_head siblings;
120 } u;
121};
122
Harald Welte586d7102014-05-04 17:01:16 +0200123/*! Decoded data for a single file, consisting of all decoded elements */
Harald Welted54c2ee2012-01-17 18:25:50 +0100124struct osim_decoded_data {
125 /*! file to which we belong */
126 const struct osim_file *file;
127 /*! list of 'struct decoded_element' */
128 struct llist_head decoded_elements;
129};
130
131
132enum osim_file_type {
133 TYPE_NONE,
Harald Welte586d7102014-05-04 17:01:16 +0200134 TYPE_DF, /*!< Dedicated File */
135 TYPE_ADF, /*!< Application Dedicated File */
136 TYPE_EF, /*!< Entry File */
137 TYPE_EF_INT, /*!< Internal Entry File */
Harald Welte053bebc2020-02-15 18:58:16 +0100138 TYPE_MF, /*!< Master File */
Harald Welted54c2ee2012-01-17 18:25:50 +0100139};
140
141enum osim_ef_type {
Harald Welte586d7102014-05-04 17:01:16 +0200142 EF_TYPE_TRANSP, /*!< Transparent EF */
143 EF_TYPE_RECORD_FIXED, /*!< Fixed-Size Record EF */
144 EF_TYPE_RECORD_CYCLIC, /*!< Cyclic Record EF */
145 EF_TYPE_KEY, /*!< Key file as used in TETRA */
Harald Welted54c2ee2012-01-17 18:25:50 +0100146};
147
148#define F_OPTIONAL 0x0001
149
Harald Welte2656e652014-05-03 14:23:44 +0200150#define SFI_NONE 0xFF
151
Harald Welted54c2ee2012-01-17 18:25:50 +0100152struct osim_file_desc {
153 struct llist_head list; /*!< local element in list */
154 struct llist_head child_list; /*!< list of children EF in DF */
155 struct osim_file_desc *parent; /*!< parent DF */
156
Harald Welte586d7102014-05-04 17:01:16 +0200157 enum osim_file_type type; /*!< Type of the file (EF, DF, ...) */
158 enum osim_ef_type ef_type; /*!< Type of the EF, if type == TYPE_EF */
Harald Welted54c2ee2012-01-17 18:25:50 +0100159
160 uint16_t fid; /*!< File Identifier */
161 uint8_t sfid; /*!< Short File IDentifier */
Harald Welte6729a972014-10-26 19:04:56 +0100162 const uint8_t *df_name;
Harald Welted54c2ee2012-01-17 18:25:50 +0100163 uint8_t df_name_len;
164
165 const char *short_name; /*!< Short Name (like EF.ICCID) */
166 const char *long_name; /*!< Long / description */
167 unsigned int flags;
168
Harald Welte586d7102014-05-04 17:01:16 +0200169 struct osim_file_ops ops; /*!< Operations (parse/encode */
Harald Welte1e0dfda2014-05-03 14:22:12 +0200170
171 struct {
172 size_t min; /*!< Minimum size of the file
173 (transparent) or record in
174 cyclic / linear file */
175 size_t rec; /*!< Recommended size */
176 } size;
Harald Welted54c2ee2012-01-17 18:25:50 +0100177};
178
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200179/*! A single instance of a file: Descriptor and contents */
Harald Welted54c2ee2012-01-17 18:25:50 +0100180struct osim_file {
Harald Welte586d7102014-05-04 17:01:16 +0200181 /*! Descriptor for the file */
Harald Welted54c2ee2012-01-17 18:25:50 +0100182 const struct osim_file_desc *desc;
183
Harald Welte586d7102014-05-04 17:01:16 +0200184 /*! Encoded file contents */
Harald Welted54c2ee2012-01-17 18:25:50 +0100185 struct msgb *encoded_data;
Harald Welte586d7102014-05-04 17:01:16 +0200186 /*! Parsed/Decoded file contents */
Harald Welted54c2ee2012-01-17 18:25:50 +0100187 struct osim_decoded_data *decoded_data;
188};
189
Harald Welte586d7102014-05-04 17:01:16 +0200190/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200191#define EF(pfid, sfi, pns, pflags, pnl, ptype, smin, srec, pdec, penc) \
Harald Welted54c2ee2012-01-17 18:25:50 +0100192 { \
193 .fid = pfid, \
Harald Welte2656e652014-05-03 14:23:44 +0200194 .sfid = sfi, \
Harald Welted54c2ee2012-01-17 18:25:50 +0100195 .type = TYPE_EF, \
196 .ef_type = ptype, \
197 .short_name = pns, \
198 .long_name = pnl, \
199 .flags = pflags, \
200 .ops = { .encode = penc, .parse = pdec }, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200201 .size = { .min = smin, .rec = srec}, \
Harald Welted54c2ee2012-01-17 18:25:50 +0100202 }
203
204
Harald Welte586d7102014-05-04 17:01:16 +0200205/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200206#define EF_TRANSP(fid, sfi, ns, flags, smin, srec, nl, dec, enc) \
207 EF(fid, sfi, ns, flags, nl, EF_TYPE_TRANSP, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200208 smin, srec, dec, enc)
Harald Welte586d7102014-05-04 17:01:16 +0200209/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200210#define EF_TRANSP_N(fid, sfi, ns, flags, smin, srec, nl) \
211 EF_TRANSP(fid, sfi, ns, flags, smin, srec, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200212 nl, &default_decode, NULL)
Harald Welted54c2ee2012-01-17 18:25:50 +0100213
Harald Welte586d7102014-05-04 17:01:16 +0200214/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200215#define EF_CYCLIC(fid, sfi, ns, flags, smin, srec, nl, dec, enc) \
216 EF(fid, sfi, ns, flags, nl, EF_TYPE_RECORD_CYCLIC, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200217 smin, srec, dec, enc)
Harald Welte586d7102014-05-04 17:01:16 +0200218/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200219#define EF_CYCLIC_N(fid, sfi, ns, flags, smin, srec, nl) \
220 EF_CYCLIC(fid, sfi, ns, flags, smin, srec, nl, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200221 &default_decode, NULL)
Harald Welted54c2ee2012-01-17 18:25:50 +0100222
Harald Welte586d7102014-05-04 17:01:16 +0200223/*! Convenience macros for defining EF */
Harald Welte2656e652014-05-03 14:23:44 +0200224#define EF_LIN_FIX(fid, sfi, ns, flags, smin, srec, nl, dec, enc) \
225 EF(fid, sfi, ns, flags, nl, EF_TYPE_RECORD_FIXED, \
Harald Welte1e0dfda2014-05-03 14:22:12 +0200226 smin, srec, dec, enc)
Harald Welte586d7102014-05-04 17:01:16 +0200227/*! Convenience macros for defining EF */
Harald Welte1e0dfda2014-05-03 14:22:12 +0200228#define EF_LIN_FIX_N(fid, sfi, ns, flags, smin, srec, nl) \
229 EF_LIN_FIX(fid, sfi, ns, flags, smin, srec, nl, \
230 &default_decode, NULL)
Harald Welted54c2ee2012-01-17 18:25:50 +0100231
Harald Welte586d7102014-05-04 17:01:16 +0200232/*! Convenience macros for defining EF */
Harald Welteaad7e062014-05-04 16:31:24 +0200233#define EF_KEY(fid, sfi, ns, flags, smin, srec, nl, dec, enc) \
234 EF(fid, sfi, ns, flags, nl, EF_TYPE_KEY, \
235 smin, srec, dec, enc)
Harald Welte586d7102014-05-04 17:01:16 +0200236/*! Convenience macros for defining EF */
Harald Welteaad7e062014-05-04 16:31:24 +0200237#define EF_KEY_N(fid, sfi, ns, flags, smin, srec, nl) \
238 EF_KEY(fid, sfi, ns, flags, smin, srec, nl, \
239 &default_decode, NULL)
240
241
Harald Welted54c2ee2012-01-17 18:25:50 +0100242struct osim_file_desc *
Harald Welte5ffb5032016-03-11 09:40:56 +0700243osim_file_desc_find_name(struct osim_file_desc *parent, const char *name);
Harald Welted54c2ee2012-01-17 18:25:50 +0100244
Harald Weltec28f4cd2016-03-11 09:35:07 +0700245struct osim_file_desc *
Harald Weltebf90d742020-03-20 12:11:03 +0100246osim_file_desc_find_aid(struct osim_file_desc *parent, const uint8_t *aid, uint8_t aid_len);
247
248struct osim_file_desc *
Harald Welte5ffb5032016-03-11 09:40:56 +0700249osim_file_desc_find_fid(struct osim_file_desc *parent, uint16_t fid);
Harald Weltec28f4cd2016-03-11 09:35:07 +0700250
251struct osim_file_desc *
Harald Welte5ffb5032016-03-11 09:40:56 +0700252osim_file_desc_find_sfid(struct osim_file_desc *parent, uint8_t sfid);
Harald Weltec28f4cd2016-03-11 09:35:07 +0700253
Harald Welte586d7102014-05-04 17:01:16 +0200254/* STATUS WORDS */
255
Harald Welted54c2ee2012-01-17 18:25:50 +0100256enum osim_card_sw_type {
257 SW_TYPE_NONE,
258 SW_TYPE_STR,
259};
260
261enum osim_card_sw_class {
262 SW_CLS_NONE,
263 SW_CLS_OK,
264 SW_CLS_POSTP,
265 SW_CLS_WARN,
266 SW_CLS_ERROR,
267};
268
Harald Welte586d7102014-05-04 17:01:16 +0200269/*! A card status word (SW) */
Harald Welted54c2ee2012-01-17 18:25:50 +0100270struct osim_card_sw {
Harald Welte586d7102014-05-04 17:01:16 +0200271 /*! status word code (2 bytes) */
Harald Welted54c2ee2012-01-17 18:25:50 +0100272 uint16_t code;
Harald Welte586d7102014-05-04 17:01:16 +0200273 /*! status word mask (2 bytes), to match range/prefix of SW */
Harald Welted54c2ee2012-01-17 18:25:50 +0100274 uint16_t mask;
275 enum osim_card_sw_type type;
276 enum osim_card_sw_class class;
277 union {
Harald Welte586d7102014-05-04 17:01:16 +0200278 /*! Human-readable meaning of SW */
Harald Welted54c2ee2012-01-17 18:25:50 +0100279 const char *str;
280 } u;
281};
282
Harald Welte76749602012-09-19 20:55:54 +0200283#define OSIM_CARD_SW_LAST (const struct osim_card_sw) { \
Harald Welted54c2ee2012-01-17 18:25:50 +0100284 .code = 0, .mask = 0, .type = SW_TYPE_NONE, \
285 .class = SW_CLS_NONE, .u.str = NULL \
286}
287
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200288/*! A card profile (e.g. SIM card */
Harald Welted54c2ee2012-01-17 18:25:50 +0100289struct osim_card_profile {
290 const char *name;
Harald Welte586d7102014-05-04 17:01:16 +0200291 /*! Descriptor for the MF (root directory */
Harald Welted54c2ee2012-01-17 18:25:50 +0100292 struct osim_file_desc *mf;
Harald Welte586d7102014-05-04 17:01:16 +0200293 /*! Array of pointers to status words */
Harald Welte76749602012-09-19 20:55:54 +0200294 const struct osim_card_sw **sws;
Harald Welted54c2ee2012-01-17 18:25:50 +0100295};
296
Harald Welte76749602012-09-19 20:55:54 +0200297const struct osim_card_sw *osim_find_sw(const struct osim_card_profile *cp,
298 uint16_t sw);
Harald Welted83d2962013-03-04 17:52:33 +0000299enum osim_card_sw_class osim_sw_class(const struct osim_card_profile *cp,
300 uint16_t sw_in);
Harald Welte76749602012-09-19 20:55:54 +0200301
302struct osim_card_hdl;
Harald Welte4a62eda2019-03-18 18:27:00 +0100303char *osim_print_sw_buf(char *buf, size_t buf_len, const struct osim_card_hdl *ch, uint16_t sw_in);
Harald Welte76749602012-09-19 20:55:54 +0200304char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in);
Harald Welte179f3572019-03-18 18:38:47 +0100305char *osim_print_sw_c(const void *ctx, const struct osim_card_hdl *ch, uint16_t sw_in);
Harald Welte76749602012-09-19 20:55:54 +0200306
Harald Welted54c2ee2012-01-17 18:25:50 +0100307extern const struct tlv_definition ts102221_fcp_tlv_def;
Holger Hans Peter Freytherc2b44582015-04-11 19:31:03 +0200308extern const struct value_string ts102221_fcp_vals[14];
Harald Welted54c2ee2012-01-17 18:25:50 +0100309
310/* 11.1.1.3 */
311enum ts102221_fcp_tag {
312 UICC_FCP_T_FCP = 0x62,
313 UICC_FCP_T_FILE_SIZE = 0x80,
314 UICC_FCP_T_TOT_F_SIZE = 0x81,
315 UICC_FCP_T_FILE_DESC = 0x82,
316 UICC_FCP_T_FILE_ID = 0x83,
317 UICC_FCP_T_DF_NAME = 0x84,
318 UICC_FCP_T_SFID = 0x88,
319 UICC_FCP_T_LIFEC_STS = 0x8A,
320 UICC_FCP_T_SEC_ATTR_REFEXP= 0x8B,
321 UICC_FCP_T_SEC_ATTR_COMP= 0x8C,
322 UICC_FCP_T_PROPRIETARY = 0xA5,
323 UICC_FCP_T_SEC_ATTR_EXP = 0xAB,
324 UICC_FCP_T_PIN_STS_DO = 0xC6,
325};
326
327struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
328 uint8_t p2, uint16_t lc, uint16_t le);
329
Harald Welte586d7102014-05-04 17:01:16 +0200330/* CARD READERS */
331
Harald Welte55790aa2014-10-26 18:46:50 +0100332enum osim_proto {
333 OSIM_PROTO_T0 = 0,
334 OSIM_PROTO_T1 = 1,
335};
336
337enum osim_reader_driver {
338 OSIM_READER_DRV_PCSC = 0,
339 OSIM_READER_DRV_OPENCT = 1,
340 OSIM_READER_DRV_SERIAL = 2,
341};
342
Harald Welte932d2d42016-03-19 21:18:40 +0100343struct osim_reader_ops {
344 const char *name;
345 struct osim_reader_hdl *(*reader_open)(int idx, const char *name, void *ctx);
346 struct osim_card_hdl *(*card_open)(struct osim_reader_hdl *rh, enum osim_proto proto);
347 int (*transceive)(struct osim_reader_hdl *rh, struct msgb *msg);
348};
349
Harald Welted54c2ee2012-01-17 18:25:50 +0100350struct osim_reader_hdl {
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200351 /*! member in global list of readers */
Harald Welted54c2ee2012-01-17 18:25:50 +0100352 struct llist_head list;
Harald Welte67354b12014-10-26 18:47:30 +0100353 const struct osim_reader_ops *ops;
Harald Welte55790aa2014-10-26 18:46:50 +0100354 uint32_t proto_supported;
Harald Welted54c2ee2012-01-17 18:25:50 +0100355 void *priv;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200356 /*! current card, if any */
Harald Welted54c2ee2012-01-17 18:25:50 +0100357 struct osim_card_hdl *card;
358};
359
360struct osim_card_hdl {
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200361 /*! member in global list of cards */
Harald Welted54c2ee2012-01-17 18:25:50 +0100362 struct llist_head list;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200363 /*! reader through which card is accessed */
Harald Welted54c2ee2012-01-17 18:25:50 +0100364 struct osim_reader_hdl *reader;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200365 /*! card profile */
Harald Welted54c2ee2012-01-17 18:25:50 +0100366 struct osim_card_profile *prof;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200367 /*! card protocol */
Harald Welte55790aa2014-10-26 18:46:50 +0100368 enum osim_proto proto;
Harald Welted54c2ee2012-01-17 18:25:50 +0100369
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200370 /*! list of channels for this card */
Harald Welted54c2ee2012-01-17 18:25:50 +0100371 struct llist_head channels;
372};
373
374struct osim_chan_hdl {
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200375 /*! linked to card->channels */
Harald Welted54c2ee2012-01-17 18:25:50 +0100376 struct llist_head list;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200377 /*! card to which this channel belongs */
Harald Welted54c2ee2012-01-17 18:25:50 +0100378 struct osim_card_hdl *card;
379 const struct osim_file_desc *cwd;
380};
381
382/* reader.c */
383int osim_transceive_apdu(struct osim_chan_hdl *st, struct msgb *amsg);
Harald Welte55790aa2014-10-26 18:46:50 +0100384struct osim_reader_hdl *osim_reader_open(enum osim_reader_driver drv, int idx,
385 const char *name, void *ctx);
386struct osim_card_hdl *osim_card_open(struct osim_reader_hdl *rh, enum osim_proto proto);
Harald Welted54c2ee2012-01-17 18:25:50 +0100387#endif /* _OSMOCOM_SIM_H */