<p>pespin <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/15603">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
osmith: Looks good to me, approved
</div><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;"><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-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>