aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gb_proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/gprs/gb_proxy.c')
-rw-r--r--openbsc/src/gprs/gb_proxy.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 8b014eafc..fbac298e3 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -253,6 +253,22 @@ uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer,
return sgsn_tlli;
}
+/* Returns != 0 iff IMSI acquisition was in progress */
+int gbproxy_reset_imsi_acquisition(struct gbproxy_tlli_info* tlli_info)
+{
+ int in_progress = 0;
+ if (!tlli_info)
+ return 0;
+
+ if (tlli_info->imsi_acq_pending)
+ in_progress = 1;
+
+ gbproxy_tlli_info_discard_messages(tlli_info);
+ tlli_info->imsi_acq_pending = 0;
+
+ return in_progress;
+}
+
/* patch BSSGP message */
static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
struct msgb *msg,
@@ -315,10 +331,21 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
gbprox_update_current_raid(parse_ctx.bssgp_raid_enc, peer,
parse_ctx.llc_msg_name);
+ gprs_gb_log_parse_context(&parse_ctx, "BSSGP");
+
+ tlli_info = gbproxy_update_tlli_state_ul(peer, now, &parse_ctx);
+
if (parse_ctx.g48_hdr) {
switch (parse_ctx.g48_hdr->msg_type) {
case GSM48_MT_GMM_ATTACH_REQ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REQS]);
+ if (gbproxy_reset_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));
+ tlli_info->imsi_acq_retries += 1;
+ }
break;
default:
@@ -326,10 +353,6 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
}
}
- gprs_gb_log_parse_context(&parse_ctx, "BSSGP");
-
- tlli_info = gbproxy_update_tlli_state_ul(peer, now, &parse_ctx);
-
if (tlli_info && cfg->route_to_sgsn2 && gbproxy_check_tlli(peer, tlli_info)) {
sgsn_nsei = cfg->nsip_sgsn2_nsei;
send_msg_directly = 1;
@@ -415,8 +438,15 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
/* Send IDENT REQ */
idreq_msg = gsm48_msgb_alloc();
gprs_put_identity_req(idreq_msg, GSM_MI_TYPE_IMSI);
+ /* Workaround to avoid N(U) collisions and to enable a restart
+ * of the IMSI acquisition procedure. This will work unless the
+ * SGSN has an initial V(UT) within [256-32, 256+n_retries]
+ * (see GSM 04.64, 8.4.2).
+ * TODO: Check whether it is sensible to rely on this, it might
+ * be an issue when P-TMSI patching is _not_ enabled and the SGSN
+ * doesn't reset V(UT) after a detach. */
gprs_push_llc_ui(idreq_msg, 0, GPRS_SAPI_GMM,
- /* TODO: use a real N(U) */0);
+ (tlli_info->imsi_acq_retries + 256) % 512);
gprs_push_bssgp_dl_unitdata(idreq_msg, tlli_info->tlli.current);
gbprox_relay2peer(idreq_msg, peer, msgb_bvci(msg));
msgb_free(idreq_msg);