[PATCH] osmo-pcu[master]: Add support for Split block handling for EGPRS UL TBF

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

arvind.sirsikar gerrit-no-reply at lists.osmocom.org
Wed Jul 13 14:18:45 UTC 2016


Review at  https://gerrit.osmocom.org/537

Add support for Split block handling for EGPRS UL TBF

This patch will modify the EGPRS UL TBF flow to support Split block
handling.

Change-Id: I39ca53218b6e0982abc2ab9c703c24c8bf0a09c0
---
M src/encoding.cpp
M src/tbf.h
M src/tbf_ul.cpp
M tests/tbf/TbfTest.err
4 files changed, 170 insertions(+), 26 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/37/537/1

diff --git a/src/encoding.cpp b/src/encoding.cpp
index e174c80..61c63ec 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -276,7 +276,8 @@
 		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
@@ -613,7 +614,8 @@
 	/* 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 ad8ad4c..54c605f 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -439,6 +439,18 @@
 	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 9c9154b..ebb4406 100644
--- a/src/tbf_ul.cpp
+++ b/src/tbf_ul.cpp
@@ -223,36 +223,26 @@
 			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;
-		}
 
-		block->len =
-			Decoding::rlc_copy_to_aligned_buffer(rlc, block_idx, data,
-				rlc_data);
+		if (rdbi->spb) {
+			egprs_rlc_ul_reseg_bsn_state re_assemble_status =
+				handle_egprs_ul_spb(rlc, block,
+							data, block_idx);
+			if (re_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 +383,143 @@
 	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 struct gprs_rlc_data_block_info *rdbi =
+			&rlc->block_info[block_idx];
+
+	union split_block_status *spb_status =
+			&block->spb_status_current;
+
+	uint8_t *rlc_data = &(block->block[0]);
+
+	if (spb_status->block_status_ul &
+				EGPRS_RESEG_FIRST_SEG_RXD) {
+		LOGP(DRLCMACUL, LOGL_DEBUG,
+				"--- Second seg is received "
+				"first seg is already present "
+				"set the status to complete\n");
+		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;
+		return EGPRS_RESEG_DEFAULT;
+
+	} else if (spb_status->block_status_ul == EGPRS_RESEG_DEFAULT) {
+		LOGP(DRLCMACUL, LOGL_DEBUG,
+				"--- Second seg is received "
+				"first seg is not received "
+				"set the status to second seg received\n");
+		block->len = Decoding::rlc_copy_to_aligned_buffer(rlc,
+				block_idx, data, rlc_data);
+		spb_status->block_status_ul = EGPRS_RESEG_SECOND_SEG_RXD;
+		block->block_info = *rdbi;
+		return EGPRS_RESEG_SECOND_SEG_RXD;
+	}
+	return EGPRS_RESEG_INVALID;
+}
+
+
+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 struct 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_current;
+
+	if (spb_status->block_status_ul & EGPRS_RESEG_SECOND_SEG_RXD) {
+		LOGP(DRLCMACUL, LOGL_DEBUG,
+				"--- First seg is received "
+				"second seg is already present "
+				"set the status to complete");
+		static uint8_t seg_data[RLC_MAX_LEN];
+		uint8_t len = block->len;
+
+		/* Assembling the resegmented split blocks */
+		memcpy(seg_data, block->block, len);
+		block->len = Decoding::rlc_copy_to_aligned_buffer(rlc,
+				block_idx, data, rlc_data);
+		memcpy(block->block + block->len, seg_data, len);
+		block->len += len;
+		block->block_info.data_len += rdbi->data_len;
+		spb_status->block_status_ul = EGPRS_RESEG_DEFAULT;
+		return EGPRS_RESEG_DEFAULT;
+	} else if (spb_status->block_status_ul == EGPRS_RESEG_DEFAULT) {
+		LOGP(DRLCMACUL, LOGL_DEBUG,
+				"--- First seg is received "
+				"second seg is not received "
+				"set the status to first seg "
+				"received\n");
+
+		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 EGPRS_RESEG_FIRST_SEG_RXD;
+	}
+	return EGPRS_RESEG_INVALID;
+}
+
+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 struct gprs_rlc_data_block_info *rdbi =
+					&rlc->block_info[block_idx];
+
+	LOGP(DRLCMACUL, LOGL_NOTICE,
+		"-- Got SPB(%d)  "
+		"cs(%s) data block with BSN (%d), "
+		"TFI(%d).\n", rdbi->spb,  rlc->cs.name(), rdbi->bsn,
+		rlc->tfi);
+
+	egprs_rlc_ul_reseg_bsn_state re_assemble_status = EGPRS_RESEG_INVALID;
+
+	/* Section 10.4.8b of 44.060*/
+	if (rdbi->spb == 2)
+		re_assemble_status = handle_egprs_ul_first_seg(rlc,
+						block, data, block_idx);
+	else if (rdbi->spb == 3)
+		re_assemble_status = handle_egprs_ul_second_seg(rlc,
+						block, data, block_idx);
+	else {
+		LOGP(DRLCMACUL, LOGL_ERROR,
+			"-- Not supported SPB for this EGPRS configuration\n");
+		OSMO_ASSERT(false);
+	}
+
+	/*
+	 * When the block is successfully constructed out of segmented blocks
+	 * upgrade the MCS to the type 2
+	 */
+	if (re_assemble_status == EGPRS_RESEG_DEFAULT) {
+		switch (GprsCodingScheme::Scheme(rlc->cs)) {
+		case GprsCodingScheme::MCS3 :
+			block->cs_last = GprsCodingScheme::MCS6;
+			LOGP(DRLCMACUL, LOGL_DEBUG,
+				"-- Upgrading to MCS6\n");
+			break;
+		case GprsCodingScheme::MCS2 :
+			block->cs_last = GprsCodingScheme::MCS5;
+			LOGP(DRLCMACUL, LOGL_DEBUG,
+				"-- Upgrading to MCS5\n");
+			break;
+		case GprsCodingScheme::MCS1 :
+			LOGP(DRLCMACUL, LOGL_DEBUG,
+				"-- Upgrading to MCS4\n");
+			block->cs_last = GprsCodingScheme::MCS4;
+			break;
+		default:
+			OSMO_ASSERT(false);
+			break;
+		}
+	}
+	return re_assemble_status;
+}
diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err
index dc984af..d3e4f46 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) 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 -------------------------

-- 
To view, visit https://gerrit.osmocom.org/537
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I39ca53218b6e0982abc2ab9c703c24c8bf0a09c0
Gerrit-PatchSet: 1
Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Owner: arvind.sirsikar <arvind.sirsikar at radisys.com>



More information about the gerrit-log mailing list