Change in ...osmo-sgsn[master]: Implement GMM State using osmocom FSM

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Fri Sep 6 19:07:02 UTC 2019


laforge has submitted this change and it was merged. ( https://gerrit.osmocom.org/c/osmo-sgsn/+/15385 )

Change subject: Implement GMM State using osmocom FSM
......................................................................

Implement GMM State using osmocom FSM

State machine inspired in the one from TS 24.008 4.1.3.3.1. Some state
transitions are inroduced in the code but are still commented out since
we lack some functionalitites or improvements in the code to handle
different scenarios.

Most of the logic is still outside of the FSM, but at least now the
states are handled in a sane way triggered by events.

Change-Id: Idecb43c10d66224d4f9ba9320825040ce6cf9a07
---
M include/osmocom/sgsn/Makefile.am
A include/osmocom/sgsn/gprs_gmm_fsm.h
M include/osmocom/sgsn/gprs_sgsn.h
M src/sgsn/Makefile.am
M src/sgsn/gprs_gmm.c
A src/sgsn/gprs_gmm_fsm.c
M src/sgsn/gprs_sgsn.c
M src/sgsn/sgsn_libgtp.c
M src/sgsn/sgsn_vty.c
M tests/sgsn/Makefile.am
M tests/sgsn/sgsn_test.c
11 files changed, 261 insertions(+), 53 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved



diff --git a/include/osmocom/sgsn/Makefile.am b/include/osmocom/sgsn/Makefile.am
index 0ab00fe..9ddc2bc 100644
--- a/include/osmocom/sgsn/Makefile.am
+++ b/include/osmocom/sgsn/Makefile.am
@@ -6,6 +6,7 @@
 	gprs_gb.h \
 	gprs_gb_parse.h \
 	gprs_gmm.h \
+	gprs_gmm_fsm.h \
 	gprs_gmm_attach.h \
 	gprs_mm_state_gb_fsm.h \
 	gprs_mm_state_iu_fsm.h \
diff --git a/include/osmocom/sgsn/gprs_gmm_fsm.h b/include/osmocom/sgsn/gprs_gmm_fsm.h
new file mode 100644
index 0000000..fd5b4bf
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_gmm_fsm.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <osmocom/core/fsm.h>
+
+/* 3GPP TS 24.008 § 4.1.3.3 GMM mobility management states on the network side */
+enum gmm_fsm_states {
+	ST_GMM_DEREGISTERED,		/* 4.1.3.3.1.1 */
+	ST_GMM_COMMON_PROC_INIT,	/* 4.1.3.3.1.2 */
+	ST_GMM_REGISTERED_NORMAL,	/* 4.1.3.3.2.1 */
+	ST_GMM_REGISTERED_SUSPENDED,	/* 4.1.3.3.2.2 */
+	ST_GMM_DEREGISTERED_INIT,	/* 4.1.3.3.1.4 */
+};
+
+enum gmm_fsm_events {
+	E_GMM_COMMON_PROC_INIT_REQ,
+	/* E_GMM_COMMON_PROC_FAILED, NOT USED */
+	/* E_GMM_LOWER_LAYER_FAILED, NOT USED */
+	E_GMM_COMMON_PROC_SUCCESS,
+	E_GMM_ATTACH_SUCCESS,
+	/* E_GMM_NET_INIT_DETACH_REQ, NOT USED */
+	/* E_GMM_MS_INIT_DETACH_REQ, NOT USED */
+	/* E_GMM_DETACH_ACCEPTED, */
+	E_GMM_SUSPEND,
+	E_GMM_RESUME,
+	E_GMM_CLEANUP,
+};
+
+static inline bool gmm_fsm_is_registered(struct osmo_fsm_inst *fi)
+{
+	return fi->state == ST_GMM_REGISTERED_NORMAL ||
+	       fi->state == ST_GMM_REGISTERED_SUSPENDED;
+}
+
+extern struct osmo_fsm gmm_fsm;
diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h
index 20e0e06..0a52a7d 100644
--- a/include/osmocom/sgsn/gprs_sgsn.h
+++ b/include/osmocom/sgsn/gprs_sgsn.h
@@ -23,15 +23,6 @@
 
 enum gsm48_gsm_cause;
 
-/* 3GPP TS 24.008 § 4.1.3.3 GMM mobility management states on the network side */
-enum gprs_gmm_state {
-	GMM_DEREGISTERED,		/* 4.1.3.3.1.1 */
-	GMM_COMMON_PROC_INIT,		/* 4.1.3.3.1.2 */
-	GMM_REGISTERED_NORMAL,		/* 4.1.3.3.2.1 */
-	GMM_REGISTERED_SUSPENDED,	/* 4.1.3.3.2.2 */
-	GMM_DEREGISTERED_INIT,		/* 4.1.3.3.1.4 */
-};
-
 enum gprs_mm_ctr {
 	GMM_CTR_PKTS_SIG_IN,
 	GMM_CTR_PKTS_SIG_OUT,
@@ -128,7 +119,7 @@
 	enum sgsn_ran_type	ran_type;
 
 	char 			imsi[GSM23003_IMSI_MAX_DIGITS+1];
-	enum gprs_gmm_state	gmm_state;
+	struct osmo_fsm_inst	*gmm_fsm;
 	uint32_t 		p_tmsi;
 	uint32_t 		p_tmsi_old;	/* old P-TMSI before new is confirmed */
 	uint32_t 		p_tmsi_sig;
diff --git a/src/sgsn/Makefile.am b/src/sgsn/Makefile.am
index a8da943..4402c9c 100644
--- a/src/sgsn/Makefile.am
+++ b/src/sgsn/Makefile.am
@@ -43,6 +43,7 @@
 	gprs_gb.c \
 	gprs_gmm_attach.c \
 	gprs_gmm.c \
+	gprs_gmm_fsm.c \
 	gprs_mm_state_gb_fsm.c \
 	gprs_mm_state_iu_fsm.c \
 	gprs_ranap.c \
diff --git a/src/sgsn/gprs_gmm.c b/src/sgsn/gprs_gmm.c
index 399f7bf..3317a09 100644
--- a/src/sgsn/gprs_gmm.c
+++ b/src/sgsn/gprs_gmm.c
@@ -57,6 +57,7 @@
 #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_gmm_fsm.h>
 #include <osmocom/sgsn/signal.h>
 #include <osmocom/sgsn/gprs_sndcp.h>
 #include <osmocom/sgsn/gprs_ranap.h>
@@ -211,7 +212,7 @@
 	LOGMMCTXP(LOGL_INFO, ctx, "Cleaning MM context due to %s\n", log_text);
 
 	/* Mark MM state as deregistered */
-	ctx->gmm_state = GMM_DEREGISTERED;
+	osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_CLEANUP, NULL);
 
 	switch(ctx->ran_type) {
 	case MM_CTX_T_UTRAN_Iu:
@@ -967,7 +968,7 @@
 		memset(&sig_data, 0, sizeof(sig_data));
 		sig_data.mm = mmctx;
 		osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data);
-		ctx->gmm_state = GMM_REGISTERED_NORMAL;
+		osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
 #endif
 
 		return gsm48_tx_gmm_att_ack(ctx);
@@ -1009,8 +1010,8 @@
 
 void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *ctx)
 {
-	switch (ctx->gmm_state) {
-	case GMM_COMMON_PROC_INIT:
+	switch (ctx->gmm_fsm->state) {
+	case ST_GMM_COMMON_PROC_INIT:
 		LOGMMCTXP(LOGL_NOTICE, ctx,
 		     "Authorized, continuing procedure, IMSI=%s\n",
 		     ctx->imsi);
@@ -1030,8 +1031,8 @@
 	if (gmm_cause == SGSN_ERROR_CAUSE_NONE)
 		gmm_cause = GMM_CAUSE_GPRS_NOTALLOWED;
 
-	switch (ctx->gmm_state) {
-	case GMM_COMMON_PROC_INIT:
+	switch (ctx->gmm_fsm->state) {
+	case ST_GMM_COMMON_PROC_INIT:
 		LOGMMCTXP(LOGL_NOTICE, ctx,
 			  "Not authorized, rejecting ATTACH REQUEST "
 			  "with cause '%s' (%d)\n",
@@ -1040,8 +1041,8 @@
 		if (ctx->gmm_att_req.fsm->state != ST_INIT)
 			osmo_fsm_inst_dispatch(ctx->gmm_att_req.fsm, E_REJECT, (void *) (long) gmm_cause);
 		break;
-	case GMM_REGISTERED_NORMAL:
-	case GMM_REGISTERED_SUSPENDED:
+	case ST_GMM_REGISTERED_NORMAL:
+	case ST_GMM_REGISTERED_SUSPENDED:
 		LOGMMCTXP(LOGL_NOTICE, ctx,
 			  "Authorization lost, detaching "
 			  "with cause '%s' (%d)\n",
@@ -1142,7 +1143,7 @@
 {
 	uint32_t ptmsi;
 	/* Don't change the P-TMSI if a P-TMSI re-assignment is under way */
-	if (ctx->gmm_state != GMM_COMMON_PROC_INIT) {
+	if (ctx->gmm_fsm->state != ST_GMM_COMMON_PROC_INIT) {
 		ptmsi = sgsn_alloc_ptmsi();
 		if (ptmsi != GSM_RESERVED_TMSI) {
 			ctx->p_tmsi_old = ctx->p_tmsi;
@@ -1150,7 +1151,7 @@
 		} else
 			LOGMMCTXP(LOGL_ERROR, ctx, "P-TMSI allocation failure: using old one.\n");
 	}
-	ctx->gmm_state = GMM_COMMON_PROC_INIT;
+	osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
 }
 
 /* 3GPP TS 24.008 § 9.4.1 Attach request */
@@ -1360,7 +1361,7 @@
 	mmctx->t3350_mode = GMM_T3350_MODE_NONE;
 	mmctx->p_tmsi_old = 0;
 	mmctx->pending_req = 0;
-	mmctx->gmm_state = GMM_REGISTERED_NORMAL;
+	osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
 	switch(mmctx->ran_type) {
 	case MM_CTX_T_UTRAN_Iu:
 		osmo_fsm_inst_dispatch(mmctx->iu.mm_state_fsm, E_PMM_PS_ATTACH, NULL);
@@ -1658,11 +1659,10 @@
 				mmctx->p_tmsi, mmctx->p_tmsi_old,
 				mmctx->gb.tlli, mmctx->gb.tlli_new,
 				osmo_rai_name(&mmctx->ra));
-
-			mmctx->gmm_state = GMM_COMMON_PROC_INIT;
+			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_state == GMM_DEREGISTERED)
+		mmctx->gmm_fsm->state == ST_GMM_DEREGISTERED)
 	{
 		/* We cannot use the mmctx */
 		LOGMMCTXP(LOGL_INFO, mmctx,
@@ -1715,7 +1715,7 @@
 	mmctx_timer_start(mmctx, 3350);
 #else
 	/* Make sure we are NORMAL (i.e. not SUSPENDED anymore) */
-	mmctx->gmm_state = GMM_REGISTERED_NORMAL;
+	osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
 
 	memset(&sig_data, 0, sizeof(sig_data));
 	sig_data.mm = mmctx;
@@ -1768,7 +1768,7 @@
 	mmctx->t3350_mode = GMM_T3350_MODE_NONE;
 	mmctx->p_tmsi_old = 0;
 	mmctx->pending_req = 0;
-	mmctx->gmm_state = GMM_REGISTERED_NORMAL;
+	osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_SUCCESS, NULL);
 	switch(mmctx->ran_type) {
 	case MM_CTX_T_UTRAN_Iu:
 		osmo_fsm_inst_dispatch(mmctx->iu.mm_state_fsm, E_PMM_RA_UPDATE, NULL);
@@ -1883,7 +1883,7 @@
 		goto rejected;
 	}
 
-	ctx->gmm_state = GMM_COMMON_PROC_INIT;
+	osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
 
 	ctx->iu.service.type = service_type;
 
@@ -2832,15 +2832,14 @@
 		return -EINVAL;
 	}
 
-	if (mmctx->gmm_state != GMM_REGISTERED_NORMAL &&
-	    mmctx->gmm_state != GMM_REGISTERED_SUSPENDED) {
+	if (!gmm_fsm_is_registered(mmctx->gmm_fsm)) {
 		LOGMMCTXP(LOGL_NOTICE, mmctx, "SUSPEND request while state "
 			"!= REGISTERED (TLLI=%08x)\n", tlli);
 		return -EINVAL;
 	}
 
 	/* Transition from REGISTERED_NORMAL to REGISTERED_SUSPENDED */
-	mmctx->gmm_state = GMM_REGISTERED_SUSPENDED;
+	osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_SUSPEND, NULL);
 	return 0;
 }
 
@@ -2858,8 +2857,7 @@
 		return -EINVAL;
 	}
 
-	if (mmctx->gmm_state != GMM_REGISTERED_NORMAL &&
-	    mmctx->gmm_state != GMM_REGISTERED_SUSPENDED) {
+	if (!gmm_fsm_is_registered(mmctx->gmm_fsm)) {
 		LOGMMCTXP(LOGL_NOTICE, mmctx, "RESUME request while state "
 			"!= SUSPENDED (TLLI=%08x)\n", tlli);
 		/* FIXME: should we not simply ignore it? */
@@ -2867,6 +2865,6 @@
 	}
 
 	/* Transition from SUSPENDED to NORMAL */
-	mmctx->gmm_state = GMM_REGISTERED_NORMAL;
+	osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_RESUME, NULL);
 	return 0;
 }
diff --git a/src/sgsn/gprs_gmm_fsm.c b/src/sgsn/gprs_gmm_fsm.c
new file mode 100644
index 0000000..fac06f2
--- /dev/null
+++ b/src/sgsn/gprs_gmm_fsm.c
@@ -0,0 +1,187 @@
+#include <osmocom/core/tdef.h>
+
+#include <osmocom/sgsn/gprs_gmm_fsm.h>
+
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/sgsn.h>
+
+#define X(s) (1 << (s))
+
+static const struct osmo_tdef_state_timeout gmm_fsm_timeouts[32] = {
+	[ST_GMM_DEREGISTERED] = { },
+	[ST_GMM_COMMON_PROC_INIT] = { },
+	[ST_GMM_REGISTERED_NORMAL] = { },
+	[ST_GMM_REGISTERED_SUSPENDED] = { },
+	[ST_GMM_DEREGISTERED_INIT] = { },
+};
+
+#define gmm_fsm_state_chg(fi, NEXT_STATE) \
+	osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, gmm_fsm_timeouts, sgsn->cfg.T_defs, -1)
+
+static void st_gmm_deregistered(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	case E_GMM_COMMON_PROC_INIT_REQ:
+		gmm_fsm_state_chg(fi, ST_GMM_COMMON_PROC_INIT);
+		break;
+	case E_GMM_ATTACH_SUCCESS:
+		gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_NORMAL);
+		break;
+	}
+}
+
+static void st_gmm_common_proc_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	/* TODO: events not used
+	case E_GMM_LOWER_LAYER_FAILED:
+	case E_GMM_COMMON_PROC_FAILED:
+		gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED);
+		break;
+	*/
+	case E_GMM_COMMON_PROC_SUCCESS:
+	case E_GMM_ATTACH_SUCCESS:
+		gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_NORMAL);
+		break;
+	}
+}
+
+static void st_gmm_registered_normal(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	case E_GMM_COMMON_PROC_INIT_REQ:
+		gmm_fsm_state_chg(fi, ST_GMM_COMMON_PROC_INIT);
+		break;
+	/* case E_GMM_NET_INIT_DETACH_REQ:
+		gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED_INIT);
+		break; */
+	/* case E_GMM_MS_INIT_DETACH_REQ:
+		gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED);
+		break; */
+	case E_GMM_SUSPEND:
+		gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_SUSPENDED);
+		break;
+	}
+}
+
+static void st_gmm_registered_suspended(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	case E_GMM_RESUME:
+		gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_NORMAL);
+		break;
+	}
+}
+
+static void st_gmm_deregistered_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	/* TODO: events not used in osmo-sgsn code
+	case E_GMM_DETACH_ACCEPTED:
+	case E_GMM_LOWER_LAYER_FAILED:
+		gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED);
+		break;
+	*/
+	}
+}
+
+static struct osmo_fsm_state gmm_fsm_states[] = {
+	[ST_GMM_DEREGISTERED] = {
+		.in_event_mask =
+			X(E_GMM_COMMON_PROC_INIT_REQ) |
+			X(E_GMM_ATTACH_SUCCESS),
+		.out_state_mask = X(ST_GMM_COMMON_PROC_INIT),
+		.name = "Deregistered",
+		.action = st_gmm_deregistered,
+	},
+	[ST_GMM_COMMON_PROC_INIT] = {
+		.in_event_mask =
+			/* X(E_GMM_LOWER_LAYER_FAILED) | */
+			/* X(E_GMM_COMMON_PROC_FAILED) | */
+			X(E_GMM_COMMON_PROC_SUCCESS) |
+			X(E_GMM_ATTACH_SUCCESS),
+		.out_state_mask =
+			X(ST_GMM_DEREGISTERED) |
+			X(ST_GMM_REGISTERED_NORMAL),
+		.name = "CommonProcedureInitiated",
+		.action = st_gmm_common_proc_init,
+	},
+	[ST_GMM_REGISTERED_NORMAL] = {
+		.in_event_mask =
+			X(E_GMM_COMMON_PROC_INIT_REQ) |
+			/* X(E_GMM_NET_INIT_DETACH_REQ) | */
+			/* X(E_GMM_MS_INIT_DETACH_REQ) | */
+			X(E_GMM_SUSPEND),
+		.out_state_mask =
+			X(ST_GMM_DEREGISTERED) |
+			X(ST_GMM_COMMON_PROC_INIT) |
+			X(ST_GMM_DEREGISTERED_INIT) |
+			X(ST_GMM_REGISTERED_SUSPENDED),
+		.name = "Registered.NORMAL",
+		.action = st_gmm_registered_normal,
+	},
+	[ST_GMM_REGISTERED_SUSPENDED] = {
+		.in_event_mask = X(E_GMM_RESUME),
+		.out_state_mask =
+			X(ST_GMM_DEREGISTERED) |
+			X(ST_GMM_REGISTERED_NORMAL),
+		.name = "Registered.SUSPENDED",
+		.action = st_gmm_registered_suspended,
+	},
+	[ST_GMM_DEREGISTERED_INIT] = {
+		.in_event_mask = 0
+			/* X(E_GMM_DETACH_ACCEPTED) | */
+			/* X(E_GMM_LOWER_LAYER_FAILED) */,
+		.out_state_mask = X(ST_GMM_DEREGISTERED),
+		.name = "DeregisteredInitiated",
+		.action = st_gmm_deregistered_init,
+	},
+};
+
+const struct value_string gmm_fsm_event_names[] = {
+	OSMO_VALUE_STRING(E_GMM_COMMON_PROC_INIT_REQ),
+	/* OSMO_VALUE_STRING(E_GMM_COMMON_PROC_FAILED), */
+	/*  OSMO_VALUE_STRING(E_GMM_LOWER_LAYER_FAILED),  */
+	OSMO_VALUE_STRING(E_GMM_COMMON_PROC_SUCCESS),
+	OSMO_VALUE_STRING(E_GMM_ATTACH_SUCCESS),
+	/*  OSMO_VALUE_STRING(E_GMM_NET_INIT_DETACH_REQ), */
+	/*  OSMO_VALUE_STRING(E_GMM_MS_INIT_DETACH_REQ), */
+	/* OSMO_VALUE_STRING(E_GMM_DETACH_ACCEPTED), */
+	OSMO_VALUE_STRING(E_GMM_SUSPEND),
+	OSMO_VALUE_STRING(E_GMM_CLEANUP),
+	{ 0, NULL }
+};
+
+void gmm_fsm_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) {
+	switch (event) {
+	case E_GMM_CLEANUP:
+		switch (fi->state) {
+		case ST_GMM_DEREGISTERED:
+			break;
+		default:
+			gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED);
+			break;
+		}
+	}
+}
+
+int gmm_fsm_timer_cb(struct osmo_fsm_inst *fi)
+{
+	return 0;
+}
+
+struct osmo_fsm gmm_fsm = {
+	.name = "GMM",
+	.states = gmm_fsm_states,
+	.num_states = ARRAY_SIZE(gmm_fsm_states),
+	.event_names = gmm_fsm_event_names,
+	.allstate_event_mask = X(E_GMM_CLEANUP),
+	.allstate_action = gmm_fsm_allstate_action,
+	.log_subsys = DMM,
+	.timer_cb = gmm_fsm_timer_cb,
+};
+
+static __attribute__((constructor)) void gmm_fsm_init(void)
+{
+	osmo_fsm_register(&gmm_fsm);
+}
diff --git a/src/sgsn/gprs_sgsn.c b/src/sgsn/gprs_sgsn.c
index 387c0d5..1c23d06 100644
--- a/src/sgsn/gprs_sgsn.c
+++ b/src/sgsn/gprs_sgsn.c
@@ -44,6 +44,7 @@
 #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_gmm_fsm.h>
 #include <osmocom/sgsn/gprs_llc.h>
 
 #include <pdp.h>
@@ -234,7 +235,6 @@
 	if (!ctx)
 		return NULL;
 
-	ctx->gmm_state = GMM_DEREGISTERED;
 	ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
 	ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, rate_ctr_id);
 	if (!ctx->ctrg) {
@@ -242,6 +242,7 @@
 		talloc_free(ctx);
 		return NULL;
 	}
+	ctx->gmm_fsm = osmo_fsm_inst_alloc(&gmm_fsm, ctx, ctx, LOGL_DEBUG, "gmm_fsm");
 	ctx->gmm_att_req.fsm = osmo_fsm_inst_alloc(&gmm_attach_req_fsm, ctx, ctx, LOGL_DEBUG, "gb_gmm_req");
 	INIT_LLIST_HEAD(&ctx->pdp_list);
 
@@ -368,6 +369,8 @@
 		osmo_fsm_inst_free(mm->gb.mm_state_fsm);
 	if (mm->iu.mm_state_fsm)
 		osmo_fsm_inst_free(mm->iu.mm_state_fsm);
+	if (mm->gmm_fsm)
+		osmo_fsm_inst_free(mm->gmm_fsm);
 
 	sgsn_mm_ctx_free(mm);
 	mm = NULL;
@@ -736,7 +739,7 @@
 {
 	/* the MM context can be deleted while the GGSN is not reachable or
 	 * if has been crashed. */
-	if (pctx->mm && pctx->mm->gmm_state == GMM_REGISTERED_NORMAL) {
+	if (pctx->mm && pctx->mm->gmm_fsm->state == ST_GMM_REGISTERED_NORMAL) {
 		gsm48_tx_gsm_deact_pdp_req(pctx, GSM_CAUSE_NET_FAIL, true);
 		sgsn_ggsn_ctx_remove_pdp(pctx->ggsn, pctx);
 	} else  {
diff --git a/src/sgsn/sgsn_libgtp.c b/src/sgsn/sgsn_libgtp.c
index 5e3f48f..f6d7a69 100644
--- a/src/sgsn/sgsn_libgtp.c
+++ b/src/sgsn/sgsn_libgtp.c
@@ -51,6 +51,7 @@
 #include <osmocom/sgsn/gprs_subscriber.h>
 #include <osmocom/sgsn/gprs_sndcp.h>
 #include <osmocom/sgsn/gprs_ranap.h>
+#include <osmocom/sgsn/gprs_gmm_fsm.h>
 
 #include <gtp.h>
 #include <pdp.h>
@@ -655,8 +656,8 @@
 	msgb_bvci(msg) = mm->gb.bvci;
 	msgb_nsei(msg) = mm->gb.nsei;
 
-	switch (mm->gmm_state) {
-	case GMM_REGISTERED_SUSPENDED:
+	switch (mm->gmm_fsm->state) {
+	case ST_GMM_REGISTERED_SUSPENDED:
 		/* initiate PS PAGING procedure */
 		memset(&pinfo, 0, sizeof(pinfo));
 		pinfo.mode = BSSGP_PAGING_PS;
@@ -670,11 +671,11 @@
 		rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PAGING_PS]);
 		/* FIXME: queue the packet we received from GTP */
 		break;
-	case GMM_REGISTERED_NORMAL:
+	case ST_GMM_REGISTERED_NORMAL:
 		break;
 	default:
 		LOGP(DGPRS, LOGL_ERROR, "GTP DATA IND for TLLI %08X in state "
-			"%u\n", mm->gb.tlli, mm->gmm_state);
+			"%s\n", mm->gb.tlli, osmo_fsm_inst_state_name(mm->gmm_fsm));
 		msgb_free(msg);
 		return -1;
 	}
diff --git a/src/sgsn/sgsn_vty.c b/src/sgsn/sgsn_vty.c
index 184ece7..9200822 100644
--- a/src/sgsn/sgsn_vty.c
+++ b/src/sgsn/sgsn_vty.c
@@ -476,15 +476,6 @@
 	return add_apn_ggsn_mapping(vty, argv[0], argv[1], atoi(argv[2]));
 }
 
-const struct value_string gprs_mm_st_strs[] = {
-	{ GMM_DEREGISTERED, "DEREGISTERED" },
-	{ GMM_COMMON_PROC_INIT, "COMMON PROCEDURE (INIT)" },
-	{ GMM_REGISTERED_NORMAL, "REGISTERED (NORMAL)" },
-	{ GMM_REGISTERED_SUSPENDED, "REGISTERED (SUSPENDED)" },
-	{ GMM_DEREGISTERED_INIT, "DEREGISTERED (INIT)" },
-	{ 0, NULL }
-};
-
 char *sgsn_gtp_ntoa(struct ul16_t *ul)
 {
 	struct in_addr ia;
@@ -546,7 +537,7 @@
 	vty_out(vty, "%s  MSISDN: %s, TLLI: %08x%s HLR: %s",
 		pfx, mm->msisdn, id, mm->hlr, VTY_NEWLINE);
 	vty_out(vty, "%s  GMM State: %s, Routeing Area: %s, Cell ID: %u%s",
-		pfx, get_value_string(gprs_mm_st_strs, mm->gmm_state),
+		pfx, osmo_fsm_inst_state_name(mm->gmm_fsm),
 		osmo_rai_name(&mm->ra), mm->gb.cell_id, VTY_NEWLINE);
 	vty_out(vty, "%s  MM State: %s, RAN Type: %s%s", pfx, mm_state_name,
 		get_value_string(sgsn_ran_type_names, mm->ran_type), VTY_NEWLINE);
diff --git a/tests/sgsn/Makefile.am b/tests/sgsn/Makefile.am
index 7ba70eb..9afe0f7 100644
--- a/tests/sgsn/Makefile.am
+++ b/tests/sgsn/Makefile.am
@@ -48,6 +48,7 @@
 	$(top_builddir)/src/sgsn/gprs_sndcp.o \
 	$(top_builddir)/src/sgsn/gprs_gmm_attach.o \
 	$(top_builddir)/src/sgsn/gprs_gmm.o \
+	$(top_builddir)/src/sgsn/gprs_gmm_fsm.o \
 	$(top_builddir)/src/sgsn/gprs_mm_state_gb_fsm.o \
 	$(top_builddir)/src/sgsn/gprs_mm_state_iu_fsm.o \
 	$(top_builddir)/src/sgsn/gprs_sgsn.o \
diff --git a/tests/sgsn/sgsn_test.c b/tests/sgsn/sgsn_test.c
index cc25d47..7399573 100644
--- a/tests/sgsn/sgsn_test.c
+++ b/tests/sgsn/sgsn_test.c
@@ -28,6 +28,7 @@
 #include <osmocom/gsupclient/gsup_client.h>
 #include <osmocom/sgsn/gprs_utils.h>
 #include <osmocom/sgsn/gprs_gb_parse.h>
+#include <osmocom/sgsn/gprs_gmm_fsm.h>
 
 #include <osmocom/gprs/gprs_bssgp.h>
 
@@ -192,7 +193,6 @@
 
 	lle = gprs_lle_get_or_create(tlli, 3);
 	ctx = sgsn_mm_ctx_alloc_gb(tlli, raid);
-	ctx->gmm_state = GMM_REGISTERED_NORMAL;
 	ctx->gb.llme = lle->llme;
 
 	ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
@@ -1286,7 +1286,7 @@
 
 	ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
 	OSMO_ASSERT(ctx != NULL);
-	OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
+	OSMO_ASSERT(ctx->gmm_fsm->state == ST_GMM_COMMON_PROC_INIT);
 
 	/* we expect an identity request (IMEI) */
 	OSMO_ASSERT(sgsn_tx_counter == 1);
@@ -1306,7 +1306,7 @@
 	 * authorization */
 	OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
 
-	OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
+	OSMO_ASSERT(ctx->gmm_fsm->state == ST_GMM_COMMON_PROC_INIT);
 
 	/* we expect an attach accept/reject */
 	OSMO_ASSERT(sgsn_tx_counter == 1);
@@ -1320,7 +1320,7 @@
 	send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
 			  attach_compl, ARRAY_SIZE(attach_compl));
 
-	OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
+	OSMO_ASSERT(ctx->gmm_fsm->state == ST_GMM_REGISTERED_NORMAL);
 
 	/* we don't expect a response */
 	OSMO_ASSERT(sgsn_tx_counter == 0);

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

Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Change-Id: Idecb43c10d66224d4f9ba9320825040ce6cf9a07
Gerrit-Change-Number: 15385
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at gnumonks.org>
Gerrit-Reviewer: lynxis lazus <lynxis at fe80.eu>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-CC: fixeria <axilirator at gmail.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190906/79c5cfdc/attachment.htm>


More information about the gerrit-log mailing list