<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/25104">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Move timer X2002 to tbf_fsm<br><br>Related: OS#2709<br>Change-Id: I94b71c60ed49d51ebdf6d6b428056b4b94354676<br>---<br>M src/bts.cpp<br>M src/gprs_rlcmac_sched.cpp<br>M src/pdch.cpp<br>M src/tbf.cpp<br>M src/tbf.h<br>M src/tbf_dl.cpp<br>M src/tbf_dl.h<br>M src/tbf_fsm.c<br>M src/tbf_fsm.h<br>M tests/tbf/TbfTest.cpp<br>M tests/tbf/TbfTest.err<br>11 files changed, 133 insertions(+), 86 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/04/25104/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/bts.cpp b/src/bts.cpp</span><br><span>index ee6b915..3cb2265 100644</span><br><span>--- a/src/bts.cpp</span><br><span>+++ b/src/bts.cpp</span><br><span>@@ -648,11 +648,7 @@</span><br><span>     }</span><br><span> </span><br><span>        LOGP(DRLCMAC, LOGL_DEBUG, "Got IMM.ASS confirm for TLLI=%08x\n", tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (dl_tbf->m_wait_confirm) {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Transition to FLOW in gprs_rlcmac_tbf::handle_timeout() when timer expires */</span><br><span style="color: hsl(0, 100%, 40%);">-                T_START(dl_tbf, T0, -2002, "assignment (AGCH)", true);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);</span><br><span> </span><br><span>  return 0;</span><br><span> }</span><br><span>diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp</span><br><span>index 18c0763..d73e55d 100644</span><br><span>--- a/src/gprs_rlcmac_sched.cpp</span><br><span>+++ b/src/gprs_rlcmac_sched.cpp</span><br><span>@@ -308,10 +308,6 @@</span><br><span>                && tbf->state_is_not(TBF_ST_FINISHED))</span><br><span>                   continue;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           /* waiting for CCCH IMM.ASS confirm */</span><br><span style="color: hsl(0, 100%, 40%);">-          if (tbf->m_wait_confirm)</span><br><span style="color: hsl(0, 100%, 40%);">-                     continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>            /* If a GPRS (CS1-4) Dl block is required, skip EGPRS(_GSMK) tbfs: */</span><br><span>                if (req_mcs_kind == GPRS && tbf->is_egprs_enabled())</span><br><span>                      continue;</span><br><span>diff --git a/src/pdch.cpp b/src/pdch.cpp</span><br><span>index 9477178..439759f 100644</span><br><span>--- a/src/pdch.cpp</span><br><span>+++ b/src/pdch.cpp</span><br><span>@@ -369,8 +369,6 @@</span><br><span>                         tbf_free(tbf);</span><br><span> </span><br><span>           osmo_fsm_inst_dispatch(new_tbf->state_fsm.fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                /* stop pending assignment timer */</span><br><span style="color: hsl(0, 100%, 40%);">-             new_tbf->t_stop(T0, "control acked (DL-TBF)");</span><br><span> </span><br><span>              tbf_assign_control_ts(new_tbf);</span><br><span>              return;</span><br><span>diff --git a/src/tbf.cpp b/src/tbf.cpp</span><br><span>index 74a44d9..5efbe7f 100644</span><br><span>--- a/src/tbf.cpp</span><br><span>+++ b/src/tbf.cpp</span><br><span>@@ -59,8 +59,6 @@</span><br><span> </span><br><span> unsigned int next_tbf_ctr_group_id = 0; /* Incrementing group id */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void tbf_timer_cb(void *_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> const struct value_string gprs_rlcmac_tbf_ul_ack_state_names[] = {</span><br><span>       OSMO_VALUE_STRING(GPRS_RLCMAC_UL_ACK_NONE),</span><br><span>  OSMO_VALUE_STRING(GPRS_RLCMAC_UL_ACK_SEND_ACK), /* send acknowledge on next RTS */</span><br><span>@@ -76,7 +74,6 @@</span><br><span> };</span><br><span> </span><br><span> static const struct value_string tbf_timers_names[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_VALUE_STRING(T0),</span><br><span>       OSMO_VALUE_STRING(T3141),</span><br><span>    OSMO_VALUE_STRING(T3191),</span><br><span>    OSMO_VALUE_STRING(T3193),</span><br><span>@@ -422,7 +419,6 @@</span><br><span>      if (t != T_MAX)</span><br><span>              return osmo_timer_pending(&Tarr[t]);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    /* we don't start with T0 because it's internal timer which requires special handling */</span><br><span>     for (i = T3141; i < T_MAX; i++)</span><br><span>           if (osmo_timer_pending(&Tarr[i]))</span><br><span>                        return true;</span><br><span>@@ -433,8 +429,7 @@</span><br><span> void gprs_rlcmac_tbf::stop_timers(const char *reason)</span><br><span> {</span><br><span>     uint8_t i;</span><br><span style="color: hsl(0, 100%, 40%);">-      /* we start with T0 because timer reset does not require any special handling */</span><br><span style="color: hsl(0, 100%, 40%);">-        for (i = T0; i < T_MAX; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = T3141; i < T_MAX; i++)</span><br><span>           t_stop((enum tbf_timers)i, reason);</span><br><span> }</span><br><span> </span><br><span>@@ -502,9 +497,6 @@</span><br><span>   Tarr[t].data = this;</span><br><span> </span><br><span>     switch(t) {</span><br><span style="color: hsl(0, 100%, 40%);">-     case T0:</span><br><span style="color: hsl(0, 100%, 40%);">-                Tarr[t].cb = tbf_timer_cb;</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span>       case T3141:</span><br><span>          Tarr[t].cb = cb_T3141;</span><br><span>               break;</span><br><span>@@ -594,7 +586,6 @@</span><br><span> </span><br><span> void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_fn, enum pdch_ulc_tbf_poll_reason reason)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      uint16_t pgroup;</span><br><span>     gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this);</span><br><span> </span><br><span>    LOGPTBF(this, LOGL_NOTICE, "poll timeout for FN=%d, TS=%d (curr FN %d)\n",</span><br><span>@@ -645,7 +636,8 @@</span><br><span>           /* Timeout waiting for CTRL ACK acking Pkt Cell Change Continue */</span><br><span>           osmo_fsm_inst_dispatch(m_ms->nacc->fi, NACC_EV_TIMEOUT_CELL_CHG_CONTINUE, NULL);</span><br><span>               return;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (direction == GPRS_RLCMAC_DL_TBF) {</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (reason == PDCH_ULC_POLL_DL_ACK) {</span><br><span style="color: hsl(120, 100%, 40%);">+          /* POLL Timeout expecting DL ACK/NACK: implies direction == GPRS_RLCMAC_DL_TBF */</span><br><span>            gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);</span><br><span> </span><br><span>            if (!(dl_tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {</span><br><span>@@ -669,16 +661,7 @@</span><br><span>                      return;</span><br><span>              }</span><br><span>            /* resend IMM.ASS on CCCH on timeout */</span><br><span style="color: hsl(0, 100%, 40%);">-         if ((dl_tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))</span><br><span style="color: hsl(0, 100%, 40%);">-          && !(dl_tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   LOGPTBF(dl_tbf, LOGL_DEBUG, "Re-send dowlink assignment on PCH (IMSI=%s)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                          imsi());</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* send immediate assignment */</span><br><span style="color: hsl(0, 100%, 40%);">-                 if ((pgroup = imsi2paging_group(imsi())) > 999)</span><br><span style="color: hsl(0, 100%, 40%);">-                              LOGPTBF(dl_tbf, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi());</span><br><span style="color: hsl(0, 100%, 40%);">-                   bts_snd_dl_ass(dl_tbf->bts, dl_tbf, pgroup);</span><br><span style="color: hsl(0, 100%, 40%);">-                 dl_tbf->m_wait_confirm = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_DL_ACKNACK_MISS, NULL);</span><br><span>         } else</span><br><span>               LOGPTBF(this, LOGL_ERROR, "Poll Timeout, but no event!\n");</span><br><span> }</span><br><span>@@ -729,48 +712,6 @@</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void tbf_timer_cb(void *_tbf)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf;</span><br><span style="color: hsl(0, 100%, 40%);">-   tbf->handle_timeout();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gprs_rlcmac_tbf::handle_timeout()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       int current_fn = bts_current_frame_number(bts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPTBF(this, LOGL_DEBUG, "timer 0 expired. cur_fn=%d\n", current_fn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Finish waiting after IMM.ASS confirm timer for CCCH assignment (see timer X2002) */</span><br><span style="color: hsl(0, 100%, 40%);">-  if ((state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {</span><br><span style="color: hsl(0, 100%, 40%);">-         gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);</span><br><span style="color: hsl(0, 100%, 40%);">-           dl_tbf->m_wait_confirm = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-          if (dl_tbf->state_is(TBF_ST_ASSIGN)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       tbf_assign_control_ts(dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                  if (!dl_tbf->upgrade_to_multislot) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         /* change state to FLOW, so scheduler</span><br><span style="color: hsl(0, 100%, 40%);">-                            * will start transmission */</span><br><span style="color: hsl(0, 100%, 40%);">-                           osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_READY_CCCH, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                                return;</span><br><span style="color: hsl(0, 100%, 40%);">-                 }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       /* This tbf can be upgraded to use multiple DL</span><br><span style="color: hsl(0, 100%, 40%);">-                   * timeslots and now that there is already one</span><br><span style="color: hsl(0, 100%, 40%);">-                   * slot assigned send another DL assignment via</span><br><span style="color: hsl(0, 100%, 40%);">-                  * PDCH. */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                     /* keep to flags */</span><br><span style="color: hsl(0, 100%, 40%);">-                     dl_tbf->state_fsm.state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       dl_tbf->update();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                    dl_tbf->trigger_ass(dl_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-         } else</span><br><span style="color: hsl(0, 100%, 40%);">-                  LOGPTBF(dl_tbf, LOGL_NOTICE, "Continue flow after IMM.ASS confirm\n");</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> int gprs_rlcmac_tbf::establish_dl_tbf_on_pacch()</span><br><span> {</span><br><span>  struct gprs_rlcmac_dl_tbf *new_tbf = NULL;</span><br><span>@@ -977,6 +918,16 @@</span><br><span>    return tbf->is_control_ts(ts);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+bool tbf_can_upgrade_to_multislot(const struct gprs_rlcmac_tbf *tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return tbf->upgrade_to_multislot;</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%);">+int tbf_update(struct gprs_rlcmac_tbf *tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return tbf->update();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> const char* tbf_rlcmac_diag(const struct gprs_rlcmac_tbf *tbf)</span><br><span> {</span><br><span>         static char buf[256];</span><br><span>diff --git a/src/tbf.h b/src/tbf.h</span><br><span>index 4218cf5..84c3d39 100644</span><br><span>--- a/src/tbf.h</span><br><span>+++ b/src/tbf.h</span><br><span>@@ -100,9 +100,6 @@</span><br><span> #define LOGPTBF(tbf, level, fmt, args...) LOGP(DTBF, level, "%s " fmt, tbf_name(tbf), ## args)</span><br><span> </span><br><span> enum tbf_timers {</span><br><span style="color: hsl(0, 100%, 40%);">-       /* internal assign/reject timer */</span><br><span style="color: hsl(0, 100%, 40%);">-      T0,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>  /* Wait contention resolution success on UL TBFs assigned over CCCH */</span><br><span>       T3141,</span><br><span> </span><br><span>@@ -164,6 +161,8 @@</span><br><span> void tbf_update_state_fsm_name(struct gprs_rlcmac_tbf *tbf);</span><br><span> const char* tbf_rlcmac_diag(const struct gprs_rlcmac_tbf *tbf);</span><br><span> bool tbf_is_control_ts(const struct gprs_rlcmac_tbf *tbf, uint8_t ts);</span><br><span style="color: hsl(120, 100%, 40%);">+bool tbf_can_upgrade_to_multislot(const struct gprs_rlcmac_tbf *tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+int tbf_update(struct gprs_rlcmac_tbf *tbf);</span><br><span> #ifdef __cplusplus</span><br><span> }</span><br><span> #endif</span><br><span>diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp</span><br><span>index 10492d9..bed7a08 100644</span><br><span>--- a/src/tbf_dl.cpp</span><br><span>+++ b/src/tbf_dl.cpp</span><br><span>@@ -191,7 +191,6 @@</span><br><span> gprs_rlcmac_dl_tbf::gprs_rlcmac_dl_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms) :</span><br><span>     gprs_rlcmac_tbf(bts_, ms, GPRS_RLCMAC_DL_TBF),</span><br><span>       m_tx_counter(0),</span><br><span style="color: hsl(0, 100%, 40%);">-        m_wait_confirm(0),</span><br><span>   m_dl_ack_requested(false),</span><br><span>   m_last_dl_poll_fn(-1),</span><br><span>       m_last_dl_drained_fn(-1),</span><br><span>@@ -622,7 +621,6 @@</span><br><span>              if ((pgroup = imsi2paging_group(imsi())) > 999)</span><br><span>                   LOGPTBFDL(this, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi());</span><br><span>                bts_snd_dl_ass(bts, this, pgroup);</span><br><span style="color: hsl(0, 100%, 40%);">-              m_wait_confirm = 1;</span><br><span>  }</span><br><span> }</span><br><span> </span><br><span>@@ -1170,7 +1168,6 @@</span><br><span> </span><br><span>       /* reset rlc states */</span><br><span>       m_tx_counter = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       m_wait_confirm = 0;</span><br><span>  m_window.reset();</span><br><span> </span><br><span>        osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_ASSIGN_DEL_CCCH, NULL);</span><br><span>@@ -1464,3 +1461,8 @@</span><br><span>         else</span><br><span>                 return NULL;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void tbf_dl_trigger_ass(struct gprs_rlcmac_dl_tbf *tbf, struct gprs_rlcmac_tbf *old_tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return tbf->trigger_ass(old_tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/tbf_dl.h b/src/tbf_dl.h</span><br><span>index 9719327..ad1469a 100644</span><br><span>--- a/src/tbf_dl.h</span><br><span>+++ b/src/tbf_dl.h</span><br><span>@@ -71,7 +71,6 @@</span><br><span>      * variables are in both (dl and ul) structs and not outside union.</span><br><span>   */</span><br><span>  int32_t m_tx_counter; /* count all transmitted blocks */</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t m_wait_confirm; /* wait for CCCH IMM.ASS cnf */</span><br><span>      bool m_dl_ack_requested;</span><br><span>     int32_t m_last_dl_poll_fn;</span><br><span>   int32_t m_last_dl_drained_fn;</span><br><span>@@ -153,6 +152,7 @@</span><br><span>            const uint8_t egprs_ms_class, const uint16_t delay_csec,</span><br><span>             const uint8_t *data, const uint16_t len);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void tbf_dl_trigger_ass(struct gprs_rlcmac_dl_tbf *tbf, struct gprs_rlcmac_tbf *old_tbf);</span><br><span> #ifdef __cplusplus</span><br><span> }</span><br><span> #endif</span><br><span>diff --git a/src/tbf_fsm.c b/src/tbf_fsm.c</span><br><span>index 0dbf04c..7d6d009 100644</span><br><span>--- a/src/tbf_fsm.c</span><br><span>+++ b/src/tbf_fsm.c</span><br><span>@@ -46,6 +46,8 @@</span><br><span>         { TBF_EV_ASSIGN_DEL_CCCH, "ASSIGN_DEL_CCCH" },</span><br><span>     { TBF_EV_ASSIGN_ACK_PACCH, "ASSIGN_ACK_PACCH" },</span><br><span>   { TBF_EV_ASSIGN_READY_CCCH, "ASSIGN_READY_CCCH" },</span><br><span style="color: hsl(120, 100%, 40%);">+  { TBF_EV_ASSIGN_PCUIF_CNF, "ASSIGN_PCUIF_CNF" },</span><br><span style="color: hsl(120, 100%, 40%);">+    { TBF_EV_DL_ACKNACK_MISS, "DL_ACKNACK_MISS" },</span><br><span>     { TBF_EV_LAST_DL_DATA_SENT, "LAST_DL_DATA_SENT" },</span><br><span>         { TBF_EV_LAST_UL_DATA_RECVD, "LAST_UL_DATA_RECVD" },</span><br><span>       { TBF_EV_FINAL_ACK_RECVD, "FINAL_ACK_RECVD" },</span><br><span>@@ -136,12 +138,17 @@</span><br><span>                     "Starting timer X2001 [assignment (PACCH)] with %u sec. %u microsec\n",</span><br><span>                    sec, micro);</span><br><span>                 osmo_timer_schedule(&fi->timer, sec, micro);</span><br><span style="color: hsl(120, 100%, 40%);">+   } else if (tbf_direction(ctx->tbf) == GPRS_RLCMAC_DL_TBF) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* GPRS_RLCMAC_FLAG_CCCH is set, so here we submitted an DL Ass through PCUIF on CCCH */</span><br><span>    }</span><br><span> }</span><br><span> </span><br><span> static void st_assign(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span> {</span><br><span>       struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned long val;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int sec, micro;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   switch (event) {</span><br><span>     case TBF_EV_ASSIGN_ADD_CCCH:</span><br><span>                 mod_ass_type(ctx, GPRS_RLCMAC_FLAG_CCCH, true);</span><br><span>@@ -160,6 +167,23 @@</span><br><span>               }</span><br><span>            tbf_fsm_state_chg(fi, TBF_ST_FLOW);</span><br><span>          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case TBF_EV_ASSIGN_PCUIF_CNF:</span><br><span style="color: hsl(120, 100%, 40%);">+         /* BTS informs us it sent Imm Ass for DL TBF over CCCH. We now</span><br><span style="color: hsl(120, 100%, 40%);">+                 * have to wait for X2002 to trigger (meaning MS is already</span><br><span style="color: hsl(120, 100%, 40%);">+            * listening on PDCH) in order to move to FLOW state and start</span><br><span style="color: hsl(120, 100%, 40%);">+                 * transmitting data to it. When X2002 triggers (see cb timer</span><br><span style="color: hsl(120, 100%, 40%);">+          * end of the file) it will send  TBF_EV_ASSIGN_READY_CCCH back</span><br><span style="color: hsl(120, 100%, 40%);">+                * to us here. */</span><br><span style="color: hsl(120, 100%, 40%);">+             OSMO_ASSERT(tbf_direction(ctx->tbf) == GPRS_RLCMAC_DL_TBF);</span><br><span style="color: hsl(120, 100%, 40%);">+                fi->T = -2002;</span><br><span style="color: hsl(120, 100%, 40%);">+             val = osmo_tdef_get(the_pcu->T_defs, fi->T, OSMO_TDEF_MS, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+          sec = val / 1000;</span><br><span style="color: hsl(120, 100%, 40%);">+             micro = (val % 1000) * 1000;</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGPTBF(ctx->tbf, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+                      "Starting timer X2002 [assignment (AGCH)] with %u sec. %u microsec\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      sec, micro);</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_timer_schedule(&fi->timer, sec, micro);</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</span><br><span>       case TBF_EV_ASSIGN_READY_CCCH:</span><br><span>               /* change state to FLOW, so scheduler will start transmission */</span><br><span>             tbf_fsm_state_chg(fi, TBF_ST_FLOW);</span><br><span>@@ -172,7 +196,28 @@</span><br><span> static void st_flow(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span> {</span><br><span>         struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case TBF_EV_DL_ACKNACK_MISS:</span><br><span style="color: hsl(120, 100%, 40%);">+          /* DL TBF: we missed a DL ACK/NACK. If we started assignment</span><br><span style="color: hsl(120, 100%, 40%);">+           * over CCCH and never received any DL ACK/NACK yet, it means we</span><br><span style="color: hsl(120, 100%, 40%);">+               * don't even know if the MS successfuly received the Imm Ass on</span><br><span style="color: hsl(120, 100%, 40%);">+           * CCCH and hence is listening on PDCH. Let's better refrain</span><br><span style="color: hsl(120, 100%, 40%);">+               * from continuing and start assignment on CCCH again */</span><br><span style="color: hsl(120, 100%, 40%);">+              if ((ctx->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))</span><br><span style="color: hsl(120, 100%, 40%);">+                 && !(ctx->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  struct GprsMs *ms = tbf_ms(ctx->tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+                      const char *imsi = ms_imsi(ms);</span><br><span style="color: hsl(120, 100%, 40%);">+                       uint16_t pgroup;</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOGPTBF(ctx->tbf, LOGL_DEBUG, "Re-send dowlink assignment on PCH (IMSI=%s)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                           imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+                        tbf_fsm_state_chg(fi, TBF_ST_ASSIGN);</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* send immediate assignment */</span><br><span style="color: hsl(120, 100%, 40%);">+                       if ((pgroup = imsi2paging_group(imsi)) > 999)</span><br><span style="color: hsl(120, 100%, 40%);">+                              LOGPTBF(ctx->tbf, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+                      bts_snd_dl_ass(ms->bts, ctx->tbf, pgroup);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span>       case TBF_EV_LAST_DL_DATA_SENT:</span><br><span>       case TBF_EV_LAST_UL_DATA_RECVD:</span><br><span>              /* All data has been sent or received, change state to FINISHED */</span><br><span>@@ -201,6 +246,8 @@</span><br><span> {</span><br><span>        struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv;</span><br><span>         switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case TBF_EV_DL_ACKNACK_MISS:</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span>       case TBF_EV_FINAL_ACK_RECVD:</span><br><span>                 /* We received Final Ack (DL ACK/NACK) from MS. move to</span><br><span>                 WAIT_RELEASE, we wait there for release or re-use the TBF in</span><br><span>@@ -267,10 +314,42 @@</span><br><span>       */</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void handle_timeout_X2002(struct tbf_fsm_ctx *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(ctx->tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ctx->fi->state == TBF_ST_ASSIGN) {</span><br><span style="color: hsl(120, 100%, 40%);">+          tbf_assign_control_ts(ctx->tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!tbf_can_upgrade_to_multislot(ctx->tbf)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* change state to FLOW, so scheduler</span><br><span style="color: hsl(120, 100%, 40%);">+                  * will start transmission */</span><br><span style="color: hsl(120, 100%, 40%);">+                 osmo_fsm_inst_dispatch(ctx->fi, TBF_EV_ASSIGN_READY_CCCH, NULL);</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%);">+           /* This tbf can be upgraded to use multiple DL</span><br><span style="color: hsl(120, 100%, 40%);">+                 * timeslots and now that there is already one</span><br><span style="color: hsl(120, 100%, 40%);">+                 * slot assigned send another DL assignment via</span><br><span style="color: hsl(120, 100%, 40%);">+                * PDCH. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* keep to flags */</span><br><span style="color: hsl(120, 100%, 40%);">+           ctx->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                tbf_update(ctx->tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            tbf_dl_trigger_ass(dl_tbf, ctx->tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+      } else</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGPTBF(ctx->tbf, LOGL_NOTICE, "Continue flow after IMM.ASS confirm\n");</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int tbf_fsm_timer_cb(struct osmo_fsm_inst *fi)</span><br><span> {</span><br><span>     struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv;</span><br><span>         switch (fi->T) {</span><br><span style="color: hsl(120, 100%, 40%);">+   case -2002:</span><br><span style="color: hsl(120, 100%, 40%);">+           handle_timeout_X2002(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span>       case -2001:</span><br><span>          LOGPTBF(ctx->tbf, LOGL_NOTICE, "releasing due to PACCH assignment timeout.\n");</span><br><span>                 /* fall-through */</span><br><span>@@ -301,6 +380,7 @@</span><br><span>                     X(TBF_EV_ASSIGN_ADD_CCCH) |</span><br><span>                  X(TBF_EV_ASSIGN_ADD_PACCH) |</span><br><span>                         X(TBF_EV_ASSIGN_ACK_PACCH) |</span><br><span style="color: hsl(120, 100%, 40%);">+                  X(TBF_EV_ASSIGN_PCUIF_CNF) |</span><br><span>                         X(TBF_EV_ASSIGN_READY_CCCH),</span><br><span>                 .out_state_mask =</span><br><span>                    X(TBF_ST_FLOW) |</span><br><span>@@ -312,6 +392,7 @@</span><br><span>       },</span><br><span>   [TBF_ST_FLOW] = {</span><br><span>            .in_event_mask =</span><br><span style="color: hsl(120, 100%, 40%);">+                      X(TBF_EV_DL_ACKNACK_MISS) |</span><br><span>                  X(TBF_EV_LAST_DL_DATA_SENT) |</span><br><span>                        X(TBF_EV_LAST_UL_DATA_RECVD) |</span><br><span>                       X(TBF_EV_FINAL_ACK_RECVD) |</span><br><span>@@ -326,6 +407,7 @@</span><br><span>    },</span><br><span>   [TBF_ST_FINISHED] = {</span><br><span>                .in_event_mask =</span><br><span style="color: hsl(120, 100%, 40%);">+                      X(TBF_EV_DL_ACKNACK_MISS) |</span><br><span>                  X(TBF_EV_FINAL_ACK_RECVD) |</span><br><span>                  X(TBF_EV_MAX_N3103) |</span><br><span>                        X(TBF_EV_MAX_N3105),</span><br><span>diff --git a/src/tbf_fsm.h b/src/tbf_fsm.h</span><br><span>index 9d2919d..2f63eef 100644</span><br><span>--- a/src/tbf_fsm.h</span><br><span>+++ b/src/tbf_fsm.h</span><br><span>@@ -32,6 +32,8 @@</span><br><span>    TBF_EV_ASSIGN_DEL_CCCH, /* An assignment previously sent over CCCH has been confirmed by MS */</span><br><span>       TBF_EV_ASSIGN_ACK_PACCH, /*  We received a CTRL ACK confirming assignment started on PACCH */</span><br><span>        TBF_EV_ASSIGN_READY_CCCH, /* TBF Start Time timer triggered */</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_EV_ASSIGN_PCUIF_CNF, /* Transmission of IMM.ASS for DL TBF to the MS confirmed by BTS over PCUIF */</span><br><span style="color: hsl(120, 100%, 40%);">+       TBF_EV_DL_ACKNACK_MISS, /* DL TBF: We polled for DL ACK/NACK but we received none (POLL timeout) */</span><br><span>  TBF_EV_LAST_DL_DATA_SENT, /* DL TBF sends RLCMAC block containing last DL avilable data buffered */</span><br><span>  TBF_EV_LAST_UL_DATA_RECVD, /* UL TBF sends RLCMAC block containing last UL data (cv=0) */</span><br><span>    TBF_EV_FINAL_ACK_RECVD, /* DL ACK/NACK with FINAL_ACK=1 received from MS */</span><br><span>diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp</span><br><span>index 1fcaead..19611a7 100644</span><br><span>--- a/tests/tbf/TbfTest.cpp</span><br><span>+++ b/tests/tbf/TbfTest.cpp</span><br><span>@@ -219,7 +219,6 @@</span><br><span>   osmo_fsm_inst_dispatch(dl_tbf->dl_ass_fsm.fi, TBF_DL_ASS_EV_SCHED_ASS, NULL);</span><br><span>     osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);</span><br><span>       osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- dl_tbf->m_wait_confirm = 0;</span><br><span>       check_tbf(dl_tbf);</span><br><span> </span><br><span>       *trx_no_ = trx_no;</span><br><span>@@ -591,9 +590,13 @@</span><br><span>    OSMO_ASSERT(ms_dl_tbf(ms) != NULL);</span><br><span> </span><br><span>      /* Here PCU would answer with data_cnf and trigger</span><br><span style="color: hsl(0, 100%, 40%);">-       * bts_rcv_imm_ass_cnf(), which would set up the timer X2002. In this</span><br><span style="color: hsl(0, 100%, 40%);">-    * test we go directly to T0 timeout to move it to FLOW state: */</span><br><span style="color: hsl(0, 100%, 40%);">-       ms_dl_tbf(ms)->handle_timeout();</span><br><span style="color: hsl(120, 100%, 40%);">+    * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF.</span><br><span style="color: hsl(120, 100%, 40%);">+         * That in turn would set up timer X2002. Finally, X2002 timeout</span><br><span style="color: hsl(120, 100%, 40%);">+       * moves it to FLOW state. We set X2002 timeout to 0 here to get</span><br><span style="color: hsl(120, 100%, 40%);">+       * immediate trigger through osmo_select_main() */</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_fsm_inst_dispatch(ms_dl_tbf(ms)->state_fsm.fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_select_main(0);</span><br><span>         OSMO_ASSERT(ms_dl_tbf(ms)->state_is(TBF_ST_FLOW));</span><br><span> </span><br><span>    /* Get first BSN */</span><br><span>diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err</span><br><span>index b66707a..e5664ef 100644</span><br><span>--- a/tests/tbf/TbfTest.err</span><br><span>+++ b/tests/tbf/TbfTest.err</span><br><span>@@ -1681,7 +1681,9 @@</span><br><span> TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) TX: START Immediate Assignment Downlink (PCH)</span><br><span>  - TRX=0 (0) TS=4 TA=0</span><br><span> TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) appending 19 bytes</span><br><span style="color: hsl(0, 100%, 40%);">-TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) timer 0 expired. cur_fn=2654167</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){ASSIGN}: Received Event ASSIGN_PCUIF_CNF</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Starting timer X2002 [assignment (AGCH)] with 0 sec. 0 microsec</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){ASSIGN}: Timeout of X2002</span><br><span> TBF(DL-TFI_0){ASSIGN}: Received Event ASSIGN_READY_CCCH</span><br><span> TBF(DL-TFI_0){ASSIGN}: state_chg to FLOW</span><br><span> TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) mcs_mode_restrict=EGPRS</span><br><span>@@ -2047,6 +2049,7 @@</span><br><span> TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) poll timeout for FN=2654292, TS=7 (curr FN 2654292)</span><br><span> TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) N3105 0 => 1 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FINISHED}: Received Event DL_ACKNACK_MISS</span><br><span> PDCH(bts=0,trx=0,ts=7) Received RTS for PDCH: FN=2654296 block_nr=2 scheduling USF=0 for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW), expect answer on UL FN=2654301</span><br><span> PDCH(bts=0,trx=0,ts=7) FN=2654296 Scheduling data message at RTS for DL TFI=0 prio=5 mcs_mode_restrict=EGPRS_GMSK-only</span><br><span> TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) downlink (V(A)==0 .. V(S)==1) mcs_mode_restrict=EGPRS_GMSK-only</span><br><span>@@ -2107,6 +2110,7 @@</span><br><span> TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) poll timeout for FN=2654309, TS=7 (curr FN 2654348)</span><br><span> TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FINISHED}: Received Event DL_ACKNACK_MISS</span><br><span> PDCH(bts=0,trx=0,ts=7) Received RTS for PDCH: FN=2654348 block_nr=2 scheduling USF=0 for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW), expect answer on UL FN=2654353</span><br><span> UL_ASS_TBF(UL-TFI_1){SEND_ASS}: Received Event CREATE_RLCMAC_MSG</span><br><span> PDCH(bts=0,trx=0,ts=7) POLL scheduled at FN 2654348 + 13 = 2654361</span><br><span>@@ -4283,10 +4287,12 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 112)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> PDCH(bts=0,trx=0,ts=4) Expiring FN=112 but previous FN=104 is still reserved!</span><br><span> PDCH(bts=0,trx=0,ts=4) Timeout for registered POLL (FN=104): TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=104, TS=4 (curr FN 112)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 2 => 3 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=24)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:25, lost=0, recv=25, skipped=0, bsn=0, info='RRRRRRRRRRRRRRRRRRRRRRRRR.......................................'</span><br><span>@@ -4546,6 +4552,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 91)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RRRRRRRRRRRRRRRRRRRR"(BSN=19)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:20, lost=0, recv=20, skipped=0, bsn=0, info='RRRRRRRRRRRRRRRRRRRR............................................'</span><br><span>@@ -4765,6 +4772,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 69)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RRRRRRRRRRRRRRR"(BSN=14)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:15, lost=0, recv=15, skipped=0, bsn=0, info='RRRRRRRRRRRRRRR.................................................'</span><br><span>@@ -4968,6 +4976,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 60)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RRRRRRRRRRRRR"(BSN=12)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:13, lost=0, recv=13, skipped=0, bsn=0, info='RRRRRRRRRRRRR...................................................'</span><br><span>@@ -5155,6 +5164,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 52)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RRRRRRRRRRR"(BSN=10)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:11, lost=0, recv=11, skipped=0, bsn=0, info='RRRRRRRRRRR.....................................................'</span><br><span>@@ -5318,6 +5328,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 39)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RRRRRRRR"(BSN=7)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:8, lost=0, recv=8, skipped=0, bsn=0, info='RRRRRRRR........................................................'</span><br><span>@@ -5490,6 +5501,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 34)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RRRRRRRRRRR"(BSN=10)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:11, lost=0, recv=10, skipped=1, bsn=0, info='xRRRRRRRRRR.....................................................'</span><br><span>@@ -5653,6 +5665,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 30)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RRRRRRRRR"(BSN=8)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:9, lost=0, recv=9, skipped=0, bsn=0, info='RRRRRRRRR.......................................................'</span><br><span>@@ -5805,6 +5818,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 26)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 1 => 2 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RRRRRRRR"(BSN=7)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:8, lost=0, recv=8, skipped=0, bsn=0, info='RRRRRRRR........................................................'</span><br><span>@@ -6119,6 +6133,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=21, TS=4 (curr FN 63)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 0 => 1 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RR"(BSN=1)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:2, lost=0, recv=2, skipped=0, bsn=0, info='RR..............................................................'</span><br><span>@@ -6213,6 +6228,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=21, TS=4 (curr FN 63)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 0 => 1 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RR"(BSN=1)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:2, lost=0, recv=2, skipped=0, bsn=0, info='RR..............................................................'</span><br><span>@@ -6307,6 +6323,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 63)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 0 => 1 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RR"(BSN=1)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:2, lost=0, recv=2, skipped=0, bsn=0, info='RR..............................................................'</span><br><span>@@ -6401,6 +6418,7 @@</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) poll timeout for FN=17, TS=4 (curr FN 63)</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Timeout for polling PACKET DOWNLINK ACK: |Assignment was on PACCH|No downlink ACK received yet|</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) N3105 0 => 1 (< MAX 8)</span><br><span style="color: hsl(120, 100%, 40%);">+TBF(DL-TFI_0){FLOW}: Received Event DL_ACKNACK_MISS</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) ack:  (BSN=0)"RR"(BSN=1)  R=ACK I=NACK</span><br><span> TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=0:2, lost=0, recv=2, skipped=0, bsn=0, info='RR..............................................................'</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/25104">change 25104</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/c/osmo-pcu/+/25104"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-pcu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I94b71c60ed49d51ebdf6d6b428056b4b94354676 </div>
<div style="display:none"> Gerrit-Change-Number: 25104 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>