blob: 40a49cf2390d582728341de7b42e605f686ff0f0 [file] [log] [blame]
Harald Welted54c2ee2012-01-17 18:25:50 +01001#include <stdlib.h>
2#include <stdint.h>
3
4#include <osmocom/core/talloc.h>
5#include <osmocom/sim/sim.h>
6
7static struct osim_decoded_element *
8__element_alloc(void *ctx, const char *name, enum osim_element_type type,
9 enum osim_element_repr repr)
10{
11 struct osim_decoded_element *elem;
12
13 elem = talloc_zero(ctx, struct osim_decoded_element);
14 if (!elem)
15 return NULL;
16 elem->name = name;
17 elem->type = type;
18 elem->representation = repr;
19
20 if (elem->type == ELEM_T_GROUP)
21 INIT_LLIST_HEAD(&elem->u.siblings);
22
23 return elem;
24}
25
26
27struct osim_decoded_element *
28element_alloc(struct osim_decoded_data *dd, const char *name,
29 enum osim_element_type type, enum osim_element_repr repr)
30{
31 struct osim_decoded_element *elem;
32
33 elem = __element_alloc(dd, name, type, repr);
34 if (!elem)
35 return NULL;
36
37 llist_add_tail(&elem->list, &dd->decoded_elements);
38
39 return elem;
40}
41
42struct osim_decoded_element *
43element_alloc_sub(struct osim_decoded_element *ee, const char *name,
44 enum osim_element_type type, enum osim_element_repr repr)
45{
46 struct osim_decoded_element *elem;
47
48 elem = __element_alloc(ee, name, type, repr);
49 if (!elem)
50 return NULL;
51
52 llist_add(&elem->list, &ee->u.siblings);
53
54 return elem;
55}
56
57
58void add_filedesc(struct osim_file_desc *root, const struct osim_file_desc *in, int num)
59{
60 int i;
61
62 for (i = 0; i < num; i++) {
63 struct osim_file_desc *ofd = talloc_memdup(root, &in[i], sizeof(*in));
64 llist_add_tail(&ofd->list, &root->child_list);
65 }
66}
67
68struct osim_file_desc *alloc_df(void *ctx, uint16_t fid, const char *name)
69{
70 struct osim_file_desc *mf;
71
72 mf = talloc_zero(ctx, struct osim_file_desc);
73 mf->type = TYPE_DF;
74 mf->fid = fid;
75 mf->short_name = name;
76 INIT_LLIST_HEAD(&mf->child_list);
77
78 return mf;
79}
80
81struct osim_file_desc *
82add_df_with_ef(struct osim_file_desc *parent,
83 uint16_t fid, const char *name,
84 const struct osim_file_desc *in, int num)
85{
86 struct osim_file_desc *df;
87
88 df = alloc_df(parent, fid, name);
89 df->parent = parent;
90 llist_add_tail(&df->list, &parent->child_list);
91 add_filedesc(df, in, num);
92
93 return df;
94}
95
96struct osim_file_desc *
97add_adf_with_ef(struct osim_file_desc *parent,
98 const uint8_t *adf_name, uint8_t adf_name_len,
99 const char *name, const struct osim_file_desc *in,
100 int num)
101{
102 struct osim_file_desc *df;
103
104 df = alloc_df(parent, 0xffff, name);
105 df->type = TYPE_ADF;
106 df->df_name = adf_name;
107 df->df_name_len = adf_name_len;
108 df->parent = parent;
109 llist_add_tail(&df->list, &parent->child_list);
110 add_filedesc(df, in, num);
111
112 return df;
113}
114
115struct osim_file_desc *
116osim_file_find_name(struct osim_file_desc *parent, const char *name)
117{
118 struct osim_file_desc *ofd;
119 llist_for_each_entry(ofd, &parent->child_list, list) {
120 if (!strcmp(ofd->short_name, name)) {
121 return ofd;
122 }
123 }
124 return NULL;
125}
126
127
128
129struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
130 uint8_t p2, uint16_t lc, uint16_t le)
131{
132 struct osim_apdu_cmd_hdr *ch;
133 struct msgb *msg = msgb_alloc(lc+le+sizeof(*ch)+2, "APDU");
134 if (!msg)
135 return NULL;
136
137 ch = (struct osim_apdu_cmd_hdr *) msgb_put(msg, sizeof(*ch));
138 msg->l2h = (char *) ch;
139
140 ch->cla = cla;
141 ch->ins = ins;
142 ch->p1 = p1;
143 ch->p2 = p2;
144
145 msgb_apdu_lc(msg) = lc;
146 msgb_apdu_le(msg) = le;
147
148 if (lc == 0 && le == 0)
149 msgb_apdu_case(msg) = APDU_CASE_1;
150 else if (lc == 0 && le >= 1) {
151 if (le <= 256)
152 msgb_apdu_case(msg) = APDU_CASE_2;
153 else
154 msgb_apdu_case(msg) = APDU_CASE_2_EXT;
155 } else if (le == 0 && lc >= 1) {
156 if (lc <= 255)
157 msgb_apdu_case(msg) = APDU_CASE_3;
158 else
159 msgb_apdu_case(msg) = APDU_CASE_3_EXT;
160 } else if (lc >= 1 && le >= 1) {
161 if (lc <= 255 & le <= 256)
162 msgb_apdu_case(msg) = APDU_CASE_4;
163 else
164 msgb_apdu_case(msg) = APDU_CASE_4_EXT;
165 }
166
167 return msg;
168}
169
170
171
172