aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gprs_ms.cpp32
-rw-r--r--src/gprs_ms.h10
-rw-r--r--src/tbf.cpp3
-rw-r--r--src/tbf.h6
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)
{
}
diff --git a/src/tbf.h b/src/tbf.h
index f1484f05..4a92bbf2 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -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];
};