aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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