<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/15603">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Move out tbf subclasses from tbf.h to their own headers<br><br>It's a good start towards clearing current mess between parent and the 2<br>children classes.<br><br>Change-Id: Ibc22ea2e02609af7ee058b8bc15df2115d4c6f60<br>---<br>M src/Makefile.am<br>M src/bts.cpp<br>M src/encoding.cpp<br>M src/gprs_ms.cpp<br>M src/gprs_ms.h<br>M src/gprs_rlcmac_meas.cpp<br>M src/gprs_rlcmac_sched.cpp<br>M src/gprs_rlcmac_ts_alloc.cpp<br>M src/pcu_vty_functions.cpp<br>M src/pdch.cpp<br>M src/poll_controller.cpp<br>M src/tbf.cpp<br>M src/tbf.h<br>M src/tbf_dl.cpp<br>A src/tbf_dl.h<br>M src/tbf_ul.cpp<br>A src/tbf_ul.h<br>M tests/alloc/AllocTest.cpp<br>M tests/ms/MsTest.cpp<br>M tests/tbf/TbfTest.cpp<br>M tests/types/TypesTest.cpp<br>21 files changed, 319 insertions(+), 238 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/03/15603/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index 7148267..a84a511 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -91,6 +91,8 @@</span><br><span>   pcu_vty_functions.h \</span><br><span>        mslot_class.h \</span><br><span>      tbf.h \</span><br><span style="color: hsl(120, 100%, 40%);">+       tbf_ul.h \</span><br><span style="color: hsl(120, 100%, 40%);">+    tbf_dl.h \</span><br><span>   bts.h \</span><br><span>      pdch.h \</span><br><span>     poll_controller.h \</span><br><span>diff --git a/src/bts.cpp b/src/bts.cpp</span><br><span>index a8760ae..df58494 100644</span><br><span>--- a/src/bts.cpp</span><br><span>+++ b/src/bts.cpp</span><br><span>@@ -21,6 +21,7 @@</span><br><span> #include <bts.h></span><br><span> #include <poll_controller.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <encoding.h></span><br><span> #include <decoding.h></span><br><span> #include <rlc.h></span><br><span>diff --git a/src/encoding.cpp b/src/encoding.cpp</span><br><span>index 3fac75e..8270354 100644</span><br><span>--- a/src/encoding.cpp</span><br><span>+++ b/src/encoding.cpp</span><br><span>@@ -23,6 +23,7 @@</span><br><span> #include <gprs_rlcmac.h></span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <gprs_debug.h></span><br><span> #include <egprs_rlc_compression.h></span><br><span> </span><br><span>diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp</span><br><span>index 75f75e1..5b35e65 100644</span><br><span>--- a/src/gprs_ms.cpp</span><br><span>+++ b/src/gprs_ms.cpp</span><br><span>@@ -23,6 +23,7 @@</span><br><span> #include <gprs_coding_scheme.h></span><br><span> #include "bts.h"</span><br><span> #include "tbf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_ul.h"</span><br><span> #include "gprs_debug.h"</span><br><span> #include "gprs_codel.h"</span><br><span> #include "pcu_utils.h"</span><br><span>diff --git a/src/gprs_ms.h b/src/gprs_ms.h</span><br><span>index 781dd59..688708e 100644</span><br><span>--- a/src/gprs_ms.h</span><br><span>+++ b/src/gprs_ms.h</span><br><span>@@ -26,6 +26,7 @@</span><br><span> #include "cxx_linuxlist.h"</span><br><span> #include "llc.h"</span><br><span> #include "tbf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_dl.h"</span><br><span> #include "pcu_l1_if.h"</span><br><span> #include <gprs_coding_scheme.h></span><br><span> </span><br><span>diff --git a/src/gprs_rlcmac_meas.cpp b/src/gprs_rlcmac_meas.cpp</span><br><span>index 4e58df3..998e01c 100644</span><br><span>--- a/src/gprs_rlcmac_meas.cpp</span><br><span>+++ b/src/gprs_rlcmac_meas.cpp</span><br><span>@@ -23,6 +23,7 @@</span><br><span> #include <gprs_debug.h></span><br><span> #include <pcu_l1_if.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_dl.h></span><br><span> </span><br><span> #include <string.h></span><br><span> #include <errno.h></span><br><span>diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp</span><br><span>index 5fedb5a..fe6f159 100644</span><br><span>--- a/src/gprs_rlcmac_sched.cpp</span><br><span>+++ b/src/gprs_rlcmac_sched.cpp</span><br><span>@@ -22,6 +22,7 @@</span><br><span> #include <pcu_l1_if.h></span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <gprs_debug.h></span><br><span> #include <gprs_ms.h></span><br><span> #include <rlc.h></span><br><span>diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp</span><br><span>index 0476d6d..cf3f9a9 100644</span><br><span>--- a/src/gprs_rlcmac_ts_alloc.cpp</span><br><span>+++ b/src/gprs_rlcmac_ts_alloc.cpp</span><br><span>@@ -23,6 +23,7 @@</span><br><span> #include <gprs_debug.h></span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <pdch.h></span><br><span> #include <gprs_ms.h></span><br><span> #include <pcu_utils.h></span><br><span>diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp</span><br><span>index 98e8185..3008267 100644</span><br><span>--- a/src/pcu_vty_functions.cpp</span><br><span>+++ b/src/pcu_vty_functions.cpp</span><br><span>@@ -32,6 +32,7 @@</span><br><span> #include <pcu_l1_if.h></span><br><span> #include <rlc.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <pdch.h></span><br><span> </span><br><span> extern "C" {</span><br><span>diff --git a/src/pdch.cpp b/src/pdch.cpp</span><br><span>index 24bbbb1..e4b25e1 100644</span><br><span>--- a/src/pdch.cpp</span><br><span>+++ b/src/pdch.cpp</span><br><span>@@ -32,6 +32,7 @@</span><br><span> #include <rlc.h></span><br><span> #include <sba.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <cxx_linuxlist.h></span><br><span> #include <gsm_rlcmac.h></span><br><span> </span><br><span>diff --git a/src/poll_controller.cpp b/src/poll_controller.cpp</span><br><span>index 744b612..ac79510 100644</span><br><span>--- a/src/poll_controller.cpp</span><br><span>+++ b/src/poll_controller.cpp</span><br><span>@@ -23,6 +23,7 @@</span><br><span> #include <poll_controller.h></span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <cxx_linuxlist.h></span><br><span> #include <sba.h></span><br><span> </span><br><span>diff --git a/src/tbf.cpp b/src/tbf.cpp</span><br><span>index 37435f5..3ca39bf 100644</span><br><span>--- a/src/tbf.cpp</span><br><span>+++ b/src/tbf.cpp</span><br><span>@@ -21,6 +21,8 @@</span><br><span> </span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_dl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <rlc.h></span><br><span> #include <encoding.h></span><br><span> #include <gprs_rlcmac.h></span><br><span>diff --git a/src/tbf.h b/src/tbf.h</span><br><span>index 6eab9d0..fd65b20 100644</span><br><span>--- a/src/tbf.h</span><br><span>+++ b/src/tbf.h</span><br><span>@@ -95,15 +95,6 @@</span><br><span>  GPRS_RLCMAC_UL_TBF</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum tbf_dl_prio {</span><br><span style="color: hsl(0, 100%, 40%);">-  DL_PRIO_NONE,</span><br><span style="color: hsl(0, 100%, 40%);">-   DL_PRIO_SENT_DATA, /* the data has been sent and not (yet) nacked */</span><br><span style="color: hsl(0, 100%, 40%);">-    DL_PRIO_LOW_AGE,   /* the age has reached the first threshold */</span><br><span style="color: hsl(0, 100%, 40%);">-        DL_PRIO_NEW_DATA,  /* the data has not been sent yet or nacked */</span><br><span style="color: hsl(0, 100%, 40%);">-       DL_PRIO_HIGH_AGE,  /* the age has reached the second threshold */</span><br><span style="color: hsl(0, 100%, 40%);">-       DL_PRIO_CONTROL,   /* a control block needs to be sent */</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> enum tbf_rlc_counters {</span><br><span>       TBF_CTR_RLC_NACKED,</span><br><span> };</span><br><span>@@ -127,28 +118,7 @@</span><br><span>     TBF_CTR_EGPRS_DL_MCS9,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum tbf_gprs_ul_counters {</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_GPRS_UL_CS1,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_GPRS_UL_CS2,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_GPRS_UL_CS3,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_GPRS_UL_CS4,</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%);">-enum tbf_egprs_ul_counters {</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_EGPRS_UL_MCS1,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_EGPRS_UL_MCS2,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_EGPRS_UL_MCS3,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_EGPRS_UL_MCS4,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_EGPRS_UL_MCS5,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_EGPRS_UL_MCS6,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_EGPRS_UL_MCS7,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_EGPRS_UL_MCS8,</span><br><span style="color: hsl(0, 100%, 40%);">-        TBF_CTR_EGPRS_UL_MCS9,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #define LOGPTBF(tbf, level, fmt, args...) LOGP(DTBF, level, "%s " fmt, tbf_name(tbf), ## args)</span><br><span style="color: hsl(0, 100%, 40%);">-#define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args)</span><br><span style="color: hsl(0, 100%, 40%);">-#define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(tbf), ## args)</span><br><span> </span><br><span> enum tbf_timers {</span><br><span>       /* internal assign/reject timer */</span><br><span>@@ -612,220 +582,12 @@</span><br><span>  m_egprs_enabled = false;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf {</span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_rlcmac_dl_tbf(BTS *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_rlc_dl_window *window();</span><br><span style="color: hsl(0, 100%, 40%);">-   void cleanup();</span><br><span style="color: hsl(0, 100%, 40%);">- void enable_egprs();</span><br><span style="color: hsl(0, 100%, 40%);">-    /* dispatch Unitdata.DL messages */</span><br><span style="color: hsl(0, 100%, 40%);">-     static int handle(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(0, 100%, 40%);">-          const uint32_t tlli, const uint32_t old_tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-           const char *imsi, const uint8_t ms_class,</span><br><span style="color: hsl(0, 100%, 40%);">-               const uint8_t egprs_ms_class, const uint16_t delay_csec,</span><br><span style="color: hsl(0, 100%, 40%);">-                const uint8_t *data, const uint16_t len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       int append_data(const uint8_t ms_class,</span><br><span style="color: hsl(0, 100%, 40%);">-                 const uint16_t pdu_delay_csec,</span><br><span style="color: hsl(0, 100%, 40%);">-                  const uint8_t *data, const uint16_t len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       int rcvd_dl_ack(bool final, uint8_t ssn, uint8_t *rbb);</span><br><span style="color: hsl(0, 100%, 40%);">- int rcvd_dl_ack(bool final_ack, unsigned first_bsn, struct bitvec *rbb);</span><br><span style="color: hsl(0, 100%, 40%);">-        struct msgb *create_dl_acked_block(uint32_t fn, uint8_t ts);</span><br><span style="color: hsl(0, 100%, 40%);">-    void trigger_ass(struct gprs_rlcmac_tbf *old_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      bool handle_ack_nack();</span><br><span style="color: hsl(0, 100%, 40%);">- void request_dl_ack();</span><br><span style="color: hsl(0, 100%, 40%);">-  bool need_control_ts() const;</span><br><span style="color: hsl(0, 100%, 40%);">-   bool have_data() const;</span><br><span style="color: hsl(0, 100%, 40%);">- int frames_since_last_poll(unsigned fn) const;</span><br><span style="color: hsl(0, 100%, 40%);">-  int frames_since_last_drain(unsigned fn) const;</span><br><span style="color: hsl(0, 100%, 40%);">- bool keep_open(unsigned fn) const;</span><br><span style="color: hsl(0, 100%, 40%);">-      int release();</span><br><span style="color: hsl(0, 100%, 40%);">-  int abort();</span><br><span style="color: hsl(0, 100%, 40%);">-    uint16_t window_size() const;</span><br><span style="color: hsl(0, 100%, 40%);">-   void set_window_size();</span><br><span style="color: hsl(0, 100%, 40%);">- void update_coding_scheme_counter_dl(enum CodingScheme cs);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* TODO: add the gettimeofday as parameter */</span><br><span style="color: hsl(0, 100%, 40%);">-   struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* Please note that all variables here will be reset when changing</span><br><span style="color: hsl(0, 100%, 40%);">-       * from WAIT RELEASE back to FLOW state (re-use of TBF).</span><br><span style="color: hsl(0, 100%, 40%);">-         * All states that need reset must be in this struct, so this is why</span><br><span style="color: hsl(0, 100%, 40%);">-     * variables are in both (dl and ul) structs and not outside union.</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-     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 style="color: hsl(0, 100%, 40%);">- bool m_dl_ack_requested;</span><br><span style="color: hsl(0, 100%, 40%);">-        int32_t m_last_dl_poll_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-      int32_t m_last_dl_drained_fn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   struct BandWidth {</span><br><span style="color: hsl(0, 100%, 40%);">-              struct timespec dl_bw_tv; /* timestamp for dl bw calculation */</span><br><span style="color: hsl(0, 100%, 40%);">-         uint32_t dl_bw_octets; /* number of octets since bw_tv */</span><br><span style="color: hsl(0, 100%, 40%);">-               uint32_t dl_throughput; /* throughput to be displayed in stats */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               struct timespec dl_loss_tv; /* timestamp for loss calculation */</span><br><span style="color: hsl(0, 100%, 40%);">-                uint16_t dl_loss_lost; /* sum of lost packets */</span><br><span style="color: hsl(0, 100%, 40%);">-                uint16_t dl_loss_received; /* sum of received packets */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                BandWidth();</span><br><span style="color: hsl(0, 100%, 40%);">-    } m_bw;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- struct rate_ctr_group *m_dl_gprs_ctrs;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct rate_ctr_group *m_dl_egprs_ctrs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-protected:</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ana_result {</span><br><span style="color: hsl(0, 100%, 40%);">-             unsigned received_packets;</span><br><span style="color: hsl(0, 100%, 40%);">-              unsigned lost_packets;</span><br><span style="color: hsl(0, 100%, 40%);">-          unsigned received_bytes;</span><br><span style="color: hsl(0, 100%, 40%);">-                unsigned lost_bytes;</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%);">-      int take_next_bsn(uint32_t fn, int previous_bsn,</span><br><span style="color: hsl(0, 100%, 40%);">-                bool *may_combine);</span><br><span style="color: hsl(0, 100%, 40%);">-     bool restart_bsn_cycle();</span><br><span style="color: hsl(0, 100%, 40%);">-       int create_new_bsn(const uint32_t fn, GprsCodingScheme cs);</span><br><span style="color: hsl(0, 100%, 40%);">-     struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 int index, int index2 = -1);</span><br><span style="color: hsl(0, 100%, 40%);">-    int update_window(const uint8_t ssn, const uint8_t *rbb);</span><br><span style="color: hsl(0, 100%, 40%);">-       int update_window(unsigned first_bsn, const struct bitvec *rbb);</span><br><span style="color: hsl(0, 100%, 40%);">-        int maybe_start_new_window();</span><br><span style="color: hsl(0, 100%, 40%);">-   bool dl_window_stalled() const;</span><br><span style="color: hsl(0, 100%, 40%);">- void reuse_tbf();</span><br><span style="color: hsl(0, 100%, 40%);">-       void start_llc_timer();</span><br><span style="color: hsl(0, 100%, 40%);">- int analyse_errors(char *show_rbb, uint8_t ssn, ana_result *res);</span><br><span style="color: hsl(0, 100%, 40%);">-       void schedule_next_frame();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     enum egprs_rlc_dl_reseg_bsn_state egprs_dl_get_data</span><br><span style="color: hsl(0, 100%, 40%);">-             (int bsn, uint8_t **block_data);</span><br><span style="color: hsl(0, 100%, 40%);">-        unsigned int get_egprs_dl_spb_status(int bsn);</span><br><span style="color: hsl(0, 100%, 40%);">-  enum egprs_rlcmac_dl_spb get_egprs_dl_spb(int bsn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     struct osmo_timer_list m_llc_timer;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Please note that all variables below will be reset when changing</span><br><span style="color: hsl(0, 100%, 40%);">-      * from WAIT RELEASE back to FLOW state (re-use of TBF).</span><br><span style="color: hsl(0, 100%, 40%);">-         * All states that need reset must be in this struct, so this is why</span><br><span style="color: hsl(0, 100%, 40%);">-     * variables are in both (dl and ul) structs and not outside union.</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-     gprs_rlc_dl_window m_window;</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%);">-struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {</span><br><span style="color: hsl(0, 100%, 40%);">-      gprs_rlcmac_ul_tbf(BTS *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_rlc_ul_window *window();</span><br><span style="color: hsl(0, 100%, 40%);">-   struct msgb *create_ul_ack(uint32_t fn, uint8_t ts);</span><br><span style="color: hsl(0, 100%, 40%);">-    bool ctrl_ack_to_toggle();</span><br><span style="color: hsl(0, 100%, 40%);">-      bool handle_ctrl_ack();</span><br><span style="color: hsl(0, 100%, 40%);">- void enable_egprs();</span><br><span style="color: hsl(0, 100%, 40%);">-    /* blocks were acked */</span><br><span style="color: hsl(0, 100%, 40%);">- int rcv_data_block_acknowledged(</span><br><span style="color: hsl(0, 100%, 40%);">-                const struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-           uint8_t *data, struct pcu_l1_meas *meas);</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%);">-       /* TODO: extract LLC class? */</span><br><span style="color: hsl(0, 100%, 40%);">-  int assemble_forward_llc(const gprs_rlc_data *data);</span><br><span style="color: hsl(0, 100%, 40%);">-    int snd_ul_ud();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_spb(</span><br><span style="color: hsl(0, 100%, 40%);">-               const struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-           struct gprs_rlc_data *block,</span><br><span style="color: hsl(0, 100%, 40%);">-            uint8_t *data, const uint8_t block_idx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_first_seg(</span><br><span style="color: hsl(0, 100%, 40%);">-         const struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-           struct gprs_rlc_data *block,</span><br><span style="color: hsl(0, 100%, 40%);">-            uint8_t *data, const uint8_t block_idx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_second_seg(</span><br><span style="color: hsl(0, 100%, 40%);">-                const struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(0, 100%, 40%);">-           struct gprs_rlc_data *block,</span><br><span style="color: hsl(0, 100%, 40%);">-            uint8_t *data, const uint8_t block_idx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        uint16_t window_size() const;</span><br><span style="color: hsl(0, 100%, 40%);">-   void set_window_size();</span><br><span style="color: hsl(0, 100%, 40%);">- void update_coding_scheme_counter_ul(enum CodingScheme cs);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Please note that all variables here will be reset when changing</span><br><span style="color: hsl(0, 100%, 40%);">-       * from WAIT RELEASE back to FLOW state (re-use of TBF).</span><br><span style="color: hsl(0, 100%, 40%);">-         * All states that need reset must be in this struct, so this is why</span><br><span style="color: hsl(0, 100%, 40%);">-     * variables are in both (dl and ul) structs and not outside union.</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-     int32_t m_rx_counter; /* count all received blocks */</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t m_usf[8];       /* list USFs per PDCH (timeslot) */</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t m_contention_resolution_done; /* set after done */</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t m_final_ack_sent; /* set if we sent final ack */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        struct rate_ctr_group *m_ul_gprs_ctrs;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct rate_ctr_group *m_ul_egprs_ctrs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-protected:</span><br><span style="color: hsl(0, 100%, 40%);">-       void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Please note that all variables below will be reset when changing</span><br><span style="color: hsl(0, 100%, 40%);">-      * from WAIT RELEASE back to FLOW state (re-use of TBF).</span><br><span style="color: hsl(0, 100%, 40%);">-         * All states that need reset must be in this struct, so this is why</span><br><span style="color: hsl(0, 100%, 40%);">-     * variables are in both (dl and ul) structs and not outside union.</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-     gprs_rlc_ul_window m_window;</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%);">-#ifdef __cplusplus</span><br><span style="color: hsl(0, 100%, 40%);">-extern "C" {</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta);</span><br><span style="color: hsl(0, 100%, 40%);">-void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta);</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef __cplusplus</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> inline enum gprs_rlcmac_tbf_direction reverse(enum gprs_rlcmac_tbf_direction dir)</span><br><span> {</span><br><span>      return (enum gprs_rlcmac_tbf_direction)</span><br><span>              ((int)GPRS_RLCMAC_UL_TBF - (int)dir + (int)GPRS_RLCMAC_DL_TBF);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-inline uint16_t gprs_rlcmac_ul_tbf::window_size() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        return m_window.ws();</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%);">-inline uint16_t gprs_rlcmac_dl_tbf::window_size() const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return m_window.ws();</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%);">-inline void gprs_rlcmac_ul_tbf::enable_egprs()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   m_window.set_sns(RLC_EGPRS_SNS);</span><br><span style="color: hsl(0, 100%, 40%);">-        gprs_rlcmac_tbf::enable_egprs();</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%);">-inline void gprs_rlcmac_dl_tbf::enable_egprs()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        m_window.set_sns(RLC_EGPRS_SNS);</span><br><span style="color: hsl(0, 100%, 40%);">-        gprs_rlcmac_tbf::enable_egprs();</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%);">-inline gprs_rlcmac_ul_tbf *as_ul_tbf(gprs_rlcmac_tbf *tbf)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    if (tbf && tbf->direction == GPRS_RLCMAC_UL_TBF)</span><br><span style="color: hsl(0, 100%, 40%);">-             return static_cast<gprs_rlcmac_ul_tbf *>(tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-    else</span><br><span style="color: hsl(0, 100%, 40%);">-            return NULL;</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%);">-inline gprs_rlcmac_dl_tbf *as_dl_tbf(gprs_rlcmac_tbf *tbf)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        if (tbf && tbf->direction == GPRS_RLCMAC_DL_TBF)</span><br><span style="color: hsl(0, 100%, 40%);">-             return static_cast<gprs_rlcmac_dl_tbf *>(tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-    else</span><br><span style="color: hsl(0, 100%, 40%);">-            return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> uint16_t egprs_window_size(const struct gprs_rlcmac_bts *bts_data, uint8_t slots);</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 12c098a..e9190f6 100644</span><br><span>--- a/src/tbf_dl.cpp</span><br><span>+++ b/src/tbf_dl.cpp</span><br><span>@@ -21,6 +21,8 @@</span><br><span> </span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_dl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <rlc.h></span><br><span> #include <gprs_rlcmac.h></span><br><span> #include <gprs_debug.h></span><br><span>diff --git a/src/tbf_dl.h b/src/tbf_dl.h</span><br><span>new file mode 100644</span><br><span>index 0000000..1011665</span><br><span>--- /dev/null</span><br><span>+++ b/src/tbf_dl.h</span><br><span>@@ -0,0 +1,160 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2013 by Holger Hans Peter Freyther</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * as published by the Free Software Foundation; either version 2</span><br><span style="color: hsl(120, 100%, 40%);">+ * of the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program; if not, write to the Free Software</span><br><span style="color: hsl(120, 100%, 40%);">+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.</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%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef __cplusplus</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf.h"</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%);">+ * TBF instance</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%);">+enum tbf_dl_prio {</span><br><span style="color: hsl(120, 100%, 40%);">+ DL_PRIO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+ DL_PRIO_SENT_DATA, /* the data has been sent and not (yet) nacked */</span><br><span style="color: hsl(120, 100%, 40%);">+  DL_PRIO_LOW_AGE,   /* the age has reached the first threshold */</span><br><span style="color: hsl(120, 100%, 40%);">+      DL_PRIO_NEW_DATA,  /* the data has not been sent yet or nacked */</span><br><span style="color: hsl(120, 100%, 40%);">+     DL_PRIO_HIGH_AGE,  /* the age has reached the second threshold */</span><br><span style="color: hsl(120, 100%, 40%);">+     DL_PRIO_CONTROL,   /* a control block needs to be sent */</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%);">+#define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(tbf), ## args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf {</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_rlcmac_dl_tbf(BTS *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_rlc_dl_window *window();</span><br><span style="color: hsl(120, 100%, 40%);">+ void cleanup();</span><br><span style="color: hsl(120, 100%, 40%);">+       void enable_egprs();</span><br><span style="color: hsl(120, 100%, 40%);">+  /* dispatch Unitdata.DL messages */</span><br><span style="color: hsl(120, 100%, 40%);">+   static int handle(struct gprs_rlcmac_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                const uint32_t tlli, const uint32_t old_tlli,</span><br><span style="color: hsl(120, 100%, 40%);">+         const char *imsi, const uint8_t ms_class,</span><br><span style="color: hsl(120, 100%, 40%);">+             const uint8_t egprs_ms_class, const uint16_t delay_csec,</span><br><span style="color: hsl(120, 100%, 40%);">+              const uint8_t *data, const uint16_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   int append_data(const uint8_t ms_class,</span><br><span style="color: hsl(120, 100%, 40%);">+                       const uint16_t pdu_delay_csec,</span><br><span style="color: hsl(120, 100%, 40%);">+                        const uint8_t *data, const uint16_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   int rcvd_dl_ack(bool final, uint8_t ssn, uint8_t *rbb);</span><br><span style="color: hsl(120, 100%, 40%);">+       int rcvd_dl_ack(bool final_ack, unsigned first_bsn, struct bitvec *rbb);</span><br><span style="color: hsl(120, 100%, 40%);">+      struct msgb *create_dl_acked_block(uint32_t fn, uint8_t ts);</span><br><span style="color: hsl(120, 100%, 40%);">+  void trigger_ass(struct gprs_rlcmac_tbf *old_tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  bool handle_ack_nack();</span><br><span style="color: hsl(120, 100%, 40%);">+       void request_dl_ack();</span><br><span style="color: hsl(120, 100%, 40%);">+        bool need_control_ts() const;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool have_data() const;</span><br><span style="color: hsl(120, 100%, 40%);">+       int frames_since_last_poll(unsigned fn) const;</span><br><span style="color: hsl(120, 100%, 40%);">+        int frames_since_last_drain(unsigned fn) const;</span><br><span style="color: hsl(120, 100%, 40%);">+       bool keep_open(unsigned fn) const;</span><br><span style="color: hsl(120, 100%, 40%);">+    int release();</span><br><span style="color: hsl(120, 100%, 40%);">+        int abort();</span><br><span style="color: hsl(120, 100%, 40%);">+  uint16_t window_size() const;</span><br><span style="color: hsl(120, 100%, 40%);">+ void set_window_size();</span><br><span style="color: hsl(120, 100%, 40%);">+       void update_coding_scheme_counter_dl(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* TODO: add the gettimeofday as parameter */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Please note that all variables here will be reset when changing</span><br><span style="color: hsl(120, 100%, 40%);">+     * from WAIT RELEASE back to FLOW state (re-use of TBF).</span><br><span style="color: hsl(120, 100%, 40%);">+       * All states that need reset must be in this struct, so this is why</span><br><span style="color: hsl(120, 100%, 40%);">+   * variables are in both (dl and ul) structs and not outside union.</span><br><span style="color: hsl(120, 100%, 40%);">+    */</span><br><span style="color: hsl(120, 100%, 40%);">+   int32_t m_tx_counter; /* count all transmitted blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t m_wait_confirm; /* wait for CCCH IMM.ASS cnf */</span><br><span style="color: hsl(120, 100%, 40%);">+       bool m_dl_ack_requested;</span><br><span style="color: hsl(120, 100%, 40%);">+      int32_t m_last_dl_poll_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+    int32_t m_last_dl_drained_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       struct BandWidth {</span><br><span style="color: hsl(120, 100%, 40%);">+            struct timespec dl_bw_tv; /* timestamp for dl bw calculation */</span><br><span style="color: hsl(120, 100%, 40%);">+               uint32_t dl_bw_octets; /* number of octets since bw_tv */</span><br><span style="color: hsl(120, 100%, 40%);">+             uint32_t dl_throughput; /* throughput to be displayed in stats */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           struct timespec dl_loss_tv; /* timestamp for loss calculation */</span><br><span style="color: hsl(120, 100%, 40%);">+              uint16_t dl_loss_lost; /* sum of lost packets */</span><br><span style="color: hsl(120, 100%, 40%);">+              uint16_t dl_loss_received; /* sum of received packets */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            BandWidth();</span><br><span style="color: hsl(120, 100%, 40%);">+  } m_bw;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     struct rate_ctr_group *m_dl_gprs_ctrs;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct rate_ctr_group *m_dl_egprs_ctrs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+protected:</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ana_result {</span><br><span style="color: hsl(120, 100%, 40%);">+           unsigned received_packets;</span><br><span style="color: hsl(120, 100%, 40%);">+            unsigned lost_packets;</span><br><span style="color: hsl(120, 100%, 40%);">+                unsigned received_bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+              unsigned lost_bytes;</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 take_next_bsn(uint32_t fn, int previous_bsn,</span><br><span style="color: hsl(120, 100%, 40%);">+              bool *may_combine);</span><br><span style="color: hsl(120, 100%, 40%);">+   bool restart_bsn_cycle();</span><br><span style="color: hsl(120, 100%, 40%);">+     int create_new_bsn(const uint32_t fn, GprsCodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+   struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       int index, int index2 = -1);</span><br><span style="color: hsl(120, 100%, 40%);">+  int update_window(const uint8_t ssn, const uint8_t *rbb);</span><br><span style="color: hsl(120, 100%, 40%);">+     int update_window(unsigned first_bsn, const struct bitvec *rbb);</span><br><span style="color: hsl(120, 100%, 40%);">+      int maybe_start_new_window();</span><br><span style="color: hsl(120, 100%, 40%);">+ bool dl_window_stalled() const;</span><br><span style="color: hsl(120, 100%, 40%);">+       void reuse_tbf();</span><br><span style="color: hsl(120, 100%, 40%);">+     void start_llc_timer();</span><br><span style="color: hsl(120, 100%, 40%);">+       int analyse_errors(char *show_rbb, uint8_t ssn, ana_result *res);</span><br><span style="color: hsl(120, 100%, 40%);">+     void schedule_next_frame();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ enum egprs_rlc_dl_reseg_bsn_state egprs_dl_get_data</span><br><span style="color: hsl(120, 100%, 40%);">+           (int bsn, uint8_t **block_data);</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int get_egprs_dl_spb_status(int bsn);</span><br><span style="color: hsl(120, 100%, 40%);">+        enum egprs_rlcmac_dl_spb get_egprs_dl_spb(int bsn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_timer_list m_llc_timer;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Please note that all variables below will be reset when changing</span><br><span style="color: hsl(120, 100%, 40%);">+    * from WAIT RELEASE back to FLOW state (re-use of TBF).</span><br><span style="color: hsl(120, 100%, 40%);">+       * All states that need reset must be in this struct, so this is why</span><br><span style="color: hsl(120, 100%, 40%);">+   * variables are in both (dl and ul) structs and not outside union.</span><br><span style="color: hsl(120, 100%, 40%);">+    */</span><br><span style="color: hsl(120, 100%, 40%);">+   gprs_rlc_dl_window m_window;</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%);">+inline uint16_t gprs_rlcmac_dl_tbf::window_size() const</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return m_window.ws();</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%);">+inline void gprs_rlcmac_dl_tbf::enable_egprs()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ m_window.set_sns(RLC_EGPRS_SNS);</span><br><span style="color: hsl(120, 100%, 40%);">+      gprs_rlcmac_tbf::enable_egprs();</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%);">+inline gprs_rlcmac_dl_tbf *as_dl_tbf(gprs_rlcmac_tbf *tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (tbf && tbf->direction == GPRS_RLCMAC_DL_TBF)</span><br><span style="color: hsl(120, 100%, 40%);">+           return static_cast<gprs_rlcmac_dl_tbf *>(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+  else</span><br><span style="color: hsl(120, 100%, 40%);">+          return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp</span><br><span>index 3fa8009..a993cce 100644</span><br><span>--- a/src/tbf_ul.cpp</span><br><span>+++ b/src/tbf_ul.cpp</span><br><span>@@ -21,6 +21,7 @@</span><br><span> </span><br><span> #include <bts.h></span><br><span> #include <tbf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tbf_ul.h></span><br><span> #include <rlc.h></span><br><span> #include <encoding.h></span><br><span> #include <gprs_rlcmac.h></span><br><span>diff --git a/src/tbf_ul.h b/src/tbf_ul.h</span><br><span>new file mode 100644</span><br><span>index 0000000..85da4f6</span><br><span>--- /dev/null</span><br><span>+++ b/src/tbf_ul.h</span><br><span>@@ -0,0 +1,138 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2013 by Holger Hans Peter Freyther</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * as published by the Free Software Foundation; either version 2</span><br><span style="color: hsl(120, 100%, 40%);">+ * of the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program; if not, write to the Free Software</span><br><span style="color: hsl(120, 100%, 40%);">+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.</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%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef __cplusplus</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * TBF instance</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%);">+enum tbf_gprs_ul_counters {</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_GPRS_UL_CS1,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_GPRS_UL_CS2,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_GPRS_UL_CS3,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_GPRS_UL_CS4,</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%);">+enum tbf_egprs_ul_counters {</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_EGPRS_UL_MCS1,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_EGPRS_UL_MCS2,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_EGPRS_UL_MCS3,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_EGPRS_UL_MCS4,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_EGPRS_UL_MCS5,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_EGPRS_UL_MCS6,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_EGPRS_UL_MCS7,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_EGPRS_UL_MCS8,</span><br><span style="color: hsl(120, 100%, 40%);">+        TBF_CTR_EGPRS_UL_MCS9,</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%);">+#define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_rlcmac_ul_tbf(BTS *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+ gprs_rlc_ul_window *window();</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *create_ul_ack(uint32_t fn, uint8_t ts);</span><br><span style="color: hsl(120, 100%, 40%);">+  bool ctrl_ack_to_toggle();</span><br><span style="color: hsl(120, 100%, 40%);">+    bool handle_ctrl_ack();</span><br><span style="color: hsl(120, 100%, 40%);">+       void enable_egprs();</span><br><span style="color: hsl(120, 100%, 40%);">+  /* blocks were acked */</span><br><span style="color: hsl(120, 100%, 40%);">+       int rcv_data_block_acknowledged(</span><br><span style="color: hsl(120, 100%, 40%);">+              const struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(120, 100%, 40%);">+         uint8_t *data, struct pcu_l1_meas *meas);</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%);">+ /* TODO: extract LLC class? */</span><br><span style="color: hsl(120, 100%, 40%);">+        int assemble_forward_llc(const gprs_rlc_data *data);</span><br><span style="color: hsl(120, 100%, 40%);">+  int snd_ul_ud();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_spb(</span><br><span style="color: hsl(120, 100%, 40%);">+             const struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(120, 100%, 40%);">+         struct gprs_rlc_data *block,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t *data, const uint8_t block_idx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_first_seg(</span><br><span style="color: hsl(120, 100%, 40%);">+               const struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(120, 100%, 40%);">+         struct gprs_rlc_data *block,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t *data, const uint8_t block_idx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_second_seg(</span><br><span style="color: hsl(120, 100%, 40%);">+              const struct gprs_rlc_data_info *rlc,</span><br><span style="color: hsl(120, 100%, 40%);">+         struct gprs_rlc_data *block,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t *data, const uint8_t block_idx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    uint16_t window_size() const;</span><br><span style="color: hsl(120, 100%, 40%);">+ void set_window_size();</span><br><span style="color: hsl(120, 100%, 40%);">+       void update_coding_scheme_counter_ul(enum CodingScheme cs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Please note that all variables here will be reset when changing</span><br><span style="color: hsl(120, 100%, 40%);">+     * from WAIT RELEASE back to FLOW state (re-use of TBF).</span><br><span style="color: hsl(120, 100%, 40%);">+       * All states that need reset must be in this struct, so this is why</span><br><span style="color: hsl(120, 100%, 40%);">+   * variables are in both (dl and ul) structs and not outside union.</span><br><span style="color: hsl(120, 100%, 40%);">+    */</span><br><span style="color: hsl(120, 100%, 40%);">+   int32_t m_rx_counter; /* count all received blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t m_usf[8];       /* list USFs per PDCH (timeslot) */</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t m_contention_resolution_done; /* set after done */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t m_final_ack_sent; /* set if we sent final ack */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    struct rate_ctr_group *m_ul_gprs_ctrs;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct rate_ctr_group *m_ul_egprs_ctrs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+protected:</span><br><span style="color: hsl(120, 100%, 40%);">+ void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Please note that all variables below will be reset when changing</span><br><span style="color: hsl(120, 100%, 40%);">+    * from WAIT RELEASE back to FLOW state (re-use of TBF).</span><br><span style="color: hsl(120, 100%, 40%);">+       * All states that need reset must be in this struct, so this is why</span><br><span style="color: hsl(120, 100%, 40%);">+   * variables are in both (dl and ul) structs and not outside union.</span><br><span style="color: hsl(120, 100%, 40%);">+    */</span><br><span style="color: hsl(120, 100%, 40%);">+   gprs_rlc_ul_window m_window;</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%);">+#ifdef __cplusplus</span><br><span style="color: hsl(120, 100%, 40%);">+extern "C" {</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta);</span><br><span style="color: hsl(120, 100%, 40%);">+void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta);</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef __cplusplus</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+inline uint16_t gprs_rlcmac_ul_tbf::window_size() const</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return m_window.ws();</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%);">+inline void gprs_rlcmac_ul_tbf::enable_egprs()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ m_window.set_sns(RLC_EGPRS_SNS);</span><br><span style="color: hsl(120, 100%, 40%);">+      gprs_rlcmac_tbf::enable_egprs();</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%);">+inline gprs_rlcmac_ul_tbf *as_ul_tbf(gprs_rlcmac_tbf *tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (tbf && tbf->direction == GPRS_RLCMAC_UL_TBF)</span><br><span style="color: hsl(120, 100%, 40%);">+           return static_cast<gprs_rlcmac_ul_tbf *>(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+  else</span><br><span style="color: hsl(120, 100%, 40%);">+          return NULL;</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%);">+#endif</span><br><span>diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp</span><br><span>index 64d6a50..123f879 100644</span><br><span>--- a/tests/alloc/AllocTest.cpp</span><br><span>+++ b/tests/alloc/AllocTest.cpp</span><br><span>@@ -20,6 +20,7 @@</span><br><span> #include "gprs_rlcmac.h"</span><br><span> #include "gprs_debug.h"</span><br><span> #include "tbf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_ul.h"</span><br><span> #include "bts.h"</span><br><span> </span><br><span> #include <string.h></span><br><span>diff --git a/tests/ms/MsTest.cpp b/tests/ms/MsTest.cpp</span><br><span>index c74b3a6..0c5ab9e 100644</span><br><span>--- a/tests/ms/MsTest.cpp</span><br><span>+++ b/tests/ms/MsTest.cpp</span><br><span>@@ -21,6 +21,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include "tbf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_ul.h"</span><br><span> #include "gprs_debug.h"</span><br><span> #include "gprs_ms.h"</span><br><span> #include "gprs_ms_storage.h"</span><br><span>diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp</span><br><span>index 2036023..bd4fbc1 100644</span><br><span>--- a/tests/tbf/TbfTest.cpp</span><br><span>+++ b/tests/tbf/TbfTest.cpp</span><br><span>@@ -22,6 +22,7 @@</span><br><span> </span><br><span> #include "bts.h"</span><br><span> #include "tbf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_ul.h"</span><br><span> #include "gprs_debug.h"</span><br><span> #include "pcu_utils.h"</span><br><span> #include "gprs_bssgp_pcu.h"</span><br><span>diff --git a/tests/types/TypesTest.cpp b/tests/types/TypesTest.cpp</span><br><span>index ee4e937..aa0a366 100644</span><br><span>--- a/tests/types/TypesTest.cpp</span><br><span>+++ b/tests/types/TypesTest.cpp</span><br><span>@@ -22,6 +22,7 @@</span><br><span>  */</span><br><span> #include "bts.h"</span><br><span> #include "tbf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "tbf_ul.h"</span><br><span> #include "pcu_utils.h"</span><br><span> #include "gprs_debug.h"</span><br><span> #include "encoding.h"</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/15603">change 15603</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/+/15603"/><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: Ibc22ea2e02609af7ee058b8bc15df2115d4c6f60 </div>
<div style="display:none"> Gerrit-Change-Number: 15603 </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>