tbf: Remove TBF chaining (m_new_tbf and m_old_tbf)

Currently a new TBF is chained to an existing older one, either of
the other direction (active or releasing) or of the same direction
(releasing). This does not work properly work if and uplink and a
downlink TBF are being established at the same time while an old TBF
is being released. In that case, one of them is thrown away and the
pending procedure is cancelled.

The chaining is no longer necessary since the GprsMs objects have
been introduced which keep track of the active TBFs.

This commit removes the TBF members m_new_tbf and m_old_tbf and the
related methods and code paths.

Note that a new TBF can replace an older TBF entry of the same
direction within an MS object when it is associated with an MS (e.g.
by TLLI or because it is assigned via another, already associated
TBF). In that case, the old TBF is no longer associated with an MS
object.

Ticket: #1674
Sponsored-by: On-Waves ehf
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 83d0a70..84ecb97 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -44,8 +44,6 @@
 static void check_tbf(gprs_rlcmac_tbf *tbf)
 {
 	OSMO_ASSERT(tbf);
-	OSMO_ASSERT(tbf->m_new_tbf == NULL || tbf->m_new_tbf->m_old_tbf == tbf);
-	OSMO_ASSERT(tbf->m_old_tbf == NULL || tbf->m_old_tbf->m_new_tbf == tbf);
 }
 
 static void test_tbf_tlli_update()
@@ -143,7 +141,6 @@
 	dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
 	dl_tbf->set_state(GPRS_RLCMAC_FLOW);
 	dl_tbf->m_wait_confirm = 0;
-	dl_tbf->set_new_tbf(dl_tbf);
 	check_tbf(dl_tbf);
 
 	*trx_no_ = trx_no;
@@ -177,6 +174,7 @@
 	uint32_t fn;
 	uint8_t block_nr;
 	uint8_t trx_no;
+	GprsMs *ms;
 	uint32_t tlli = 0xffeeddcc;
 
 	uint8_t rbb[64/8];
@@ -189,6 +187,7 @@
 	setup_bts(&the_bts, ts_no);
 	dl_tbf = create_dl_tbf(&the_bts, ms_class, &trx_no);
 	dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
+	ms = dl_tbf->ms();
 
 	for (i = 0; i < sizeof(llc_data); i++)
 		llc_data[i] = i%256;
@@ -215,22 +214,25 @@
 
 	/* Clean up and ensure tbfs are in the correct state */
 	OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
-	new_tbf = dl_tbf->new_tbf();
+	new_tbf = ms->dl_tbf();
 	check_tbf(new_tbf);
 	OSMO_ASSERT(new_tbf != dl_tbf);
 	OSMO_ASSERT(new_tbf->tfi() == 1);
 	check_tbf(dl_tbf);
 	dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
 	if (test_mode == TEST_MODE_REVERSE_FREE) {
+		GprsMs::Guard guard(ms);
 		tbf_free(new_tbf);
-		OSMO_ASSERT(dl_tbf->m_new_tbf != new_tbf);
+		OSMO_ASSERT(ms->dl_tbf() == NULL);
 		check_tbf(dl_tbf);
 		tbf_free(dl_tbf);
 	} else {
+		GprsMs::Guard guard(ms);
 		tbf_free(dl_tbf);
-		OSMO_ASSERT(new_tbf->m_new_tbf != dl_tbf);
+		OSMO_ASSERT(ms->dl_tbf() == new_tbf);
 		check_tbf(new_tbf);
 		tbf_free(new_tbf);
+		OSMO_ASSERT(ms->dl_tbf() == NULL);
 	}
 }
 
@@ -302,7 +304,6 @@
 
 	/* Clean up and ensure tbfs are in the correct state */
 	OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
-	OSMO_ASSERT(dl_tbf->new_tbf() == dl_tbf);
 	dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
 	check_tbf(dl_tbf);
 	tbf_free(dl_tbf);
diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err
index 2d97c9b..03921c5 100644
--- a/tests/tbf/TbfTest.err
+++ b/tests/tbf/TbfTest.err
@@ -83,13 +83,12 @@
 TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) starting timer 0.
 DL packet loss of IMSI= / TLLI=0x00000000: 0%
 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=WAIT RELEASE) free
-TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=WAIT RELEASE) New TBF TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) still exists, detaching
 ********** TBF ends here **********
 TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) free
 TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) stopping timer 0.
 Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN)
-Destroying MS object, TLLI = 0xffeeddcc
 ********** TBF ends here **********
+Destroying MS object, TLLI = 0xffeeddcc
 Searching for first unallocated TFI: TRX=0 first TS=4
  Found TFI=0.
 ********** TBF starts here **********
@@ -154,13 +153,12 @@
 TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) starting timer 0.
 TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) free
 TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) stopping timer 0.
-TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) Old TBF TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=WAIT RELEASE) still exists, detaching
 Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN)
-Destroying MS object, TLLI = 0xffeeddcc
 ********** TBF ends here **********
 DL packet loss of IMSI= / TLLI=0x00000000: 0%
 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=WAIT RELEASE) free
 ********** TBF ends here **********
+Destroying MS object, TLLI = 0xffeeddcc
 Searching for first unallocated TFI: TRX=0 first TS=4
  Found TFI=0.
 ********** TBF starts here **********