blob: 12f0074d1543e6e2482dd7bf8f9b7d1595e2658f [file] [log] [blame]
Harald Welted54c2ee2012-01-17 18:25:50 +01001#ifndef _OSMOCOM_SIM_H
2#define _OSMOCOM_SIM_H
3
4#include <osmocom/core/msgb.h>
5#include <osmocom/core/linuxlist.h>
6
7#define APDU_HDR_LEN 5
8
Kevin Redon6956ee12012-09-11 11:42:29 +02009/* command-response pairs cases, as specified in ISO/IEC 7816-3:2006(E) §12.1 */
Harald Welted54c2ee2012-01-17 18:25:50 +010010enum osim_apdu_case {
Kevin Redon6956ee12012-09-11 11:42:29 +020011 APDU_CASE_1, /* command header, no command data field, no response data field */
Kevin Redone07967f2012-09-11 11:44:18 +020012 APDU_CASE_2S, /* command header, no command data field, response data field (short) */
13 APDU_CASE_2E, /* command header, no command data field, response data field (extended) */
14 APDU_CASE_3S, /* command header, command data field (short), no response data field */
15 APDU_CASE_3E, /* command header, command data field (extended), no response data field */
16 APDU_CASE_4S, /* command header, command data field (short), response data field (short) */
17 APDU_CASE_4E /* command header, command data field (extended), response data field (extended) */
Harald Welted54c2ee2012-01-17 18:25:50 +010018};
19
Kevin Redon17073062012-09-11 11:54:52 +020020/* command header, as specified in ISO/IEC 7816-3:2006(E) §12.2 */
Harald Welted54c2ee2012-01-17 18:25:50 +010021struct osim_apdu_cmd_hdr {
Kevin Redon17073062012-09-11 11:54:52 +020022 uint8_t cla; /* CLASS byte */
23 uint8_t ins; /* INSTRUCTION byte */
24 uint8_t p1; /* Parameter 1 byte */
25 uint8_t p2; /* Parameter 2 byte */
26 uint8_t p3; /* Parameter 3 byte, used for TPDU */
Harald Welted54c2ee2012-01-17 18:25:50 +010027} __attribute__ ((packed));
28
29#define msgb_apdu_dr(__x)
30
31struct osim_msgb_cb {
32 enum osim_apdu_case apduc;
33 uint16_t lc;
34 uint16_t le;
35 uint16_t sw;
36};
37#define OSIM_MSGB_CB(__msgb) ((struct osim_msgb_cb *)&((__msgb)->cb[0]))
38/*! \brief status word from msgb->cb */
39#define msgb_apdu_case(__x) OSIM_MSGB_CB(__x)->apduc
40#define msgb_apdu_lc(__x) OSIM_MSGB_CB(__x)->lc
41#define msgb_apdu_le(__x) OSIM_MSGB_CB(__x)->le
42#define msgb_apdu_sw(__x) OSIM_MSGB_CB(__x)->sw
43/*! \brief pointer to the command header of the APDU */
44#define msgb_apdu_h(__x) ((struct osim_apdu_cmd_hdr *)(__x)->l2h)
45
46#define msgb_apdu_dc(__x) ((__x)->l2h + sizeof(struct osim_apdu_cmd_hdr))
47#define msgb_apdu_de(__x) ((__x)->l2h + sizeof(struct osim_apdu_cmd_hdr) + msgb_apdu_lc(__x))
48
49struct osim_file;
50struct osim_file_desc;
51struct osim_decoded_data;
52
53struct osim_file_ops {
54 int (*parse)(struct osim_decoded_data *dd,
55 const struct osim_file_desc *desc,
56 int len, uint8_t *data);
57 struct msgb * (*encode)(const struct osim_file *file,
58 const struct osim_decoded_data *decoded);
59};
60
61enum osim_element_type {
62 ELEM_T_NONE,
63 ELEM_T_BOOL, /*!< a boolean flag */
64 ELEM_T_UINT8, /*!< unsigned integer */
65 ELEM_T_UINT16, /*!< unsigned integer */
66 ELEM_T_UINT32, /*!< unsigned integer */
67 ELEM_T_STRING, /*!< generic string */
68 ELEM_T_BCD, /*!< BCD encoded digits */
69 ELEM_T_BYTES, /*!< BCD encoded digits */
70 ELEM_T_GROUP, /*!< group container, has siblings */
71};
72
73enum osim_element_repr {
74 ELEM_REPR_NONE,
75 ELEM_REPR_DEC,
76 ELEM_REPR_HEX,
77};
78
79struct osim_decoded_element {
80 struct llist_head list;
81
82 enum osim_element_type type;
83 enum osim_element_repr representation;
84 const char *name;
85
86 unsigned int length;
87 union {
88 uint8_t u8;
89 uint16_t u16;
90 uint32_t u32;
91 uint8_t *buf;
92 struct llist_head siblings;
93 } u;
94};
95
96struct osim_decoded_data {
97 /*! file to which we belong */
98 const struct osim_file *file;
99 /*! list of 'struct decoded_element' */
100 struct llist_head decoded_elements;
101};
102
103
104enum osim_file_type {
105 TYPE_NONE,
106 TYPE_DF,
107 TYPE_ADF,
108 TYPE_EF,
109 TYPE_EF_INT,
110};
111
112enum osim_ef_type {
113 EF_TYPE_TRANSP,
114 EF_TYPE_RECORD_FIXED,
115 EF_TYPE_RECORD_CYCLIC,
116};
117
118#define F_OPTIONAL 0x0001
119
120struct osim_file_desc {
121 struct llist_head list; /*!< local element in list */
122 struct llist_head child_list; /*!< list of children EF in DF */
123 struct osim_file_desc *parent; /*!< parent DF */
124
125 enum osim_file_type type;
126 enum osim_ef_type ef_type;
127
128 uint16_t fid; /*!< File Identifier */
129 uint8_t sfid; /*!< Short File IDentifier */
130 const char *df_name;
131 uint8_t df_name_len;
132
133 const char *short_name; /*!< Short Name (like EF.ICCID) */
134 const char *long_name; /*!< Long / description */
135 unsigned int flags;
136
137 struct osim_file_ops ops;
138};
139
140struct osim_file {
141 const struct osim_file_desc *desc;
142
143 struct msgb *encoded_data;
144 struct osim_decoded_data *decoded_data;
145};
146
147#define EF(pfid, pns, pflags, pnl, ptype, pdec, penc) \
148 { \
149 .fid = pfid, \
150 .type = TYPE_EF, \
151 .ef_type = ptype, \
152 .short_name = pns, \
153 .long_name = pnl, \
154 .flags = pflags, \
155 .ops = { .encode = penc, .parse = pdec }, \
156 }
157
158
159#define EF_TRANSP(fid, ns, flags, nl, dec, enc) \
160 EF(fid, ns, flags, nl, EF_TYPE_TRANSP, dec, enc)
161#define EF_TRANSP_N(fid, ns, flags, nl) \
162 EF_TRANSP(fid, ns, flags, nl, &default_decode, NULL)
163
164#define EF_CYCLIC(fid, ns, flags, nl, dec, enc) \
165 EF(fid, ns, flags, nl, EF_TYPE_RECORD_CYCLIC, dec, enc)
166#define EF_CYCLIC_N(fid, ns, flags, nl) \
167 EF_CYCLIC(fid, ns, flags, nl, &default_decode, NULL)
168
169#define EF_LIN_FIX(fid, ns, flags, nl, dec, enc) \
170 EF(fid, ns, flags, nl, EF_TYPE_RECORD_FIXED, dec, enc)
171#define EF_LIN_FIX_N(fid, ns, flags, nl) \
172 EF_LIN_FIX(fid, ns, flags, nl, &default_decode, NULL)
173
174struct osim_file_desc *
175osim_file_find_name(struct osim_file_desc *parent, const char *name);
176
177enum osim_card_sw_type {
178 SW_TYPE_NONE,
179 SW_TYPE_STR,
180};
181
182enum osim_card_sw_class {
183 SW_CLS_NONE,
184 SW_CLS_OK,
185 SW_CLS_POSTP,
186 SW_CLS_WARN,
187 SW_CLS_ERROR,
188};
189
190struct osim_card_sw {
191 uint16_t code;
192 uint16_t mask;
193 enum osim_card_sw_type type;
194 enum osim_card_sw_class class;
195 union {
196 const char *str;
197 } u;
198};
199
200#define OSIM_CARD_SW_LAST { \
201 .code = 0, .mask = 0, .type = SW_TYPE_NONE, \
202 .class = SW_CLS_NONE, .u.str = NULL \
203}
204
205struct osim_card_profile {
206 const char *name;
207 struct osim_file_desc *mf;
208 struct osim_card_sw **sws;
209};
210
211extern const struct tlv_definition ts102221_fcp_tlv_def;
212const struct value_string ts102221_fcp_vals[14];
213
214/* 11.1.1.3 */
215enum ts102221_fcp_tag {
216 UICC_FCP_T_FCP = 0x62,
217 UICC_FCP_T_FILE_SIZE = 0x80,
218 UICC_FCP_T_TOT_F_SIZE = 0x81,
219 UICC_FCP_T_FILE_DESC = 0x82,
220 UICC_FCP_T_FILE_ID = 0x83,
221 UICC_FCP_T_DF_NAME = 0x84,
222 UICC_FCP_T_SFID = 0x88,
223 UICC_FCP_T_LIFEC_STS = 0x8A,
224 UICC_FCP_T_SEC_ATTR_REFEXP= 0x8B,
225 UICC_FCP_T_SEC_ATTR_COMP= 0x8C,
226 UICC_FCP_T_PROPRIETARY = 0xA5,
227 UICC_FCP_T_SEC_ATTR_EXP = 0xAB,
228 UICC_FCP_T_PIN_STS_DO = 0xC6,
229};
230
231struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
232 uint8_t p2, uint16_t lc, uint16_t le);
233
234struct osim_reader_ops;
235
236struct osim_reader_hdl {
237 /*! \brief member in global list of readers */
238 struct llist_head list;
239 struct osim_reader_ops *ops;
240 void *priv;
241 /*! \brief current card, if any */
242 struct osim_card_hdl *card;
243};
244
245struct osim_card_hdl {
246 /*! \brief member in global list of cards */
247 struct llist_head list;
248 /*! \brief reader through which card is accessed */
249 struct osim_reader_hdl *reader;
250 /*! \brief card profile */
251 struct osim_card_profile *prof;
252
253 /*! \brief list of channels for this card */
254 struct llist_head channels;
255};
256
257struct osim_chan_hdl {
258 /*! \brief linked to card->channels */
259 struct llist_head list;
260 /*! \brief card to which this channel belongs */
261 struct osim_card_hdl *card;
262 const struct osim_file_desc *cwd;
263};
264
265/* reader.c */
266int osim_transceive_apdu(struct osim_chan_hdl *st, struct msgb *amsg);
267struct osim_reader_hdl *osim_reader_open(int idx, const char *name);
268struct osim_card_hdl *osim_card_open(struct osim_reader_hdl *rh);
269#endif /* _OSMOCOM_SIM_H */