aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAravind Sirsikar <Arvind.Sirsikar@radisys.com>2016-07-26 18:26:21 +0530
committerHolger Freyther <holger@freyther.de>2016-08-02 06:58:58 +0000
commit505a86d396d4ee6e821e8337056e85362a55848f (patch)
tree8b36c01fc40bd0021bbc4c96ba7327589a84cf68
parent36bdc5f7a425426675f7be33fa405501fb45d95a (diff)
Add support for SPB handling for EGPRS UL TBF
This patch will modify the EGPRS UL TBF flow to support Split block handling. This patch also contains test suite modification for SPB UL. Scenarios like MCS6->MCS3, MCS4->MCS1, MCS5->MCS2, MCS9->MCS3 MCS7->MCS2, MCS8->MCS3 have been simulated and Integration tested in NuRAN 1.0 hardware thoroughly. The scope of Unit testing is limited. Change-Id: I39ca53218b6e0982abc2ab9c703c24c8bf0a09c0
-rw-r--r--src/encoding.cpp6
-rw-r--r--src/tbf.h15
-rw-r--r--src/tbf_ul.cpp164
-rw-r--r--tests/tbf/TbfTest.cpp488
-rw-r--r--tests/tbf/TbfTest.err258
-rw-r--r--tests/tbf/TbfTest.ok2
6 files changed, 908 insertions, 25 deletions
diff --git a/src/encoding.cpp b/src/encoding.cpp
index a778ef0b..63049ac3 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -283,7 +283,8 @@ void Encoding::write_packet_uplink_assignment(
bitvec_write_field(dest, wp,0x0,1); // No CONTENTION_RESOLUTION_TLLI
bitvec_write_field(dest, wp,0x0,1); // No COMPACT reduced MA
bitvec_write_field(dest, wp,tbf->current_cs().to_num()-1, 4); // EGPRS Modulation and Coding IE
- bitvec_write_field(dest, wp,0x0,1); // No RESEGMENT
+ /* 0: no RESEGMENT, 1: Segmentation*/
+ bitvec_write_field(dest, wp, 0x1, 1);
bitvec_write_field(dest, wp,ws_enc,5); // EGPRS Window Size
bitvec_write_field(dest, wp,0x0,1); // No Access Technologies Request
bitvec_write_field(dest, wp,0x0,1); // No ARAC RETRANSMISSION REQUEST
@@ -620,7 +621,8 @@ static void write_packet_uplink_ack_egprs(
/* CHANNEL_CODING_COMMAND */
bitvec_write_field(dest, wp,
tbf->current_cs().to_num() - 1, 4);
- bitvec_write_field(dest, wp, 0, 1); // 0: no RESEGMENT (nyi)
+ /* 0: no RESEGMENT, 1: Segmentation*/
+ bitvec_write_field(dest, wp, 1, 1);
bitvec_write_field(dest, wp, 1, 1); // PRE_EMPTIVE_TRANSMISSION, TODO: This resembles GPRS, change it?
bitvec_write_field(dest, wp, 0, 1); // 0: no PRR_RETRANSMISSION_REQUEST, TODO: clarify
bitvec_write_field(dest, wp, 0, 1); // 0: no ARAC_RETRANSMISSION_REQUEST, TODO: clarify
diff --git a/src/tbf.h b/src/tbf.h
index ad8ad4c2..1bd78782 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -439,6 +439,21 @@ struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
int assemble_forward_llc(const gprs_rlc_data *data);
int snd_ul_ud();
+ egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_spb(
+ const struct gprs_rlc_data_info *rlc,
+ struct gprs_rlc_data *block,
+ uint8_t *data, const uint8_t block_idx);
+
+ egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_first_seg(
+ const struct gprs_rlc_data_info *rlc,
+ struct gprs_rlc_data *block,
+ uint8_t *data, const uint8_t block_idx);
+
+ egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_second_seg(
+ const struct gprs_rlc_data_info *rlc,
+ struct gprs_rlc_data *block,
+ uint8_t *data, const uint8_t block_idx);
+
/* Please note that all variables here will be reset when changing
* from WAIT RELEASE back to FLOW state (re-use of TBF).
* All states that need reset must be in this struct, so this is why
diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp
index 9c9154bc..7e0732c8 100644
--- a/src/tbf_ul.cpp
+++ b/src/tbf_ul.cpp
@@ -223,36 +223,28 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(
rdbi->bsn, m_window.v_q(),
m_window.mod_sns(m_window.v_q() + ws - 1));
block = m_rlc.block(rdbi->bsn);
- block->block_info = *rdbi;
- block->cs_last = rlc->cs;
OSMO_ASSERT(rdbi->data_len <= sizeof(block->block));
rlc_data = &(block->block[0]);
- /* TODO: Handle SPB != 0 -> Set length to 2*len, add offset if
- * 2nd part. Note that resegmentation is currently disabled
- * within the UL assignment.
- */
+
if (rdbi->spb) {
- LOGP(DRLCMACUL, LOGL_NOTICE,
- "Got SPB != 0 but resegmentation has been "
- "disabled, skipping %s data block with BSN %d, "
- "TFI=%d.\n", rlc->cs.name(), rdbi->bsn,
- rlc->tfi);
- continue;
- }
+ egprs_rlc_ul_reseg_bsn_state assemble_status;
+
+ assemble_status = handle_egprs_ul_spb(rlc,
+ block, data, block_idx);
- block->len =
- Decoding::rlc_copy_to_aligned_buffer(rlc, block_idx, data,
- rlc_data);
+ if (assemble_status != EGPRS_RESEG_DEFAULT)
+ return 0;
+ } else {
+ block->block_info = *rdbi;
+ block->cs_last = rlc->cs;
+ block->len =
+ Decoding::rlc_copy_to_aligned_buffer(rlc,
+ block_idx, data, rlc_data);
+ }
LOGP(DRLCMACUL, LOGL_DEBUG,
"%s: data_length=%d, data=%s\n",
name(), block->len, osmo_hexdump(rlc_data, block->len));
-
- /* TODO: Handle SPB != 0 -> set state to partly received
- * (upper/lower) and continue with the loop, unless the other
- * part is already present.
- */
-
/* Get/Handle TLLI */
if (rdbi->ti) {
num_chunks = Decoding::rlc_data_from_ul_data(
@@ -393,3 +385,131 @@ int gprs_rlcmac_ul_tbf::snd_ul_ud()
return 0;
}
+egprs_rlc_ul_reseg_bsn_state gprs_rlcmac_ul_tbf::handle_egprs_ul_second_seg(
+ const struct gprs_rlc_data_info *rlc, struct gprs_rlc_data *block,
+ uint8_t *data, const uint8_t block_idx)
+{
+ const gprs_rlc_data_block_info *rdbi = &rlc->block_info[block_idx];
+ union split_block_status *spb_status = &block->spb_status;
+ uint8_t *rlc_data = &block->block[0];
+
+ if (spb_status->block_status_ul &
+ EGPRS_RESEG_FIRST_SEG_RXD) {
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "---%s: Second seg is received "
+ "first seg is already present "
+ "set the status to complete\n", name());
+ spb_status->block_status_ul = EGPRS_RESEG_DEFAULT;
+
+ block->len += Decoding::rlc_copy_to_aligned_buffer(rlc,
+ block_idx, data, rlc_data + block->len);
+ block->block_info.data_len += rdbi->data_len;
+ } else if (spb_status->block_status_ul == EGPRS_RESEG_DEFAULT) {
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "---%s: Second seg is received "
+ "first seg is not received "
+ "set the status to second seg received\n",
+ name());
+
+ block->len = Decoding::rlc_copy_to_aligned_buffer(rlc,
+ block_idx, data,
+ rlc_data + rlc->block_info[block_idx].data_len);
+
+ spb_status->block_status_ul = EGPRS_RESEG_SECOND_SEG_RXD;
+ block->block_info = *rdbi;
+ }
+ return spb_status->block_status_ul;
+}
+
+egprs_rlc_ul_reseg_bsn_state gprs_rlcmac_ul_tbf::handle_egprs_ul_first_seg(
+ const struct gprs_rlc_data_info *rlc, struct gprs_rlc_data *block,
+ uint8_t *data, const uint8_t block_idx)
+{
+ const gprs_rlc_data_block_info *rdbi = &rlc->block_info[block_idx];
+ uint8_t *rlc_data = &block->block[0];
+ union split_block_status *spb_status = &block->spb_status;
+
+ if (spb_status->block_status_ul & EGPRS_RESEG_SECOND_SEG_RXD) {
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "---%s: First seg is received "
+ "second seg is already present "
+ "set the status to complete\n", name());
+
+ block->len += Decoding::rlc_copy_to_aligned_buffer(rlc,
+ block_idx, data, rlc_data);
+
+ block->block_info.data_len = block->len;
+ spb_status->block_status_ul = EGPRS_RESEG_DEFAULT;
+ } else if (spb_status->block_status_ul == EGPRS_RESEG_DEFAULT) {
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "---%s: First seg is received "
+ "second seg is not received "
+ "set the status to first seg "
+ "received\n", name());
+
+ spb_status->block_status_ul = EGPRS_RESEG_FIRST_SEG_RXD;
+ block->len = Decoding::rlc_copy_to_aligned_buffer(rlc,
+ block_idx, data, rlc_data);
+ block->block_info = *rdbi;
+ }
+ return spb_status->block_status_ul;
+}
+
+egprs_rlc_ul_reseg_bsn_state gprs_rlcmac_ul_tbf::handle_egprs_ul_spb(
+ const struct gprs_rlc_data_info *rlc, struct gprs_rlc_data *block,
+ uint8_t *data, const uint8_t block_idx)
+{
+ const gprs_rlc_data_block_info *rdbi = &rlc->block_info[block_idx];
+
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "--%s: Got SPB(%d) "
+ "cs(%s) data block with BSN (%d), "
+ "TFI(%d).\n", name(), rdbi->spb, rlc->cs.name(), rdbi->bsn,
+ rlc->tfi);
+
+ egprs_rlc_ul_reseg_bsn_state assemble_status = EGPRS_RESEG_INVALID;
+
+ /* Section 10.4.8b of 44.060*/
+ if (rdbi->spb == 2)
+ assemble_status = handle_egprs_ul_first_seg(rlc,
+ block, data, block_idx);
+ else if (rdbi->spb == 3)
+ assemble_status = handle_egprs_ul_second_seg(rlc,
+ block, data, block_idx);
+ else {
+ LOGP(DRLCMACUL, LOGL_ERROR,
+ "--%s: spb(%d) Not supported SPB for this EGPRS "
+ "configuration\n",
+ name(), rdbi->spb);
+ }
+
+ /*
+ * When the block is successfully constructed out of segmented blocks
+ * upgrade the MCS to the type 2
+ */
+ if (assemble_status == EGPRS_RESEG_DEFAULT) {
+ switch (GprsCodingScheme::Scheme(rlc->cs)) {
+ case GprsCodingScheme::MCS3 :
+ block->cs_last = GprsCodingScheme::MCS6;
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "--%s: Upgrading to MCS6\n", name());
+ break;
+ case GprsCodingScheme::MCS2 :
+ block->cs_last = GprsCodingScheme::MCS5;
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "--%s: Upgrading to MCS5\n", name());
+ break;
+ case GprsCodingScheme::MCS1 :
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "--%s: Upgrading to MCS4\n", name());
+ block->cs_last = GprsCodingScheme::MCS4;
+ break;
+ default:
+ LOGP(DRLCMACUL, LOGL_ERROR,
+ "--%s: cs(%s) Error in Upgrading to higher MCS\n",
+ name(), rlc->cs.name());
+ break;
+ }
+ }
+ return assemble_status;
+}
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 1071ba30..90253b05 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -35,6 +35,7 @@ extern "C" {
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/vty/vty.h>
+#include <osmocom/gprs/protocol/gsm_04_60.h>
}
#include <errno.h>
@@ -617,6 +618,457 @@ static void send_control_ack(gprs_rlcmac_tbf *tbf)
&ulreq, tbf->poll_fn);
}
+static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
+ uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
+ uint8_t ms_class, uint8_t egprs_ms_class)
+{
+ GprsMs *ms;
+ uint32_t rach_fn = *fn - 51;
+ uint32_t sba_fn = *fn + 52;
+ uint8_t trx_no = 0;
+ int tfi = 0, i = 0;
+ gprs_rlcmac_ul_tbf *ul_tbf;
+ struct gprs_rlcmac_pdch *pdch;
+ gprs_rlcmac_bts *bts;
+ RlcMacUplink_t ulreq = {0};
+ struct pcu_l1_meas meas;
+ struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
+ GprsCodingScheme cs;
+
+ meas.set_rssi(31);
+ bts = the_bts->bts_data();
+
+ /* needed to set last_rts_fn in the PDCH object */
+ request_dl_rlc_block(bts, trx_no, ts_no, fn);
+
+ /*
+ * simulate RACH, this sends an Immediate
+ * Assignment Uplink on the AGCH
+ */
+ the_bts->rcv_rach(0x73, rach_fn, qta);
+
+ /* get next free TFI */
+ tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
+
+ /* fake a resource request */
+ ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
+ ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
+ ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
+ ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
+ ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1;
+ ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
+ Count_MS_RA_capability_value = 1;
+ ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
+ MS_RA_capability_value[0].u.Content.
+ Exist_Multislot_capability = 1;
+ ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
+ MS_RA_capability_value[0].u.Content.Multislot_capability.
+ Exist_GPRS_multislot_class = 1;
+ ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
+ MS_RA_capability_value[0].u.Content.Multislot_capability.
+ GPRS_multislot_class = ms_class;
+ if (egprs_ms_class) {
+ ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
+ MS_RA_capability_value[0].u.Content.
+ Multislot_capability.Exist_EGPRS_multislot_class = 1;
+ ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability.
+ MS_RA_capability_value[0].u.Content.
+ Multislot_capability.EGPRS_multislot_class = ms_class;
+ }
+
+ send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
+
+ /* check the TBF */
+ ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
+ OSMO_ASSERT(ul_tbf != NULL);
+ OSMO_ASSERT(ul_tbf->ta() == qta / 4);
+
+ /* send packet uplink assignment */
+ *fn = sba_fn;
+ request_dl_rlc_block(ul_tbf, fn);
+
+ /* send real acknowledgement */
+ send_control_ack(ul_tbf);
+
+ check_tbf(ul_tbf);
+
+ /* send fake data */
+ uint8_t data_msg[42] = {
+ 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
+ uint8_t(0 | (tfi << 1)),
+ uint8_t(1), /* BSN:7, E:1 */
+ };
+
+ pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
+ pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
+
+ ms = the_bts->ms_by_tlli(tlli);
+ OSMO_ASSERT(ms != NULL);
+ OSMO_ASSERT(ms->ta() == qta/4);
+ OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
+
+ /*
+ * TS 44.060, B.8.1
+ * first seg received first, later second seg
+ */
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 1;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 2;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
+
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_FIRST_SEG_RXD);
+
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 1;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 3;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_DEFAULT);
+ OSMO_ASSERT(block->cs_last ==
+ GprsCodingScheme::MCS6);
+ /* Assembled MCS is MCS6. so the size is 74 */
+ OSMO_ASSERT(block->len == 74);
+
+ /*
+ * TS 44.060, B.8.1
+ * second seg first, later first seg
+ */
+ memset(data_msg, 0, sizeof(data_msg));
+
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 2;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 3;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ block = ul_tbf->m_rlc.block(2);
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_SECOND_SEG_RXD);
+
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 2;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 2;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_DEFAULT);
+ OSMO_ASSERT(block->cs_last ==
+ GprsCodingScheme::MCS6);
+ /* Assembled MCS is MCS6. so the size is 74 */
+ OSMO_ASSERT(block->len == 74);
+
+ /*
+ * TS 44.060, B.8.1
+ * Error scenario with spb as 1
+ */
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 3;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 1;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ block = ul_tbf->m_rlc.block(3);
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_DEFAULT);
+ /*
+ * TS 44.060, B.8.1
+ * comparison of rlc_data for multiple scenarios
+ * Receive First, the second(BSN 3)
+ * Receive First, First then Second(BSN 4)
+ * Receive Second then First(BSN 5)
+ * after above 3 scenarios are triggered,
+ * rlc_data of all 3 BSN are compared
+ */
+
+ /* Initialize the data_msg */
+ for (i = 0; i < 42; i++)
+ data_msg[i] = i;
+
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 3;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 2;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ block = ul_tbf->m_rlc.block(3);
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_FIRST_SEG_RXD);
+
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 3;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 3;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ block = ul_tbf->m_rlc.block(3);
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_DEFAULT);
+ /* Assembled MCS is MCS6. so the size is 74 */
+ OSMO_ASSERT(block->len == 74);
+ OSMO_ASSERT(block->cs_last ==
+ GprsCodingScheme::MCS6);
+
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 4;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 2;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ block = ul_tbf->m_rlc.block(4);
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_FIRST_SEG_RXD);
+
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 4;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 2;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ block = ul_tbf->m_rlc.block(4);
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_FIRST_SEG_RXD);
+
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 4;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 3;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ block = ul_tbf->m_rlc.block(4);
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_DEFAULT);
+ OSMO_ASSERT(block->cs_last ==
+ GprsCodingScheme::MCS6);
+ /* Assembled MCS is MCS6. so the size is 74 */
+ OSMO_ASSERT(block->len == 74);
+
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 5;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 3;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ block = ul_tbf->m_rlc.block(5);
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_SECOND_SEG_RXD);
+
+ cs = GprsCodingScheme::MCS3;
+ egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
+ egprs3->si = 1;
+ egprs3->r = 1;
+ egprs3->cv = 7;
+ egprs3->tfi_hi = tfi & 0x03;
+ egprs3->tfi_lo = (tfi & 0x1c) >> 2;
+ egprs3->bsn1_hi = 5;
+ egprs3->bsn1_lo = 0;
+ egprs3->cps_hi = 1;
+ data_msg[3] = 0xff;
+ egprs3->pi = 0;
+ egprs3->cps_lo = 1;
+ egprs3->rsb = 0;
+ egprs3->spb = 2;
+ egprs3->pi = 0;
+
+ pdch->rcv_block(data_msg, 42, *fn, &meas);
+
+ block = ul_tbf->m_rlc.block(5);
+
+ /* check the status of the block */
+ OSMO_ASSERT(block->spb_status.block_status_ul ==
+ EGPRS_RESEG_DEFAULT);
+ OSMO_ASSERT(block->cs_last ==
+ GprsCodingScheme::MCS6);
+ /* Assembled MCS is MCS6. so the size is 74 */
+ OSMO_ASSERT(block->len == 74);
+
+ OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
+ ul_tbf->m_rlc.block(4)->len);
+ OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
+ ul_tbf->m_rlc.block(3)->len);
+
+ /* Compare the spb status of each BSNs(3,4,5). should be same */
+ OSMO_ASSERT(
+ ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
+ ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
+ OSMO_ASSERT(
+ ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
+ ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
+
+ /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
+ OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
+ ul_tbf->m_rlc.block(4)->cs_last);
+ OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
+ ul_tbf->m_rlc.block(3)->cs_last);
+
+ /* Compare the data of each BSNs(3,4,5). should be same */
+ OSMO_ASSERT(
+ !memcmp(ul_tbf->m_rlc.block(5)->block,
+ ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
+ ));
+ OSMO_ASSERT(
+ !memcmp(ul_tbf->m_rlc.block(5)->block,
+ ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
+ ));
+
+ return ul_tbf;
+}
+
static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts,
uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
uint8_t ms_class, uint8_t egprs_ms_class)
@@ -1179,6 +1631,41 @@ static void test_tbf_ws()
gprs_bssgp_destroy();
}
+static void test_tbf_egprs_two_phase_spb(void)
+{
+ BTS the_bts;
+ int ts_no = 7;
+ uint32_t fn = 2654218;
+ uint16_t qta = 31;
+ uint32_t tlli = 0xf1223344;
+ const char *imsi = "0011223344";
+ uint8_t ms_class = 1;
+ uint8_t egprs_ms_class = 1;
+ gprs_rlcmac_ul_tbf *ul_tbf;
+ GprsMs *ms;
+ uint8_t test_data[256];
+
+ printf("=== start %s ===\n", __func__);
+
+ memset(test_data, 1, sizeof(test_data));
+
+ setup_bts(&the_bts, ts_no, 4);
+ the_bts.bts_data()->initial_mcs_dl = 9;
+ the_bts.bts_data()->egprs_enabled = 1;
+
+ ul_tbf = establish_ul_tbf_two_phase_spb(&the_bts, ts_no, tlli, &fn, qta,
+ ms_class, egprs_ms_class);
+
+ ms = ul_tbf->ms();
+ fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
+ fprintf(stderr,
+ "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta());
+
+ send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data));
+
+ printf("=== end %s ===\n", __func__);
+}
+
static void test_tbf_egprs_two_phase()
{
BTS the_bts;
@@ -1581,6 +2068,7 @@ int main(int argc, char **argv)
test_tbf_gprs_egprs();
test_tbf_ws();
test_tbf_egprs_two_phase();
+ test_tbf_egprs_two_phase_spb();
test_tbf_egprs_dl();
test_tbf_egprs_retx_dl();
diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err
index dc984af6..3eebe1ae 100644
--- a/tests/tbf/TbfTest.err
+++ b/tests/tbf/TbfTest.err
@@ -3351,7 +3351,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2
TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN
TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7
Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7)
-Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f0 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b
+Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b
Got RLC block, coding scheme: CS-1, length: 23 (23))
+++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++
------------------------- RX : Uplink Control Block -------------------------
@@ -3398,6 +3398,262 @@ Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE
TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN
TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0.
TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append
+Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
+MS requests UL TBF on RACH, so we provide one:
+MS requests single block allocation
+RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270
+TX: Immediate Assignment Uplink (AGCH)
+ - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7
+Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b
+Searching for first unallocated TFI: TRX=0
+ Found TFI=0.
+Got RLC block, coding scheme: CS-1, length: 23 (23))
++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++
+------------------------- RX : Uplink Control Block -------------------------
+MS requests UL TBF in packet resource request of single block, so we provide one:
+MS supports EGPRS multislot class 1.
+********** TBF starts here **********
+Allocating UL TBF: MS_CLASS=1/1
+Creating MS object, TLLI = 0x00000000
+Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1
+Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1
+Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS
+Slot Allocation (Algorithm A) for class 1
+- Skipping TS 0, because not enabled
+- Skipping TS 1, because not enabled
+- Skipping TS 2, because not enabled
+- Skipping TS 3, because not enabled
+- Skipping TS 4, because not enabled
+- Skipping TS 5, because not enabled
+- Skipping TS 6, because not enabled
+- Assign uplink TS=7 TFI=0 USF=0
+PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001.
+- Setting Control TS 7
+Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS)
+Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00
+TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN
+TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169.
+Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed
+Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7
+Change control TS to 7 until assinment is complete.
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH)
++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++
+------------------------- TX : Packet Uplink Assignment -------------------------
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7
+Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7)
+Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b
+Got RLC block, coding scheme: CS-1, length: 23 (23))
++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++
+------------------------- RX : Uplink Control Block -------------------------
+RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack
+TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW
+Got RLC block, coding scheme: CS-1, length: 23 (23))
+ UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184
+UL DATA TFI=0 received (V(Q)=0 .. V(R)=0)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got CS-1 RLC data block: CV=15, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=24
+- BSN 0 storing in window (0..63)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=20, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+- Raising V(R) to 1
+- Taking block 0 out, raising V(Q) to 1
+- Assembling frames: (len=20)
+-- Frame 1 starts at offset 0, length=20, is_complete=0
+- No gaps in received block, last block: BSN=0 CV=15
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 08 40 c9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=1 .. V(R)=1)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=1, SPB=2, PI=0, E=1, TI=0, bitoffs=33
+- BSN 1 storing in window (1..64)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(2) cs(MCS-3) data block with BSN (1), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): First seg is received second seg is not received set the status to first seg received
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 08 40 cd 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=1 .. V(R)=1)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=1, SPB=3, PI=0, E=1, TI=0, bitoffs=33
+- BSN 1 storing in window (1..64)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(3) cs(MCS-3) data block with BSN (1), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Second seg is received first seg is already present set the status to complete
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Upgrading to MCS6
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=74, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+- Raising V(R) to 2
+- Taking block 1 out, raising V(Q) to 2
+- Assembling frames: (len=74)
+-- Frame 1 starts at offset 0, length=74, is_complete=0
+- No gaps in received block, last block: BSN=1 CV=7
+- Scheduling Ack/Nack, because MS is stalled.
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 10 40 cd 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=2 .. V(R)=2)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=2, SPB=3, PI=0, E=1, TI=0, bitoffs=33
+- BSN 2 storing in window (2..65)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(3) cs(MCS-3) data block with BSN (2), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Second seg is received first seg is not received set the status to second seg received
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 10 40 c9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=2 .. V(R)=2)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=2, SPB=2, PI=0, E=1, TI=0, bitoffs=33
+- BSN 2 storing in window (2..65)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(2) cs(MCS-3) data block with BSN (2), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): First seg is received second seg is already present set the status to complete
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Upgrading to MCS6
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=74, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+- Raising V(R) to 3
+- Taking block 2 out, raising V(Q) to 3
+- Assembling frames: (len=74)
+-- Frame 1 starts at offset 0, length=74, is_complete=0
+- No gaps in received block, last block: BSN=2 CV=7
+- Scheduling Ack/Nack, because MS is stalled.
+- Sending Ack/Nack is already triggered, don't schedule!
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 18 40 c5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=3 .. V(R)=3)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=3, SPB=1, PI=0, E=1, TI=0, bitoffs=33
+- BSN 3 storing in window (3..66)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(1) cs(MCS-3) data block with BSN (3), TFI(0).
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): spb(1) Not supported SPB for this EGPRS configuration
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 18 40 c9 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=3 .. V(R)=3)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=3, SPB=2, PI=0, E=1, TI=0, bitoffs=33
+- BSN 3 storing in window (3..66)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(2) cs(MCS-3) data block with BSN (3), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): First seg is received second seg is not received set the status to first seg received
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 18 40 cd 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=3 .. V(R)=3)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=3, SPB=3, PI=0, E=1, TI=0, bitoffs=33
+- BSN 3 storing in window (3..66)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(3) cs(MCS-3) data block with BSN (3), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Second seg is received first seg is already present set the status to complete
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Upgrading to MCS6
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=74, data=82 02 83 03 84 04 85 05 86 06 87 07 88 08 89 09 8a 0a 8b 0b 8c 0c 8d 0d 8e 0e 8f 0f 90 10 91 11 92 12 93 13 94 82 02 83 03 84 04 85 05 86 06 87 07 88 08 89 09 8a 0a 8b 0b 8c 0c 8d 0d 8e 0e 8f 0f 90 10 91 11 92 12 93 13 94
+- Raising V(R) to 4
+- Taking block 3 out, raising V(Q) to 4
+- Assembling frames: (len=74)
+-- Frame 1 starts at offset 0, length=74, is_complete=0
+- No gaps in received block, last block: BSN=3 CV=7
+- Scheduling Ack/Nack, because MS is stalled.
+- Sending Ack/Nack is already triggered, don't schedule!
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 20 40 c9 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=4 .. V(R)=4)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=4, SPB=2, PI=0, E=1, TI=0, bitoffs=33
+- BSN 4 storing in window (4..67)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(2) cs(MCS-3) data block with BSN (4), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): First seg is received second seg is not received set the status to first seg received
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 20 40 c9 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=4 .. V(R)=4)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=4, SPB=2, PI=0, E=1, TI=0, bitoffs=33
+- BSN 4 storing in window (4..67)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(2) cs(MCS-3) data block with BSN (4), TFI(0).
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 20 40 cd 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=4 .. V(R)=4)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=4, SPB=3, PI=0, E=1, TI=0, bitoffs=33
+- BSN 4 storing in window (4..67)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(3) cs(MCS-3) data block with BSN (4), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Second seg is received first seg is already present set the status to complete
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Upgrading to MCS6
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=74, data=82 02 83 03 84 04 85 05 86 06 87 07 88 08 89 09 8a 0a 8b 0b 8c 0c 8d 0d 8e 0e 8f 0f 90 10 91 11 92 12 93 13 94 82 02 83 03 84 04 85 05 86 06 87 07 88 08 89 09 8a 0a 8b 0b 8c 0c 8d 0d 8e 0e 8f 0f 90 10 91 11 92 12 93 13 94
+- Raising V(R) to 5
+- Taking block 4 out, raising V(Q) to 5
+- Assembling frames: (len=74)
+-- Frame 1 starts at offset 0, length=74, is_complete=0
+- No gaps in received block, last block: BSN=4 CV=7
+- Scheduling Ack/Nack, because MS is stalled.
+- Sending Ack/Nack is already triggered, don't schedule!
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 28 40 cd 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=5 .. V(R)=5)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=5, SPB=3, PI=0, E=1, TI=0, bitoffs=33
+- BSN 5 storing in window (5..68)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(3) cs(MCS-3) data block with BSN (5), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Second seg is received first seg is not received set the status to second seg received
+Got RLC block, coding scheme: MCS-3, length: 42 (42))
+ UL data: 1f 28 40 c9 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29
+Got MCS-3 RLC block: R=1, SI=1, TFI=0, CPS=5, RSB=0, rc=329
+UL DATA TFI=0 received (V(Q)=5 .. V(R)=5)
+max_cs_ul cannot be derived (current UL CS: UNKNOWN)
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-3 RLC data block: CV=7, BSN=5, SPB=2, PI=0, E=1, TI=0, bitoffs=33
+- BSN 5 storing in window (5..68)
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got SPB(2) cs(MCS-3) data block with BSN (5), TFI(0).
+---TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): First seg is received second seg is already present set the status to complete
+--TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Upgrading to MCS6
+TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=74, data=82 02 83 03 84 04 85 05 86 06 87 07 88 08 89 09 8a 0a 8b 0b 8c 0c 8d 0d 8e 0e 8f 0f 90 10 91 11 92 12 93 13 94 82 02 83 03 84 04 85 05 86 06 87 07 88 08 89 09 8a 0a 8b 0b 8c 0c 8d 0d 8e 0e 8f 0f 90 10 91 11 92 12 93 13 94
+- Raising V(R) to 6
+- Taking block 5 out, raising V(Q) to 6
+- Assembling frames: (len=74)
+-- Frame 1 starts at offset 0, length=74, is_complete=0
+- No gaps in received block, last block: BSN=5 CV=7
+- Scheduling Ack/Nack, because MS is stalled.
+- Sending Ack/Nack is already triggered, don't schedule!
+Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7
+Got MS: TLLI = 0xf1223344, TA = 7
+********** TBF starts here **********
+Allocating DL TBF: MS_CLASS=1/1
+Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS
+Slot Allocation (Algorithm A) for class 0
+- Skipping TS 0, because not enabled
+- Skipping TS 1, because not enabled
+- Skipping TS 2, because not enabled
+- Skipping TS 3, because not enabled
+- Skipping TS 4, because not enabled
+- Skipping TS 5, because not enabled
+- Skipping TS 6, because not enabled
+- Assign downlink TS=7 TFI=0
+PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001.
+- Setting Control TS 7
+Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS)
+Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80
+TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64
+Modifying MS object, TLLI: 0xf1223344 confirmed
+TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START
+Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344'
+Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists
+TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN
+TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0.
+TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append
Searching for first unallocated TFI: TRX=0
Found TFI=0.
********** TBF starts here **********
diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok
index 8a7862ff..0e2edc4f 100644
--- a/tests/tbf/TbfTest.ok
+++ b/tests/tbf/TbfTest.ok
@@ -32,6 +32,8 @@
=== end test_tbf_ws ===
=== start test_tbf_egprs_two_phase ===
=== end test_tbf_egprs_two_phase ===
+=== start test_tbf_egprs_two_phase_spb ===
+=== end test_tbf_egprs_two_phase_spb ===
=== start test_tbf_egprs_dl ===
Testing MCS-1
Testing MCS-2