diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-09-12 12:12:31 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-09-18 13:21:16 +0200 |
commit | 2a5096dfc680f4dff3889607e47588f2e0080655 (patch) | |
tree | 21752239150c5f163a7eee71cb6665c38cbc4e29 /openbsc/src/gprs/gb_proxy.c | |
parent | 948c07f490f7be7be3d5b3a2efe3390af61bfafc (diff) |
gbproxy: Send DETACH_ACC if the IMSI has not been acquired
If IMSI acquisition is enabled and the gbproxy receives a Detach
request from the MS, it cannot pass it to the SGSN since the
acquisition has not yet been completed.
This patch implements the generation of a Detach Accept message and
for this case and updates the TLLI state accordingly.
Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/gprs/gb_proxy.c')
-rw-r--r-- | openbsc/src/gprs/gb_proxy.c | 66 |
1 files changed, 57 insertions, 9 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index 344e16448..ee8037565 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -110,6 +110,17 @@ static void gprs_put_identity_req(struct msgb *msg, uint8_t id_type) gh->data[0] = id_type; } +/* Transmit Chapter 9.4.6.2 Detach Accept (mobile originated detach) */ +static void gprs_put_mo_detach_acc(struct msgb *msg) +{ + struct gsm48_hdr *gh; + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); + gh->proto_discr = GSM48_PDISC_MM_GPRS; + gh->msg_type = GSM48_MT_GMM_DETACH_ACK; + gh->data[0] = 0; /* no force to standby */ +} + static void gprs_push_llc_ui(struct msgb *msg, int is_uplink, unsigned sapi, unsigned nu) { @@ -348,6 +359,21 @@ static void gbproxy_acquire_imsi(struct gbproxy_peer *peer, msgb_free(idreq_msg); } +static void gbproxy_tx_detach_acc(struct gbproxy_peer *peer, + struct gbproxy_tlli_info* tlli_info, + uint16_t bvci) +{ + struct msgb *detacc_msg; + + /* Send DETACH ACC */ + detacc_msg = gsm48_msgb_alloc(); + gprs_put_mo_detach_acc(detacc_msg); + gprs_push_llc_ui(detacc_msg, 0, GPRS_SAPI_GMM, + (tlli_info->imsi_acq_retries + 256) % 512); + gprs_push_bssgp_dl_unitdata(detacc_msg, tlli_info->tlli.current); + gbprox_relay2peer(detacc_msg, peer, bvci); + msgb_free(detacc_msg); +} /* Return != 0 iff msg still needs to be processed */ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer, @@ -365,16 +391,38 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer, if (!tlli_info->imsi_acq_pending && tlli_info->imsi_len > 0) return 1; - if (parse_ctx->g48_hdr && - parse_ctx->g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_REQ) - { - if (gbproxy_restart_imsi_acquisition(tlli_info)) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI acquisition was in progress " - "when receiving an ATTACH_REQ.\n", - msgb_nsei(msg)); + if (parse_ctx->g48_hdr) + switch (parse_ctx->g48_hdr->msg_type) + { + case GSM48_MT_GMM_ATTACH_REQ: + if (gbproxy_restart_imsi_acquisition(tlli_info)) { + LOGP(DLLC, LOGL_INFO, + "NSEI=%d(BSS) IMSI acquisition was in progress " + "when receiving an ATTACH_REQ.\n", + msgb_nsei(msg)); + } + break; + case GSM48_MT_GMM_DETACH_REQ: + /* Nothing has been sent to the SGSN yet */ + if (tlli_info->imsi_acq_pending) { + LOGP(DLLC, LOGL_INFO, + "NSEI=%d(BSS) IMSI acquisition was in progress " + "when receiving a DETACH_REQ.\n", + msgb_nsei(msg)); + } + if (!parse_ctx->invalidate_tlli) { + LOGP(DLLC, LOGL_INFO, + "NSEI=%d(BSS) IMSI not yet acquired, " + "faking a DETACH_ACC.\n", + msgb_nsei(msg)); + gbproxy_tx_detach_acc(peer, tlli_info, msgb_bvci(msg)); + parse_ctx->invalidate_tlli = 1; + } + gbproxy_reset_imsi_acquisition(tlli_info); + gbproxy_update_tlli_state_after(peer, tlli_info, now, + parse_ctx); + return 0; } - } if (tlli_info->imsi_acq_pending && tlli_info->imsi_len > 0) { int is_ident_resp = |