Change in ...osmo-sgsn[master]: gprs/gprs_gmm: implement T3314. Timeout to reset MM state READY->STANDBY

pespin gerrit-no-reply at lists.osmocom.org
Wed Aug 21 09:07:45 UTC 2019


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

Change subject: gprs/gprs_gmm: implement T3314. Timeout to reset MM state READY->STANDBY
......................................................................

gprs/gprs_gmm: implement T3314. Timeout to reset MM state READY->STANDBY

When a MS MM state is READY its exact location is known (PCU).
On Gb, T3314 (aka TS 23.060 "READY timer") sets the MM state from
READY to STANDBY, where only the RA is known.

Introduce a second set of timer variables, because state timer
can run while another packet state timer is timing out.

Related: OS#1941
Change-Id: I4ce23ebe50d141076c20c9c56990b7103cd25e55
---
M include/osmocom/sgsn/gprs_sgsn.h
M src/gprs/gprs_gmm.c
M src/gprs/gprs_sgsn.c
M src/gprs/sgsn_vty.c
M tests/test_nodes.vty
5 files changed, 98 insertions(+), 2 deletions(-)

Approvals:
  Jenkins Builder: Verified
  osmith: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved



diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h
index 9753ea2..336155c 100644
--- a/include/osmocom/sgsn/gprs_sgsn.h
+++ b/include/osmocom/sgsn/gprs_sgsn.h
@@ -156,6 +156,10 @@
 		struct gprs_llc_llme	*llme;
 		uint32_t		tlli;
 		uint32_t		tlli_new;
+
+		/* timer for mm state. state=READY: T3314 (aka TS 23.060 "READY timer") */
+		struct osmo_timer_list  state_timer;
+		unsigned int		state_T;	/* Txxxx number but only used for pmm_states */
 	} gb;
 	struct {
 		int			new_key;
diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c
index db8defc..f7aff73 100644
--- a/src/gprs/gprs_gmm.c
+++ b/src/gprs/gprs_gmm.c
@@ -137,6 +137,57 @@
 	}
 }
 
+static void mmctx_set_mm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state);
+static void mmctx_state_timer_cb(void *_mm)
+{
+	struct sgsn_mm_ctx *mm = _mm;
+
+	switch (mm->gb.state_T) {
+	case 3314:
+		switch (mm->pmm_state) {
+		case MM_READY:
+			LOGMMCTXP(LOGL_INFO, mm, "T3314 expired\n");
+			mmctx_set_mm_state(mm, MM_STANDBY);
+			break;
+		default:
+			LOGMMCTXP(LOGL_ERROR, mm, "T3314 expired in state %s != MM_READY\n",
+				  get_value_string(gprs_pmm_state_names, mm->pmm_state));
+			break;
+		}
+		break;
+	default:
+		LOGMMCTXP(LOGL_ERROR, mm, "state timer expired in unknown mode %u\n",
+			mm->gb.state_T);
+		break;
+	}
+}
+
+static void mmctx_state_timer_start(struct sgsn_mm_ctx *mm, unsigned int T)
+{
+	unsigned long seconds;
+
+	if (mm->gb.state_T && mm->gb.state_T != T)
+		LOGMMCTXP(LOGL_ERROR, mm, "Attempting to start timer %u but %u is active!\n",
+			  T, mm->gb.state_T);
+
+	mm->gb.state_T = T;
+	mm->gb.state_timer.data = mm;
+	mm->gb.state_timer.cb = &mmctx_state_timer_cb;
+
+	seconds = osmo_tdef_get(sgsn->cfg.T_defs, T, OSMO_TDEF_S, -1);
+	osmo_timer_schedule(&mm->gb.state_timer, seconds, 0);
+}
+
+static void mmctx_state_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T)
+{
+	if (mm->gb.state_T == T)
+		osmo_timer_del(&mm->gb.state_timer);
+	else
+		LOGMMCTXP(LOGL_ERROR, mm, "Attempting to stop timer %u but %u is active!\n",
+			  T, mm->gb.state_T);
+	mm->gb.state_T = 0;
+}
+
 static void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state)
 {
 	OSMO_ASSERT(ctx->ran_type == MM_CTX_T_UTRAN_Iu);
@@ -173,6 +224,24 @@
 		  get_value_string(gprs_pmm_state_names, ctx->pmm_state),
 		  get_value_string(gprs_pmm_state_names, state));
 
+	switch (state) {
+	case MM_READY:
+		/* on expiration, T3314 moves mm state back to MM_STANDBY */
+		mmctx_state_timer_start(ctx, 3314);
+		break;
+	case MM_IDLE:
+		if (ctx->pmm_state == MM_READY)
+			mmctx_state_timer_stop(ctx, 3314);
+		break;
+	case MM_STANDBY:
+		if (ctx->pmm_state == MM_READY)
+			mmctx_state_timer_stop(ctx, 3314);
+		break;
+	default:
+		/* when changing to state != MM_READY */
+		break;
+	}
+
 	ctx->pmm_state = state;
 }
 
@@ -2968,6 +3037,21 @@
 	return rc;
 }
 
+/* Update the MM context state */
+static void gsm0408_gprs_notify_pdu_gb(struct sgsn_mm_ctx *mmctx)
+{
+	switch (mmctx->pmm_state) {
+	case MM_STANDBY:
+		mmctx_set_mm_state(mmctx, MM_READY);
+		break;
+	case MM_READY: /* RE-arm the timer upon receival of Gb PDUs */
+		mmctx_state_timer_start(mmctx, 3314);
+		break;
+	default:
+		break;
+	}
+}
+
 /* Main entry point for incoming 04.08 GPRS messages from Gb */
 int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
 			   bool drop_cipherable)
@@ -2988,6 +3072,9 @@
 
 	/* MMCTX can be NULL */
 
+	if (mmctx)
+		gsm0408_gprs_notify_pdu_gb(mmctx);
+
 	switch (pdisc) {
 	case GSM48_PDISC_MM_GPRS:
 		rc = gsm0408_rcv_gmm(mmctx, msg, llme, drop_cipherable);
diff --git a/src/gprs/gprs_sgsn.c b/src/gprs/gprs_sgsn.c
index eb04846..9f02d54 100644
--- a/src/gprs/gprs_sgsn.c
+++ b/src/gprs/gprs_sgsn.c
@@ -341,6 +341,11 @@
 		osmo_timer_del(&mm->timer);
 	}
 
+	if (osmo_timer_pending(&mm->gb.state_timer)) {
+		LOGMMCTXP(LOGL_INFO, mm, "Cancelling MM state timer %u\n", mm->gb.state_T);
+		osmo_timer_del(&mm->gb.state_timer);
+	}
+
 	memset(&sig_data, 0, sizeof(sig_data));
 	sig_data.mm = mm;
 	osmo_signal_dispatch(SS_SGSN, S_SGSN_MM_FREE, &sig_data);
diff --git a/src/gprs/sgsn_vty.c b/src/gprs/sgsn_vty.c
index ae26cbe..6698691 100644
--- a/src/gprs/sgsn_vty.c
+++ b/src/gprs/sgsn_vty.c
@@ -94,7 +94,7 @@
 static struct osmo_tdef sgsn_T_defs[] = {
 	{ .T=3312, .default_val=GSM0408_T3312_SECS, .desc="Periodic RA Update timer (s)" },
 	{ .T=3313, .default_val=GSM0408_T3313_SECS, .desc="Waiting for paging response timer (s)" },
-	{ .T=3314, .default_val=GSM0408_T3314_SECS, .desc="Force to STANDBY on expiry timer (s)" },
+	{ .T=3314, .default_val=GSM0408_T3314_SECS, .desc="READY timer. Force to STANDBY on expiry timer (s)" },
 	{ .T=3316, .default_val=GSM0408_T3316_SECS, .desc="AA-Ready timer (s)" },
 	{ .T=3322, .default_val=GSM0408_T3322_SECS, .desc="Detach request -> accept timer (s)" },
 	{ .T=3350, .default_val=GSM0408_T3350_SECS, .desc="Waiting for ATT/RAU/TMSI_COMPL timer (s)" },
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index 630094f..2ef926a 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -2,7 +2,7 @@
 OsmoSGSN# show timer
 T3312 = 600 s	Periodic RA Update timer (s) (default: 600 s)
 T3313 = 30 s	Waiting for paging response timer (s) (default: 30 s)
-T3314 = 44 s	Force to STANDBY on expiry timer (s) (default: 44 s)
+T3314 = 44 s	READY timer. Force to STANDBY on expiry timer (s) (default: 44 s)
 T3316 = 44 s	AA-Ready timer (s) (default: 44 s)
 T3322 = 6 s	Detach request -> accept timer (s) (default: 6 s)
 T3350 = 6 s	Waiting for ATT/RAU/TMSI_COMPL timer (s) (default: 6 s)

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

Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Change-Id: I4ce23ebe50d141076c20c9c56990b7103cd25e55
Gerrit-Change-Number: 12009
Gerrit-PatchSet: 4
Gerrit-Owner: laforge <laforge at gnumonks.org>
Gerrit-Assignee: lynxis lazus <lynxis at fe80.eu>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at gnumonks.org>
Gerrit-Reviewer: lynxis lazus <lynxis at fe80.eu>
Gerrit-Reviewer: osmith <osmith at sysmocom.de>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190821/290cabed/attachment.html>


More information about the gerrit-log mailing list