diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gprs_ms.cpp | 32 | ||||
-rw-r--r-- | src/gprs_ms.h | 10 | ||||
-rw-r--r-- | src/tbf.cpp | 3 | ||||
-rw-r--r-- | src/tbf.h | 6 |
4 files changed, 43 insertions, 8 deletions
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index cb7773fc..807f3459 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -140,6 +140,8 @@ GprsMs::GprsMs(BTS *bts, uint32_t tlli) : GprsMs::~GprsMs() { + LListHead<gprs_rlcmac_tbf> *pos, *tmp; + LOGP(DRLCMAC, LOGL_INFO, "Destroying MS object, TLLI = 0x%08x\n", tlli()); set_reserved_slots(NULL, 0, 0); @@ -156,6 +158,10 @@ GprsMs::~GprsMs() m_dl_tbf->set_ms(NULL); m_dl_tbf = NULL; } + + llist_for_each_safe(pos, tmp, &m_old_tbfs) + pos->entry()->set_ms(NULL); + m_llc_queue.clear(m_bts); } @@ -227,7 +233,7 @@ void GprsMs::attach_ul_tbf(struct gprs_rlcmac_ul_tbf *tbf) Guard guard(this); if (m_ul_tbf) - detach_tbf(m_ul_tbf); + llist_add_tail(&m_ul_tbf->ms_list(), &m_old_tbfs); m_ul_tbf = tbf; @@ -246,7 +252,7 @@ void GprsMs::attach_dl_tbf(struct gprs_rlcmac_dl_tbf *tbf) Guard guard(this); if (m_dl_tbf) - detach_tbf(m_dl_tbf); + llist_add_tail(&m_dl_tbf->ms_list(), &m_old_tbfs); m_dl_tbf = tbf; @@ -256,12 +262,26 @@ void GprsMs::attach_dl_tbf(struct gprs_rlcmac_dl_tbf *tbf) void GprsMs::detach_tbf(gprs_rlcmac_tbf *tbf) { - if (m_ul_tbf && tbf == static_cast<gprs_rlcmac_tbf *>(m_ul_tbf)) + if (tbf == static_cast<gprs_rlcmac_tbf *>(m_ul_tbf)) { m_ul_tbf = NULL; - else if (m_dl_tbf && tbf == static_cast<gprs_rlcmac_tbf *>(m_dl_tbf)) + } else if (tbf == static_cast<gprs_rlcmac_tbf *>(m_dl_tbf)) { m_dl_tbf = NULL; - else - return; + } else { + bool found = false; + + LListHead<gprs_rlcmac_tbf> *pos, *tmp; + llist_for_each_safe(pos, tmp, &m_old_tbfs) { + if (pos->entry() == tbf) { + llist_del(pos); + found = true; + break; + } + } + + /* Protect against recursive calls via set_ms() */ + if (!found) + return; + } LOGP(DRLCMAC, LOGL_INFO, "Detaching TBF from MS object, TLLI = 0x%08x, TBF = %s\n", tlli(), tbf->name()); diff --git a/src/gprs_ms.h b/src/gprs_ms.h index c490e7ab..1f080ff2 100644 --- a/src/gprs_ms.h +++ b/src/gprs_ms.h @@ -109,13 +109,14 @@ public: void update_error_rate(gprs_rlcmac_tbf *tbf, int percent); - bool is_idle() const {return !m_ul_tbf && !m_dl_tbf && !m_ref;} + bool is_idle() const; void* operator new(size_t num); void operator delete(void* p); LListHead<GprsMs>& list() {return this->m_list;} const LListHead<GprsMs>& list() const {return this->m_list;} + const LListHead<gprs_rlcmac_tbf>& old_tbfs() const {return m_old_tbfs;} void update_l1_meas(const pcu_l1_meas *meas); const pcu_l1_meas* l1_meas() const {return &m_l1_meas;}; @@ -136,6 +137,8 @@ private: Callback * m_cb; gprs_rlcmac_ul_tbf *m_ul_tbf; gprs_rlcmac_dl_tbf *m_dl_tbf; + LListHead<gprs_rlcmac_tbf> m_old_tbfs; + uint32_t m_tlli; uint32_t m_new_ul_tlli; uint32_t m_new_dl_tlli; @@ -167,6 +170,11 @@ private: struct gprs_codel *m_codel_state; }; +inline bool GprsMs::is_idle() const +{ + return !m_ul_tbf && !m_dl_tbf && !m_ref && llist_empty(&m_old_tbfs); +} + inline uint32_t GprsMs::tlli() const { return m_new_ul_tlli ? m_new_ul_tlli : diff --git a/src/tbf.cpp b/src/tbf.cpp index 9d4363fa..4a59faa8 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -42,7 +42,8 @@ extern void *tall_pcu_ctx; static void tbf_timer_cb(void *_tbf); gprs_rlcmac_tbf::gprs_rlcmac_tbf(gprs_rlcmac_tbf_direction dir) : - direction(dir) + direction(dir), + m_ms_list(this) { } @@ -23,6 +23,7 @@ #include "gprs_rlcmac.h" #include "llc.h" #include "rlc.h" +#include "cxx_linuxlist.h" #include <gprs_debug.h> #include <stdint.h> @@ -165,6 +166,9 @@ struct gprs_rlcmac_tbf { /* attempt to make things a bit more fair */ void rotate_in_list(); + LListHead<gprs_rlcmac_tbf>& ms_list() {return this->m_ms_list;} + const LListHead<gprs_rlcmac_tbf>& ms_list() const {return this->m_ms_list;} + struct llist_pods list; uint32_t state_flags; enum gprs_rlcmac_tbf_direction direction; @@ -238,6 +242,8 @@ protected: uint8_t m_ms_class; private: + LListHead<gprs_rlcmac_tbf> m_ms_list; + mutable char m_name_buf[60]; }; |