From f8edc4550671dcf0339091f5218e8275be0d2502 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Thu, 4 Oct 2018 03:29:43 +0700 Subject: layer23/common: move SIM APDU caching from l1ctl.c L1CTL implementation (i.e. l1ctl.c) is not a good place for the SIM specific stuff. Let's move it to the proper place (i.e. sim.c). As a bonus, this change fixes a possible problem of loosing the cached APDUs if two or more L2&3 applications are using a single LAPDm connection. The APDU buffer is dedicated per MS now. Change-Id: I564c610e45aa3b630ca5d1ec6bc1cace0dc9c566 --- src/host/layer23/include/osmocom/bb/common/sim.h | 4 ++++ src/host/layer23/src/common/l1ctl.c | 16 --------------- src/host/layer23/src/common/sim.c | 25 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/host/layer23/include/osmocom/bb/common/sim.h b/src/host/layer23/include/osmocom/bb/common/sim.h index 95d2147c..8b1f830c 100644 --- a/src/host/layer23/include/osmocom/bb/common/sim.h +++ b/src/host/layer23/include/osmocom/bb/common/sim.h @@ -176,6 +176,10 @@ struct gsm_sim { uint8_t reset; uint8_t chv1_remain, chv2_remain; uint8_t unblk1_remain, unblk2_remain; + + /* APDU cache (used by GSMTAP) */ + uint8_t apdu_data[256 + 7]; + uint16_t apdu_len; }; struct sim_hdr { diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c index 6f4a6d8e..b3f73a81 100644 --- a/src/host/layer23/src/common/l1ctl.c +++ b/src/host/layer23/src/common/l1ctl.c @@ -50,9 +50,6 @@ extern struct gsmtap_inst *gsmtap_inst; -static int apdu_len = -1; -static uint8_t apdu_data[256 + 7]; - static struct msgb *osmo_l1_alloc(uint8_t msg_type) { struct l1ctl_hdr *l1h; @@ -620,12 +617,6 @@ int l1ctl_tx_sim_req(struct osmocom_ms *ms, uint8_t *data, uint16_t length) struct msgb *msg; uint8_t *dat; - if (length <= sizeof(apdu_data)) { - memcpy(apdu_data, data, length); - apdu_len = length; - } else - apdu_len = -1; - msg = osmo_l1_alloc(L1CTL_SIM_REQ); if (!msg) return -1; @@ -642,13 +633,6 @@ static int rx_l1_sim_conf(struct osmocom_ms *ms, struct msgb *msg) uint16_t len = msgb_l2len(msg); uint8_t *data = msg->data; - if (apdu_len > -1 && apdu_len + len <= sizeof(apdu_data)) { - memcpy(apdu_data + apdu_len, data, len); - apdu_len += len; - gsmtap_send_ex(gsmtap_inst, GSMTAP_TYPE_SIM, 0, 0, 0, 0, 0, 0, - 0, apdu_data, apdu_len); - } - LOGP(DL1C, LOGL_INFO, "SIM %s\n", osmo_hexdump(data, len)); sim_apdu_resp(ms, msg); diff --git a/src/host/layer23/src/common/sim.c b/src/host/layer23/src/common/sim.c index c2d6033c..7f5240dd 100644 --- a/src/host/layer23/src/common/sim.c +++ b/src/host/layer23/src/common/sim.c @@ -24,11 +24,15 @@ #include #include #include +#include +#include #include #include #include +extern struct gsmtap_inst *gsmtap_inst; + static int sim_process_job(struct osmocom_ms *ms); /* @@ -185,6 +189,16 @@ static int sim_apdu_send(struct osmocom_ms *ms, uint8_t *data, uint16_t length) LOGP(DSIM, LOGL_INFO, "sending APDU (class 0x%02x, ins 0x%02x)\n", data[0], data[1]); + /* Cache this APDU, so it can be sent to GSMTAP on response */ + if (length <= sizeof(ms->sim.apdu_data)) { + memcpy(ms->sim.apdu_data, data, length); + ms->sim.apdu_len = length; + } else { + LOGP(DSIM, LOGL_NOTICE, "Cannot cache SIM APDU " + "(len=%u), so it won't be sent to GSMTAP\n", length); + ms->sim.apdu_len = 0; + } + /* adding SAP client support * it makes more sense to do it here then in L1CTL */ if (ms->subscr.sim_type == GSM_SIM_TYPE_SAP) { @@ -861,6 +875,17 @@ int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg) struct gsm1111_response_mfdf_gsm *mfdf_gsm; int i; + /* If there is cached APDU */ + if (ms->sim.apdu_len) { + /* ... and APDU buffer has enough space, send it to GSMTAP */ + if ((ms->sim.apdu_len + length) <= sizeof(ms->sim.apdu_data)) { + memcpy(ms->sim.apdu_data + ms->sim.apdu_len, data, length); + ms->sim.apdu_len += length; + gsmtap_send_ex(gsmtap_inst, GSMTAP_TYPE_SIM, + 0, 0, 0, 0, 0, 0, 0, ms->sim.apdu_data, ms->sim.apdu_len); + } + } + /* ignore, if current job already gone */ if (!sim->job_msg) { LOGP(DSIM, LOGL_ERROR, "received APDU but no job, " -- cgit v1.2.3