[PATCH] openbsc[master]: gprs/gprs_gmm: implement T3314. Timeout to reset MM state to...

lynxis lazus gerrit-no-reply at lists.osmocom.org
Tue Feb 7 15:48:14 UTC 2017


Review at  https://gerrit.osmocom.org/1762

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

When a MS MM state is READY the exakt location is known (PCU).
T3141 set the MM state 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.

Change-Id: I4ce23ebe50d141076c20c9c56990b7103cd25e55
---
M openbsc/include/openbsc/gprs_sgsn.h
M openbsc/src/gprs/gprs_gmm.c
M openbsc/src/gprs/gprs_sgsn.c
3 files changed, 100 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/62/1762/1

diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index 2cc5b0c..e7dcfad 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -208,6 +208,10 @@
 	unsigned int		T;		/* Txxxx number */
 	unsigned int		num_T_exp;	/* number of consecutive T expirations */
 
+	/* timer for pmm state */
+	struct osmo_timer_list  state_timer;
+	unsigned int		state_T;	/* Txxxx number but only used for pmm_states */
+
 	enum gprs_t3350_mode	t3350_mode;
 	uint8_t			t3370_id_type;
 	uint8_t			pending_req;	/* the request's message type */
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 1026474..5e12654 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -116,6 +116,12 @@
 
 static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx);
 
+static void mmctx_state_timer_cb(void *_mm);
+static void mmctx_state_timer_start(struct sgsn_mm_ctx *mm, unsigned int T, int seconds);
+static void mmctx_state_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T);
+
+static void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg);
+
 static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx)
 {
 	struct sgsn_pdp_ctx *pdp;
@@ -164,8 +170,78 @@
 		  get_value_string(gprs_pmm_state_names, ctx->pmm_state),
 		  get_value_string(gprs_pmm_state_names, state));
 
+	switch (state) {
+	case MM_READY:
+		/* T3314 change state to MM_STANDBY */
+		mmctx_state_timer_start(ctx, 3314, sgsn->cfg.timers.T3314);
+		break;
+	case MM_IDLE:
+		mmctx_state_timer_stop(ctx, 3314);
+		break;
+	case MM_STANDBY:
+		mmctx_state_timer_stop(ctx, 3314);
+		break;
+	default:
+		/* when changing to state != MM_READY */
+		break;
+	}
+
 	ctx->pmm_state = state;
 }
+
+void mmctx_recv_pdu(struct sgsn_mm_ctx *ctx, struct msgb *msg)
+{
+	msgid2mmctx(ctx, msg);
+
+	if (ctx->ran_type != MM_CTX_T_GERAN_Gb)
+		return;
+
+	switch (ctx->pmm_state) {
+	case MM_STANDBY:
+		mmctx_set_mm_state(ctx, MM_READY);
+		break;
+	case MM_READY: /* the timer is started when switching to READY */
+		mmctx_state_timer_start(ctx, 3314, sgsn->cfg.timers.T3314);
+		break;
+	default:
+		break;
+	}
+}
+
+static void mmctx_state_timer_cb(void *_mm)
+{
+	struct sgsn_mm_ctx *mm = _mm;
+
+	if (mm->ran_type != MM_CTX_T_GERAN_Gb)
+		return;
+
+	switch (mm->state_T) {
+	case 3314:
+		if (mm->pmm_state == MM_READY)
+			mmctx_set_mm_state(mm, MM_STANDBY);
+		break;
+	default:
+		LOGMMCTXP(LOGL_ERROR, mm, "state timer expired in unknown mode %u\n",
+			mm->state_T);
+		break;
+	}
+}
+
+static void mmctx_state_timer_start(struct sgsn_mm_ctx *mm, unsigned int T, int seconds)
+{
+	mm->state_T = T;
+	mm->state_timer.data = mm;
+	mm->state_timer.cb = &mmctx_state_timer_cb;
+
+	osmo_timer_schedule(&mm->state_timer, seconds, 0);
+}
+
+static void mmctx_state_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T)
+{
+	if (mm->state_T == T)
+		osmo_timer_del(&mm->state_timer);
+}
+
 
 #ifdef BUILD_IU
 int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies);
@@ -2659,6 +2735,21 @@
 	return rc;
 }
 
+/* Update the MM context, called also for other PDUs than MM PDU from Gb */
+void gsm0408_gprs_notify_pdu_gb(struct msgb *msg)
+{
+	struct sgsn_mm_ctx *mmctx;
+	struct gprs_ra_id ra_id;
+
+	bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
+	mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id);
+	if (!mmctx) {
+		return;
+	}
+
+	mmctx_recv_pdu(mmctx, msg);
+}
+
 /* 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)
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index 260e032..c3de671 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -314,6 +314,11 @@
 		osmo_timer_del(&mm->timer);
 	}
 
+	if (osmo_timer_pending(&mm->state_timer)) {
+		LOGMMCTXP(LOGL_INFO, mm, "Cancelling MM timer %u\n", mm->state_T);
+		osmo_timer_del(&mm->state_timer);
+	}
+
 	memset(&sig_data, 0, sizeof(sig_data));
 	sig_data.mm = mm;
 	osmo_signal_dispatch(SS_SGSN, S_SGSN_MM_FREE, &sig_data);

-- 
To view, visit https://gerrit.osmocom.org/1762
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4ce23ebe50d141076c20c9c56990b7103cd25e55
Gerrit-PatchSet: 1
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: lynxis lazus <lynxis at fe80.eu>


More information about the gerrit-log mailing list