Change in osmo-bts[master]: osmo-bts-trx: refactor handling of version specific TRXD parts

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/.

fixeria gerrit-no-reply at lists.osmocom.org
Tue Apr 20 23:05:21 UTC 2021


fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/23832 )


Change subject: osmo-bts-trx: refactor handling of version specific TRXD parts
......................................................................

osmo-bts-trx: refactor handling of version specific TRXD parts

Change-Id: I7aedd85a8d4f6d6191cd3b75272a688208fb2879
Related: SYS#4895, OS#4941, OS#4006
---
M src/osmo-bts-trx/trx_if.c
1 file changed, 103 insertions(+), 122 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/32/23832/1

diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index a458fa6..bd04f5c 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -723,29 +723,18 @@
 /* Uplink TRXDv1 header length: additional MTS + C/I */
 #define TRX_UL_V1HDR_LEN	(TRX_UL_V0HDR_LEN + 1 + 2)
 
-/* TRXD header dissector for version 0 */
-static int trx_data_handle_hdr_v0(struct trx_l1h *l1h,
-				  struct trx_ul_burst_ind *bi,
-				  const uint8_t *buf, size_t buf_len)
+/* Parser for TRXDv0 header (and part of TRXDv1) */
+static inline void trx_data_parse_hdr_v0(struct trx_ul_burst_ind *bi,
+					 const uint8_t *buf)
 {
-	/* Make sure we have enough data */
-	if (buf_len < TRX_UL_V0HDR_LEN) {
-		LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR,
-			"Short read on TRXD, missing version 0 header "
-			"(len=%zu vs expected %d)\n", buf_len, TRX_UL_V0HDR_LEN);
-		return -EIO;
-	}
-
 	bi->tn = buf[0] & 0b111;
 	bi->fn = osmo_load32be(buf + 1);
 	bi->rssi = -(int8_t)buf[5];
 	bi->toa256 = (int16_t) osmo_load16be(buf + 6);
-
-	return TRX_UL_V0HDR_LEN;
 }
 
 /* Parser for MTS (Modulation and Training Sequence) */
-static int trx_data_parse_mts(struct trx_l1h *l1h,
+static int trx_data_parse_mts(struct phy_instance *phy_inst,
 			      struct trx_ul_burst_ind *bi,
 			      const uint8_t mts)
 {
@@ -764,7 +753,7 @@
 		bi->mod = TRX_MOD_T_8PSK;
 		bi->tsc_set = (mts >> 3) & 0x01;
 	} else {
-		LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR,
+		LOGPPHI(phy_inst, DTRX, LOGL_ERROR,
 			"Rx TRXD PDU with unknown or not supported "
 			"modulation (MTS=0x%02x)\n", mts);
 		return -ENOTSUP;
@@ -778,32 +767,51 @@
 	return 0;
 }
 
-/* TRXD header dissector for version 0x01 */
-static int trx_data_handle_hdr_v1(struct trx_l1h *l1h,
-				  struct trx_ul_burst_ind *bi,
-				  const uint8_t *buf, size_t buf_len)
+/* Parser for TRXDv0 PDU */
+static int trx_data_parse_pdu_v0(struct phy_instance *phy_inst,
+				 struct trx_ul_burst_ind *bi,
+				 const uint8_t *buf, size_t buf_len)
+{
+	/* Parse TRXDv0 specific header part */
+	trx_data_parse_hdr_v0(bi, buf);
+	buf_len -= TRX_UL_V0HDR_LEN;
+
+	/* Guess modulation and burst length by the rest octets.
+	 * NOTE: a legacy transceiver may append two garbage bytes. */
+	switch (buf_len) {
+	case EGPRS_BURST_LEN + 2:
+	case EGPRS_BURST_LEN:
+		bi->burst_len = EGPRS_BURST_LEN;
+		bi->mod = TRX_MOD_T_GMSK;
+		break;
+	case GSM_BURST_LEN + 2:
+	case GSM_BURST_LEN:
+		bi->burst_len = GSM_BURST_LEN;
+		bi->mod = TRX_MOD_T_GMSK;
+		break;
+	default:
+		LOGPPHI(phy_inst, DTRX, LOGL_NOTICE,
+			"Rx TRXD PDU with odd burst length %zu\n", buf_len);
+		return -EINVAL;
+	}
+
+	return TRX_UL_V0HDR_LEN;
+}
+
+/* Parser for TRXDv1 PDU */
+static int trx_data_parse_pdu_v1(struct phy_instance *phy_inst,
+				 struct trx_ul_burst_ind *bi,
+				 const uint8_t *buf, size_t buf_len)
 {
 	int rc;
 
-	/* Make sure we have enough data */
-	if (buf_len < TRX_UL_V1HDR_LEN) {
-		LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR,
-			"Short read on TRXD, missing version 1 header "
-			"(len=%zu vs expected %d)\n", buf_len, TRX_UL_V1HDR_LEN);
-		return -EIO;
-	}
-
-	/* Parse v0 specific part */
-	rc = trx_data_handle_hdr_v0(l1h, bi, buf, buf_len);
-	if (rc < 0)
-		return rc;
-
-	/* Move closer to the v1 specific part */
-	buf_len -= rc;
-	buf += rc;
+	/* Parse TRXDv0 specific header part */
+	trx_data_parse_hdr_v0(bi, buf);
+	buf_len -= TRX_UL_V0HDR_LEN;
+	buf += TRX_UL_V0HDR_LEN;
 
 	/* MTS (Modulation and Training Sequence) */
-	rc = trx_data_parse_mts(l1h, bi, buf[0]);
+	rc = trx_data_parse_mts(phy_inst, bi, buf[0]);
 	if (rc < 0)
 		return rc;
 
@@ -814,31 +822,28 @@
 	return TRX_UL_V1HDR_LEN;
 }
 
-/* TRXD burst handler for PDU version 0 */
-static int trx_data_handle_burst_v0(struct trx_l1h *l1h,
-				    struct trx_ul_burst_ind *bi,
-				    const uint8_t *buf, size_t buf_len)
+/* Parser for burst bits (version independent) */
+static int trx_data_parse_burst(struct trx_ul_burst_ind *bi,
+				const uint8_t *buf, size_t buf_len)
 {
 	size_t i;
 
-	/* Verify burst length */
-	switch (buf_len) {
-	/* Legacy transceivers append two padding bytes */
-	case EGPRS_BURST_LEN + 2:
-	case GSM_BURST_LEN + 2:
-		bi->burst_len = buf_len - 2;
-		break;
-	case EGPRS_BURST_LEN:
-	case GSM_BURST_LEN:
-		bi->burst_len = buf_len;
-		break;
-
-	default:
-		LOGPPHI(l1h->phy_inst, DTRX, LOGL_NOTICE,
-			"Rx TRXD message with odd burst length %zu\n", buf_len);
-		return -EINVAL;
+	/* NOPE.ind contains no burst */
+	if (bi->flags | TRX_BI_F_NOPE_IND) {
+		bi->burst_len = 0;
+		return 0;
 	}
 
+	/* Modulation types defined in 3GPP TS 45.002 */
+	static const size_t bl[] = {
+		[TRX_MOD_T_GMSK] = 148, /* 1 bit per symbol */
+		[TRX_MOD_T_8PSK] = 444, /* 3 bits per symbol */
+	};
+
+	bi->burst_len = bl[bi->mod];
+	if (buf_len < bi->burst_len)
+		return -EINVAL;
+
 	/* Convert unsigned soft-bits [254..0] to soft-bits [-127..127] */
 	for (i = 0; i < bi->burst_len; i++) {
 		if (buf[i] == 255)
@@ -850,30 +855,6 @@
 	return 0;
 }
 
-/* TRXD burst handler for PDU version 1 */
-static int trx_data_handle_burst_v1(struct trx_l1h *l1h,
-				    struct trx_ul_burst_ind *bi,
-				    const uint8_t *buf, size_t buf_len)
-{
-	/* Modulation types defined in 3GPP TS 45.002 */
-	static const size_t bl[] = {
-		[TRX_MOD_T_GMSK] = 148, /* 1 bit per symbol */
-		[TRX_MOD_T_8PSK] = 444, /* 3 bits per symbol */
-	};
-
-	/* Verify burst length */
-	if (bl[bi->mod] != buf_len) {
-		LOGPPHI(l1h->phy_inst, DTRX, LOGL_NOTICE,
-			"Rx TRXD message with odd burst length %zu, "
-			"expected %zu\n", buf_len, bl[bi->mod]);
-		return -EINVAL;
-	}
-
-	/* The PDU format is the same as for version 0.
-	 * NOTE: other modulation types to be handled separately. */
-	return trx_data_handle_burst_v0(l1h, bi, buf, buf_len);
-}
-
 static const char *trx_data_desc_msg(const struct trx_ul_burst_ind *bi)
 {
 	struct osmo_strbuf sb;
@@ -916,15 +897,31 @@
 	return buf;
 }
 
+static const struct {
+	int (*parse)(struct phy_instance *phy_inst,
+		     struct trx_ul_burst_ind *bi,
+		     const uint8_t *buf, size_t buf_len);
+	size_t hdr_len;
+} trx_data_codec[16] = {
+	[0] = { /* TRXDv0 */
+		.hdr_len = TRX_UL_V0HDR_LEN,
+		.parse = &trx_data_parse_pdu_v0,
+	},
+	[1] = { /* TRXDv1 */
+		.hdr_len = TRX_UL_V1HDR_LEN,
+		.parse = &trx_data_parse_pdu_v1,
+	},
+};
+
 /* Parse TRXD message from transceiver, compose an UL burst indication. */
 static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what)
 {
 	struct trx_l1h *l1h = ofd->data;
 	uint8_t buf[TRXD_MSG_BUF_SIZE];
+	const uint8_t *ptr = &buf[0];
 	struct trx_ul_burst_ind bi;
 	ssize_t hdr_len, buf_len;
 	uint8_t pdu_ver;
-	int rc;
 
 	buf_len = recv(ofd->fd, buf, sizeof(buf), 0);
 	if (buf_len <= 0) {
@@ -948,56 +945,40 @@
 		return -EIO;
 	}
 
-	/* Parse header depending on the PDU version */
-	switch (pdu_ver) {
-	case 0:
-		/* Legacy protocol has no version indicator */
-		hdr_len = trx_data_handle_hdr_v0(l1h, &bi, buf, buf_len);
-		break;
-	case 1:
-		hdr_len = trx_data_handle_hdr_v1(l1h, &bi, buf, buf_len);
-		break;
-	default:
+	OSMO_ASSERT(trx_data_codec[pdu_ver].parse != NULL);
+
+	/* Make sure that we have enough bytes to parse the header */
+	if (buf_len < trx_data_codec[pdu_ver].hdr_len) {
 		LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR,
-			"TRXD PDU version %u is not supported\n", pdu_ver);
-		return -ENOTSUP;
-	}
-
-	/* Header parsing error */
-	if (hdr_len < 0)
-		return hdr_len;
-
-	if (bi.fn >= GSM_TDMA_HYPERFRAME) {
-		LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR, "Illegal TDMA fn=%u\n", bi.fn);
+			"Rx malformed TRXDv%u PDU: len=%zd < expected %zu\n",
+			pdu_ver, buf_len, trx_data_codec[pdu_ver].hdr_len);
 		return -EINVAL;
 	}
 
-	if (bi.flags & TRX_BI_F_NOPE_IND) {
-		bi.burst_len = 0;
-		goto skip_burst;
-	}
+	/* Call version specific header parser */
+	hdr_len = trx_data_codec[pdu_ver].parse(l1h->phy_inst, &bi, buf, buf_len);
+	if (hdr_len < 0)
+		return hdr_len;
 
-	/* We're done with the header now */
+	/* We're done with the header */
 	buf_len -= hdr_len;
+	ptr += hdr_len;
 
-	/* Handle burst bits */
-	switch (pdu_ver) {
-	case 0:
-		rc = trx_data_handle_burst_v0(l1h, &bi, buf + hdr_len, buf_len);
-		break;
-	case 1:
-		rc = trx_data_handle_burst_v1(l1h, &bi, buf + hdr_len, buf_len);
-		break;
-	default:
-		/* Shall not happen, just to make GCC happy */
-		OSMO_ASSERT(0);
+	if (bi.fn >= GSM_TDMA_HYPERFRAME) {
+		LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR,
+			"Rx malformed TRXDv%u PDU: illegal TDMA fn=%u\n",
+			pdu_ver, bi.fn);
+		return -EINVAL;
 	}
 
-	/* Burst parsing error */
-	if (rc < 0)
-		return rc;
+	/* Calculate burst length and parse it (if present) */
+	if (trx_data_parse_burst(&bi, ptr, buf_len) != 0) {
+		LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR,
+			"Rx malformed TRXDv%u PDU: odd burst length=%zd\n",
+			pdu_ver, buf_len);
+		return -EINVAL;
+	}
 
-skip_burst:
 	/* Print header & burst info */
 	LOGPPHI(l1h->phy_inst, DTRX, LOGL_DEBUG, "Rx %s (pdu_ver=%u): %s\n",
 		(bi.flags & TRX_BI_F_NOPE_IND) ? "NOPE.ind" : "UL burst",

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

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I7aedd85a8d4f6d6191cd3b75272a688208fb2879
Gerrit-Change-Number: 23832
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210420/034dfacd/attachment.htm>


More information about the gerrit-log mailing list