aboutsummaryrefslogtreecommitdiffstats
path: root/src/gprs_ms.cpp
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-08-21 15:24:02 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2015-08-24 12:23:50 +0200
commit6835cead8c9e13fbbbb7b100a4c18a031f92421f (patch)
tree27da88a0ba5154254f67fab840f7a81f5cd26b95 /src/gprs_ms.cpp
parent6e013a136a9286e92cee0d9b5b4f0c7bcea5fd51 (diff)
ms: Store references to replaced TBFs in the MS object
Currently when calling GprsMs::attach_tbf and a TBF of the same direction already exists, the old TBF gets detached from the MS object. Therefore that TBF object loses access to that MS object including for instance TLLI and IMSI. This leads to failing DL TBF reuses, since the downlink assigment cannot be sent on the PACCH later on because that must be sent on the old DL TBF which ms() is NULL and the new DL TBF cannot be retrieved. This commit fixes this bug by changing the GprsMs implementation to keep a list of replaced (old) TBFs. TBFs are only removed when they are being detached explicitely (see tbf_free and set_ms). Addresses: tbf.cpp:741 We have a schedule for downlink assignment at uplink TBF(TFI=1 TLLI=0xf35a680e DIR=UL STATE=RELEASING), but there is no downlink TBF Sponsored-by: On-Waves ehf
Diffstat (limited to 'src/gprs_ms.cpp')
-rw-r--r--src/gprs_ms.cpp32
1 files changed, 26 insertions, 6 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());