aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Couzens <lynxis@fe80.eu>2019-09-10 21:00:18 +0200
committerlynxis lazus <lynxis@fe80.eu>2019-10-03 20:29:37 +0000
commiteb5aee580d01d9f0f30c1190697f8499ce1f070a (patch)
treeed6512105799d6cfe46a2b365f65aa128471d45f
parente30f19542bcfa3493dc428a638580f34c773081b (diff)
gprs_ranap: release Iu UE Context when exiting PMM Connected
PMM Connected defines a Iu signaling connection. The 2 other PMM states do not have an active Iu signaling connection. Change-Id: Ie05d2bdf8dfb593b4c7e837107a3a06f22e90119
-rw-r--r--include/osmocom/sgsn/gprs_ranap.h13
-rw-r--r--src/sgsn/gprs_mm_state_iu_fsm.c5
-rw-r--r--src/sgsn/gprs_ranap.c36
3 files changed, 52 insertions, 2 deletions
diff --git a/include/osmocom/sgsn/gprs_ranap.h b/include/osmocom/sgsn/gprs_ranap.h
index b300130a..62fdf6f2 100644
--- a/include/osmocom/sgsn/gprs_ranap.h
+++ b/include/osmocom/sgsn/gprs_ranap.h
@@ -12,8 +12,19 @@ void activate_pdp_rabs(struct sgsn_mm_ctx *ctx);
int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type, void *data);
int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp);
+/* free the Iu UE context */
+void sgsn_ranap_iu_free(struct sgsn_mm_ctx *ctx);
+
+/* send a Iu Release Command and free afterwards the UE context */
+void sgsn_ranap_iu_release_free(struct sgsn_mm_ctx *ctx,
+ const struct RANAP_Cause *cause);
+
int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, uint16_t *sai);
-#endif
+
+#else /* ifndef BUILD_IU */
+inline static void sgsn_ranap_iu_free(void *ctx) {};
+inline static void sgsn_ranap_iu_release_free(void *ctx, void *cause) {};
+#endif /* BUILD_IU*/
struct ranap_ue_conn_ctx;
/* On RANAP, Returns pointer to he associated ranap_ue_conn_ctx in msg, filled
diff --git a/src/sgsn/gprs_mm_state_iu_fsm.c b/src/sgsn/gprs_mm_state_iu_fsm.c
index 1ed5f56f..b098f201 100644
--- a/src/sgsn/gprs_mm_state_iu_fsm.c
+++ b/src/sgsn/gprs_mm_state_iu_fsm.c
@@ -6,6 +6,7 @@
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_ranap.h>
#define X(s) (1 << (s))
@@ -45,11 +46,15 @@ static void st_pmm_detached(struct osmo_fsm_inst *fi, uint32_t event, void *data
static void st_pmm_connected(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+
switch(event) {
case E_PMM_PS_CONN_RELEASE:
+ sgsn_ranap_iu_free(ctx);
mm_state_iu_fsm_state_chg(fi, ST_PMM_IDLE);
break;
case E_PMM_IMPLICIT_DETACH:
+ sgsn_ranap_iu_release_free(ctx, NULL);
mm_state_iu_fsm_state_chg(fi, ST_PMM_DETACHED);
break;
case E_PMM_RA_UPDATE:
diff --git a/src/sgsn/gprs_ranap.c b/src/sgsn/gprs_ranap.c
index d2b34554..8f456504 100644
--- a/src/sgsn/gprs_ranap.c
+++ b/src/sgsn/gprs_ranap.c
@@ -119,6 +119,7 @@ int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type
mm = sgsn_mm_ctx_by_ue_ctx(ctx);
if (!mm) {
LOGIUP(ctx, LOGL_NOTICE, "Cannot find mm ctx for IU event %d\n", type);
+ ranap_iu_free_ue(ctx);
return rc;
}
@@ -131,7 +132,11 @@ int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type
case RANAP_IU_EVENT_LINK_INVALIDATED:
/* Clean up ranap_ue_conn_ctx here */
LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
- osmo_fsm_inst_dispatch(mm->iu.mm_state_fsm, E_PMM_PS_CONN_RELEASE, NULL);
+ if (mm->iu.mm_state_fsm->state == ST_PMM_CONNECTED)
+ osmo_fsm_inst_dispatch(mm->iu.mm_state_fsm, E_PMM_PS_CONN_RELEASE, NULL);
+ else
+ sgsn_ranap_iu_free(mm);
+
rc = 0;
break;
case RANAP_IU_EVENT_SECURITY_MODE_COMPLETE:
@@ -153,6 +158,35 @@ int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type
return rc;
}
+/* TODO: use timers */
+#define TIMEOUT_RANAP_RELEASE_SEC 5
+void sgsn_ranap_iu_free(struct sgsn_mm_ctx *ctx)
+{
+ if (!ctx)
+ return;
+
+ if (!ctx->iu.ue_ctx)
+ return;
+
+ ranap_iu_free_ue(ctx->iu.ue_ctx);
+ ctx->iu.ue_ctx = NULL;
+}
+
+void sgsn_ranap_iu_release_free(struct sgsn_mm_ctx *ctx,
+ const struct RANAP_Cause *cause)
+{
+ if (!ctx)
+ return;
+
+ if (!ctx->iu.ue_ctx)
+ return;
+
+ ranap_iu_tx_release_free(ctx->iu.ue_ctx,
+ cause,
+ TIMEOUT_RANAP_RELEASE_SEC);
+ ctx->iu.ue_ctx = NULL;
+}
+
int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp)
{
struct msgb *msg;