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