aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/tbf.cpp58
-rw-r--r--src/tbf.h1
-rw-r--r--tests/tbf/TbfTest.cpp19
-rw-r--r--tests/tbf/TbfTest.err17
4 files changed, 79 insertions, 16 deletions
diff --git a/src/tbf.cpp b/src/tbf.cpp
index e3a441a..9f873dc 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -83,7 +83,8 @@ void gprs_rlcmac_tbf::assign_imsi(const char *imsi_)
"%s the IMSI '%s' was already assigned to another "
"MS object: TLLI = 0x%08x, that IMSI will be removed\n",
name(), imsi_, old_ms->tlli());
- old_ms->set_imsi("");
+
+ merge_and_clear_ms(old_ms);
}
m_ms->set_imsi(imsi_);
@@ -156,6 +157,49 @@ void gprs_rlcmac_tbf::set_ms(GprsMs *ms)
m_ms->attach_tbf(this);
}
+void gprs_rlcmac_tbf::merge_and_clear_ms(GprsMs *old_ms)
+{
+ if (old_ms == ms())
+ return;
+
+ GprsMs::Guard guard_old(old_ms);
+
+ if (strlen(ms()->imsi()) == 0 && strlen(old_ms->imsi()) != 0) {
+ ms()->set_imsi(old_ms->imsi());
+ old_ms->set_imsi("");
+ }
+
+ if (!ms()->ms_class() && old_ms->ms_class())
+ ms()->set_ms_class(old_ms->ms_class());
+
+ /* Clean up the old MS object */
+ /* TODO: Use timer? */
+ if (old_ms->ul_tbf() && old_ms->ul_tbf()->T == 0) {
+ if (old_ms->ul_tbf() == this) {
+ LOGP(DRLCMAC, LOGL_ERROR,
+ "%s is referred by the old MS "
+ "and will not be deleted\n",
+ name());
+ set_ms(NULL);
+ } else {
+ tbf_free(old_ms->ul_tbf());
+ }
+ }
+ if (old_ms->dl_tbf() && old_ms->dl_tbf()->T == 0) {
+ if (old_ms->dl_tbf() == this) {
+ LOGP(DRLCMAC, LOGL_ERROR,
+ "%s is referred by the old MS "
+ "and will not be deleted\n",
+ name());
+ set_ms(NULL);
+ } else {
+ tbf_free(old_ms->dl_tbf());
+ }
+ }
+
+ old_ms->reset();
+}
+
void gprs_rlcmac_tbf::update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction dir)
{
if (!ms())
@@ -164,6 +208,18 @@ void gprs_rlcmac_tbf::update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction di
if (!tlli)
return;
+ /* TODO: When the TLLI does not match the ms, check if there is another
+ * MS object that belongs to that TLLI and if yes make sure one of them
+ * gets deleted. This is the same problem that can arise with
+ * assign_imsi() so there should be a unified solution */
+ if (!ms()->check_tlli(tlli)) {
+ GprsMs *old_ms;
+
+ old_ms = bts->ms_store().get_ms(tlli, 0, NULL);
+ if (old_ms)
+ merge_and_clear_ms(old_ms);
+ }
+
if (dir == GPRS_RLCMAC_UL_TBF)
ms()->set_tlli(tlli);
else
diff --git a/src/tbf.h b/src/tbf.h
index 5c198d3..a596ad7 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -226,6 +226,7 @@ protected:
gprs_rlcmac_bts *bts_data() const;
int extract_tlli(const uint8_t *data, const size_t len);
+ void merge_and_clear_ms(GprsMs *old_ms);
static const char *tbf_state_name[6];
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 80bc818..19895ad 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -388,18 +388,23 @@ static void test_tbf_imsi()
OSMO_ASSERT(ms1 == ms2);
/* use the same IMSI on TBF 2 */
- dl_tbf[1]->assign_imsi("001001000000002");
- ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
- OSMO_ASSERT(ms1 != NULL);
- OSMO_ASSERT(ms1 != ms2);
- OSMO_ASSERT(strcmp(ms1->imsi(), "001001000000002") == 0);
- OSMO_ASSERT(strcmp(ms2->imsi(), "") == 0);
+ {
+ GprsMs::Guard guard(ms2);
+ dl_tbf[1]->assign_imsi("001001000000002");
+ ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
+ OSMO_ASSERT(ms1 != NULL);
+ OSMO_ASSERT(ms1 != ms2);
+ OSMO_ASSERT(strcmp(ms1->imsi(), "001001000000002") == 0);
+ OSMO_ASSERT(strcmp(ms2->imsi(), "") == 0);
+ }
+
+ ms2 = the_bts.ms_store().get_ms(0xf1000001);
+ OSMO_ASSERT(ms2 == NULL);
tbf_free(dl_tbf[1]);
ms1 = the_bts.ms_store().get_ms(0, 0, "001001000000002");
OSMO_ASSERT(ms1 == NULL);
- tbf_free(dl_tbf[0]);
printf("=== end %s ===\n", __func__);
}
diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err
index 099504f..3524522 100644
--- a/tests/tbf/TbfTest.err
+++ b/tests/tbf/TbfTest.err
@@ -462,20 +462,21 @@ The MS object cannot fully confirm an unexpected TLLI: 0xf1000002, partly confir
Modifying MS object, TLLI = 0xf1000001, IMSI '' -> '001001000000001'
Modifying MS object, TLLI = 0xf1000001, IMSI '001001000000001' -> '001001000000002'
TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW) the IMSI '001001000000002' was already assigned to another MS object: TLLI = 0xf1000001, that IMSI will be removed
-Modifying MS object, TLLI = 0xf1000001, IMSI '001001000000002' -> ''
Modifying MS object, TLLI = 0xf1000002, IMSI '' -> '001001000000002'
+Modifying MS object, TLLI = 0xf1000001, IMSI '001001000000002' -> ''
+TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW) free
+TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX!
+PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW), 1 TBFs, USFs = 00, TFIs = 00000002.
+Detaching TBF from MS object, TLLI = 0xf1000001, TBF = TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW)
+********** TBF ends here **********
+Clearing MS object, TLLI: 0xf1000001, IMSI: ''
+Destroying MS object, TLLI = 0x00000000
TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW) free
TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX!
-PDCH(TS 4, TRX 0): Detaching TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW), 1 TBFs, USFs = 00, TFIs = 00000001.
+PDCH(TS 4, TRX 0): Detaching TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW), 0 TBFs, USFs = 00, TFIs = 00000000.
Detaching TBF from MS object, TLLI = 0xf1000002, TBF = TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW)
Destroying MS object, TLLI = 0xf1000002
********** TBF ends here **********
-TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW) free
-TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX!
-PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW), 0 TBFs, USFs = 00, TFIs = 00000000.
-Detaching TBF from MS object, TLLI = 0xf1000001, TBF = TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW)
-Destroying MS object, TLLI = 0xf1000001
-********** TBF ends here **********
********** TBF starts here **********
Allocating DL TBF: MS_CLASS=45
Creating MS object, TLLI = 0x00000000