summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-09-19 20:55:54 +0200
committerHarald Welte <laforge@gnumonks.org>2014-10-26 19:09:23 +0100
commit7674960ffadd5d7cb1a58ecee77252fe19e1e86f (patch)
tree3f18d49d9cc6643a7cfb0547039ea10c4ff1918e /src
parent43eabeeeaa993b6628e0490fbf6b78f24cee4788 (diff)
sim: add decoding of status words
Diffstat (limited to 'src')
-rw-r--r--src/sim/core.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/src/sim/core.c b/src/sim/core.c
index cbbb9f81..bf682777 100644
--- a/src/sim/core.c
+++ b/src/sim/core.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <stdint.h>
+#include <string.h>
#include <osmocom/core/talloc.h>
#include <osmocom/sim/sim.h>
@@ -196,7 +197,7 @@ struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
return NULL;
ch = (struct osim_apdu_cmd_hdr *) msgb_put(msg, sizeof(*ch));
- msg->l2h = (char *) ch;
+ msg->l2h = (uint8_t *) ch;
ch->cla = cla;
ch->ins = ins;
@@ -219,7 +220,7 @@ struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
else
msgb_apdu_case(msg) = APDU_CASE_3E;
} else if (lc >= 1 && le >= 1) {
- if (lc <= 255 & le <= 256)
+ if (lc <= 255 && le <= 256)
msgb_apdu_case(msg) = APDU_CASE_4S;
else
msgb_apdu_case(msg) = APDU_CASE_4E;
@@ -227,3 +228,54 @@ struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
return msg;
}
+
+/* FIXME: do we want to mark this as __thread? */
+static char sw_print_buf[256];
+
+char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in)
+{
+ const struct osim_card_sw *csw;
+
+ if (!ch || !ch->prof)
+ goto ret_def;
+
+ csw = osim_find_sw(ch->prof, sw_in);
+ if (!csw)
+ goto ret_def;
+
+ switch (csw->type) {
+ case SW_TYPE_STR:
+ snprintf(sw_print_buf, sizeof(sw_print_buf),
+ "%04x (%s)", sw_in, csw->u.str);
+ break;
+ default:
+ goto ret_def;
+ }
+
+ sw_print_buf[sizeof(sw_print_buf)-1] = '\0';
+
+ return sw_print_buf;
+
+ret_def:
+ snprintf(sw_print_buf, sizeof(sw_print_buf),
+ "%04x (Unknown)", sw_in);
+ sw_print_buf[sizeof(sw_print_buf)-1] = '\0';
+
+ return sw_print_buf;
+}
+
+
+const struct osim_card_sw *osim_find_sw(const struct osim_card_profile *cp,
+ uint16_t sw_in)
+{
+ const struct osim_card_sw **sw_lists = cp->sws;
+ const struct osim_card_sw *sw_list, *sw;
+
+ for (sw_list = *sw_lists++; sw_list != NULL; sw = sw_list = *sw_lists++) {
+ for (sw = sw_list; sw->code != 0 && sw->mask != 0; sw++) {
+ if ((sw_in & sw->mask) == sw->code)
+ return sw;
+ }
+ }
+ return NULL;
+}