mirror of https://gerrit.osmocom.org/libosmocore
sim: add decoding of status words
This commit is contained in:
parent
43eabeeeaa
commit
7674960ffa
|
@ -218,7 +218,7 @@ struct osim_card_sw {
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OSIM_CARD_SW_LAST { \
|
#define OSIM_CARD_SW_LAST (const struct osim_card_sw) { \
|
||||||
.code = 0, .mask = 0, .type = SW_TYPE_NONE, \
|
.code = 0, .mask = 0, .type = SW_TYPE_NONE, \
|
||||||
.class = SW_CLS_NONE, .u.str = NULL \
|
.class = SW_CLS_NONE, .u.str = NULL \
|
||||||
}
|
}
|
||||||
|
@ -226,9 +226,15 @@ struct osim_card_sw {
|
||||||
struct osim_card_profile {
|
struct osim_card_profile {
|
||||||
const char *name;
|
const char *name;
|
||||||
struct osim_file_desc *mf;
|
struct osim_file_desc *mf;
|
||||||
struct osim_card_sw **sws;
|
const struct osim_card_sw **sws;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct osim_card_sw *osim_find_sw(const struct osim_card_profile *cp,
|
||||||
|
uint16_t sw);
|
||||||
|
|
||||||
|
struct osim_card_hdl;
|
||||||
|
char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in);
|
||||||
|
|
||||||
extern const struct tlv_definition ts102221_fcp_tlv_def;
|
extern const struct tlv_definition ts102221_fcp_tlv_def;
|
||||||
const struct value_string ts102221_fcp_vals[14];
|
const struct value_string ts102221_fcp_vals[14];
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <osmocom/core/talloc.h>
|
#include <osmocom/core/talloc.h>
|
||||||
#include <osmocom/sim/sim.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;
|
return NULL;
|
||||||
|
|
||||||
ch = (struct osim_apdu_cmd_hdr *) msgb_put(msg, sizeof(*ch));
|
ch = (struct osim_apdu_cmd_hdr *) msgb_put(msg, sizeof(*ch));
|
||||||
msg->l2h = (char *) ch;
|
msg->l2h = (uint8_t *) ch;
|
||||||
|
|
||||||
ch->cla = cla;
|
ch->cla = cla;
|
||||||
ch->ins = ins;
|
ch->ins = ins;
|
||||||
|
@ -219,7 +220,7 @@ struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
|
||||||
else
|
else
|
||||||
msgb_apdu_case(msg) = APDU_CASE_3E;
|
msgb_apdu_case(msg) = APDU_CASE_3E;
|
||||||
} else if (lc >= 1 && le >= 1) {
|
} else if (lc >= 1 && le >= 1) {
|
||||||
if (lc <= 255 & le <= 256)
|
if (lc <= 255 && le <= 256)
|
||||||
msgb_apdu_case(msg) = APDU_CASE_4S;
|
msgb_apdu_case(msg) = APDU_CASE_4S;
|
||||||
else
|
else
|
||||||
msgb_apdu_case(msg) = APDU_CASE_4E;
|
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;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -297,6 +297,7 @@ static int dump_file(struct osim_chan_hdl *chan, uint16_t fid)
|
||||||
printf("Unable to select file\n");
|
printf("Unable to select file\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
printf("SW: %s\n", osim_print_sw(chan->card, msgb_apdu_sw(msg)));
|
||||||
if (msgb_apdu_sw(msg) != 0x9000) {
|
if (msgb_apdu_sw(msg) != 0x9000) {
|
||||||
printf("status 0x%04x selecting file\n", msgb_apdu_sw(msg));
|
printf("status 0x%04x selecting file\n", msgb_apdu_sw(msg));
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -334,6 +335,7 @@ static int dump_file(struct osim_chan_hdl *chan, uint16_t fid)
|
||||||
rmsg = read_record_nr(chan, i+1, ffdd.rec_len);
|
rmsg = read_record_nr(chan, i+1, ffdd.rec_len);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
printf("SW: %s\n", osim_print_sw(chan->card, msgb_apdu_sw(msg)));
|
||||||
printf("Rec %03u: %s\n", i+1,
|
printf("Rec %03u: %s\n", i+1,
|
||||||
osmo_hexdump(msgb_apdu_de(rmsg), msgb_apdu_le(rmsg)));
|
osmo_hexdump(msgb_apdu_de(rmsg), msgb_apdu_le(rmsg)));
|
||||||
}
|
}
|
||||||
|
@ -390,6 +392,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
msg = select_file(chan, 0x6fc5);
|
msg = select_file(chan, 0x6fc5);
|
||||||
dump_fcp_template_msg(msg);
|
dump_fcp_template_msg(msg);
|
||||||
|
printf("SW: %s\n", osim_print_sw(chan->card, msgb_apdu_sw(msg)));
|
||||||
msgb_free(msg);
|
msgb_free(msg);
|
||||||
|
|
||||||
verify_pin(chan, 1, "1653");
|
verify_pin(chan, 1, "1653");
|
||||||
|
|
Loading…
Reference in New Issue