aboutsummaryrefslogtreecommitdiffstats
path: root/src/sgsn/gprs_gmm.c
diff options
context:
space:
mode:
authorAlexander Couzens <lynxis@fe80.eu>2019-09-11 03:38:14 +0200
committerDaniel Willmann <dwillmann@sysmocom.de>2020-02-04 10:21:12 +0100
commit91a8bbd5db47bae83c4b63f58536eeae73738b4a (patch)
tree28a6e2823993427c8058dc8cd10c7ed0569f8ebf /src/sgsn/gprs_gmm.c
parentd999e54aa264254a66de425ccf7edcd68f8420f2 (diff)
gprs_gmm_fsm.c: Implement RAT change between 2g and 3g
Diffstat (limited to 'src/sgsn/gprs_gmm.c')
-rw-r--r--src/sgsn/gprs_gmm.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/sgsn/gprs_gmm.c b/src/sgsn/gprs_gmm.c
index c574dac5..03ff513b 100644
--- a/src/sgsn/gprs_gmm.c
+++ b/src/sgsn/gprs_gmm.c
@@ -1109,6 +1109,23 @@ static bool mmctx_did_rat_change(struct sgsn_mm_ctx *mmctx, struct msgb *msg)
return false;
}
+/* Notify the FSM of a RAT change */
+static void mmctx_handle_rat_change(struct sgsn_mm_ctx *mmctx, struct msgb *msg, struct gprs_llc_llme *llme)
+{
+ struct gmm_rat_change_data rat_chg = {
+ .llme = llme
+ };
+
+ rat_chg.new_ran_type = MSG_IU_UE_CTX(msg) ? MM_CTX_T_UTRAN_Iu : MM_CTX_T_GERAN_Gb;
+
+ if (rat_chg.new_ran_type != mmctx->ran_type)
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_RAT_CHANGE, (void *) &rat_chg);
+ else
+ LOGMMCTXP(LOGL_ERROR, mmctx, "RAT didn't change or not implemented (ran_type=%u, "
+ "msg_iu_ue_ctx=%p\n", mmctx->ran_type, MSG_IU_UE_CTX(msg));
+
+}
+
/* 3GPP TS 24.008 ยง 9.4.1 Attach request */
static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
struct gprs_llc_llme *llme)
@@ -1234,6 +1251,9 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
goto rejected;
}
+ if (mmctx_did_rat_change(ctx, msg))
+ mmctx_handle_rat_change(ctx, msg, llme);
+
if (ctx->ran_type == MM_CTX_T_GERAN_Gb) {
ctx->gb.tlli = msgb_tlli(msg);
ctx->gb.llme = llme;
@@ -1614,7 +1634,12 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
mmctx->p_tmsi, mmctx->p_tmsi_old,
mmctx->gb.tlli, mmctx->gb.tlli_new,
osmo_rai_name(&mmctx->ra));
- osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
+ /* A RAT change will trigger the common procedure
+ * below after handling the RAT change. Protect it
+ * here from being called twice */
+ if (!mmctx_did_rat_change(mmctx, msg))
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
+
}
} else if (!gprs_ra_id_equals(&mmctx->ra, &old_ra_id) ||
mmctx->gmm_fsm->state == ST_GMM_DEREGISTERED)
@@ -1646,6 +1671,11 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
goto rejected;
}
+ if (mmctx_did_rat_change(mmctx, msg)) {
+ mmctx_handle_rat_change(mmctx, msg, llme);
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
+ }
+
/* Store new BVCI/NSEI in MM context (FIXME: delay until we ack?) */
msgid2mmctx(mmctx, msg);
/* Bump the statistics of received signalling msgs for this MM context */