This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 559b16b75a152e1ced0d24a3975eedbff1d672f1
Author: Mariusz Skamra <[email protected]>
AuthorDate: Thu Feb 13 08:40:00 2025 +0100

    nimble/ll/isoal: Fix broadcast of a Zero-Length SDU
    
    This fixes invalid LLID and PDU length of Zero-Length SDU in tests
    IAL/BIS/UNF/BRD/BV-21-C
    IAL/BIS/UNF/BRD/BV-22-C
---
 nimble/controller/src/ble_ll_isoal.c      |   9 ++-
 nimble/controller/test/src/ble_ll_isoal.c | 128 ++++++++++++++++++++++++++++++
 2 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/nimble/controller/src/ble_ll_isoal.c 
b/nimble/controller/src/ble_ll_isoal.c
index 8c8516b6d..fd2c6ac6a 100644
--- a/nimble/controller/src/ble_ll_isoal.c
+++ b/nimble/controller/src/ble_ll_isoal.c
@@ -297,10 +297,10 @@ ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux 
*mux, uint8_t idx,
 {
     struct os_mbuf_pkthdr *pkthdr;
     struct os_mbuf *om;
+    int32_t rem_len;
     uint8_t sdu_idx;
     uint8_t pdu_idx;
     uint16_t sdu_offset;
-    uint16_t rem_len;
     uint8_t pdu_len;
 
     sdu_idx = idx / mux->pdu_per_sdu;
@@ -325,7 +325,12 @@ ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux 
*mux, uint8_t idx,
     sdu_offset = pdu_idx * mux->max_pdu;
     rem_len = OS_MBUF_PKTLEN(om) - sdu_offset;
 
-    if ((int32_t)rem_len <= 0) {
+    if (OS_MBUF_PKTLEN(om) == 0) {
+        /* LLID = 0b00: Zero-Length SDU (complete SDU) */
+        *llid = 0;
+        pdu_len = 0;
+    } else if (rem_len <= 0) {
+        /* LLID = 0b01: ISO Data PDU used as padding */
         *llid = 1;
         pdu_len = 0;
     } else {
diff --git a/nimble/controller/test/src/ble_ll_isoal.c 
b/nimble/controller/test/src/ble_ll_isoal.c
index c10006c14..6423ed725 100644
--- a/nimble/controller/test/src/ble_ll_isoal.c
+++ b/nimble/controller/test/src/ble_ll_isoal.c
@@ -850,6 +850,54 @@ test_ial_broadcast_zero_length_sdu_bis(const struct 
test_ial_broadcast_zero_leng
     test_ial_teardown(&mux);
 }
 
+TEST_CASE_SELF(test_ial_bis_unf_brd_bv_21_c) {
+    const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = {
+        .NSE = 4,
+        .Framed = 0,
+        .Framing_Mode = 0,
+        .LLID = 0b00,
+        .BN = 2,
+    };
+
+    test_ial_broadcast_zero_length_sdu_bis(&cfg);
+}
+
+TEST_CASE_SELF(test_ial_bis_unf_brd_bv_22_c) {
+    const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = {
+        .NSE = 6,
+        .Framed = 0,
+        .Framing_Mode = 0,
+        .LLID = 0b00,
+        .BN = 3,
+    };
+
+    test_ial_broadcast_zero_length_sdu_bis(&cfg);
+}
+
+TEST_CASE_SELF(test_ial_bis_unf_brd_bv_23_c) {
+    const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = {
+        .NSE = 1,
+        .Framed = 0,
+        .Framing_Mode = 0,
+        .LLID = 0b00,
+        .BN = 1,
+    };
+
+    test_ial_broadcast_zero_length_sdu_bis(&cfg);
+}
+
+TEST_CASE_SELF(test_ial_bis_unf_brd_bv_24_c) {
+    const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = {
+        .NSE = 2,
+        .Framed = 0,
+        .Framing_Mode = 0,
+        .LLID = 0b00,
+        .BN = 1,
+    };
+
+    test_ial_broadcast_zero_length_sdu_bis(&cfg);
+}
+
 TEST_CASE_SELF(test_ial_bis_fra_brd_bv_25_c) {
     const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = {
         .NSE = 6,
@@ -930,6 +978,76 @@ TEST_CASE_SELF(test_ial_bis_fra_brd_bv_30_c) {
     test_ial_broadcast_zero_length_sdu_bis(&cfg);
 }
 
+struct test_ial_unframed_empty_pdus_with_llid_0b01_cfg {
+    uint32_t sdu_int;
+    uint32_t iso_int;
+    uint8_t nse;
+    uint16_t mx_sdu;
+    uint8_t mx_pdu;
+    uint8_t bn;
+    uint8_t irc;
+    uint8_t pto;
+};
+
+static void
+test_ial_unframed_empty_pdus_with_llid_0b01(const struct 
test_ial_unframed_empty_pdus_with_llid_0b01_cfg *cfg)
+{
+    struct ble_ll_isoal_mux mux;
+    int pdu_len;
+    uint8_t pdu[cfg->mx_pdu];
+    uint32_t timestamp;
+    uint8_t llid = 0xff;
+
+    ble_ll_isoal_mux_init(&mux, cfg->mx_pdu, cfg->iso_int, cfg->sdu_int,
+                          cfg->bn, 0, false, 0);
+
+    for (uint16_t sdu_len = 4; sdu_len < cfg->mx_sdu; sdu_len++) {
+        timestamp = sdu_len * cfg->sdu_int;
+        test_sdu_enqueue(&mux, sdu_len, sdu_len, timestamp);
+
+        ble_ll_isoal_mux_event_start(&mux, timestamp + 50);
+
+        /* As the mx_sdu == mx_pdu, the data will always fit the single PDU */
+        TEST_ASSERT(cfg->mx_sdu == cfg->mx_pdu,
+                    "#%d: SDU and PDU length should be same", sdu_len);
+
+        pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu);
+        TEST_ASSERT(llid == 0b00,
+                    "#%d: LLID is incorrect %d", sdu_len, llid);
+        TEST_ASSERT(pdu_len == sdu_len,
+                    "#%d: PDU length is incorrect %d", sdu_len, pdu_len);
+
+        /* Padding */
+        for (uint8_t idx = 1; idx < cfg->bn; idx++) {
+            pdu_len = ble_ll_isoal_mux_pdu_get(&mux, idx, &llid, pdu);
+            TEST_ASSERT(llid == 0b01,
+                        "#%d #%d: LLID is incorrect %d", sdu_len, idx, llid);
+            TEST_ASSERT(pdu_len == 0,
+                        "#%d #%d: PDU length is incorrect %d",
+                        sdu_len, idx, pdu_len);
+        }
+
+        (void)ble_ll_isoal_mux_event_done(&mux);
+    }
+
+    ble_ll_isoal_mux_free(&mux);
+}
+
+TEST_CASE_SELF(test_ial_bis_unf_brd_bv_29_c) {
+    const struct test_ial_unframed_empty_pdus_with_llid_0b01_cfg cfg = {
+        .sdu_int = 100,
+        .iso_int = 100,
+        .nse = 12,
+        .mx_sdu = 128,
+        .mx_pdu = 128,
+        .bn = 4,
+        .irc = 3,
+        .pto = 0,
+    };
+
+    test_ial_unframed_empty_pdus_with_llid_0b01(&cfg);
+}
+
 TEST_SUITE(ble_ll_isoal_test_suite) {
     os_mbuf_test_setup();
 
@@ -956,11 +1074,21 @@ TEST_SUITE(ble_ll_isoal_test_suite) {
     test_ial_bis_fra_brd_bv_20_c();
 
     /* Broadcast a Zero-Length SDU, BIS */
+    test_ial_bis_unf_brd_bv_21_c();
+    test_ial_bis_unf_brd_bv_22_c();
+    test_ial_bis_unf_brd_bv_23_c();
+    test_ial_bis_unf_brd_bv_24_c();
     test_ial_bis_fra_brd_bv_25_c();
     test_ial_bis_fra_brd_bv_26_c();
     test_ial_bis_fra_brd_bv_27_c();
     test_ial_bis_fra_brd_bv_28_c();
     test_ial_bis_fra_brd_bv_30_c();
 
+    /* Broadcasting Unframed Empty PDUs with LLID=0b01, BIS */
+    test_ial_bis_unf_brd_bv_29_c();
+    /* test_ial_bis_unf_brd_bv_30_c();
+     * Same as test_ial_bis_unf_brd_bv_29_c except encryption is required.
+     */
+
     ble_ll_isoal_reset();
 }

Reply via email to