Change in osmo-bsc[master]: RSL: rx and tx VAMOS Channel Number cbits for VAMOS lchans

neels gerrit-no-reply at lists.osmocom.org
Thu Jun 10 15:22:04 UTC 2021


neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bsc/+/24430 )

Change subject: RSL: rx and tx VAMOS Channel Number cbits for VAMOS lchans
......................................................................

RSL: rx and tx VAMOS Channel Number cbits for VAMOS lchans

Add the Osmocom-specific extension to indicate VAMOS shadow lchans in
RSL, in lchan lookup and RSL message transmission.

Note that RR messages containing cbits (Assignment Command, Handover
Command, ...) must *not* send Osmocom specific cbits to the MS. Only the
RSL messages directed to the BTS send Osmocom specific bits.

Related: SYS#5315 OS#4940
Depends: If33c1695922d110c0d2c60d5c0136caf2587194e (libosmocore)
Change-Id: I957eff0d2c33ec795eda75a4bff21965b0179f73
---
M include/osmocom/bsc/gsm_data.h
M src/osmo-bsc/abis_rsl.c
M src/osmo-bsc/bts_trx.c
M src/osmo-bsc/gsm_04_08_rr.c
M src/osmo-bsc/gsm_data.c
M src/osmo-bsc/lcs_loc_req.c
M tests/handover/handover_test.c
7 files changed, 83 insertions(+), 42 deletions(-)

Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, approved
  fixeria: Looks good to me, but someone else must approve



diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 0d207b8..11b19ec 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -1028,12 +1028,12 @@
 	     const struct abis_om_obj_inst *obj_inst);
 
 int gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
-		      uint8_t ts_nr, uint8_t lchan_nr);
-int gsm_lchan2chan_nr(const struct gsm_lchan *lchan);
+		      uint8_t ts_nr, uint8_t lchan_nr, bool vamos_is_secondary);
+int gsm_lchan2chan_nr(const struct gsm_lchan *lchan, bool allow_osmo_cbits);
 
 int gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
 			  const struct gsm_lchan *lchan,
-			  uint8_t tsc);
+			  uint8_t tsc, bool allow_osmo_cbits);
 int gsm48_lchan2chan_desc_as_configured(struct gsm48_chan_desc *cd, const struct gsm_lchan *lchan,
 					uint8_t tsc);
 
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 9fb5362..c430a16 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -280,7 +280,7 @@
 {
 	struct abis_rsl_dchan_hdr *dh;
 	struct msgb *msg;
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -304,7 +304,7 @@
 	struct abis_rsl_dchan_hdr *dh;
 	struct msgb *msg;
 	uint8_t bs_power_enc;
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -336,7 +336,7 @@
 {
 	struct abis_rsl_dchan_hdr *dh;
 	struct msgb *msg;
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -534,7 +534,7 @@
 
 	struct rsl_ie_chan_mode cm;
 	struct gsm48_chan_desc cd;
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -554,7 +554,7 @@
 	}
 
 	memset(&cd, 0, sizeof(cd));
-	rc = gsm48_lchan2chan_desc(&cd, lchan, lchan->activate.tsc);
+	rc = gsm48_lchan2chan_desc(&cd, lchan, lchan->activate.tsc, true);
 	if (rc) {
 		LOG_LCHAN(lchan, LOGL_ERROR, "Error encoding Channel Number\n");
 		return rc;
@@ -667,7 +667,7 @@
 	struct rsl_ie_chan_mode cm;
 	struct gsm_bts *bts = lchan->ts->trx->bts;
 
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -721,7 +721,7 @@
 	uint8_t l3_len = msg->len;
 	int rc;
 
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -753,7 +753,7 @@
 	struct abis_rsl_dchan_hdr *dh;
 	struct msgb *msg = rsl_msgb_alloc();
 
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -775,7 +775,7 @@
 	struct abis_rsl_dchan_hdr *dh;
 	struct msgb *msg;
 
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -914,7 +914,7 @@
 	struct msgb *msg;
 	struct abis_rsl_dchan_hdr *dh;
 
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -939,7 +939,7 @@
 /* Chapter 8.3.1 */
 int rsl_data_request(struct msgb *msg, uint8_t link_id)
 {
-	int chan_nr = gsm_lchan2chan_nr(msg->lchan);
+	int chan_nr = gsm_lchan2chan_nr(msg->lchan, true);
 	if (chan_nr < 0) {
 		msgb_free(msg);
 		return chan_nr;
@@ -963,7 +963,7 @@
 int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
 {
 	struct msgb *msg;
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -986,7 +986,7 @@
 {
 
 	struct msgb *msg;
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -1903,7 +1903,7 @@
 	ia->proto_discr = GSM48_PDISC_RR;
 	ia->msg_type = GSM48_MT_RR_IMM_ASS;
 	ia->page_mode = GSM48_PM_SAME;
-	rc = gsm48_lchan2chan_desc(&ia->chan_desc, lchan, lchan->tsc);
+	rc = gsm48_lchan2chan_desc(&ia->chan_desc, lchan, lchan->tsc, true);
 	if (rc) {
 		LOG_LCHAN(lchan, LOGL_ERROR, "Error encoding Channel Number\n");
 		return rc;
@@ -2349,7 +2349,7 @@
 	struct msgb *msg;
 	struct abis_rsl_dchan_hdr *dh;
 
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return chan_nr;
 
@@ -2383,7 +2383,7 @@
 	struct abis_rsl_dchan_hdr *dh;
 	uint32_t *att_ip;
 
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	if (chan_nr < 0)
 		return NULL;
 
@@ -2614,7 +2614,7 @@
 	struct msgb *msg;
 	struct abis_rsl_dchan_hdr *dh;
 
-	int chan_nr = gsm_pchan2chan_nr(GSM_PCHAN_TCH_F, ts->nr, 0);
+	int chan_nr = gsm_pchan2chan_nr(GSM_PCHAN_TCH_F, ts->nr, 0, false);
 	if (chan_nr < 0)
 		return chan_nr;
 
diff --git a/src/osmo-bsc/bts_trx.c b/src/osmo-bsc/bts_trx.c
index 3f73f7f..f23f16e 100644
--- a/src/osmo-bsc/bts_trx.c
+++ b/src/osmo-bsc/bts_trx.c
@@ -151,6 +151,7 @@
 	uint8_t cbits = chan_nr >> 3;
 	uint8_t lch_idx;
 	struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
+	bool vamos = false;
 	bool ok;
 
 	if (rc)
@@ -160,6 +161,21 @@
 	 * timeslot that is in transition between pchan modes. That ACK actually confirms the pchan switch, so instead
 	 * of checking the current pchan mode, we must allow any pchans that a dyn TS is capable of. */
 
+	/* Interpret Osmocom specific cbits only for OsmoBTS type */
+	if (trx->bts->model->type == GSM_BTS_TYPE_OSMOBTS) {
+		/* For VAMOS cbits, set vamos = true and handle cbits as their equivalent non-VAMOS cbits below. */
+		switch (cbits) {
+		case ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Bm_ACCHs:
+		case ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Lm_ACCHs(0):
+		case ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Lm_ACCHs(1):
+			cbits &= ~RSL_CHAN_OSMO_VAMOS_MASK;
+			vamos = true;
+			break;
+		default:
+			break;
+		}
+	}
+
 	switch (cbits) {
 	case ABIS_RSL_CHAN_NR_CBITS_Bm_ACCHs:
 		lch_idx = 0;	/* TCH/F */
@@ -207,6 +223,8 @@
 	if (rc && ok)
 		*rc = 0;
 
+	if (vamos && (trx->bts->model->type == GSM_BTS_TYPE_OSMOBTS))
+		lch_idx += ts->max_primary_lchans;
 	return &ts->lchan[lch_idx];
 }
 
diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c
index dc6434b..a641b45 100644
--- a/src/osmo-bsc/gsm_04_08_rr.c
+++ b/src/osmo-bsc/gsm_04_08_rr.c
@@ -546,7 +546,7 @@
 
 	/* mandatory bits */
 	gsm48_cell_desc(&ho->cell_desc, new_lchan->ts->trx->bts);
-	if (gsm48_lchan2chan_desc(&ho->chan_desc, new_lchan, gsm_ts_tsc(new_lchan->ts))) {
+	if (gsm48_lchan2chan_desc(&ho->chan_desc, new_lchan, gsm_ts_tsc(new_lchan->ts), false)) {
 		msgb_free(msg);
 		return NULL;
 	}
@@ -622,7 +622,7 @@
 	 * the chan_desc. But as long as multi-slot configurations
 	 * are not used we seem to be fine.
 	 */
-	rc = gsm48_lchan2chan_desc(&ass->chan_desc, new_lchan, new_lchan->tsc);
+	rc = gsm48_lchan2chan_desc(&ass->chan_desc, new_lchan, new_lchan->tsc, false);
 	if (rc) {
 		msgb_free(msg);
 		return rc;
@@ -703,7 +703,7 @@
 	gh->proto_discr = GSM48_PDISC_RR;
 	gh->msg_type = GSM48_MT_RR_CHAN_MODE_MODIF;
 
-	rc = gsm48_lchan2chan_desc(&cmm->chan_desc, lchan, lchan->modify.tsc);
+	rc = gsm48_lchan2chan_desc(&cmm->chan_desc, lchan, lchan->modify.tsc, false);
 	if (rc) {
 		msgb_free(msg);
 		return rc;
diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
index ce883b0..33a2249 100644
--- a/src/osmo-bsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -496,7 +496,7 @@
 
 /* See Table 10.5.25 of GSM04.08 */
 int gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
-		      uint8_t ts_nr, uint8_t lchan_nr)
+		      uint8_t ts_nr, uint8_t lchan_nr, bool vamos_is_secondary)
 {
 	uint8_t cbits, chan_nr;
 
@@ -505,7 +505,10 @@
 	case GSM_PCHAN_TCH_F_PDCH:
 		if (lchan_nr != 0)
 			return -EINVAL;
-		cbits = 0x01;
+		if (vamos_is_secondary)
+			cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Bm_ACCHs;
+		else
+			cbits = 0x01;
 		break;
 	case GSM_PCHAN_PDCH:
 		if (lchan_nr != 0)
@@ -513,10 +516,14 @@
 		cbits = RSL_CHAN_OSMO_PDCH >> 3;
 		break;
 	case GSM_PCHAN_TCH_H:
-		if (lchan_nr > 1)
+		if (lchan_nr >= 2)
 			return -EINVAL;
-		cbits = 0x02;
-		cbits += lchan_nr;
+		if (vamos_is_secondary)
+			cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Lm_ACCHs(lchan_nr);
+		else {
+			cbits = 0x02;
+			cbits += lchan_nr;
+		}
 		break;
 	case GSM_PCHAN_CCCH_SDCCH4:
 	case GSM_PCHAN_CCCH_SDCCH4_CBCH:
@@ -527,14 +534,14 @@
 		 */
 		if (lchan_nr == CCCH_LCHAN)
 			chan_nr = 0;
-		else
+		else if (lchan_nr >= 4)
 			return -EINVAL;
 		cbits = 0x04;
 		cbits += lchan_nr;
 		break;
 	case GSM_PCHAN_SDCCH8_SACCH8C:
 	case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
-		if (lchan_nr > 7)
+		if (lchan_nr >= 8)
 			return -EINVAL;
 		cbits = 0x08;
 		cbits += lchan_nr;
@@ -552,16 +559,31 @@
 	return chan_nr;
 }
 
-int gsm_lchan2chan_nr(const struct gsm_lchan *lchan)
+/* For RSL, to talk to osmo-bts, we introduce Osmocom specific channel number cbits to indicate VAMOS secondary lchans.
+ * However, in RR, which is sent to the MS, these special cbits must not be sent, but their "normal" equivalent; for RR
+ * messages, pass allow_osmo_cbits = false. */
+int gsm_lchan2chan_nr(const struct gsm_lchan *lchan, bool allow_osmo_cbits)
 {
 	int rc;
 	uint8_t lchan_nr = lchan->nr;
+
+	/* Take care that we never send Osmocom specific cbits to non-Osmo BTS. */
+	if (allow_osmo_cbits && lchan->vamos.is_secondary
+	    && lchan->ts->trx->bts->model->type != GSM_BTS_TYPE_OSMOBTS) {
+		LOG_LCHAN(lchan, LOGL_ERROR, "Cannot address VAMOS shadow lchan on this BTS type: %s\n",
+			  get_value_string(bts_type_names, lchan->ts->trx->bts->model->type));
+		return -ENOTSUP;
+	}
+	if (allow_osmo_cbits && lchan->ts->trx->bts->model->type != GSM_BTS_TYPE_OSMOBTS)
+		allow_osmo_cbits = false;
+
 	/* The VAMOS lchans are behind the primary ones in the ts->lchan[] array. They keep their lchan->nr as in the
 	 * array, but on the wire they are the "shadow" lchans for the primary lchans. For example, for TCH/F, there is
 	 * a primary ts->lchan[0] and a VAMOS ts->lchan[1]. Still, the VAMOS lchan should send chan_nr = 0. */
 	if (lchan->vamos.is_secondary)
 		lchan_nr -= lchan->ts->max_primary_lchans;
-	rc = gsm_pchan2chan_nr(lchan->ts->pchan_is, lchan->ts->nr, lchan_nr);
+	rc = gsm_pchan2chan_nr(lchan->ts->pchan_is, lchan->ts->nr, lchan_nr,
+			       allow_osmo_cbits ? lchan->vamos.is_secondary : false);
 	/* Log an error so that we don't need to add logging to each caller of this function */
 	if (rc < 0)
 		LOG_LCHAN(lchan, LOGL_ERROR,
@@ -692,9 +714,9 @@
 
 int gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
 			  const struct gsm_lchan *lchan,
-			  uint8_t tsc)
+			  uint8_t tsc, bool allow_osmo_cbits)
 {
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, allow_osmo_cbits);
 	if (chan_nr < 0) {
 		/* Log an error so that we don't need to add logging to each caller of this function */
 		LOG_LCHAN(lchan, LOGL_ERROR, "Error encoding Channel Number\n");
@@ -712,7 +734,8 @@
 					const struct gsm_lchan *lchan,
 					uint8_t tsc)
 {
-	int chan_nr = gsm_pchan2chan_nr(lchan->ts->pchan_from_config, lchan->ts->nr, lchan->nr);
+	int chan_nr = gsm_pchan2chan_nr(lchan->ts->pchan_from_config, lchan->ts->nr, lchan->nr,
+					lchan->vamos.is_secondary);
 	if (chan_nr < 0) {
 		/* Log an error so that we don't need to add logging to each caller of this function */
 		LOG_LCHAN(lchan, LOGL_ERROR,
diff --git a/src/osmo-bsc/lcs_loc_req.c b/src/osmo-bsc/lcs_loc_req.c
index d5298eb..7153ce6 100644
--- a/src/osmo-bsc/lcs_loc_req.c
+++ b/src/osmo-bsc/lcs_loc_req.c
@@ -369,7 +369,7 @@
 				.cause = BSSLAP_CAUSE_INTRA_BSS_HO,
 			},
 		};
-		if (gsm48_lchan2chan_desc(&apdu->reset.chan_desc, lchan, lchan->tsc)) {
+		if (gsm48_lchan2chan_desc(&apdu->reset.chan_desc, lchan, lchan->tsc, false)) {
 			lcs_loc_req_fail(LCS_CAUSE_SYSTEM_FAILURE, "Error encoding Channel Number");
 			return;
 		}
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index b741e25..bcf9019 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -103,7 +103,7 @@
 	uint8_t ulm[3], l1i[2], *buf;
 	struct gsm48_hdr *gh;
 	struct gsm48_meas_res *mr;
-	int chan_nr = gsm_lchan2chan_nr(lchan);
+	int chan_nr = gsm_lchan2chan_nr(lchan, true);
 	OSMO_ASSERT(chan_nr >= 0);
 
 	dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
@@ -555,7 +555,7 @@
 	dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
 	dh->c.msg_type = (act) ? RSL_MT_CHAN_ACTIV_ACK : RSL_MT_RF_CHAN_REL_ACK;
 	dh->ie_chan = RSL_IE_CHAN_NR;
-	dh->chan_nr = gsm_lchan2chan_nr(lchan);
+	dh->chan_nr = gsm_lchan2chan_nr(lchan, true);
 
 	msg->dst = rsl_chan_link(lchan);
 	msg->l2h = (unsigned char *)dh;
@@ -568,7 +568,7 @@
 {
 	struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL");
 	struct abis_rsl_rll_hdr *rh;
-	uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
+	uint8_t chan_nr = gsm_lchan2chan_nr(lchan, true);
 	uint8_t *buf;
 	struct gsm48_hdr *gh;
 	struct gsm48_ho_cpl *hc;
@@ -606,7 +606,7 @@
 {
 	struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL");
 	struct abis_rsl_rll_hdr *rh;
-	uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
+	uint8_t chan_nr = gsm_lchan2chan_nr(lchan, true);
 
 	fprintf(stderr, "- Send EST IND for %s\n", gsm_lchan_name(lchan));
 
@@ -628,7 +628,7 @@
 {
 	struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL");
 	struct abis_rsl_rll_hdr *rh;
-	uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
+	uint8_t chan_nr = gsm_lchan2chan_nr(lchan, true);
 
 	fprintf(stderr, "- Send HO DETECT for %s\n", gsm_lchan_name(lchan));
 
@@ -654,7 +654,7 @@
 {
 	struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL");
 	struct abis_rsl_rll_hdr *rh;
-	uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
+	uint8_t chan_nr = gsm_lchan2chan_nr(lchan, true);
 	uint8_t *buf;
 	struct gsm48_hdr *gh;
 	struct gsm48_ho_cpl *hc;

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/24430
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I957eff0d2c33ec795eda75a4bff21965b0179f73
Gerrit-Change-Number: 24430
Gerrit-PatchSet: 19
Gerrit-Owner: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-CC: laforge <laforge at osmocom.org>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210610/dc72d4d9/attachment.htm>


More information about the gerrit-log mailing list