From d54c2ee8c51b41b7f7a5a469efd6bb391a0c2b75 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 17 Jan 2012 18:25:50 +0100 Subject: initial checkin of 'libosmosim' --- src/sim/core.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 src/sim/core.c (limited to 'src/sim/core.c') diff --git a/src/sim/core.c b/src/sim/core.c new file mode 100644 index 00000000..40a49cf2 --- /dev/null +++ b/src/sim/core.c @@ -0,0 +1,172 @@ +#include +#include + +#include +#include + +static struct osim_decoded_element * +__element_alloc(void *ctx, const char *name, enum osim_element_type type, + enum osim_element_repr repr) +{ + struct osim_decoded_element *elem; + + elem = talloc_zero(ctx, struct osim_decoded_element); + if (!elem) + return NULL; + elem->name = name; + elem->type = type; + elem->representation = repr; + + if (elem->type == ELEM_T_GROUP) + INIT_LLIST_HEAD(&elem->u.siblings); + + return elem; +} + + +struct osim_decoded_element * +element_alloc(struct osim_decoded_data *dd, const char *name, + enum osim_element_type type, enum osim_element_repr repr) +{ + struct osim_decoded_element *elem; + + elem = __element_alloc(dd, name, type, repr); + if (!elem) + return NULL; + + llist_add_tail(&elem->list, &dd->decoded_elements); + + return elem; +} + +struct osim_decoded_element * +element_alloc_sub(struct osim_decoded_element *ee, const char *name, + enum osim_element_type type, enum osim_element_repr repr) +{ + struct osim_decoded_element *elem; + + elem = __element_alloc(ee, name, type, repr); + if (!elem) + return NULL; + + llist_add(&elem->list, &ee->u.siblings); + + return elem; +} + + +void add_filedesc(struct osim_file_desc *root, const struct osim_file_desc *in, int num) +{ + int i; + + for (i = 0; i < num; i++) { + struct osim_file_desc *ofd = talloc_memdup(root, &in[i], sizeof(*in)); + llist_add_tail(&ofd->list, &root->child_list); + } +} + +struct osim_file_desc *alloc_df(void *ctx, uint16_t fid, const char *name) +{ + struct osim_file_desc *mf; + + mf = talloc_zero(ctx, struct osim_file_desc); + mf->type = TYPE_DF; + mf->fid = fid; + mf->short_name = name; + INIT_LLIST_HEAD(&mf->child_list); + + return mf; +} + +struct osim_file_desc * +add_df_with_ef(struct osim_file_desc *parent, + uint16_t fid, const char *name, + const struct osim_file_desc *in, int num) +{ + struct osim_file_desc *df; + + df = alloc_df(parent, fid, name); + df->parent = parent; + llist_add_tail(&df->list, &parent->child_list); + add_filedesc(df, in, num); + + return df; +} + +struct osim_file_desc * +add_adf_with_ef(struct osim_file_desc *parent, + const uint8_t *adf_name, uint8_t adf_name_len, + const char *name, const struct osim_file_desc *in, + int num) +{ + struct osim_file_desc *df; + + df = alloc_df(parent, 0xffff, name); + df->type = TYPE_ADF; + df->df_name = adf_name; + df->df_name_len = adf_name_len; + df->parent = parent; + llist_add_tail(&df->list, &parent->child_list); + add_filedesc(df, in, num); + + return df; +} + +struct osim_file_desc * +osim_file_find_name(struct osim_file_desc *parent, const char *name) +{ + struct osim_file_desc *ofd; + llist_for_each_entry(ofd, &parent->child_list, list) { + if (!strcmp(ofd->short_name, name)) { + return ofd; + } + } + return NULL; +} + + + +struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1, + uint8_t p2, uint16_t lc, uint16_t le) +{ + struct osim_apdu_cmd_hdr *ch; + struct msgb *msg = msgb_alloc(lc+le+sizeof(*ch)+2, "APDU"); + if (!msg) + return NULL; + + ch = (struct osim_apdu_cmd_hdr *) msgb_put(msg, sizeof(*ch)); + msg->l2h = (char *) ch; + + ch->cla = cla; + ch->ins = ins; + ch->p1 = p1; + ch->p2 = p2; + + msgb_apdu_lc(msg) = lc; + msgb_apdu_le(msg) = le; + + if (lc == 0 && le == 0) + msgb_apdu_case(msg) = APDU_CASE_1; + else if (lc == 0 && le >= 1) { + if (le <= 256) + msgb_apdu_case(msg) = APDU_CASE_2; + else + msgb_apdu_case(msg) = APDU_CASE_2_EXT; + } else if (le == 0 && lc >= 1) { + if (lc <= 255) + msgb_apdu_case(msg) = APDU_CASE_3; + else + msgb_apdu_case(msg) = APDU_CASE_3_EXT; + } else if (lc >= 1 && le >= 1) { + if (lc <= 255 & le <= 256) + msgb_apdu_case(msg) = APDU_CASE_4; + else + msgb_apdu_case(msg) = APDU_CASE_4_EXT; + } + + return msg; +} + + + + -- cgit v1.2.3