diff options
author | Vadim Yanitskiy <axilirator@gmail.com> | 2018-10-04 03:29:43 +0700 |
---|---|---|
committer | Vadim Yanitskiy <axilirator@gmail.com> | 2018-10-27 05:49:45 +0700 |
commit | f8edc4550671dcf0339091f5218e8275be0d2502 (patch) | |
tree | 106507a1d14140040cc10707d6658bd5f7e8dde7 /src/host | |
parent | d464fe5388819f3c432797e229740277da478d7d (diff) |
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
Diffstat (limited to 'src/host')
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/sim.h | 4 | ||||
-rw-r--r-- | src/host/layer23/src/common/l1ctl.c | 16 | ||||
-rw-r--r-- | src/host/layer23/src/common/sim.c | 25 |
3 files changed, 29 insertions, 16 deletions
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 <arpa/inet.h> #include <osmocom/core/talloc.h> #include <osmocom/core/utils.h> +#include <osmocom/core/gsmtap_util.h> +#include <osmocom/core/gsmtap.h> #include <osmocom/bb/common/logging.h> #include <osmocom/bb/common/osmocom_data.h> #include <osmocom/bb/common/l1ctl.h> +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, " |