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