<p>Harald Welte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/12009">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gprs/gprs_gmm: implement T3314. Timeout to reset MM state to STANDBY<br><br>When a MS MM state is READY the exakt location is known (PCU).<br>T3141 set the MM state to STANDBY, where only the RA is known.<br><br>Introduce a second set of timer variables, because state timer<br>can run while another packet state timer is timing out.<br><br>Change-Id: I4ce23ebe50d141076c20c9c56990b7103cd25e55<br>---<br>M include/osmocom/sgsn/gprs_sgsn.h<br>M src/gprs/gprs_gmm.c<br>M src/gprs/gprs_sgsn.c<br>3 files changed, 100 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/09/12009/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h</span><br><span>index cf78766..c9933e4 100644</span><br><span>--- a/include/osmocom/sgsn/gprs_sgsn.h</span><br><span>+++ b/include/osmocom/sgsn/gprs_sgsn.h</span><br><span>@@ -225,6 +225,10 @@</span><br><span>        unsigned int            T;              /* Txxxx number */</span><br><span>   unsigned int            num_T_exp;      /* number of consecutive T expirations */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* timer for pmm state */</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_timer_list  state_timer;</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned int            state_T;        /* Txxxx number but only used for pmm_states */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    enum gprs_t3350_mode    t3350_mode;</span><br><span>  uint8_t                 t3370_id_type;</span><br><span>       uint8_t                 pending_req;    /* the request's message type */</span><br><span>diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c</span><br><span>index cc6ea4a..53de36d 100644</span><br><span>--- a/src/gprs/gprs_gmm.c</span><br><span>+++ b/src/gprs/gprs_gmm.c</span><br><span>@@ -115,6 +115,12 @@</span><br><span> </span><br><span> static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void mmctx_state_timer_cb(void *_mm);</span><br><span style="color: hsl(120, 100%, 40%);">+static void mmctx_state_timer_start(struct sgsn_mm_ctx *mm, unsigned int T, int seconds);</span><br><span style="color: hsl(120, 100%, 40%);">+static void mmctx_state_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx)</span><br><span> {</span><br><span>     struct sgsn_pdp_ctx *pdp;</span><br><span>@@ -165,9 +171,79 @@</span><br><span>               get_value_string(gprs_pmm_state_names, ctx->pmm_state),</span><br><span>                   get_value_string(gprs_pmm_state_names, state));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ switch (state) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case MM_READY:</span><br><span style="color: hsl(120, 100%, 40%);">+                /* T3314 change state to MM_STANDBY */</span><br><span style="color: hsl(120, 100%, 40%);">+                mmctx_state_timer_start(ctx, 3314, sgsn->cfg.timers.T3314);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case MM_IDLE:</span><br><span style="color: hsl(120, 100%, 40%);">+         mmctx_state_timer_stop(ctx, 3314);</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case MM_STANDBY:</span><br><span style="color: hsl(120, 100%, 40%);">+              mmctx_state_timer_stop(ctx, 3314);</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              /* when changing to state != MM_READY */</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  ctx->pmm_state = state;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void mmctx_recv_pdu(struct sgsn_mm_ctx *ctx, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        msgid2mmctx(ctx, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ctx->ran_type != MM_CTX_T_GERAN_Gb)</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (ctx->pmm_state) {</span><br><span style="color: hsl(120, 100%, 40%);">+  case MM_STANDBY:</span><br><span style="color: hsl(120, 100%, 40%);">+              mmctx_set_mm_state(ctx, MM_READY);</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case MM_READY: /* the timer is started when switching to READY */</span><br><span style="color: hsl(120, 100%, 40%);">+             mmctx_state_timer_start(ctx, 3314, sgsn->cfg.timers.T3314);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void mmctx_state_timer_cb(void *_mm)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct sgsn_mm_ctx *mm = _mm;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (mm->ran_type != MM_CTX_T_GERAN_Gb)</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (mm->state_T) {</span><br><span style="color: hsl(120, 100%, 40%);">+     case 3314:</span><br><span style="color: hsl(120, 100%, 40%);">+            if (mm->pmm_state == MM_READY)</span><br><span style="color: hsl(120, 100%, 40%);">+                     mmctx_set_mm_state(mm, MM_STANDBY);</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGMMCTXP(LOGL_ERROR, mm, "state timer expired in unknown mode %u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                       mm->state_T);</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void mmctx_state_timer_start(struct sgsn_mm_ctx *mm, unsigned int T, int seconds)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   mm->state_T = T;</span><br><span style="color: hsl(120, 100%, 40%);">+   mm->state_timer.data = mm;</span><br><span style="color: hsl(120, 100%, 40%);">+ mm->state_timer.cb = &mmctx_state_timer_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_timer_schedule(&mm->state_timer, seconds, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void mmctx_state_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mm->state_T == T)</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_timer_del(&mm->state_timer);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifdef BUILD_IU</span><br><span> int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies);</span><br><span> int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type, void *data)</span><br><span>@@ -2895,6 +2971,21 @@</span><br><span>     return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Update the MM context, called also for other PDUs than MM PDU from Gb */</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm0408_gprs_notify_pdu_gb(struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct sgsn_mm_ctx *mmctx;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gprs_ra_id ra_id;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+      mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!mmctx) {</span><br><span style="color: hsl(120, 100%, 40%);">+         return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   mmctx_recv_pdu(mmctx, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Main entry point for incoming 04.08 GPRS messages from Gb */</span><br><span> int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,</span><br><span>                         bool drop_cipherable)</span><br><span>diff --git a/src/gprs/gprs_sgsn.c b/src/gprs/gprs_sgsn.c</span><br><span>index 01f039a..fe089e4 100644</span><br><span>--- a/src/gprs/gprs_sgsn.c</span><br><span>+++ b/src/gprs/gprs_sgsn.c</span><br><span>@@ -342,6 +342,11 @@</span><br><span>                 osmo_timer_del(&mm->timer);</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (osmo_timer_pending(&mm->state_timer)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGMMCTXP(LOGL_INFO, mm, "Cancelling MM timer %u\n", mm->state_T);</span><br><span style="color: hsl(120, 100%, 40%);">+               osmo_timer_del(&mm->state_timer);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  memset(&sig_data, 0, sizeof(sig_data));</span><br><span>  sig_data.mm = mm;</span><br><span>    osmo_signal_dispatch(SS_SGSN, S_SGSN_MM_FREE, &sig_data);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12009">change 12009</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/12009"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-sgsn </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I4ce23ebe50d141076c20c9c56990b7103cd25e55 </div>
<div style="display:none"> Gerrit-Change-Number: 12009 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: lynxis lazus <lynxis@fe80.eu> </div>