[PATCH] osmo-pcu[master]: Handle Immediate assignment reject

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
Mon Nov 7 10:33:16 UTC 2016


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

Handle Immediate assignment reject

When RACH is received, PCU will generate the Immediate assignment reject
message if no resources are present. The encoding is done based on section
9.1.20 of 44.018 version 11.7.0 Release 11. This patch also includes the
test case to validate the generated Immediate assignment reject message.

This patch is integration tested on Osmo-trx setup with Ettus B210 board
and LG F70 MS with some simulation code changes in Osmo-pcu.

Change-Id: I3d33e2b9746fa4f338fad0e6b63b1c5f07de6f9b
---
M src/bts.cpp
M src/encoding.cpp
M src/encoding.h
M tests/types/TypesTest.cpp
M tests/types/TypesTest.ok
5 files changed, 157 insertions(+), 26 deletions(-)


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

diff --git a/src/bts.cpp b/src/bts.cpp
index 4aa5c2c..345af76 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -475,12 +475,13 @@
 	uint8_t trx_no, ts_no = 0;
 	uint8_t sb = 0;
 	uint32_t sb_fn = 0;
-	int rc;
+	int rc = 0;
 	int plen;
 	uint8_t usf = 7;
-	uint8_t tsc, ta = qta2ta(qta);
+	uint8_t tsc = 0, ta = qta2ta(qta);
 	uint16_t ms_class = 0;
 	uint16_t priority = 0;
+	bool failure = false;
 
 	rach_frame();
 
@@ -492,7 +493,8 @@
 	if (sb) {
 		rc = sba()->alloc(&trx_no, &ts_no, &sb_fn, ta);
 		if (rc < 0)
-			return rc;
+			failure = true;
+
 		LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] RACH qbit-ta=%d "
 			"ra=0x%02x, Fn=%d (%d,%d,%d), SBFn=%d\n",
 			qta, ra,
@@ -516,25 +518,28 @@
 
 		if (!tbf) {
 			LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
-			/* FIXME: send reject */
-			return -EBUSY;
+			rc = -EBUSY;
+			failure = true;
+		} else {
+			tbf->set_ta(ta);
+			tbf->set_state(GPRS_RLCMAC_FLOW);
+			tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH);
+			tbf_timer_start(tbf, 3169, m_bts.t3169, 0);
+			LOGP(DRLCMAC, LOGL_DEBUG, "%s [UPLINK] START\n",
+					tbf_name(tbf));
+			LOGP(DRLCMAC, LOGL_DEBUG, "%s RX: [PCU <- BTS] RACH "
+					"qbit-ta=%d ra=0x%02x, Fn=%d (%d,%d,%d)\n",
+					tbf_name(tbf),
+					qta, ra, Fn, (Fn / (26 * 51)) % 32,
+					Fn % 51, Fn % 26);
+			LOGP(DRLCMAC, LOGL_INFO, "%s TX: START Immediate "
+					"Assignment Uplink (AGCH)\n",
+					tbf_name(tbf));
+			trx_no = tbf->trx->trx_no;
+			ts_no = tbf->first_ts;
+			usf = tbf->m_usf[ts_no];
+			tsc = tbf->tsc();
 		}
-		tbf->set_ta(ta);
-		tbf->set_state(GPRS_RLCMAC_FLOW);
-		tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH);
-		tbf_timer_start(tbf, 3169, m_bts.t3169, 0);
-		LOGP(DRLCMAC, LOGL_DEBUG, "%s [UPLINK] START\n",
-			tbf_name(tbf));
-		LOGP(DRLCMAC, LOGL_DEBUG, "%s RX: [PCU <- BTS] RACH "
-			"qbit-ta=%d ra=0x%02x, Fn=%d (%d,%d,%d)\n",
-			tbf_name(tbf),
-			qta, ra, Fn, (Fn / (26 * 51)) % 32, Fn % 51, Fn % 26);
-		LOGP(DRLCMAC, LOGL_INFO, "%s TX: START Immediate "
-			"Assignment Uplink (AGCH)\n", tbf_name(tbf));
-		trx_no = tbf->trx->trx_no;
-		ts_no = tbf->first_ts;
-		usf = tbf->m_usf[ts_no];
-		tsc = tbf->tsc();
 	}
 	bitvec *immediate_assignment = bitvec_alloc(22) /* without plen */;
 	bitvec_unhex(immediate_assignment,
@@ -545,17 +550,22 @@
 		trx_no, m_bts.trx[trx_no].arfcn, ts_no, ta, tsc,
 		tbf ? tbf->tfi() : -1, usf);
 
-	plen = Encoding::write_immediate_assignment(
-		tbf, immediate_assignment, 0, ra, Fn, ta,
-		m_bts.trx[trx_no].arfcn, ts_no, tsc, usf, 0, sb_fn,
-		m_bts.alpha, m_bts.gamma, -1, burst_type, sb);
+	if (failure == false)
+		plen = Encoding::write_immediate_assignment(
+			tbf, immediate_assignment, 0, ra, Fn, ta,
+			m_bts.trx[trx_no].arfcn, ts_no, tsc, usf, 0, sb_fn,
+			m_bts.alpha, m_bts.gamma, -1, burst_type, sb);
+	else
+		plen = Encoding::write_immediate_assignment_reject(
+			immediate_assignment, ra, Fn,
+			burst_type);
 
 	if (plen >= 0)
 		pcu_l1if_tx_agch(immediate_assignment, plen);
 
 	bitvec_free(immediate_assignment);
 
-	return 0;
+	return rc;
 }
 
 uint8_t BTS::is_single_block(uint16_t ra, enum ph_burst_type burst_type,
diff --git a/src/encoding.cpp b/src/encoding.cpp
index 7d3fa14..970714d 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -215,6 +215,82 @@
 }
 
 /*
+ * Immediate assignment reject, sent on the CCCH/AGCH
+ * see GSM 44.018, 9.1.20 + 10.5.2.30
+ */
+int Encoding::write_immediate_assignment_reject(
+	bitvec *dest, uint16_t ra,
+	uint32_t ref_fn,
+	enum ph_burst_type burst_type)
+{
+	unsigned wp = 0;
+	int plen;
+	int i;
+
+	bitvec_write_field(dest, wp, 0x0, 4);  // Skip Indicator
+	bitvec_write_field(dest, wp, 0x6, 4);  // Protocol Discriminator
+	bitvec_write_field(dest, wp, 0x3A, 8); // Immediate Assign Message Type
+
+	// feature indicator
+	bitvec_write_field(dest, wp, 0x0, 1);      // spare
+	bitvec_write_field(dest, wp, 0x0, 1);      // spare
+	bitvec_write_field(dest, wp, 0x0, 1);      // no cs
+	bitvec_write_field(dest, wp, 0x1, 1);      // implicit detach for PS
+
+	bitvec_write_field(dest, wp, 0x0, 4); // Page Mode
+	/*
+	 * 9.1.20.2 of 44.018 version 11.7.0 Release 11
+	 * Filling of the message
+	 * If necessary the request reference information element and the
+	 * wait indication information element should be duplicated to
+	 * fill the message.
+	*/
+	for (i = 0; i < 4; i++) {
+		//10.5.2.30 Request Reference
+		if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) ||
+			(burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) {
+			//9.1.20.2a of 44.018 version 11.7.0 Release 11
+			bitvec_write_field(dest, wp, 0x7f, 8);  /* RACH value */
+		} else {
+			bitvec_write_field(dest, wp, ra, 8);	/* RACH value */
+		}
+
+		bitvec_write_field(dest, wp,
+					(ref_fn / (26 * 51)) % 32, 5); // T1'
+		bitvec_write_field(dest, wp, ref_fn % 51, 6);          // T3
+		bitvec_write_field(dest, wp, ref_fn % 26, 5);          // T2
+
+		/* TODO: Make it configurable */
+		bitvec_write_field(dest, wp, 20, 8); //Wait Indication 1
+	}
+
+	plen = wp / 8;
+
+	if ((wp % 8)) {
+		LOGP(DRLCMACUL, LOGL_ERROR, "Length of IMM.ASS.Rej without"
+			"rest octets is not multiple of 8 bits, PLEASE FIX!\n");
+		return -1;
+	}
+
+	// Extended RA
+	else if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) ||
+			(burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) {
+		//9.1.20.2a of 44.018 version 11.7.0 Release 11
+		uint8_t extended_ra = 0;
+		extended_ra = (ra & 0x1F);
+		bitvec_write_field(dest, wp, 0x1, 1);
+		bitvec_write_field(dest, wp, extended_ra, 5); /* Extended RA */
+	} else {
+		bitvec_write_field(dest, wp, 0x0, 1);
+	}
+	bitvec_write_field(dest, wp, 0x0, 1);
+	bitvec_write_field(dest, wp, 0x0, 1);
+	bitvec_write_field(dest, wp, 0x0, 1);
+
+	return plen;
+}
+
+/*
  * Immediate assignment, sent on the CCCH/AGCH
  * see GSM 04.08, 9.1.18 and GSM 44.018, 9.1.18 + 10.5.2.16
  */
diff --git a/src/encoding.h b/src/encoding.h
index 69f8cdc..79dc32d 100644
--- a/src/encoding.h
+++ b/src/encoding.h
@@ -52,6 +52,12 @@
 				GSM_L1_BURST_TYPE_ACCESS_0,
 			uint8_t sb = 1);
 
+	static int write_immediate_assignment_reject(
+			bitvec *dest, uint16_t ra,
+			uint32_t ref_fn,
+			enum ph_burst_type burst_type
+		);
+
 	static void write_packet_uplink_assignment(
 			struct gprs_rlcmac_bts *bts,
 			bitvec * dest, uint8_t old_tfi,
diff --git a/tests/types/TypesTest.cpp b/tests/types/TypesTest.cpp
index 8b3cfd1..ee1c817 100644
--- a/tests/types/TypesTest.cpp
+++ b/tests/types/TypesTest.cpp
@@ -427,6 +427,42 @@
 	}
 }
 
+void test_immediate_assign_rej()
+{
+	uint8_t plen;
+	bitvec *immediate_assignment_rej = bitvec_alloc(22);
+
+	bitvec_unhex(immediate_assignment_rej,
+		"2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
+	plen = Encoding::write_immediate_assignment_reject(
+		immediate_assignment_rej, 112, 100,
+		GSM_L1_BURST_TYPE_ACCESS_1);
+
+	printf("assignment reject: %s\n",
+		osmo_hexdump(immediate_assignment_rej->data, 22));
+
+	OSMO_ASSERT(plen == 19);
+	/* RA value */
+	OSMO_ASSERT(immediate_assignment_rej->data[3] == 0x7f);
+	/* Extended RA value */
+	OSMO_ASSERT(immediate_assignment_rej->data[19] == 0xc0);
+
+	bitvec_unhex(immediate_assignment_rej,
+		"2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
+
+	plen = Encoding::write_immediate_assignment_reject(
+		immediate_assignment_rej, 112, 100,
+		GSM_L1_BURST_TYPE_ACCESS_0);
+
+	printf("assignment reject: %s\n",
+		osmo_hexdump(immediate_assignment_rej->data, 22));
+
+	OSMO_ASSERT(plen == 19);
+	/* RA value */
+	OSMO_ASSERT(immediate_assignment_rej->data[3] == 0x70);
+
+}
+
 int main(int argc, char **argv)
 {
 	osmo_init_logging(&gprs_log_info);
@@ -439,6 +475,7 @@
 	test_rlc_v_b();
 	test_rlc_v_n();
 	test_rlc_dl_ul_basic();
+	test_immediate_assign_rej();
 	return EXIT_SUCCESS;
 }
 
diff --git a/tests/types/TypesTest.ok b/tests/types/TypesTest.ok
index cb40d39..fe5162c 100644
--- a/tests/types/TypesTest.ok
+++ b/tests/types/TypesTest.ok
@@ -6,3 +6,5 @@
 rbb: 10 00 00 00 00 00 00 01 
 show_rbb: RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
 show_rbb: IIRRIIIR
+assignment reject: 06 3a 10 7f 06 36 14 7f 06 36 14 7f 06 36 14 7f 06 36 14 c0 2b 2b 
+assignment reject: 06 3a 10 70 06 36 14 70 06 36 14 70 06 36 14 70 06 36 14 0b 2b 2b 

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3d33e2b9746fa4f338fad0e6b63b1c5f07de6f9b
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