laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/simtrace2/+/42229?usp=email )
Change subject: WIP: make 6Cxx status codes in case 2/4 ambiguous situations work ......................................................................
WIP: make 6Cxx status codes in case 2/4 ambiguous situations work
Change-Id: I968608e73057e9f57d3a89aae485d1a278e503e4 --- M host/include/osmocom/simtrace2/simtrace2_api.h M host/src/simtrace2-cardem-pcsc.c 2 files changed, 30 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/simtrace2 refs/changes/29/42229/1
diff --git a/host/include/osmocom/simtrace2/simtrace2_api.h b/host/include/osmocom/simtrace2/simtrace2_api.h index a29389c..baa5ed7 100644 --- a/host/include/osmocom/simtrace2/simtrace2_api.h +++ b/host/include/osmocom/simtrace2/simtrace2_api.h @@ -37,6 +37,12 @@ struct osim_chan_hdl *chan; /* path of the underlying USB device */ char *usb_path; + struct { + /* did we just send a PB=0x6C and hence need to assume case2 on re-transmit? */ + bool last_pb_was_6c; + /* cache of the last APDU header */ + struct osim_apdu_cmd_hdr last_hdr; + } state; /* opaque data TBD by user */ void *priv; }; diff --git a/host/src/simtrace2-cardem-pcsc.c b/host/src/simtrace2-cardem-pcsc.c index f26698e..5d4940d 100644 --- a/host/src/simtrace2-cardem-pcsc.c +++ b/host/src/simtrace2-cardem-pcsc.c @@ -178,6 +178,18 @@ exit(1); }
+ if (data->flags & CEMU_DATA_F_TPDU_HDR && ci->state.last_pb_was_6c) { + LOGCI(ci, LOGL_INFO, "==== last one was 6C\n"); + if (!memcmp(&ci->state.last_hdr, &ac.hdr, 4)) { + /* force case 2 treatment */ + LOGCI(ci, LOGL_INFO, "==== last one was 6C and hdr matches!\n"); + rc = APDU_ACT_TX_CAPDU_TO_CARD; + ac.lc.tot = 0; + } + LOGCI(ci, LOGL_INFO, "==== last_pb_was_6c => false\n"); + ci->state.last_pb_was_6c = false; + } + if (rc & APDU_ACT_TX_CAPDU_TO_CARD) { struct msgb *tmsg = msgb_alloc(1024, "TPDU"); struct osim_reader_hdl *rh = ci->chan->card->reader; @@ -193,12 +205,14 @@ } /* send to actual card */ tmsg->l3h = tmsg->tail; + LOGCI(ci, LOGL_INFO, "pcsc in: %s\n", msgb_hexdump(tmsg)); rc = rh->ops->transceive(rh, tmsg); if (rc < 0) { fprintf(stderr, "error during transceive: %d\n", rc); msgb_free(tmsg); return rc; } + LOGCI(ci, LOGL_INFO, "pcsc out: %s\n", msgb_hexdump(tmsg)); /* send via GSMTAP for wireshark tracing */ osmo_st2_gsmtap_send_apdu(GSMTAP_SIM_APDU, tmsg->data, msgb_length(tmsg));
@@ -208,6 +222,16 @@ if (msgb_l3len(tmsg)) osmo_st2_cardem_request_pb_and_tx(ci, ac.hdr.ins, tmsg->l3h, msgb_l3len(tmsg)); osmo_st2_cardem_request_sw_tx(ci, ac.sw); + /* update our state for proper handling of case2/4 distinction */ + if (ac.sw[0] == 0x6c) { + LOGCI(ci, LOGL_INFO, "==== last_pb_was_6c => true\n"); + ci->state.last_pb_was_6c = true; + } else { + if (ci->state.last_pb_was_6c) + LOGCI(ci, LOGL_INFO, "==== last_pb_was_6c => false\n"); + ci->state.last_pb_was_6c = false; + } + memcpy(&ci->state.last_hdr, &ac.hdr, sizeof(ci->state.last_hdr)); } else if (ac.lc.tot > ac.lc.cur) { osmo_st2_cardem_request_pb_and_rx(ci, ac.hdr.ins, ac.lc.tot - ac.lc.cur); }