fixeria submitted this change.
libosmo-trx/trxd: support NOPE.{ind,req} in TRXDv0/v1 PDUs
TRXDv0 (and TRXDv1 in the downlink direction) has no MTS field, but
NOPE indications/requests do exist there in practice: the burst payload
is simply omitted, i.e. a header-only PDU. This is how osmocom-bb's
trxcon transmits NOPE.req (see trx_if_handle_phyif_burst_req()).
Change-Id: I1a59f31d0f00c8509a016dc2bac71b6aa467f3a4
---
M libosmo-trx/include/osmocom/trx/trxd.h
M libosmo-trx/src/trxd.c
M tests/libosmo-trx/trxd_test.c
M tests/libosmo-trx/trxd_test.ok
4 files changed, 71 insertions(+), 18 deletions(-)
diff --git a/libosmo-trx/include/osmocom/trx/trxd.h b/libosmo-trx/include/osmocom/trx/trxd.h
index b415c47..bf9baeb 100644
--- a/libosmo-trx/include/osmocom/trx/trxd.h
+++ b/libosmo-trx/include/osmocom/trx/trxd.h
@@ -39,6 +39,8 @@
/* Presence/meta flags for osmo_trxd_burst_{ind,req} */
#define OSMO_TRXD_F_NOPE_IND (1 << 0) /*!< no burst detected / idle indication */
+/*! alias of OSMO_TRXD_F_NOPE_IND, reading cleaner in BURST.req context */
+#define OSMO_TRXD_F_NOPE_REQ OSMO_TRXD_F_NOPE_IND
#define OSMO_TRXD_F_MOD_TYPE (1 << 1) /*!< 'mod' is valid */
#define OSMO_TRXD_F_TS_INFO (1 << 2) /*!< 'tsc_set'/'tsc' are valid */
#define OSMO_TRXD_F_CI_CB (1 << 3) /*!< 'ci_cb' is valid */
diff --git a/libosmo-trx/src/trxd.c b/libosmo-trx/src/trxd.c
index 9b8cf39..6e68542 100644
--- a/libosmo-trx/src/trxd.c
+++ b/libosmo-trx/src/trxd.c
@@ -210,6 +210,12 @@
trxd_burst_ind_parse_hdr_v0(bi, buf);
+ /* NOPE.ind: TRXDv0 has no MTS, the burst payload is simply omitted */
+ if (burst_len == 0) {
+ bi->flags |= OSMO_TRXD_F_NOPE_IND;
+ return buf_len;
+ }
+
switch (burst_len) {
case OSMO_TRXD_BURST_LEN_GMSK:
case OSMO_TRXD_BURST_LEN_GMSK + 2:
@@ -382,9 +388,9 @@
* \param[inout] msg destination message buffer
* \param[in] pdu_ver TRXD PDU version to encode
* \param[in] bi burst indication to be encoded
- * \returns 0 on success; negative on error. Note that TRXDv0 cannot
- * carry NOPE.ind PDUs: -ENOTSUP is returned and the caller
- * shall skip (not send) them. */
+ * \returns 0 on success; negative on error. Note that TRXDv0 has no
+ * MTS field, so a NOPE.ind is encoded as a header-only PDU
+ * with the burst payload omitted. */
int osmo_trxd_burst_ind_build(struct msgb *msg, uint8_t pdu_ver,
const struct osmo_trxd_burst_ind *bi)
{
@@ -394,9 +400,6 @@
switch (pdu_ver) {
case 0:
- /* v0 doesn't support NOPE.ind, the caller shall skip it */
- if (bi->flags & OSMO_TRXD_F_NOPE_IND)
- return -ENOTSUP;
buf = msgb_put(msg, TRXD_IND_V0HDR_LEN);
buf[0] = ((pdu_ver & 0x0f) << 4) | (bi->tn & 0x07);
osmo_store32be(bi->fn, buf + 1);
@@ -467,6 +470,10 @@
case OSMO_TRXD_BURST_LEN_GMSK:
br->mod = OSMO_TRXD_MOD_T_GMSK;
break;
+ case 0: /* NOPE.req: TRXDv0/v1 have no MTS, the burst payload is simply omitted */
+ br->flags |= OSMO_TRXD_F_NOPE_REQ;
+ br->burst_len = 0;
+ return buf_len;
default:
return -EINVAL;
}
@@ -513,6 +520,12 @@
br->fn = st->fn;
}
+ /* NOPE.req contains no burst */
+ if (br->flags & OSMO_TRXD_F_NOPE_REQ) {
+ br->burst_len = 0;
+ return hdr_len;
+ }
+
burst_len = burst_len_by_mod(br->mod);
if (burst_len < 0)
return burst_len;
@@ -629,9 +642,11 @@
return -ENOTSUP;
}
- /* copy hard-bits {0,1} */
- memcpy(msgb_put(msg, br->burst_len),
- &br->burst[0], br->burst_len);
+ if (~br->flags & OSMO_TRXD_F_NOPE_REQ) {
+ /* copy hard-bits {0,1} */
+ memcpy(msgb_put(msg, br->burst_len),
+ &br->burst[0], br->burst_len);
+ }
return 0;
}
@@ -711,9 +726,13 @@
{
struct osmo_strbuf sb = { .buf = buf, .len = buf_len };
- OSMO_STRBUF_PRINTF(sb, "BURST.req tn=%u fn=%u att=%u", br->tn, br->fn, br->att);
+ OSMO_STRBUF_PRINTF(sb, "%s tn=%u fn=%u att=%u",
+ (br->flags & OSMO_TRXD_F_NOPE_REQ) ? "NOPE.req" : "BURST.req",
+ br->tn, br->fn, br->att);
if (br->flags & OSMO_TRXD_F_TRX_NUM)
OSMO_STRBUF_PRINTF(sb, " trx_num=%u", br->trx_num);
+ if (br->flags & OSMO_TRXD_F_NOPE_REQ)
+ return buf;
if (br->flags & OSMO_TRXD_F_MOD_TYPE)
OSMO_STRBUF_PRINTF(sb, " mod=%s", osmo_trxd_mod_type_name(br->mod));
if (br->flags & OSMO_TRXD_F_TS_INFO)
diff --git a/tests/libosmo-trx/trxd_test.c b/tests/libosmo-trx/trxd_test.c
index 454de86..88b159b 100644
--- a/tests/libosmo-trx/trxd_test.c
+++ b/tests/libosmo-trx/trxd_test.c
@@ -129,13 +129,6 @@
bi.flags = OSMO_TRXD_F_NOPE_IND | OSMO_TRXD_F_CI_CB;
rc = osmo_trxd_burst_ind_build(msg, pdu_ver, &bi);
- if (pdu_ver == 0) {
- /* TRXDv0 cannot carry NOPE.ind */
- printf("build: rc=%d (expected -ENOTSUP)\n", rc);
- OSMO_ASSERT(rc == -ENOTSUP);
- msgb_free(msg);
- return;
- }
OSMO_ASSERT(rc == 0);
osmo_trxd_build_fin(msg, pdu_ver);
printf("build: %s\n", osmo_trxd_burst_ind_name(&bi));
@@ -264,6 +257,34 @@
msgb_free(msg);
}
+static void test_burst_req_nope(uint8_t pdu_ver)
+{
+ struct osmo_trxd_parse_state st;
+ struct osmo_trxd_burst_req br, br2;
+ struct msgb *msg = msgb_alloc(4096, "nope");
+ int rc;
+
+ printf("=== %s(v%u) ===\n", __func__, pdu_ver);
+
+ fill_burst_req(&br, 0);
+ br.flags = OSMO_TRXD_F_NOPE_REQ;
+
+ rc = osmo_trxd_burst_req_build(msg, pdu_ver, &br);
+ OSMO_ASSERT(rc == 0);
+ osmo_trxd_build_fin(msg, pdu_ver);
+ printf("build: %s\n", osmo_trxd_burst_req_name(&br));
+
+ osmo_trxd_parse_state_init(&st);
+ rc = osmo_trxd_burst_req_parse(&st, &br2, msgb_data(msg), msgb_length(msg));
+ OSMO_ASSERT(rc == (int)msgb_length(msg));
+ printf("parse: %s\n", osmo_trxd_burst_req_name(&br2));
+
+ OSMO_ASSERT(br2.flags & OSMO_TRXD_F_NOPE_REQ);
+ OSMO_ASSERT(br2.burst_len == 0);
+
+ msgb_free(msg);
+}
+
static void test_burst_req_batch(uint8_t pdu_ver)
{
struct osmo_trxd_parse_state st;
@@ -394,6 +415,7 @@
for (uint8_t pdu_ver = 0; pdu_ver <= OSMO_TRXD_PDU_VER_MAX; pdu_ver++) {
test_burst_req(pdu_ver, OSMO_TRXD_BURST_LEN_GMSK);
test_burst_req(pdu_ver, OSMO_TRXD_BURST_LEN_8PSK);
+ test_burst_req_nope(pdu_ver);
test_burst_req_batch(pdu_ver);
test_burst_ind(pdu_ver, OSMO_TRXD_BURST_LEN_GMSK);
diff --git a/tests/libosmo-trx/trxd_test.ok b/tests/libosmo-trx/trxd_test.ok
index e4f22da..963322b 100644
--- a/tests/libosmo-trx/trxd_test.ok
+++ b/tests/libosmo-trx/trxd_test.ok
@@ -6,6 +6,9 @@
build: BURST.req tn=2 fn=2654321 att=10 mod=8-PSK set=0 tsc=3 burst_len=444
datagram (450 bytes): 02002880710a00010001000100010001...
parse: BURST.req tn=2 fn=2654321 att=10 mod=8-PSK burst_len=444
+=== test_burst_req_nope(v0) ===
+build: NOPE.req tn=2 fn=2654321 att=10
+parse: NOPE.req tn=2 fn=2654321 att=10
=== test_burst_ind(v0, burst_len=148) ===
build: BURST.ind tn=5 fn=1234567 rssi=-63 toa256=-512 C/I=-150 cB mod=GMSK set=1 tsc=7 burst_len=148
datagram (156 bytes): 050012d6873ffe001be31be31be31be3...
@@ -15,7 +18,8 @@
datagram (452 bytes): 050012d6873ffe001be31be31be31be3...
parse: BURST.ind tn=5 fn=1234567 rssi=-63 toa256=-512 mod=8-PSK burst_len=444
=== test_burst_ind_nope(v0) ===
-build: rc=-95 (expected -ENOTSUP)
+build: NOPE.ind tn=5 fn=1234567 rssi=-63 toa256=-512 C/I=-150 cB
+parse: NOPE.ind tn=5 fn=1234567 rssi=-63 toa256=-512
=== test_burst_req(v1, burst_len=148) ===
build: BURST.req tn=2 fn=2654321 att=10 mod=GMSK set=0 tsc=3 burst_len=148
datagram (154 bytes): 12002880710a00010001000100010001...
@@ -24,6 +28,9 @@
build: BURST.req tn=2 fn=2654321 att=10 mod=8-PSK set=0 tsc=3 burst_len=444
datagram (450 bytes): 12002880710a00010001000100010001...
parse: BURST.req tn=2 fn=2654321 att=10 mod=8-PSK burst_len=444
+=== test_burst_req_nope(v1) ===
+build: NOPE.req tn=2 fn=2654321 att=10
+parse: NOPE.req tn=2 fn=2654321 att=10
=== test_burst_ind(v1, burst_len=148) ===
build: BURST.ind tn=5 fn=1234567 rssi=-63 toa256=-512 C/I=-150 cB mod=GMSK set=1 tsc=7 burst_len=148
datagram (159 bytes): 150012d6873ffe000fff6a1be31be31b...
@@ -43,6 +50,9 @@
build: BURST.req tn=2 fn=2654321 att=10 mod=8-PSK set=0 tsc=3 burst_len=444
datagram (456 bytes): 2200230a000000000028807100010001...
parse: BURST.req tn=2 fn=2654321 att=10 trx_num=0 mod=8-PSK set=0 tsc=3 burst_len=444
+=== test_burst_req_nope(v2) ===
+build: NOPE.req tn=2 fn=2654321 att=10
+parse: NOPE.req tn=2 fn=2654321 att=10 trx_num=0
=== test_burst_req_batch(v2) ===
datagram (472 bytes)
parse[0]: BURST.req tn=0 fn=2654321 att=10 trx_num=0 mod=GMSK set=0 tsc=3 burst_len=148
To view, visit change 43105. To unsubscribe, or for help writing mail filters, visit settings.