Change in ...osmo-sgsn[master]: Introduce FSM mm_state_iu_fsm

pespin gerrit-no-reply at lists.osmocom.org
Fri Aug 30 16:33:46 UTC 2019


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-sgsn/+/15354


Change subject: Introduce FSM mm_state_iu_fsm
......................................................................

Introduce FSM mm_state_iu_fsm

Implement TS 23.060 6.1.2 Mobility Management States (Iu mode) using
osmocom FSM and drop old implementation.
Most of the logic on each state is still kept in gprs_gmm.c, will be
inserted into the FSM later.

Change-Id: I4c9cf8c27194817c56e8949af0205e1cc14af317
---
M include/osmocom/sgsn/Makefile.am
M include/osmocom/sgsn/gprs_gmm.h
A include/osmocom/sgsn/gprs_mm_state_iu_fsm.h
M include/osmocom/sgsn/gprs_sgsn.h
M src/gprs/Makefile.am
M src/gprs/gprs_gmm.c
A src/gprs/gprs_mm_state_iu_fsm.c
M src/gprs/gprs_ranap.c
M src/gprs/gprs_sgsn.c
M tests/sgsn/Makefile.am
10 files changed, 165 insertions(+), 65 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/54/15354/1

diff --git a/include/osmocom/sgsn/Makefile.am b/include/osmocom/sgsn/Makefile.am
index d6ee445..0ab00fe 100644
--- a/include/osmocom/sgsn/Makefile.am
+++ b/include/osmocom/sgsn/Makefile.am
@@ -8,6 +8,7 @@
 	gprs_gmm.h \
 	gprs_gmm_attach.h \
 	gprs_mm_state_gb_fsm.h \
+	gprs_mm_state_iu_fsm.h \
 	gprs_llc.h \
 	gprs_llc_xid.h \
 	gprs_ranap.h \
diff --git a/include/osmocom/sgsn/gprs_gmm.h b/include/osmocom/sgsn/gprs_gmm.h
index 2fa12e5..982cd93 100644
--- a/include/osmocom/sgsn/gprs_gmm.h
+++ b/include/osmocom/sgsn/gprs_gmm.h
@@ -49,7 +49,5 @@
 
 void pdp_ctx_detach_mm_ctx(struct sgsn_pdp_ctx *pdp);
 
-void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_mm_state_iu state);
-
 void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg);
 #endif /* _GPRS_GMM_H */
diff --git a/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h b/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h
new file mode 100644
index 0000000..7f02bcc
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <osmocom/core/fsm.h>
+
+struct sgsn_mm_ctx;
+
+
+/* TS 23.060 6.1.1 Mobility Management States (A/Gb mode) */
+enum mm_state_iu_fsm_states {
+	ST_PMM_DETACHED,
+	ST_PMM_CONNECTED,
+	ST_PMM_IDLE
+};
+
+enum mm_state_iu_fsm_events {
+	E_PMM_PS_ATTACH,
+	/* E_PS_DETACH, TODO: not used */
+	E_PMM_PS_CONN_RELEASE,
+	E_PMM_PS_CONN_ESTABLISH,
+	E_PMM_IMPLICIT_DETACH, /* = E_PS_ATTACH_REJECT, E_RAU_REJECT */
+	E_PMM_RA_UPDATE, /* = Serving RNC relocation */
+};
+
+extern struct osmo_fsm mm_state_iu_fsm;
diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h
index 382019c..8f16c5b 100644
--- a/include/osmocom/sgsn/gprs_sgsn.h
+++ b/include/osmocom/sgsn/gprs_sgsn.h
@@ -32,13 +32,6 @@
 	GMM_DEREGISTERED_INIT,		/* 4.1.3.3.1.4 */
 };
 
-/* TS 23.060 6.1.2 Mobility Management States (Iu mode) */
-enum gprs_mm_state_iu {
-	PMM_DETACHED,
-	PMM_CONNECTED,
-	PMM_IDLE
-};
-
 enum gprs_mm_ctr {
 	GMM_CTR_PKTS_SIG_IN,
 	GMM_CTR_PKTS_SIG_OUT,
@@ -171,7 +164,7 @@
 		struct ranap_ue_conn_ctx	*ue_ctx;
 		struct service_info	service;
 		/* TS 23.060 6.1.2 Mobility Management States (Iu mode) */
-		enum gprs_mm_state_iu	mm_state;
+		struct osmo_fsm_inst	*mm_state_fsm;
 	} iu;
 	struct {
 		struct osmo_fsm_inst *fsm;
diff --git a/src/gprs/Makefile.am b/src/gprs/Makefile.am
index 94861e2..05d5b4c 100644
--- a/src/gprs/Makefile.am
+++ b/src/gprs/Makefile.am
@@ -64,6 +64,7 @@
 	gprs_gmm_attach.c \
 	gprs_gmm.c \
 	gprs_mm_state_gb_fsm.c \
+	gprs_mm_state_iu_fsm.c \
 	gprs_ranap.c \
 	gprs_sgsn.c \
 	gprs_sndcp.c \
diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c
index 75d99fb..511cf1e 100644
--- a/src/gprs/gprs_gmm.c
+++ b/src/gprs/gprs_gmm.c
@@ -56,6 +56,7 @@
 #include <osmocom/sgsn/sgsn.h>
 #include <osmocom/sgsn/gprs_gmm_attach.h>
 #include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
 #include <osmocom/sgsn/signal.h>
 #include <osmocom/sgsn/gprs_sndcp.h>
 #include <osmocom/sgsn/gprs_ranap.h>
@@ -103,52 +104,6 @@
 	},
 };
 
-static const struct value_string gprs_mm_state_iu_names[] = {
-	OSMO_VALUE_STRING(PMM_DETACHED),
-	OSMO_VALUE_STRING(PMM_CONNECTED),
-	OSMO_VALUE_STRING(PMM_IDLE),
-	{ 0, NULL }
-};
-
-static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx)
-{
-	char buf[INET_ADDRSTRLEN];
-	struct sgsn_pdp_ctx *pdp;
-	llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) {
-		LOGMMCTXP(LOGL_INFO, mm_ctx, "Changing GTP-U endpoints %s -> %s\n",
-			  sgsn_gtp_ntoa(&pdp->lib->gsnlu),
-			  inet_ntop(AF_INET, &sgsn->cfg.gtp_listenaddr.sin_addr, buf, sizeof(buf)));
-		sgsn_pdp_upd_gtp_u(pdp,
-				   &sgsn->cfg.gtp_listenaddr.sin_addr,
-				   sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
-	}
-}
-
-void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_mm_state_iu state)
-{
-	OSMO_ASSERT(ctx->ran_type == MM_CTX_T_UTRAN_Iu);
-
-	if (ctx->iu.mm_state == state)
-		return;
-
-	LOGMMCTXP(LOGL_INFO, ctx, "Changing PMM state from %s to %s\n",
-		  get_value_string(gprs_mm_state_iu_names, ctx->iu.mm_state),
-		  get_value_string(gprs_mm_state_iu_names, state));
-
-	switch (state) {
-	case PMM_IDLE:
-		/* TODO: start RA Upd timer */
-		mmctx_change_gtpu_endpoints_to_sgsn(ctx);
-		break;
-	case PMM_CONNECTED:
-		break;
-	case PMM_DETACHED:
-		break;
-	}
-
-	ctx->iu.mm_state = state;
-}
-
 /* Our implementation, should be kept in SGSN */
 
 static void mmctx_timer_cb(void *_mm);
@@ -254,7 +209,7 @@
 
 	switch(ctx->ran_type) {
 	case MM_CTX_T_UTRAN_Iu:
-		mmctx_set_pmm_state(ctx, PMM_DETACHED);
+		osmo_fsm_inst_dispatch(ctx->iu.mm_state_fsm, E_PMM_IMPLICIT_DETACH, NULL);
 		break;
 	case MM_CTX_T_GERAN_Gb:
 		osmo_fsm_inst_dispatch(ctx->gb.mm_state_fsm, E_MM_IMPLICIT_DETACH, NULL);
@@ -1013,7 +968,7 @@
 #ifdef BUILD_IU
 	case GSM48_MT_GMM_SERVICE_REQ:
 		ctx->pending_req = 0;
-		mmctx_set_pmm_state(ctx, PMM_CONNECTED);
+		osmo_fsm_inst_dispatch(ctx->iu.mm_state_fsm, E_PMM_PS_ATTACH, NULL);
 		rc = gsm48_tx_gmm_service_ack(ctx);
 
 		if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING)
@@ -2004,7 +1959,7 @@
 		mmctx->gmm_state = GMM_REGISTERED_NORMAL;
 		switch(mmctx->ran_type) {
 		case MM_CTX_T_UTRAN_Iu:
-			mmctx_set_pmm_state(mmctx, PMM_CONNECTED);
+			osmo_fsm_inst_dispatch(mmctx->iu.mm_state_fsm, E_PMM_PS_ATTACH, NULL);
 			break;
 		case MM_CTX_T_GERAN_Gb:
 			/* Unassign the old TLLI */
@@ -2034,7 +1989,7 @@
 		mmctx->gmm_state = GMM_REGISTERED_NORMAL;
 		switch(mmctx->ran_type) {
 		case MM_CTX_T_UTRAN_Iu:
-			mmctx_set_pmm_state(mmctx, PMM_CONNECTED);
+			osmo_fsm_inst_dispatch(mmctx->iu.mm_state_fsm, E_PMM_RA_UPDATE, NULL);
 			break;
 		case MM_CTX_T_GERAN_Gb:
 			/* Unassign the old TLLI */
diff --git a/src/gprs/gprs_mm_state_iu_fsm.c b/src/gprs/gprs_mm_state_iu_fsm.c
new file mode 100644
index 0000000..1ed5f56
--- /dev/null
+++ b/src/gprs/gprs_mm_state_iu_fsm.c
@@ -0,0 +1,121 @@
+#include <arpa/inet.h>
+
+#include <osmocom/core/tdef.h>
+
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
+
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/sgsn.h>
+
+#define X(s) (1 << (s))
+
+static const struct osmo_tdef_state_timeout mm_state_iu_fsm_timeouts[32] = {
+	[ST_PMM_DETACHED] = { },
+	[ST_PMM_CONNECTED] = { },
+	[ST_PMM_IDLE] = { },
+};
+
+#define mm_state_iu_fsm_state_chg(fi, NEXT_STATE) \
+	osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, mm_state_iu_fsm_timeouts, sgsn->cfg.T_defs, -1)
+
+static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx)
+{
+	char buf[INET_ADDRSTRLEN];
+	struct sgsn_pdp_ctx *pdp;
+	llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) {
+		LOGMMCTXP(LOGL_INFO, mm_ctx, "Changing GTP-U endpoints %s -> %s\n",
+			  sgsn_gtp_ntoa(&pdp->lib->gsnlu),
+			  inet_ntop(AF_INET, &sgsn->cfg.gtp_listenaddr.sin_addr, buf, sizeof(buf)));
+		sgsn_pdp_upd_gtp_u(pdp,
+				   &sgsn->cfg.gtp_listenaddr.sin_addr,
+				   sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
+	}
+}
+
+static void st_pmm_detached(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	case E_PMM_PS_ATTACH:
+		mm_state_iu_fsm_state_chg(fi, ST_PMM_CONNECTED);
+		break;
+	case E_PMM_IMPLICIT_DETACH:
+		break;
+	}
+}
+
+static void st_pmm_connected(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	case E_PMM_PS_CONN_RELEASE:
+		mm_state_iu_fsm_state_chg(fi, ST_PMM_IDLE);
+		break;
+	case E_PMM_IMPLICIT_DETACH:
+		mm_state_iu_fsm_state_chg(fi, ST_PMM_DETACHED);
+		break;
+	case E_PMM_RA_UPDATE:
+		break;
+	}
+}
+
+static void st_pmm_idle_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+	struct sgsn_mm_ctx *ctx = fi->priv;
+
+	mmctx_change_gtpu_endpoints_to_sgsn(ctx);
+}
+
+static void st_pmm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	case E_PMM_PS_CONN_ESTABLISH:
+		mm_state_iu_fsm_state_chg(fi, ST_PMM_CONNECTED);
+		break;
+	case E_PMM_IMPLICIT_DETACH:
+		mm_state_iu_fsm_state_chg(fi, ST_PMM_DETACHED);
+		break;
+	}
+}
+
+static struct osmo_fsm_state mm_state_iu_fsm_states[] = {
+	[ST_PMM_DETACHED] = {
+		.in_event_mask = X(E_PMM_PS_ATTACH) | X(E_PMM_IMPLICIT_DETACH),
+		.out_state_mask = X(ST_PMM_CONNECTED),
+		.name = "Detached",
+		.action = st_pmm_detached,
+	},
+	[ST_PMM_CONNECTED] = {
+		.in_event_mask = X(E_PMM_PS_CONN_RELEASE) | X(E_PMM_RA_UPDATE) | X(E_PMM_IMPLICIT_DETACH),
+		.out_state_mask = X(ST_PMM_DETACHED) | X(ST_PMM_IDLE),
+		.name = "Connected",
+		.action = st_pmm_connected,
+	},
+	[ST_PMM_IDLE] = {
+		.in_event_mask = X(E_PMM_IMPLICIT_DETACH) | X(E_PMM_PS_CONN_ESTABLISH),
+		.out_state_mask = X(ST_PMM_DETACHED) | X(ST_PMM_CONNECTED),
+		.name = "Idle",
+		.onenter = st_pmm_idle_on_enter,
+		.action = st_pmm_idle,
+	},
+};
+
+const struct value_string mm_state_iu_fsm_event_names[] = {
+	OSMO_VALUE_STRING(E_PMM_PS_ATTACH),
+	OSMO_VALUE_STRING(E_PMM_PS_CONN_RELEASE),
+	OSMO_VALUE_STRING(E_PMM_PS_CONN_ESTABLISH),
+	OSMO_VALUE_STRING(E_PMM_IMPLICIT_DETACH),
+	OSMO_VALUE_STRING(E_PMM_RA_UPDATE),
+	{ 0, NULL }
+};
+
+struct osmo_fsm mm_state_iu_fsm = {
+	.name = "MM_STATE_Iu",
+	.states = mm_state_iu_fsm_states,
+	.num_states = ARRAY_SIZE(mm_state_iu_fsm_states),
+	.event_names = mm_state_iu_fsm_event_names,
+	.log_subsys = DMM,
+};
+
+static __attribute__((constructor)) void mm_state_iu_fsm_init(void)
+{
+	osmo_fsm_register(&mm_state_iu_fsm);
+}
diff --git a/src/gprs/gprs_ranap.c b/src/gprs/gprs_ranap.c
index 836937b..027b666 100644
--- a/src/gprs/gprs_ranap.c
+++ b/src/gprs/gprs_ranap.c
@@ -36,6 +36,7 @@
 #include <osmocom/sgsn/sgsn.h>
 #include <osmocom/sgsn/gprs_ranap.h>
 #include <osmocom/sgsn/gprs_gmm_attach.h>
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
 
 /* Send RAB activation requests for all PDP contexts */
 void activate_pdp_rabs(struct sgsn_mm_ctx *ctx)
@@ -134,12 +135,11 @@
 		/* fall thru */
 	case RANAP_IU_EVENT_LINK_INVALIDATED:
 		/* Clean up ranap_ue_conn_ctx here */
-		if (mm)
+		if (mm) {
 			LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
-		else
+			osmo_fsm_inst_dispatch(mm->iu.mm_state_fsm, E_PMM_PS_CONN_RELEASE, NULL);
+		} else
 			LOGIUP(ctx, LOGL_INFO, "IU release\n");
-		if (mm && mm->iu.mm_state == PMM_CONNECTED)
-			mmctx_set_pmm_state(mm, PMM_IDLE);
 		rc = 0;
 		break;
 	case RANAP_IU_EVENT_SECURITY_MODE_COMPLETE:
diff --git a/src/gprs/gprs_sgsn.c b/src/gprs/gprs_sgsn.c
index 82855a6..2334707 100644
--- a/src/gprs/gprs_sgsn.c
+++ b/src/gprs/gprs_sgsn.c
@@ -43,6 +43,7 @@
 #include <osmocom/sgsn/signal.h>
 #include <osmocom/sgsn/gprs_gmm_attach.h>
 #include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
 #include <osmocom/sgsn/gprs_llc.h>
 
 #include <pdp.h>
@@ -266,6 +267,7 @@
 struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx)
 {
 #if BUILD_IU
+	char buf[32];
 	struct sgsn_mm_ctx *ctx;
 	struct ranap_ue_conn_ctx *ue_ctx = uectx;
 
@@ -279,7 +281,9 @@
 	ctx->iu.ue_ctx = ue_ctx;
 	ctx->iu.ue_ctx->rab_assign_addr_enc = sgsn->cfg.iu.rab_assign_addr_enc;
 	ctx->iu.new_key = 1;
-	ctx->iu.mm_state = PMM_DETACHED;
+	snprintf(buf, sizeof(buf), "%" PRIu32, ue_ctx->conn_id);
+	ctx->iu.mm_state_fsm = osmo_fsm_inst_alloc(&mm_state_iu_fsm, ctx, ctx, LOGL_DEBUG, buf);
+
 
 	return ctx;
 #else
@@ -353,6 +357,8 @@
 		gmm_att_req_free(mm);
 	if (mm->gb.mm_state_fsm)
 		osmo_fsm_inst_free(mm->gb.mm_state_fsm);
+	if (mm->iu.mm_state_fsm)
+		osmo_fsm_inst_free(mm->iu.mm_state_fsm);
 
 	sgsn_mm_ctx_free(mm);
 	mm = NULL;
diff --git a/tests/sgsn/Makefile.am b/tests/sgsn/Makefile.am
index 8a26d88..47189e5 100644
--- a/tests/sgsn/Makefile.am
+++ b/tests/sgsn/Makefile.am
@@ -51,6 +51,7 @@
 	$(top_builddir)/src/gprs/gprs_gmm_attach.o \
 	$(top_builddir)/src/gprs/gprs_gmm.o \
 	$(top_builddir)/src/gprs/gprs_mm_state_gb_fsm.o \
+	$(top_builddir)/src/gprs/gprs_mm_state_iu_fsm.o \
 	$(top_builddir)/src/gprs/gprs_sgsn.o \
 	$(top_builddir)/src/gprs/sgsn_vty.o \
 	$(top_builddir)/src/gprs/sgsn_libgtp.o \

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-sgsn/+/15354
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Change-Id: I4c9cf8c27194817c56e8949af0205e1cc14af317
Gerrit-Change-Number: 15354
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190830/a4828d3c/attachment.html>


More information about the gerrit-log mailing list