You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ry...@apache.org on 2024/02/28 07:36:09 UTC

(mynewt-nimble) branch master updated (26df457d7 -> 6750a13cc)

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

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


    from 26df457d7 host/audio_common: Add doxygen comments in the header file
     new 90d270dfa nimble/controller: Conditionally enable BLE_LL_ISO_BROADCASTER
     new 47d1bb50d nimble/iso: Fix BLE_ISO dependency
     new 8c06f2563 nimble/iso: Add ISO Rx datapath and extend ISO Broadcast API
     new eacdbc36e nimble/iso: Fix missing BLE_ISO_BROADCAST_SOURCE guard
     new a2e68282f apps/btshell: Add ISO related commands
     new 2e368caab nimble/audio: Add LE Audio btshell target
     new 56a23bc0f apps/btshell: Fix minor coding style issue
     new 6750a13cc apps/btshell: Add 'silent' option to scan commands

The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 apps/btshell/src/btshell.h                         |   5 +-
 apps/btshell/src/cmd.c                             |  67 ++-
 apps/btshell/src/cmd_iso.c                         | 513 ++++++++++++++++
 apps/btshell/src/{cmd_l2cap.h => cmd_iso.h}        |  26 +-
 apps/btshell/src/main.c                            |  19 +-
 nimble/controller/syscfg.yml                       |   6 +-
 .../host/audio/targets/btshell_native}/pkg.yml     |   6 +-
 .../host/audio/targets/btshell_native}/syscfg.yml  |  40 +-
 .../host/audio/targets/btshell_native}/target.yml  |   1 -
 nimble/host/include/host/ble_iso.h                 | 230 +++++++-
 nimble/host/src/ble_hs.c                           |   5 +
 nimble/host/src/ble_hs_hci_evt.c                   |  43 ++
 nimble/host/src/ble_hs_startup.c                   |  11 +
 nimble/host/src/ble_iso.c                          | 650 +++++++++++++++++++--
 nimble/host/src/ble_iso_priv.h                     |   9 +
 nimble/include/nimble/hci_common.h                 |  28 +-
 nimble/syscfg.yml                                  |   4 +
 nimble/transport/socket/src/ble_hci_socket.c       |  38 ++
 18 files changed, 1609 insertions(+), 92 deletions(-)
 create mode 100644 apps/btshell/src/cmd_iso.c
 copy apps/btshell/src/{cmd_l2cap.h => cmd_iso.h} (52%)
 copy {targets/nordic_pca10095_net-blehci => nimble/host/audio/targets/btshell_native}/pkg.yml (85%)
 copy {apps/btshell => nimble/host/audio/targets/btshell_native}/syscfg.yml (65%)
 copy {.github/targets_linux/native_btshell => nimble/host/audio/targets/btshell_native}/target.yml (99%)


(mynewt-nimble) 03/08: nimble/iso: Add ISO Rx datapath and extend ISO Broadcast API

Posted by ry...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 8c06f256374ae9be9ff43d9270bcee3e9481a01f
Author: Mariusz Skamra <ma...@codecoup.pl>
AuthorDate: Mon Jan 22 20:00:49 2024 +0100

    nimble/iso: Add ISO Rx datapath and extend ISO Broadcast API
    
    This adds ISO Rx datapath and along with Broadcast Sink ISO API
    and implementation.
---
 nimble/host/include/host/ble_iso.h           | 230 +++++++++-
 nimble/host/src/ble_hs.c                     |   5 +
 nimble/host/src/ble_hs_hci_evt.c             |  43 ++
 nimble/host/src/ble_hs_startup.c             |  11 +
 nimble/host/src/ble_iso.c                    | 616 +++++++++++++++++++++++++--
 nimble/host/src/ble_iso_priv.h               |   9 +
 nimble/include/nimble/hci_common.h           |  28 +-
 nimble/transport/socket/src/ble_hci_socket.c |  38 ++
 8 files changed, 937 insertions(+), 43 deletions(-)

diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h
index 786d2eb21..8b0182fa6 100644
--- a/nimble/host/include/host/ble_iso.h
+++ b/nimble/host/include/host/ble_iso.h
@@ -19,22 +19,31 @@
 
 #ifndef H_BLE_ISO_
 #define H_BLE_ISO_
+#include <inttypes.h>
+
+#include "nimble/hci_common.h"
 #include "syscfg/syscfg.h"
 
 /** ISO event: BIG Create Completed */
-#define BLE_ISO_EVENT_BIG_CREATE_COMPLETE                  0
+#define BLE_ISO_EVENT_BIG_CREATE_COMPLETE                   0
 
 /** ISO event: BIG Terminate Completed */
-#define BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE               1
+#define BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE                1
 
-#include <inttypes.h>
+/** ISO event: BIG Sync Established */
+#define BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED                  2
 
-struct ble_iso_big_desc
-{
+/** ISO event: BIG Sync Terminated */
+#define BLE_ISO_EVENT_BIG_SYNC_TERMINATED                   3
+
+/** ISO event: ISO Data received */
+#define BLE_ISO_EVENT_ISO_RX                                4
+
+/** @brief Broadcast Isochronous Group (BIG) description */
+struct ble_iso_big_desc {
     uint8_t big_handle;
     uint32_t big_sync_delay;
     uint32_t transport_latency_big;
-    uint8_t phy;
     uint8_t nse;
     uint8_t bn;
     uint8_t pto;
@@ -45,6 +54,36 @@ struct ble_iso_big_desc
     uint16_t conn_handle[MYNEWT_VAL(BLE_MAX_BIS)];
 };
 
+/** @brief Received ISO Data status possible values */
+enum ble_iso_rx_data_status {
+    /** The complete SDU was received correctly. */
+    BLE_ISO_DATA_STATUS_VALID = BLE_HCI_ISO_PKT_STATUS_VALID,
+
+    /** May contain errors or part of the SDU may be missing. */
+    BLE_ISO_DATA_STATUS_ERROR = BLE_HCI_ISO_PKT_STATUS_INVALID,
+
+    /** Part(s) of the SDU were not received correctly */
+    BLE_ISO_DATA_STATUS_LOST = BLE_HCI_ISO_PKT_STATUS_LOST,
+};
+
+/** @brief Received ISO data info structure */
+struct ble_iso_rx_data_info {
+    /** ISO Data timestamp. Valid if @ref ble_iso_data_info.ts_valid is set */
+    uint32_t ts;
+
+    /** Packet sequence number */
+    uint16_t seq_num;
+
+    /** SDU length */
+    uint16_t sdu_len : 12;
+
+    /** ISO Data status. See @ref ble_iso_data_status */
+    uint16_t status : 2;
+
+    /** Timestamp is valid */
+    uint16_t ts_valid : 1;
+};
+
 /**
  * Represents a ISO-related event.  When such an event occurs, the host
  * notifies the application by passing an instance of this structure to an
@@ -69,17 +108,41 @@ struct ble_iso_event {
          */
         struct {
             struct ble_iso_big_desc desc;
+            uint8_t status;
+            uint8_t phy;
         } big_created;
 
         /**
          * Represents a completion of BIG termination. Valid for the following
          * event types:
          *     o BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE
+         *     o BLE_ISO_EVENT_BIG_SYNC_TERMINATED
          */
         struct {
             uint16_t big_handle;
             uint8_t reason;
         } big_terminated;
+
+        /**
+         * Represents a completion of BIG synchronization. Valid for the following
+         * event types:
+         *     o BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED
+         */
+        struct {
+            struct ble_iso_big_desc desc;
+            uint8_t status;
+        } big_sync_established;
+
+        /**
+         * Represents a reception of ISO Data. Valid for the following
+         * event types:
+         *     o BLE_ISO_EVENT_ISO_RX
+         */
+        struct {
+            uint16_t conn_handle;
+            const struct ble_iso_rx_data_info *info;
+            struct os_mbuf *om;
+        } iso_rx;
     };
 };
 
@@ -109,8 +172,161 @@ int ble_iso_create_big(const struct ble_iso_create_big_params *create_params,
 
 int ble_iso_terminate_big(uint8_t big_handle);
 
+/** @brief BIS parameters for @ref ble_iso_big_sync_create */
+struct ble_iso_bis_params {
+    /** BIS index */
+    uint8_t bis_index;
+
+    /** The callback to associate with the BIS.
+     *  Received ISO data is reported through this callback.
+     */
+    ble_iso_event_fn *cb;
+
+    /** The optional argument to pass to the callback function */
+    void *cb_arg;
+};
+
+/** @brief BIG Sync parameters for @ref ble_iso_big_sync_create */
+struct ble_iso_big_sync_create_params {
+    /** Periodic advertising train sync handle */
+    uint16_t sync_handle;
+
+    /** Null-terminated broadcast code for encrypted BIG or
+     *  NULL if the BIG is unencrypted
+     */
+    const char *broadcast_code;
+
+    /** Maximum Subevents to be used to receive data payloads in each BIS event */
+    uint8_t mse;
+
+    /** The maximum permitted time between successful receptions of BIS PDUs */
+    uint16_t sync_timeout;
+
+    /** The callback to associate with this sync procedure.
+     *  Sync establishment and termination are reported through this callback.
+     */
+    ble_iso_event_fn *cb;
+
+    /** The optional argument to pass to the callback function */
+    void *cb_arg;
+
+    /** Number of a BISes */
+    uint8_t bis_cnt;
+
+    /** BIS parameters */
+    struct ble_iso_bis_params *bis_params;
+};
+
+/**
+ * @brief Synchronize to Broadcast Isochronous Group (BIG)
+ *
+ * This function is used to synchronize to a BIG described in the periodic
+ * advertising train specified by the @p param->pa_sync_handle parameter.
+ *
+ * @param[in] params            BIG synchronization parameters
+ * @param[out] big_handle       BIG instance handle
+ *
+ * @return                      0 on success;
+ *                              A non-zero value on failure.
+ */
+int ble_iso_big_sync_create(const struct ble_iso_big_sync_create_params *params,
+                            uint8_t *big_handle);
+
+/**
+ * @brief Terminate Broadcast Isochronous Group (BIG) sync
+ *
+ * This function is used to stop synchronizing or cancel the process of
+ * synchronizing to the BIG identified by the @p big_handle parameter.
+ * The command also terminates the reception of BISes in the BIG.
+ *
+ * @param[in] big_handle        BIG handle
+ *
+ * @return                      0 on success;
+ *                              A non-zero value on failure.
+ */
+int ble_iso_big_sync_terminate(uint8_t big_handle);
+
+/** @brief ISO Data direction */
+enum ble_iso_data_dir {
+    BLE_ISO_DATA_DIR_TX,
+    BLE_ISO_DATA_DIR_RX,
+};
+
+/** @brief ISO Codec ID */
+struct ble_iso_codec_id {
+    /** Coding Format */
+    uint8_t format;
+
+    /** Company ID */
+    uint16_t company_id;
+
+    /** Vendor Specific Codec ID */
+    uint16_t vendor_specific;
+};
+
+/** @brief Setup ISO Data Path parameters */
+struct ble_iso_data_path_setup_params {
+    /** Connection handle of the CIS or BIS */
+    uint16_t conn_handle;
+
+    /** Data path direction */
+    enum ble_iso_data_dir data_path_dir;
+
+    /** Data path ID. 0x00 for HCI */
+    uint8_t data_path_id;
+
+    /** Controller delay */
+    uint32_t ctrl_delay;
+
+    /** Codec ID */
+    struct ble_iso_codec_id codec_id;
+
+    /** Codec Configuration Length */
+    uint8_t codec_config_len;
+
+    /** Codec Configuration */
+    const uint8_t *codec_config;
+};
+
+/**
+ * @brief Setup ISO Data Path
+ *
+ * This function is used to identify and create the isochronous data path
+ * between the Host and the Controller for a CIS, CIS configuration, or BIS
+ * identified by the @p param->conn_handle parameter.
+ *
+ * @param[in] params            BIG synchronization parameters
+ *
+ * @return                      0 on success;
+ *                              A non-zero value on failure.
+ */
+int ble_iso_data_path_setup(const struct ble_iso_data_path_setup_params *param);
+
+/** @brief @brief Remove ISO Data Path parameters */
+struct ble_iso_data_path_remove_params {
+    /** Connection handle of the CIS or BIS */
+    uint16_t conn_handle;
+
+    /** Data path direction */
+    enum ble_iso_data_dir data_path_dir;
+};
+
+/**
+ * @brief Remove ISO Data Path
+ *
+ * This function is used to remove the input and/or output data path(s)
+ * associated with a CIS, CIS configuration, or BIS identified by the
+ * @p param->conn_handle parameter.
+ *
+ * @param[in] params            BIG synchronization parameters
+ *
+ * @return                      0 on success;
+ *                              A non-zero value on failure.
+ */
+int ble_iso_data_path_remove(const struct ble_iso_data_path_remove_params *param);
+
 int ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len);
 
 int ble_iso_init(void);
 
-#endif
+#endif /* H_BLE_ISO_ */
diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c
index 801722177..d084c041a 100644
--- a/nimble/host/src/ble_hs.c
+++ b/nimble/host/src/ble_hs.c
@@ -26,6 +26,7 @@
 #include "host/ble_hs.h"
 #include "host/ble_audio_broadcast_source.h"
 #include "ble_hs_priv.h"
+#include "ble_iso_priv.h"
 #include "nimble/nimble_npl.h"
 #ifndef MYNEWT
 #include "nimble/nimble_port.h"
@@ -815,9 +816,13 @@ ble_transport_to_hs_acl_impl(struct os_mbuf *om)
 int
 ble_transport_to_hs_iso_impl(struct os_mbuf *om)
 {
+#if MYNEWT_VAL(BLE_ISO)
+    return ble_iso_rx_data(om, NULL);
+#else
     os_mbuf_free_chain(om);
 
     return 0;
+#endif
 }
 
 void
diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c
index e4fdad471..cc88bfd83 100644
--- a/nimble/host/src/ble_hs_hci_evt.c
+++ b/nimble/host/src/ble_hs_hci_evt.c
@@ -69,6 +69,10 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer;
 static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_create_big_complete;
 static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_terminate_big_complete;
 #endif
+#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK)
+static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_big_sync_established;
+static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_big_sync_lost;
+#endif
 #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS)
 static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_biginfo_adv_report;
 #endif
@@ -143,6 +147,12 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = {
     [BLE_HCI_LE_SUBEV_TERMINATE_BIG_COMPLETE] =
         ble_hs_hci_evt_le_terminate_big_complete,
 #endif
+#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK)
+    [BLE_HCI_LE_SUBEV_BIG_SYNC_ESTABLISHED] =
+        ble_hs_hci_evt_le_big_sync_established,
+    [BLE_HCI_LE_SUBEV_BIG_SYNC_LOST] =
+        ble_hs_hci_evt_le_big_sync_lost,
+#endif
 #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS)
     [BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT] = ble_hs_hci_evt_le_biginfo_adv_report,
 #endif
@@ -779,6 +789,39 @@ ble_hs_hci_evt_le_terminate_big_complete(uint8_t subevent, const void *data,
 }
 #endif
 
+#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK)
+static int
+ble_hs_hci_evt_le_big_sync_established(uint8_t subevent, const void *data,
+                                       unsigned int len)
+{
+    const struct ble_hci_ev_le_subev_big_sync_established *ev = data;
+
+    if (len < sizeof(*ev) ||
+        len != (sizeof(*ev) + ev->num_bis * sizeof(ev->conn_handle[0]))) {
+        return BLE_HS_EBADDATA;
+    }
+
+    ble_iso_rx_big_sync_established(ev);
+
+    return 0;
+}
+
+static int
+ble_hs_hci_evt_le_big_sync_lost(uint8_t subevent, const void *data,
+                                unsigned int len)
+{
+    const struct ble_hci_ev_le_subev_big_sync_lost *ev = data;
+
+    if (len != sizeof(*ev)) {
+        return BLE_HS_EBADDATA;
+    }
+
+    ble_iso_rx_big_sync_lost(ev);
+
+    return 0;
+}
+#endif
+
 #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS)
 static int
 ble_hs_hci_evt_le_biginfo_adv_report(uint8_t subevent, const void *data,
diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c
index d9907f376..827c00d2a 100644
--- a/nimble/host/src/ble_hs_startup.c
+++ b/nimble/host/src/ble_hs_startup.c
@@ -303,6 +303,17 @@ ble_hs_startup_le_set_evmask_tx(void)
     }
 #endif
 
+#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK)
+    if (version >= BLE_HCI_VER_BCS_5_2) {
+        /**
+         * Enable the following LE events:
+         * 0x0000000010000000 LE BIG Sync Established Complete event
+         * 0x0000000020000000 LE BIG Sync lost event
+         */
+        mask |= 0x0000000030000000;
+    }
+#endif
+
     cmd.event_mask = htole64(mask);
 
     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c
index 5c797836f..271bd27cb 100644
--- a/nimble/host/src/ble_iso.c
+++ b/nimble/host/src/ble_iso.c
@@ -17,12 +17,9 @@
  * under the License.
  */
 
-#include <inttypes.h>
 #include "syscfg/syscfg.h"
-#include "ble_hs_mbuf_priv.h"
 
 #if MYNEWT_VAL(BLE_ISO)
-
 #include "os/os_mbuf.h"
 #include "host/ble_hs_log.h"
 #include "host/ble_hs.h"
@@ -31,22 +28,85 @@
 #include "sys/queue.h"
 #include "ble_hs_priv.h"
 #include "ble_hs_hci_priv.h"
+#include "ble_hs_mbuf_priv.h"
+
+#define ble_iso_big_conn_handles_init(_big, _handles, _num_handles)         \
+    do {                                                                    \
+        struct ble_iso_conn *conn = SLIST_FIRST(&ble_iso_conns);            \
+                                                                            \
+        for (uint8_t i = 0; i < (_num_handles); i++) {                      \
+            while (conn != NULL) {                                          \
+                if (conn->type == BLE_ISO_CONN_BIS) {                       \
+                    struct ble_iso_bis *bis;                                \
+                                                                            \
+                    bis = CONTAINER_OF(conn, struct ble_iso_bis, conn);     \
+                    if (bis->big == (_big)) {                               \
+                        conn->handle = le16toh((_handles)[i]);              \
+                        conn = SLIST_NEXT(conn, next);                      \
+                        break;                                              \
+                    }                                                       \
+                }                                                           \
+                                                                            \
+                conn = SLIST_NEXT(conn, next);                              \
+            }                                                               \
+        }                                                                   \
+    } while (0);
+
+enum ble_iso_conn_type {
+    BLE_ISO_CONN_BIS,
+};
 
 struct ble_iso_big {
     SLIST_ENTRY(ble_iso_big) next;
     uint8_t handle;
     uint16_t max_pdu;
-    uint8_t num_bis;
-    uint16_t conn_handles[MYNEWT_VAL(BLE_MAX_BIS)];
+    uint8_t bis_cnt;
 
     ble_iso_event_fn *cb;
     void *cb_arg;
 };
 
+struct ble_iso_conn {
+    SLIST_ENTRY(ble_iso_conn) next;
+    enum ble_iso_conn_type type;
+    uint8_t handle;
+
+    struct ble_iso_rx_data_info rx_info;
+    struct os_mbuf *rx_buf;
+
+    ble_iso_event_fn *cb;
+    void *cb_arg;
+};
+
+struct ble_iso_bis {
+    struct ble_iso_conn conn;
+    struct ble_iso_big *big;
+};
+
 static SLIST_HEAD(, ble_iso_big) ble_iso_bigs;
+static SLIST_HEAD(, ble_iso_conn) ble_iso_conns;
 static struct os_mempool ble_iso_big_pool;
 static os_membuf_t ble_iso_big_mem[
     OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), sizeof (struct ble_iso_big))];
+static struct os_mempool ble_iso_bis_pool;
+static os_membuf_t ble_iso_bis_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS), sizeof (struct ble_iso_bis))];
+
+static void
+ble_iso_conn_append(struct ble_iso_conn *conn)
+{
+    struct ble_iso_conn *entry, *prev = NULL;
+
+    SLIST_FOREACH(entry, &ble_iso_conns, next) {
+        prev = entry;
+    }
+
+    if (prev == NULL) {
+        SLIST_INSERT_HEAD(&ble_iso_conns, conn, next);
+    } else {
+        SLIST_INSERT_AFTER(prev, conn, next);
+    }
+}
 
 static int
 ble_iso_big_handle_set(struct ble_iso_big *big)
@@ -106,6 +166,27 @@ ble_iso_big_alloc(void)
     return new_big;
 }
 
+static struct ble_iso_bis *
+ble_iso_bis_alloc(struct ble_iso_big *big)
+{
+    struct ble_iso_bis *new_bis;
+
+    new_bis = os_memblock_get(&ble_iso_bis_pool);
+    if (new_bis == NULL) {
+        BLE_HS_LOG_ERROR("No more memory in pool\n");
+        /* Out of memory. */
+        return NULL;
+    }
+
+    memset(new_bis, 0, sizeof *new_bis);
+    new_bis->conn.type = BLE_ISO_CONN_BIS;
+    new_bis->big = big;
+
+    ble_iso_conn_append(&new_bis->conn);
+
+    return new_bis;
+}
+
 static struct ble_iso_big *
 ble_iso_big_find_by_handle(uint8_t big_handle)
 {
@@ -123,6 +204,22 @@ ble_iso_big_find_by_handle(uint8_t big_handle)
 static int
 ble_iso_big_free(struct ble_iso_big *big)
 {
+    struct ble_iso_conn *conn;
+
+    SLIST_FOREACH(conn, &ble_iso_conns, next) {
+        struct ble_iso_bis *bis;
+
+        if (conn->type != BLE_ISO_CONN_BIS) {
+            continue;
+        }
+
+        bis = CONTAINER_OF(conn, struct ble_iso_bis, conn);
+        if (bis->big == big) {
+            SLIST_REMOVE(&ble_iso_conns, conn, ble_iso_conn, next);
+            os_memblock_put(&ble_iso_bis_pool, bis);
+        }
+    }
+
     SLIST_REMOVE(&ble_iso_bigs, big, ble_iso_big, next);
     os_memblock_put(&ble_iso_big_pool, big);
     return 0;
@@ -145,9 +242,21 @@ ble_iso_create_big(const struct ble_iso_create_big_params *create_params,
         return BLE_HS_ENOMEM;
     }
 
+    big->bis_cnt = create_params->bis_cnt;
     big->cb = create_params->cb;
     big->cb_arg = create_params->cb_arg;
 
+    for (uint8_t i = 0; i < create_params->bis_cnt; i++) {
+        struct ble_iso_bis *bis;
+
+        bis = ble_iso_bis_alloc(big);
+        if (bis == NULL) {
+            ble_iso_big_free(big);
+            return BLE_HS_ENOMEM;
+        }
+    }
+
+    cp.adv_handle = create_params->adv_handle;
     cp.num_bis = create_params->bis_cnt;
     put_le24(cp.sdu_interval, big_params->sdu_interval);
     cp.max_sdu = big_params->max_sdu;
@@ -202,6 +311,12 @@ ble_iso_init(void)
                          ble_iso_big_mem, "ble_iso_big_pool");
     SYSINIT_PANIC_ASSERT(rc == 0);
 
+    rc = os_mempool_init(&ble_iso_bis_pool,
+                         MYNEWT_VAL(BLE_MAX_BIS),
+                         sizeof (struct ble_iso_bis),
+                         ble_iso_bis_mem, "ble_iso_bis_pool");
+    SYSINIT_PANIC_ASSERT(rc == 0);
+
     return 0;
 }
 
@@ -209,9 +324,7 @@ void
 ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_complete *ev)
 {
     struct ble_iso_event event;
-
     struct ble_iso_big *big;
-    int i;
 
     big = ble_iso_big_find_by_handle(ev->big_handle);
     if (big == NULL) {
@@ -219,29 +332,38 @@ ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_compl
         return;
     }
 
-    big->num_bis = ev->num_bis;
-
-    for (i = 0; i < ev->num_bis; i++) {
-        big->conn_handles[i] = ev->conn_handle[i];
-    }
+    memset(&event, 0, sizeof(event));
+    event.type = BLE_ISO_EVENT_BIG_CREATE_COMPLETE;
+    event.big_created.status = ev->status;
 
-    big->max_pdu = ev->max_pdu;
+    if (event.big_created.status != 0) {
+        ble_iso_big_free(big);
+    } else {
+        if (big->bis_cnt != ev->num_bis) {
+            BLE_HS_LOG_ERROR("Unexpected num_bis=%d != bis_cnt=%d\n",
+                             ev->num_bis, big->bis_cnt);
+            /* XXX: Should we destroy the group? */
+        }
 
-    event.type = BLE_ISO_EVENT_BIG_CREATE_COMPLETE;
-    event.big_created.desc.big_handle = ev->big_handle;
-    event.big_created.desc.big_sync_delay = get_le24(ev->big_sync_delay);
-    event.big_created.desc.transport_latency_big =
-        get_le24(ev->transport_latency_big);
-    event.big_created.desc.phy = ev->phy;
-    event.big_created.desc.nse = ev->nse;
-    event.big_created.desc.bn = ev->bn;
-    event.big_created.desc.pto = ev->pto;
-    event.big_created.desc.irc = ev->irc;
-    event.big_created.desc.max_pdu = ev->max_pdu;
-    event.big_created.desc.iso_interval = ev->iso_interval;
-    event.big_created.desc.num_bis = ev->num_bis;
-    memcpy(event.big_created.desc.conn_handle, ev->conn_handle,
-           ev->num_bis * sizeof(uint16_t));
+        ble_iso_big_conn_handles_init(big, ev->conn_handle, ev->num_bis);
+
+        big->max_pdu = ev->max_pdu;
+
+        event.big_created.desc.big_handle = ev->big_handle;
+        event.big_created.desc.big_sync_delay = get_le24(ev->big_sync_delay);
+        event.big_created.desc.transport_latency_big =
+            get_le24(ev->transport_latency_big);
+        event.big_created.desc.nse = ev->nse;
+        event.big_created.desc.bn = ev->bn;
+        event.big_created.desc.pto = ev->pto;
+        event.big_created.desc.irc = ev->irc;
+        event.big_created.desc.max_pdu = ev->max_pdu;
+        event.big_created.desc.iso_interval = ev->iso_interval;
+        event.big_created.desc.num_bis = ev->num_bis;
+        memcpy(event.big_created.desc.conn_handle, ev->conn_handle,
+               ev->num_bis * sizeof(uint16_t));
+        event.big_created.phy = ev->phy;
+    }
 
     if (big->cb != NULL) {
         big->cb(&event, big->cb_arg);
@@ -375,4 +497,440 @@ ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len)
 
     return rc;
 }
-#endif
+
+#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK)
+static struct ble_iso_conn *
+ble_iso_conn_lookup_handle(uint16_t handle)
+{
+    struct ble_iso_conn *conn;
+
+    SLIST_FOREACH(conn, &ble_iso_conns, next) {
+        if (conn->handle == handle) {
+            return conn;
+        }
+    }
+
+    return NULL;
+}
+
+int
+ble_iso_big_sync_create(const struct ble_iso_big_sync_create_params *param,
+                        uint8_t *big_handle)
+{
+    struct ble_hci_le_big_create_sync_cp *cp;
+    uint8_t buf[sizeof(*cp) + MYNEWT_VAL(BLE_MAX_BIS)];
+    struct ble_iso_big *big;
+    int rc;
+
+    big = ble_iso_big_alloc();
+    if (big == NULL) {
+        return BLE_HS_ENOMEM;
+    }
+
+    big->bis_cnt = param->bis_cnt;
+    big->cb = param->cb;
+    big->cb_arg = param->cb_arg;
+
+    cp = (void *)buf;
+    cp->big_handle = big->handle;
+    put_le16(&cp->sync_handle, param->sync_handle);
+
+    if (param->broadcast_code != NULL) {
+        cp->encryption = BLE_HCI_ISO_BIG_ENCRYPTION_ENCRYPTED;
+        memcpy(cp->broadcast_code, param->broadcast_code, sizeof(cp->broadcast_code));
+    } else {
+        cp->encryption = BLE_HCI_ISO_BIG_ENCRYPTION_UNENCRYPTED;
+        memset(cp->broadcast_code, 0, sizeof(cp->broadcast_code));
+    }
+
+    cp->mse = param->mse;
+    put_le16(&cp->sync_timeout, param->sync_timeout);
+    cp->num_bis = param->bis_cnt;
+
+    for (uint8_t i = 0; i < param->bis_cnt; i++) {
+        struct ble_iso_bis *bis;
+
+        bis = ble_iso_bis_alloc(big);
+        if (bis == NULL) {
+            ble_iso_big_free(big);
+            return BLE_HS_ENOMEM;
+        }
+
+        bis->conn.cb = param->bis_params[i].cb;
+        bis->conn.cb_arg = param->bis_params[i].cb_arg;
+
+        cp->bis[i] = param->bis_params[i].bis_index;
+    }
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_BIG_CREATE_SYNC),
+                           cp, sizeof(*cp) + cp->num_bis, NULL, 0);
+    if (rc != 0) {
+        ble_iso_big_free(big);
+    } else {
+        *big_handle = big->handle;
+    }
+
+    return rc;
+}
+
+int
+ble_iso_big_sync_terminate(uint8_t big_handle)
+{
+    struct ble_hci_le_big_terminate_sync_cp cp;
+    struct ble_hci_le_big_terminate_sync_rp rp;
+    struct ble_iso_big *big;
+    int rc;
+
+    big = ble_iso_big_find_by_handle(big_handle);
+    if (big == NULL) {
+        BLE_HS_LOG_ERROR("No BIG with handle=%d\n", big_handle);
+        return BLE_HS_ENOENT;
+    }
+
+    cp.big_handle = big->handle;
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC),
+                           &cp, sizeof(cp), &rp, sizeof(rp));
+    if (rc == 0) {
+        struct ble_iso_event event;
+        ble_iso_event_fn *cb;
+        void *cb_arg;
+
+        event.type = BLE_ISO_EVENT_BIG_SYNC_TERMINATED;
+        event.big_terminated.big_handle = big_handle;
+        event.big_terminated.reason = BLE_ERR_CONN_TERM_LOCAL;
+
+        cb = big->cb;
+        cb_arg = big->cb_arg;
+
+        ble_iso_big_free(big);
+
+        if (cb != NULL) {
+            cb(&event, cb_arg);
+        }
+    }
+
+    return rc;
+}
+
+void
+ble_iso_rx_big_sync_established(const struct ble_hci_ev_le_subev_big_sync_established *ev)
+{
+    struct ble_iso_event event;
+    struct ble_iso_big *big;
+    ble_iso_event_fn *cb;
+    void *cb_arg;
+
+    big = ble_iso_big_find_by_handle(ev->big_handle);
+    if (big == NULL) {
+        return;
+    }
+
+    cb = big->cb;
+    cb_arg = big->cb_arg;
+
+    memset(&event, 0, sizeof(event));
+    event.type = BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED;
+    event.big_sync_established.status = ev->status;
+
+    if (event.big_sync_established.status != 0) {
+        ble_iso_big_free(big);
+    } else {
+        if (big->bis_cnt != ev->num_bis) {
+            BLE_HS_LOG_ERROR("Unexpected num_bis=%d != bis_cnt=%d\n",
+                             ev->num_bis, big->bis_cnt);
+            /* XXX: Should we destroy the group? */
+        }
+
+        ble_iso_big_conn_handles_init(big, ev->conn_handle, ev->num_bis);
+
+        event.big_sync_established.desc.big_handle = ev->big_handle;
+        event.big_sync_established.desc.transport_latency_big =
+            get_le24(ev->transport_latency_big);
+        event.big_sync_established.desc.nse = ev->nse;
+        event.big_sync_established.desc.bn = ev->bn;
+        event.big_sync_established.desc.pto = ev->pto;
+        event.big_sync_established.desc.irc = ev->irc;
+        event.big_sync_established.desc.max_pdu = le16toh(ev->max_pdu);
+        event.big_sync_established.desc.iso_interval = le16toh(ev->iso_interval);
+        event.big_sync_established.desc.num_bis = ev->num_bis;
+        memcpy(event.big_sync_established.desc.conn_handle, ev->conn_handle,
+               ev->num_bis * sizeof(uint16_t));
+    }
+
+    if (cb != NULL) {
+        cb(&event, cb_arg);
+    }
+}
+
+void
+ble_iso_rx_big_sync_lost(const struct ble_hci_ev_le_subev_big_sync_lost *ev)
+{
+    struct ble_iso_event event;
+    struct ble_iso_big *big;
+    ble_iso_event_fn *cb;
+    void *cb_arg;
+
+    big = ble_iso_big_find_by_handle(ev->big_handle);
+    if (big == NULL) {
+        BLE_HS_LOG_ERROR("No BIG with handle=%d\n", ev->big_handle);
+        return;
+    }
+
+    event.type = BLE_ISO_EVENT_BIG_SYNC_TERMINATED;
+    event.big_terminated.big_handle = ev->big_handle;
+    event.big_terminated.reason = ev->reason;
+
+    cb = big->cb;
+    cb_arg = big->cb_arg;
+
+    ble_iso_big_free(big);
+
+    if (cb != NULL) {
+        cb(&event, cb_arg);
+    }
+}
+
+static int
+ble_iso_rx_data_info_parse(struct os_mbuf *om, bool ts_available,
+                           struct ble_iso_rx_data_info *info)
+{
+    struct ble_hci_iso_data *iso_data;
+    uint16_t u16;
+
+    if (ts_available) {
+        if (os_mbuf_len(om) < sizeof(info->ts)) {
+            BLE_HS_LOG_DEBUG("Data missing\n");
+            return BLE_HS_EMSGSIZE;
+        }
+
+        info->ts = get_le32(om->om_data);
+        os_mbuf_adj(om, sizeof(info->ts));
+    } else {
+        info->ts = 0;
+    }
+
+    if (os_mbuf_len(om) < sizeof(*iso_data)) {
+        BLE_HS_LOG_DEBUG("Data missing\n");
+        return BLE_HS_EMSGSIZE;
+    }
+
+    iso_data = (void *)(om->om_data);
+
+    info->seq_num = le16toh(iso_data->packet_seq_num);
+    u16 = le16toh(iso_data->sdu_len);
+    info->sdu_len = BLE_HCI_ISO_SDU_LENGTH(u16);
+    info->status = BLE_HCI_ISO_PKT_STATUS_FLAG(u16);
+    info->ts_valid = ts_available;
+
+    os_mbuf_adj(om, sizeof(*iso_data));
+
+    return 0;
+}
+
+static void
+ble_iso_conn_rx_reset(struct ble_iso_conn *conn)
+{
+    memset(&conn->rx_info, 0, sizeof(conn->rx_info));
+    conn->rx_buf = NULL;
+}
+
+static void
+ble_iso_conn_rx_data_discard(struct ble_iso_conn *conn)
+{
+    os_mbuf_free_chain(conn->rx_buf);
+    ble_iso_conn_rx_reset(conn);
+}
+
+static void
+ble_iso_event_iso_rx_emit(struct ble_iso_conn *conn)
+{
+    struct ble_iso_event event = {
+        .type = BLE_ISO_EVENT_ISO_RX,
+        .iso_rx.conn_handle = conn->handle,
+        .iso_rx.info = &conn->rx_info,
+        .iso_rx.om = conn->rx_buf,
+    };
+
+    if (conn->cb != NULL) {
+        conn->cb(&event, conn->cb_arg);
+    }
+}
+
+static int
+ble_iso_conn_rx_data_load(struct ble_iso_conn *conn, struct os_mbuf *frag,
+                          uint8_t pb_flag, bool ts_available, void *arg)
+{
+    int len_remaining;
+    int rc;
+
+    switch (pb_flag) {
+    case BLE_HCI_ISO_PB_FIRST:
+    case BLE_HCI_ISO_PB_COMPLETE:
+        if (conn->rx_buf != NULL) {
+            /* Previous data packet never completed. Discard old packet. */
+            ble_iso_conn_rx_data_discard(conn);
+        }
+
+        rc = ble_iso_rx_data_info_parse(frag, ts_available, &conn->rx_info);
+        if (rc != 0) {
+            return rc;
+        }
+
+        conn->rx_buf = frag;
+        break;
+
+    case BLE_HCI_ISO_PB_CONTINUATION:
+    case BLE_HCI_ISO_PB_LAST:
+        if (conn->rx_buf == NULL) {
+            /* Last fragment without the start. Discard new packet. */
+            return BLE_HS_EBADDATA;
+        }
+
+        /* Determine whether the total length won't exceed the declared SDU length */
+        len_remaining = conn->rx_info.sdu_len - OS_MBUF_PKTLEN(conn->rx_buf);
+        if (len_remaining - os_mbuf_len(frag) < 0) {
+            /* SDU Length exceeded. Discard all packets. */
+            ble_iso_conn_rx_data_discard(conn);
+            return BLE_HS_EBADDATA;
+        }
+
+        os_mbuf_concat(conn->rx_buf, frag);
+        break;
+
+    default:
+        BLE_HS_LOG_ERROR("Invalid pb_flag %d\n", pb_flag);
+        return BLE_HS_EBADDATA;
+    }
+
+    if (pb_flag == BLE_HCI_ISO_PB_COMPLETE || pb_flag == BLE_HCI_ISO_PB_LAST) {
+        ble_iso_event_iso_rx_emit(conn);
+        ble_iso_conn_rx_reset(conn);
+    }
+
+    return 0;
+}
+
+int
+ble_iso_rx_data(struct os_mbuf *om, void *arg)
+{
+    struct ble_iso_conn *conn;
+    struct ble_hci_iso *hci_iso;
+    uint16_t conn_handle;
+    uint16_t length;
+    uint16_t pb_flag;
+    uint16_t ts_flag;
+    uint16_t u16;
+    int rc;
+
+    if (os_mbuf_len(om) < sizeof(*hci_iso)) {
+        BLE_HS_LOG_DEBUG("Data missing\n");
+        os_mbuf_free_chain(om);
+        return BLE_HS_EMSGSIZE;
+    }
+
+    hci_iso = (void *)om->om_data;
+
+    u16 = le16toh(hci_iso->handle);
+    conn_handle = BLE_HCI_ISO_CONN_HANDLE(u16);
+    pb_flag = BLE_HCI_ISO_PB_FLAG(u16);
+    ts_flag = BLE_HCI_ISO_TS_FLAG(u16);
+    length = BLE_HCI_ISO_LENGTH(le16toh(hci_iso->length));
+
+    os_mbuf_adj(om, sizeof(*hci_iso));
+
+    if (os_mbuf_len(om) < length) {
+        BLE_HS_LOG_DEBUG("Data missing\n");
+        os_mbuf_free_chain(om);
+        return BLE_HS_EMSGSIZE;
+    }
+
+    conn = ble_iso_conn_lookup_handle(conn_handle);
+    if (conn == NULL) {
+        BLE_HS_LOG_DEBUG("Unknown handle=%d\n", conn_handle);
+        os_mbuf_free_chain(om);
+        return BLE_HS_EMSGSIZE;
+    }
+
+    rc = ble_iso_conn_rx_data_load(conn, om, pb_flag, ts_flag > 0, arg);
+    if (rc != 0) {
+        os_mbuf_free_chain(om);
+        return rc;
+    }
+
+    return 0;
+}
+#endif /* BLE_ISO_BROADCAST_SINK */
+
+int
+ble_iso_data_path_setup(const struct ble_iso_data_path_setup_params *param)
+{
+    struct ble_hci_le_setup_iso_data_path_rp rp;
+    struct ble_hci_le_setup_iso_data_path_cp *cp;
+    uint8_t buf[sizeof(*cp) + UINT8_MAX];
+    int rc;
+
+    if (param->codec_config_len > 0 && param->codec_config == NULL) {
+        BLE_HS_LOG_ERROR("Missing codec_config\n");
+        return BLE_HS_EINVAL;
+    }
+
+    cp = (void *)buf;
+    put_le16(&cp->conn_handle, param->conn_handle);
+    cp->data_path_dir = 0;
+
+    if (param->data_path_dir & BLE_ISO_DATA_DIR_TX) {
+        /* Input (Host to Controller) */
+        cp->data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_INPUT;
+    }
+
+    if (param->data_path_dir & BLE_ISO_DATA_DIR_RX) {
+        /* Output (Controller to Host) */
+        cp->data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_OUTPUT;
+    }
+
+    cp->data_path_id = param->data_path_id;
+    cp->codec_id[0] = param->codec_id.format;
+    put_le16(&cp->codec_id[1], param->codec_id.company_id);
+    put_le16(&cp->codec_id[3], param->codec_id.vendor_specific);
+    put_le24(cp->controller_delay, param->ctrl_delay);
+
+    cp->codec_config_len = param->codec_config_len;
+    memcpy(cp->codec_config, param->codec_config, cp->codec_config_len);
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH),
+                           cp, sizeof(*cp) + cp->codec_config_len, &rp,
+                           sizeof(rp));
+
+    return rc;
+}
+
+int
+ble_iso_data_path_remove(const struct ble_iso_data_path_remove_params *param)
+{
+    struct ble_hci_le_remove_iso_data_path_rp rp;
+    struct ble_hci_le_remove_iso_data_path_cp cp = { 0 };
+    int rc;
+
+    put_le16(&cp.conn_handle, param->conn_handle);
+
+    if (param->data_path_dir & BLE_ISO_DATA_DIR_TX) {
+        /* Input (Host to Controller) */
+        cp.data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_INPUT;
+    }
+
+    if (param->data_path_dir & BLE_ISO_DATA_DIR_RX) {
+        /* Output (Controller to Host) */
+        cp.data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_OUTPUT;
+    }
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH),
+                           &cp, sizeof(cp), &rp, sizeof(rp));
+
+    return rc;
+}
+#endif /* BLE_ISO */
diff --git a/nimble/host/src/ble_iso_priv.h b/nimble/host/src/ble_iso_priv.h
index fb0a6aab3..9005b5067 100644
--- a/nimble/host/src/ble_iso_priv.h
+++ b/nimble/host/src/ble_iso_priv.h
@@ -31,6 +31,15 @@ ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_compl
 void
 ble_iso_rx_terminate_big_complete(const struct ble_hci_ev_le_subev_terminate_big_complete *ev);
 
+void
+ble_iso_rx_big_sync_established(const struct ble_hci_ev_le_subev_big_sync_established *ev);
+
+void
+ble_iso_rx_big_sync_lost(const struct ble_hci_ev_le_subev_big_sync_lost *ev);
+
+int
+ble_iso_rx_data(struct os_mbuf *om, void *arg);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h
index 62c62d0fb..fb74c24aa 100644
--- a/nimble/include/nimble/hci_common.h
+++ b/nimble/include/nimble/hci_common.h
@@ -2087,31 +2087,45 @@ struct hci_data_hdr
 #define BLE_HCI_PB_FIRST_FLUSH              2
 #define BLE_HCI_PB_FULL                     3
 
-#define BLE_HCI_ISO_CONN_HANDLE_MASK    (0x07ff)
-#define BLE_HCI_ISO_PB_FLAG_MASK        (0x3000)
-#define BLE_HCI_ISO_TS_FLAG_MASK        (0x4000)
-#define BLE_HCI_ISO_LENGTH_MASK         (0x7fff)
+#define BLE_HCI_ISO_CONN_HANDLE_MASK        (0x07ff)
+#define BLE_HCI_ISO_PB_FLAG_MASK            (0x3000)
+#define BLE_HCI_ISO_TS_FLAG_MASK            (0x4000)
+#define BLE_HCI_ISO_LENGTH_MASK             (0x7fff)
+#define BLE_HCI_ISO_SDU_LENGTH_MASK         (0x0fff)
+#define BLE_HCI_ISO_PKT_STATUS_FLAG_MASK    (0xC000)
 
 #define BLE_HCI_ISO_HANDLE(ch, pb, ts)  ((ch) | ((pb) << 12) | ((ts) << 14))
 
 #define BLE_HCI_ISO_CONN_HANDLE(h)      ((h) & BLE_HCI_ISO_CONN_HANDLE_MASK)
 #define BLE_HCI_ISO_PB_FLAG(h)          (((h) & BLE_HCI_ISO_PB_FLAG_MASK) >> 12)
-#define BLE_HCI_ISO_TS_FLAG(h)          ((h) & BLE_HCI_ISO_TS_FLAG_MASK)
+#define BLE_HCI_ISO_TS_FLAG(h)          (((h) & BLE_HCI_ISO_TS_FLAG_MASK) >> 14)
 #define BLE_HCI_ISO_LENGTH(l)           ((l) & BLE_HCI_ISO_LENGTH_MASK)
+#define BLE_HCI_ISO_SDU_LENGTH(l)       ((l) & BLE_HCI_ISO_SDU_LENGTH_MASK)
+#define BLE_HCI_ISO_PKT_STATUS_FLAG(l)  (((l) & BLE_HCI_ISO_PKT_STATUS_FLAG_MASK) >> 14)
 
 #define BLE_HCI_ISO_PB_FIRST            (0)
 #define BLE_HCI_ISO_PB_CONTINUATION     (1)
 #define BLE_HCI_ISO_PB_COMPLETE         (2)
 #define BLE_HCI_ISO_PB_LAST             (3)
 
+#define BLE_HCI_ISO_PKT_STATUS_VALID    0x00
+#define BLE_HCI_ISO_PKT_STATUS_INVALID  0x01
+#define BLE_HCI_ISO_PKT_STATUS_LOST     0x10
+
 #define BLE_HCI_ISO_BIG_HANDLE_MIN      0x00
 #define BLE_HCI_ISO_BIG_HANDLE_MAX      0xEF
 
+#define BLE_HCI_ISO_BIG_ENCRYPTION_UNENCRYPTED  0x00
+#define BLE_HCI_ISO_BIG_ENCRYPTION_ENCRYPTED    0x01
+
+#define BLE_HCI_ISO_DATA_PATH_DIR_INPUT         0x00
+#define BLE_HCI_ISO_DATA_PATH_DIR_OUTPUT        0x01
+
 struct ble_hci_iso {
     uint16_t handle;
     uint16_t length;
     uint8_t data[0];
-};
+} __attribute__((packed));
 
 #define BLE_HCI_ISO_HDR_SDU_LENGTH_MASK     (0x07ff)
 
@@ -2119,7 +2133,7 @@ struct ble_hci_iso_data {
     uint16_t packet_seq_num;
     uint16_t sdu_len;
     uint8_t data[0];
-};
+} __attribute__((packed));
 
 #ifdef __cplusplus
 }
diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c
index 75a813dba..0d52ec584 100644
--- a/nimble/transport/socket/src/ble_hci_socket.c
+++ b/nimble/transport/socket/src/ble_hci_socket.c
@@ -103,11 +103,13 @@ STATS_SECT_START(hci_sock_stats)
     STATS_SECT_ENTRY(icmd)
     STATS_SECT_ENTRY(ievt)
     STATS_SECT_ENTRY(iacl)
+    STATS_SECT_ENTRY(iiso)
     STATS_SECT_ENTRY(ibytes)
     STATS_SECT_ENTRY(ierr)
     STATS_SECT_ENTRY(imem)
     STATS_SECT_ENTRY(omsg)
     STATS_SECT_ENTRY(oacl)
+    STATS_SECT_ENTRY(oiso)
     STATS_SECT_ENTRY(ocmd)
     STATS_SECT_ENTRY(oevt)
     STATS_SECT_ENTRY(obytes)
@@ -120,11 +122,13 @@ STATS_NAME_START(hci_sock_stats)
     STATS_NAME(hci_sock_stats, icmd)
     STATS_NAME(hci_sock_stats, ievt)
     STATS_NAME(hci_sock_stats, iacl)
+    STATS_NAME(hci_sock_stats, iiso)
     STATS_NAME(hci_sock_stats, ibytes)
     STATS_NAME(hci_sock_stats, ierr)
     STATS_NAME(hci_sock_stats, imem)
     STATS_NAME(hci_sock_stats, omsg)
     STATS_NAME(hci_sock_stats, oacl)
+    STATS_NAME(hci_sock_stats, oiso)
     STATS_NAME(hci_sock_stats, ocmd)
     STATS_NAME(hci_sock_stats, oevt)
     STATS_NAME(hci_sock_stats, obytes)
@@ -142,6 +146,7 @@ STATS_NAME_END(hci_sock_stats)
 #define BLE_HCI_UART_H4_ACL         0x02
 #define BLE_HCI_UART_H4_SCO         0x03
 #define BLE_HCI_UART_H4_EVT         0x04
+#define BLE_HCI_UART_H4_ISO         0x05
 #define BLE_HCI_UART_H4_SYNC_LOSS   0x80
 #define BLE_HCI_UART_H4_SKIP_CMD    0x81
 #define BLE_HCI_UART_H4_SKIP_ACL    0x82
@@ -483,6 +488,39 @@ ble_hci_sock_rx_msg(void)
             ble_transport_to_ll_acl(m);
 #else
             ble_transport_to_hs_acl(m);
+#endif
+            OS_EXIT_CRITICAL(sr);
+            break;
+        case BLE_HCI_UART_H4_ISO:
+            if (bhss->rx_off < BLE_HCI_DATA_HDR_SZ) {
+                return -1;
+            }
+            len = 1 + BLE_HCI_DATA_HDR_SZ + (bhss->rx_data[4] << 8) +
+                  bhss->rx_data[3];
+            if (bhss->rx_off < len) {
+                return -1;
+            }
+            STATS_INC(hci_sock_stats, imsg);
+            STATS_INC(hci_sock_stats, iiso);
+#if MYNEWT_VAL(BLE_CONTROLLER)
+            m = ble_transport_alloc_iso_from_hs();
+#else
+            m = ble_transport_alloc_iso_from_ll();
+#endif
+            if (!m) {
+                STATS_INC(hci_sock_stats, imem);
+                break;
+            }
+            if (os_mbuf_append(m, &bhss->rx_data[1], len - 1)) {
+                STATS_INC(hci_sock_stats, imem);
+                os_mbuf_free_chain(m);
+                break;
+            }
+            OS_ENTER_CRITICAL(sr);
+#if MYNEWT_VAL(BLE_CONTROLLER)
+            ble_transport_to_ll_iso(m);
+#else
+            ble_transport_to_hs_iso(m);
 #endif
             OS_EXIT_CRITICAL(sr);
             break;


(mynewt-nimble) 08/08: apps/btshell: Add 'silent' option to scan commands

Posted by ry...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6750a13ccb1e943006d58e8f2c21d749000c4314
Author: Mariusz Skamra <ma...@codecoup.pl>
AuthorDate: Mon Jan 22 20:14:37 2024 +0100

    apps/btshell: Add 'silent' option to scan commands
    
    This adds option to silent the discovery results. This is useful in case
    there is another callback listener registered that handles the scan
    results, and the user does not want the default handler to print the
    results.
---
 apps/btshell/src/btshell.h |  1 +
 apps/btshell/src/cmd.c     |  8 ++++++++
 apps/btshell/src/main.c    | 19 ++++++++++++++++---
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h
index c74ca2fa5..c457fd7f9 100644
--- a/apps/btshell/src/btshell.h
+++ b/apps/btshell/src/btshell.h
@@ -92,6 +92,7 @@ struct btshell_scan_opts {
     uint16_t limit;
     uint8_t ignore_legacy : 1;
     uint8_t periodic_only : 1;
+    uint8_t silent : 1;
     uint8_t name_filter_len;
     char name_filter[NAME_FILTER_LEN_MAX];
 };
diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c
index 1924e4f4e..4c00d7ba3 100644
--- a/apps/btshell/src/cmd.c
+++ b/apps/btshell/src/cmd.c
@@ -1110,6 +1110,7 @@ static struct btshell_scan_opts g_scan_opts = {
     .limit = UINT16_MAX,
     .ignore_legacy = 0,
     .periodic_only = 0,
+    .silent = 0,
     .name_filter_len = 0,
 };
 
@@ -1136,6 +1137,12 @@ cmd_set_scan_opts(int argc, char **argv)
         return rc;
     }
 
+    g_scan_opts.silent = parse_arg_bool_dflt("silent", 0, &rc);
+    if (rc != 0) {
+        console_printf("invalid 'silent' parameter\n");
+        return rc;
+    }
+
     g_scan_opts.periodic_only = parse_arg_bool_dflt("periodic_only", 0, &rc);
     if (rc != 0) {
         console_printf("invalid 'periodic_only' parameter\n");
@@ -1160,6 +1167,7 @@ static const struct shell_param set_scan_opts_params[] = {
     {"decode_limit", "usage: =[0-UINT16_MAX], default: UINT16_MAX"},
     {"ignore_legacy", "usage: =[0-1], default: 0"},
     {"periodic_only", "usage: =[0-1], default: 0"},
+    {"silent", "usage: =[0-1], default: 0"},
     {"name_filter", "usage: =name, default: {none}"},
     {NULL, NULL}
 };
diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c
index 0f87b5c23..6424bf6b8 100644
--- a/apps/btshell/src/main.c
+++ b/apps/btshell/src/main.c
@@ -1315,11 +1315,23 @@ btshell_gap_event(struct ble_gap_event *event, void *arg)
 
         return btshell_restart_adv(event);
 #if MYNEWT_VAL(BLE_EXT_ADV)
-    case BLE_GAP_EVENT_EXT_DISC:
-        btshell_decode_event_type(&event->ext_disc, arg);
+    case BLE_GAP_EVENT_EXT_DISC: {
+        struct btshell_scan_opts *scan_opts = arg;
+
+        if (!scan_opts->silent) {
+            btshell_decode_event_type(&event->ext_disc, arg);
+        }
+
         return 0;
+    }
 #endif
-    case BLE_GAP_EVENT_DISC:
+    case BLE_GAP_EVENT_DISC: {
+        struct btshell_scan_opts *scan_opts = arg;
+
+        if (scan_opts->silent) {
+            return 0;
+        }
+
         console_printf("received advertisement; event_type=%d rssi=%d "
                        "addr_type=%d addr=", event->disc.event_type,
                        event->disc.rssi, event->disc.addr.type);
@@ -1337,6 +1349,7 @@ btshell_gap_event(struct ble_gap_event *event, void *arg)
         btshell_decode_adv_data(event->disc.data, event->disc.length_data, arg);
 
         return 0;
+    }
 
     case BLE_GAP_EVENT_CONN_UPDATE:
         console_printf("connection updated; status=%d ",


(mynewt-nimble) 04/08: nimble/iso: Fix missing BLE_ISO_BROADCAST_SOURCE guard

Posted by ry...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit eacdbc36e020a270181a7c8bf36dd352beec4d13
Author: Mariusz Skamra <ma...@codecoup.pl>
AuthorDate: Fri Feb 23 09:39:52 2024 +0100

    nimble/iso: Fix missing BLE_ISO_BROADCAST_SOURCE guard
    
    This makes Broadcast ISO source related code dependent on
    BLE_ISO_BROADCAST_SOURCE mynewt option.
---
 nimble/host/src/ble_iso.c | 46 ++++++++++++++++++++++++----------------------
 1 file changed, 24 insertions(+), 22 deletions(-)

diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c
index 271bd27cb..90bd613d0 100644
--- a/nimble/host/src/ble_iso.c
+++ b/nimble/host/src/ble_iso.c
@@ -225,6 +225,7 @@ ble_iso_big_free(struct ble_iso_big *big)
     return 0;
 }
 
+#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)
 int
 ble_iso_create_big(const struct ble_iso_create_big_params *create_params,
                    const struct ble_iso_big_params *big_params)
@@ -298,28 +299,6 @@ ble_iso_terminate_big(uint8_t big_handle)
     return rc;
 }
 
-int
-ble_iso_init(void)
-{
-    int rc;
-
-    SLIST_INIT(&ble_iso_bigs);
-
-    rc = os_mempool_init(&ble_iso_big_pool,
-                         MYNEWT_VAL(BLE_MAX_BIG),
-                         sizeof (struct ble_iso_big),
-                         ble_iso_big_mem, "ble_iso_big_pool");
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
-    rc = os_mempool_init(&ble_iso_bis_pool,
-                         MYNEWT_VAL(BLE_MAX_BIS),
-                         sizeof (struct ble_iso_bis),
-                         ble_iso_bis_mem, "ble_iso_bis_pool");
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
-    return 0;
-}
-
 void
 ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_complete *ev)
 {
@@ -497,6 +476,7 @@ ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len)
 
     return rc;
 }
+#endif /* BLE_ISO_BROADCAST_SOURCE */
 
 #if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK)
 static struct ble_iso_conn *
@@ -933,4 +913,26 @@ ble_iso_data_path_remove(const struct ble_iso_data_path_remove_params *param)
 
     return rc;
 }
+
+int
+ble_iso_init(void)
+{
+    int rc;
+
+    SLIST_INIT(&ble_iso_bigs);
+
+    rc = os_mempool_init(&ble_iso_big_pool,
+                         MYNEWT_VAL(BLE_MAX_BIG),
+                         sizeof (struct ble_iso_big),
+                         ble_iso_big_mem, "ble_iso_big_pool");
+    SYSINIT_PANIC_ASSERT(rc == 0);
+
+    rc = os_mempool_init(&ble_iso_bis_pool,
+                         MYNEWT_VAL(BLE_MAX_BIS),
+                         sizeof (struct ble_iso_bis),
+                         ble_iso_bis_mem, "ble_iso_bis_pool");
+    SYSINIT_PANIC_ASSERT(rc == 0);
+
+    return 0;
+}
 #endif /* BLE_ISO */


(mynewt-nimble) 06/08: nimble/audio: Add LE Audio btshell target

Posted by ry...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2e368caab2c7d910922f3b281adb5f5f98267014
Author: Mariusz Skamra <ma...@codecoup.pl>
AuthorDate: Thu Jan 25 14:04:22 2024 +0100

    nimble/audio: Add LE Audio btshell target
    
    This adds btshell for native target build with the LE Audio
    functionality enabled.
---
 nimble/host/audio/targets/btshell_native/pkg.yml   | 26 ++++++++
 .../host/audio/targets/btshell_native/syscfg.yml   | 74 ++++++++++++++++++++++
 .../host/audio/targets/btshell_native/target.yml   | 22 +++++++
 3 files changed, 122 insertions(+)

diff --git a/nimble/host/audio/targets/btshell_native/pkg.yml b/nimble/host/audio/targets/btshell_native/pkg.yml
new file mode 100644
index 000000000..67eb2d6fe
--- /dev/null
+++ b/nimble/host/audio/targets/btshell_native/pkg.yml
@@ -0,0 +1,26 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: audio/targets/btshell_native
+pkg.type: target
+pkg.description: Target for native btshell application with LE Audio
+                 functionality enabled
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.deps:
diff --git a/nimble/host/audio/targets/btshell_native/syscfg.yml b/nimble/host/audio/targets/btshell_native/syscfg.yml
new file mode 100644
index 000000000..d631ea798
--- /dev/null
+++ b/nimble/host/audio/targets/btshell_native/syscfg.yml
@@ -0,0 +1,74 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.vals:
+    CONSOLE_IMPLEMENTATION: full
+    LOG_IMPLEMENTATION: full
+    STATS_IMPLEMENTATION: full
+
+    # Enable the shell task.
+    SHELL_TASK: 1
+
+    # Set log level to info (disable debug logging).
+    LOG_LEVEL: 1
+
+    # Disable security manager (pairing and bonding).
+    BLE_SM_LEGACY: 0
+    BLE_SM_SC: 0
+
+    # Default task settings
+    OS_MAIN_STACK_SIZE: 512
+
+    # SMP is not supported in this app, so disable smp-over-shell.
+    SHELL_MGMT: 0
+
+    # Whether to save data to sys/config, or just keep it in RAM.
+    BLE_STORE_CONFIG_PERSIST: 0
+
+    # Enable Extended Advertising
+    BLE_EXT_ADV: 1
+    BLE_EXT_ADV_MAX_SIZE: 261
+
+    BLE_MULTI_ADV_INSTANCES: 1
+
+    # Enable Periodic Advertising
+    BLE_PERIODIC_ADV: 1
+    BLE_PERIODIC_ADV_SYNC_TRANSFER: 1
+    BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1
+
+    BLE_SOCK_USE_TCP: 0
+    BLE_SOCK_USE_LINUX_BLUE: 1
+    BLE_SOCK_LINUX_DEV: 1
+    BLE_TRANSPORT_HS: native
+    BLE_TRANSPORT_LL: socket
+
+    BLE_VERSION: 54
+    BLE_ISO_BROADCAST_SINK: 1
+    BLE_ISO_BROADCAST_SOURCE: 1
+    BLE_MAX_BIG: 1
+    BLE_MAX_BIS: 2
+
+    CONSOLE_UART: 1
+    CONSOLE_UART_BAUD: 1000000
+    CONSOLE_STICKY_PROMPT: 1
+    CONSOLE_UART_TX_BUF_SIZE: 256
+    STATS_CLI: 1
+    STATS_NAMES: 1
+
+    MSYS_1_BLOCK_COUNT: 100
diff --git a/nimble/host/audio/targets/btshell_native/target.yml b/nimble/host/audio/targets/btshell_native/target.yml
new file mode 100644
index 000000000..30b7d5b74
--- /dev/null
+++ b/nimble/host/audio/targets/btshell_native/target.yml
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+target.app: "@apache-mynewt-nimble/apps/btshell"
+target.bsp: "@apache-mynewt-core/hw/bsp/native"
+target.build_profile: debug


(mynewt-nimble) 07/08: apps/btshell: Fix minor coding style issue

Posted by ry...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 56a23bc0feafd8726eea65863e882bb036d566af
Author: Mariusz Skamra <ma...@codecoup.pl>
AuthorDate: Tue Feb 27 14:08:39 2024 +0100

    apps/btshell: Fix minor coding style issue
    
    This fixes minor coding style issue in btshell_scan_opts.
---
 apps/btshell/src/btshell.h | 4 ++--
 apps/btshell/src/cmd.c     | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h
index 83dadede5..c74ca2fa5 100644
--- a/apps/btshell/src/btshell.h
+++ b/apps/btshell/src/btshell.h
@@ -90,8 +90,8 @@ struct btshell_conn {
 
 struct btshell_scan_opts {
     uint16_t limit;
-    uint8_t ignore_legacy:1;
-    uint8_t periodic_only:1;
+    uint8_t ignore_legacy : 1;
+    uint8_t periodic_only : 1;
     uint8_t name_filter_len;
     char name_filter[NAME_FILTER_LEN_MAX];
 };
diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c
index 1b20078e8..1924e4f4e 100644
--- a/apps/btshell/src/cmd.c
+++ b/apps/btshell/src/cmd.c
@@ -1107,10 +1107,10 @@ static const struct shell_cmd_help disconnect_help = {
  *****************************************************************************/
 
 static struct btshell_scan_opts g_scan_opts = {
-        .limit = UINT16_MAX,
-        .ignore_legacy = 0,
-        .periodic_only = 0,
-        .name_filter_len = 0,
+    .limit = UINT16_MAX,
+    .ignore_legacy = 0,
+    .periodic_only = 0,
+    .name_filter_len = 0,
 };
 
 static int


(mynewt-nimble) 02/08: nimble/iso: Fix BLE_ISO dependency

Posted by ry...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 47d1bb50dfff9bb77736db70f5d93578861bde5a
Author: Mariusz Skamra <ma...@codecoup.pl>
AuthorDate: Tue Feb 27 13:08:45 2024 +0100

    nimble/iso: Fix BLE_ISO dependency
    
    This adds the BLE_ISO dependency on BLE_ISO_BROADCAST_SOURCE and
    BLE_ISO_BROADCAST_SINK.
    Once one of those roles is enabled, the BLE_ISO shall be enabled.
---
 nimble/syscfg.yml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml
index 47bd266ce..6264d0bc2 100644
--- a/nimble/syscfg.yml
+++ b/nimble/syscfg.yml
@@ -95,6 +95,7 @@ syscfg.defs:
         value: 0
         restrictions:
             - '(BLE_VERSION >= 52) if 1'
+            - '(BLE_ISO_BROADCAST_SOURCE || BLE_ISO_BROADCAST_SINK) if 1'
     BLE_ISO_BROADCAST_SOURCE:
         description: >
             This enables LE Audio Broadcast Source feature
@@ -160,3 +161,6 @@ syscfg.restrictions:
 # Enable VS HCI by default for combined or standalone controller build
 syscfg.vals.BLE_CONTROLLER:
     BLE_HCI_VS: 1
+
+syscfg.vals.'BLE_ISO_BROADCAST_SOURCE || BLE_ISO_BROADCAST_SINK':
+    BLE_ISO: 1


(mynewt-nimble) 01/08: nimble/controller: Conditionally enable BLE_LL_ISO_BROADCASTER

Posted by ry...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 90d270dfa1d5b9d80e330aab5c5a65e00734fe93
Author: Mariusz Skamra <ma...@codecoup.pl>
AuthorDate: Tue Jan 23 08:12:18 2024 +0100

    nimble/controller: Conditionally enable BLE_LL_ISO_BROADCASTER
    
    Enable BLE_LL_ISO_BROADCASTER if BLE_ISO_BROADCAST_SOURCE and/or
    BLE_ISO_BROADCAST_SINK is enabled.
    
    Signed-off-by: Mariusz Skamra <ma...@codecoup.pl>
---
 nimble/controller/syscfg.yml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml
index 19fae4754..8a32e2e02 100644
--- a/nimble/controller/syscfg.yml
+++ b/nimble/controller/syscfg.yml
@@ -483,8 +483,9 @@ syscfg.defs:
             Enable support for Isochronous Broadcasting state.
         restrictions:
             - BLE_LL_ISO if 1
-        value: MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)
+        value: 0
         state: experimental
+
     BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS:
         description: >
             Enables ISO synchronization feedback using vendor-specific HCI event.
@@ -613,6 +614,9 @@ syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV:
     BLE_HW_WHITELIST_ENABLE: 0
     BLE_LL_SCAN_AUX_SEGMENT_CNT: 8
 
+syscfg.vals.'BLE_ISO_BROADCAST_SOURCE || BLE_ISO_BROADCAST_SINK':
+    BLE_LL_ISO_BROADCASTER: 1
+
 syscfg.vals.BLE_LL_ISO_BROADCASTER:
     BLE_LL_CFG_FEAT_LE_ENCRYPTION: 1
     BLE_LL_STACK_SIZE: 180


(mynewt-nimble) 05/08: apps/btshell: Add ISO related commands

Posted by ry...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit a2e68282f57b206c5a6ba6146a019877cae5a994
Author: Mariusz Skamra <ma...@codecoup.pl>
AuthorDate: Thu Feb 22 16:03:22 2024 +0100

    apps/btshell: Add ISO related commands
    
    This adds ISO related commands to the btshell application.
    The commands can be used for testing purposes.
---
 apps/btshell/src/cmd.c     |  51 ++++-
 apps/btshell/src/cmd_iso.c | 513 +++++++++++++++++++++++++++++++++++++++++++++
 apps/btshell/src/cmd_iso.h |  39 ++++
 3 files changed, 602 insertions(+), 1 deletion(-)

diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c
index ff8bae8c7..1b20078e8 100644
--- a/apps/btshell/src/cmd.c
+++ b/apps/btshell/src/cmd.c
@@ -41,6 +41,7 @@
 #include "cmd.h"
 #include "btshell.h"
 #include "cmd_gatt.h"
+#include "cmd_iso.h"
 #include "cmd_l2cap.h"
 #include "cmd_leaudio.h"
 
@@ -4858,7 +4859,7 @@ static const struct shell_cmd btshell_commands[] = {
     },
 #endif
 #endif
-#if MYNEWT_VAL(BLE_ISO)
+#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)
     {
         .sc_cmd = "base_add",
         .sc_cmd_func = cmd_leaudio_base_add,
@@ -4915,7 +4916,55 @@ static const struct shell_cmd btshell_commands[] = {
         .help = &leaudio_broadcast_stop_help,
 #endif
     },
+#endif /* BLE_ISO_BROADCAST_SOURCE */
+#if MYNEWT_VAL(BLE_ISO)
+#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)
+    {
+        .sc_cmd = "big-create",
+        .sc_cmd_func = cmd_iso_big_create,
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+        .help = &cmd_iso_big_create_help,
+#endif
+    },
+    {
+        .sc_cmd = "big-terminate",
+        .sc_cmd_func = cmd_iso_big_terminate,
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+        .help = &cmd_iso_big_terminate_help,
+#endif
+    },
+#endif /* BLE_ISO_BROADCAST_SOURCE */
+#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK)
+    {
+        .sc_cmd = "big-sync-create",
+        .sc_cmd_func = cmd_iso_big_sync_create,
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+        .help = &cmd_iso_big_sync_create_help,
 #endif
+    },
+    {
+        .sc_cmd = "big-sync-terminate",
+        .sc_cmd_func = cmd_iso_big_sync_terminate,
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+        .help = &cmd_iso_big_sync_terminate_help,
+#endif
+    },
+#endif /* BLE_ISO_BROADCAST_SINK */
+    {
+        .sc_cmd = "iso-data-path-setup",
+        .sc_cmd_func = cmd_iso_data_path_setup,
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+        .help = &cmd_iso_data_path_setup_help,
+#endif
+    },
+    {
+        .sc_cmd = "iso-data-path-remove",
+        .sc_cmd_func = cmd_iso_data_path_remove,
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+        .help = &cmd_iso_data_path_remove_help,
+#endif
+    },
+#endif /* BLE_ISO */
     { 0 },
 };
 
diff --git a/apps/btshell/src/cmd_iso.c b/apps/btshell/src/cmd_iso.c
new file mode 100644
index 000000000..8d0ef343d
--- /dev/null
+++ b/apps/btshell/src/cmd_iso.c
@@ -0,0 +1,513 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "host/ble_iso.h"
+
+#include "cmd_iso.h"
+
+#include "console/console.h"
+#include "shell/shell.h"
+
+#if (MYNEWT_VAL(BLE_ISO))
+static struct iso_rx_stats {
+    uint8_t bis_index;
+    bool ts_valid;
+    uint32_t ts;
+    uint16_t seq_num;
+    uint64_t total_cnt;
+    uint64_t valid_cnt;
+    uint64_t error_cnt;
+    uint64_t lost_cnt;
+} rx_stats_pool[MYNEWT_VAL(BLE_MAX_BIS)];
+
+static void
+iso_rx_stats_update(uint16_t conn_handle, const struct ble_iso_rx_data_info *info,
+                    struct iso_rx_stats *stats)
+{
+    stats->ts_valid = info->ts_valid;
+    if (stats->ts_valid) {
+        stats->ts = info->ts;
+    }
+
+    stats->seq_num = info->seq_num;
+
+    if (info->status == BLE_ISO_DATA_STATUS_VALID) {
+        stats->valid_cnt++;
+    } else if (info->status == BLE_ISO_DATA_STATUS_ERROR) {
+        stats->error_cnt++;
+    } else if (info->status == BLE_ISO_DATA_STATUS_LOST) {
+        stats->lost_cnt++;
+    }
+
+    stats->total_cnt++;
+
+    if ((stats->total_cnt % 100) == 0) {
+        console_printf("BIS=%d, seq_num=%d, num_rx=%lld, "
+                       "(valid=%lld, error=%lld, lost=%lld) ",
+                       stats->bis_index, stats->seq_num,
+                       stats->total_cnt, stats->valid_cnt,
+                       stats->error_cnt, stats->lost_cnt);
+
+        if (stats->ts_valid) {
+            console_printf("ts=10%" PRIu32, stats->ts);
+        }
+
+        console_printf("\n");
+    }
+}
+
+static void
+print_iso_big_desc(const struct ble_iso_big_desc *desc)
+{
+    console_printf(" big_handle=0x%02x, big_sync_delay=%" PRIu32 ","
+                   " transport_latency=%" PRIu32 ", nse=%u, bn=%u, pto=%u,"
+                   " irc=%u, max_pdu=%u, iso_interval=%u num_bis=%u",
+                   desc->big_handle, desc->big_sync_delay,
+                   desc->transport_latency_big, desc->nse, desc->bn, desc->pto,
+                   desc->irc, desc->max_pdu, desc->iso_interval, desc->num_bis);
+
+    if (desc->num_bis > 0) {
+        console_printf(" conn_handles=");
+    }
+
+    for (uint8_t i = 0; i < desc->num_bis; i++) {
+        console_printf("0x%04x,", desc->conn_handle[i]);
+    }
+}
+
+static int
+ble_iso_event_handler(struct ble_iso_event *event, void *arg)
+{
+    switch (event->type) {
+    case BLE_ISO_EVENT_BIG_CREATE_COMPLETE:
+        console_printf("BIG Create Completed status: %u",
+                       event->big_created.status);
+
+        if (event->big_created.status == 0) {
+            print_iso_big_desc(&event->big_created.desc);
+            console_printf(" phy=0x%02x", event->big_created.phy);
+        }
+
+        console_printf("\n");
+        break;
+
+    case BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED:
+        console_printf("BIG Sync Established status: %u",
+                       event->big_sync_established.status);
+
+        if (event->big_sync_established.status == 0) {
+            print_iso_big_desc(&event->big_sync_established.desc);
+        }
+
+        console_printf("\n");
+        break;
+
+    case BLE_ISO_EVENT_BIG_SYNC_TERMINATED:
+        console_printf("BIG Sync Terminated handle=0x%02x reason: %u\n",
+                       event->big_terminated.big_handle,
+                       event->big_terminated.reason);
+        break;
+
+    case BLE_ISO_EVENT_ISO_RX:
+        iso_rx_stats_update(event->iso_rx.conn_handle, event->iso_rx.info, arg);
+        os_mbuf_free_chain(event->iso_rx.om);
+        break;
+
+    default:
+        break;
+    }
+
+    return 0;
+}
+
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+static const struct shell_param cmd_iso_big_create_params[] = {
+    {"adv_handle", "PA advertising handle, usage: =<UINT8>"},
+    {"bis_cnt", "BIS count, usage: =<UINT8>"},
+    {"sdu_interval", "SDU interval, usage: =<UINT32>"},
+    {"max_sdu", "Maximum SDU size, usage: =<UINT16>"},
+    {"max_latency", "Maximum transport latency, usage: =<UINT16>"},
+    {"rtn", "Retransmission number, usage: =<UINT8>"},
+    {"phy", "PHY, usage: =<UINT8>"},
+    {"packing", "Packing, usage: =<UINT8>, default: 1"},
+    {"framing", "Framing, usage: =<UINT8>, default: 0"},
+    {"broadcast_code", "Broadcast Code, usage: =[string], default: NULL"},
+
+    { NULL, NULL}
+};
+
+const struct shell_cmd_help cmd_iso_big_create_help = {
+    .summary = "Create BIG",
+    .usage = NULL,
+    .params = cmd_iso_big_create_params,
+};
+#endif /* SHELL_CMD_HELP */
+
+int
+cmd_iso_big_create(int argc, char **argv)
+{
+    struct ble_iso_create_big_params params = { 0 };
+    struct ble_iso_big_params big_params = { 0 };
+    int rc;
+
+    rc = parse_arg_init(argc - 1, argv + 1);
+    if (rc != 0) {
+        return rc;
+    }
+
+    params.adv_handle = parse_arg_uint8("adv_handle", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'adv_handle' parameter\n");
+        return rc;
+    }
+
+    params.cb = ble_iso_event_handler;
+
+    params.bis_cnt = parse_arg_uint8("bis_cnt", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'bis_cnt' parameter\n");
+        return rc;
+    }
+
+    big_params.sdu_interval = parse_arg_uint32_bounds("sdu_interval",
+                                                      0x0000FF, 0x0FFFFF,
+                                                      &rc);
+    if (rc != 0) {
+        console_printf("invalid 'sdu_interval' parameter\n");
+        return rc;
+    }
+
+    big_params.max_sdu = parse_arg_uint16_bounds("max_sdu", 0x0001, 0x0FFF,
+                                                 &rc);
+    if (rc != 0) {
+        console_printf("invalid 'max_sdu' parameter\n");
+        return rc;
+    }
+
+    big_params.max_transport_latency = parse_arg_uint16_bounds("max_latency",
+                                                               0x0005, 0x0FA0,
+                                                               &rc);
+    if (rc != 0) {
+        console_printf("invalid 'max_latency' parameter\n");
+        return rc;
+    }
+
+    big_params.rtn = parse_arg_uint8_bounds("rtn", 0x00, 0x1E, &rc);
+    if (rc != 0) {
+        console_printf("invalid 'rtn' parameter\n");
+        return rc;
+    }
+
+    big_params.phy = parse_arg_uint8_bounds("phy", 0, 2, &rc);
+    if (rc != 0) {
+        console_printf("invalid 'phy' parameter\n");
+        return rc;
+    }
+
+    big_params.packing = parse_arg_uint8_bounds_dflt("packing", 0, 1, 1, &rc);
+    if (rc != 0) {
+        console_printf("invalid 'packing' parameter\n");
+        return rc;
+    }
+
+    big_params.framing = parse_arg_uint8_bounds_dflt("framing", 0, 1, 0, &rc);
+    if (rc != 0) {
+        console_printf("invalid 'framing' parameter\n");
+        return rc;
+    }
+
+    big_params.broadcast_code = parse_arg_extract("broadcast_code");
+    big_params.encryption = big_params.broadcast_code ? 1 : 0;
+
+    rc = ble_iso_create_big(&params, &big_params);
+    if (rc != 0) {
+        console_printf("BIG create failed (%d)\n", rc);
+        return rc;
+    }
+
+    return 0;
+}
+
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+static const struct shell_param cmd_iso_big_terminate_params[] = {
+    {"big_handle", "BIG handle, usage: =<UINT8>"},
+
+    { NULL, NULL}
+};
+
+const struct shell_cmd_help cmd_iso_big_terminate_help = {
+    .summary = "Terminate BIG",
+    .usage = NULL,
+    .params = cmd_iso_big_terminate_params,
+};
+#endif /* SHELL_CMD_HELP */
+
+int
+cmd_iso_big_terminate(int argc, char **argv)
+{
+    uint8_t big_handle;
+    int rc;
+
+    rc = parse_arg_init(argc - 1, argv + 1);
+    if (rc != 0) {
+        return rc;
+    }
+
+    big_handle = parse_arg_uint8("big_handle", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'big_handle' parameter\n");
+        return rc;
+    }
+
+    rc = ble_iso_terminate_big(big_handle);
+    if (rc != 0) {
+        console_printf("BIG terminate failed (%d)\n", rc);
+        return rc;
+    }
+
+    return 0;
+}
+
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+static const struct shell_param cmd_iso_big_sync_create_params[] = {
+    {"sync_handle", "PA sync handle, usage: =<UINT16>"},
+    {"broadcast_code", "Broadcast Code, usage: =[string], default: NULL"},
+    {"mse", "Maximum Subevents to receive data, usage: =<UINT8>"},
+    {"sync_timeout", "BIG sync timeout, usage: =<UINT8>"},
+    {"idxs", "BIS indexes, usage: =XX,YY,..."},
+
+    { NULL, NULL}
+};
+
+const struct shell_cmd_help cmd_iso_big_sync_create_help = {
+    .summary = "Synchronize to BIG",
+    .usage = NULL,
+    .params = cmd_iso_big_sync_create_params,
+};
+#endif /* SHELL_CMD_HELP */
+
+int
+cmd_iso_big_sync_create(int argc, char **argv)
+{
+    struct ble_iso_bis_params bis_params[MYNEWT_VAL(BLE_MAX_BIS)];
+    struct ble_iso_big_sync_create_params params = { 0 };
+    uint8_t bis_idxs[MYNEWT_VAL(BLE_MAX_BIS)];
+    uint8_t big_handle;
+    int rc;
+
+    rc = parse_arg_init(argc - 1, argv + 1);
+    if (rc != 0) {
+        return rc;
+    }
+
+    params.sync_handle = parse_arg_uint16("sync_handle", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'sync_handle' parameter\n");
+        return rc;
+    }
+
+    params.broadcast_code = parse_arg_extract("broadcast_code");
+
+    params.mse = parse_arg_uint8_dflt("mse", 0, &rc);
+    if (rc != 0) {
+        console_printf("invalid 'mse' parameter\n");
+        return rc;
+    }
+
+    params.sync_timeout = parse_arg_uint16("sync_timeout", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'sync_timeout' parameter\n");
+        return rc;
+    }
+
+    rc = parse_arg_byte_stream_custom("idxs", ",", ARRAY_SIZE(bis_idxs),
+                                      bis_idxs, 0,
+                                      (unsigned int *)&params.bis_cnt);
+    if (rc != 0) {
+        console_printf("invalid 'idxs' parameter\n");
+        return rc;
+    }
+
+    for (uint8_t i = 0; i < params.bis_cnt; i++) {
+        bis_params[i].bis_index = bis_idxs[i];
+        bis_params[i].cb = ble_iso_event_handler;
+        bis_params[i].cb_arg = &rx_stats_pool[i];
+
+        /* Reset stats */
+        memset(&rx_stats_pool[i], 0, sizeof(rx_stats_pool[i]));
+        rx_stats_pool[i].bis_index = bis_idxs[i];
+    }
+
+    params.bis_params = bis_params;
+    params.cb = ble_iso_event_handler;
+
+    rc = ble_iso_big_sync_create(&params, &big_handle);
+    if (rc != 0) {
+        console_printf("BIG Sync create failed (%d)\n", rc);
+        return rc;
+    }
+
+    console_printf("New big_handle %u created\n", big_handle);
+
+    return 0;
+}
+
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+static const struct shell_param cmd_iso_big_sync_terminate_params[] = {
+    {"big_handle", "BIG handle, usage: =<UINT8>"},
+
+    { NULL, NULL}
+};
+
+const struct shell_cmd_help cmd_iso_big_sync_terminate_help = {
+    .summary = "Terminate BIG sync",
+    .usage = NULL,
+    .params = cmd_iso_big_sync_terminate_params,
+};
+#endif /* SHELL_CMD_HELP */
+
+int
+cmd_iso_big_sync_terminate(int argc, char **argv)
+{
+    uint8_t big_handle;
+    int rc;
+
+    rc = parse_arg_init(argc - 1, argv + 1);
+    if (rc != 0) {
+        return rc;
+    }
+
+    big_handle = parse_arg_uint8("big_handle", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'big_handle' parameter\n");
+        return rc;
+    }
+
+    rc = ble_iso_big_sync_terminate(big_handle);
+    if (rc != 0) {
+        console_printf("BIG Sync terminate failed (%d)\n", rc);
+        return rc;
+    }
+
+    return 0;
+}
+
+static const struct parse_arg_kv_pair cmd_iso_data_dir[] = {
+    { "tx",       BLE_ISO_DATA_DIR_TX },
+    { "rx",       BLE_ISO_DATA_DIR_RX },
+
+    { NULL }
+};
+
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+static const struct shell_param cmd_iso_data_path_setup_params[] = {
+    {"conn_handle", "Connection handle, usage: =<UINT16>"},
+    {"dir", "Data path direction, usage: =[tx|rx]"},
+
+    { NULL, NULL}
+};
+
+const struct shell_cmd_help cmd_iso_data_path_setup_help = {
+    .summary = "Setup ISO Data Path",
+    .usage = NULL,
+    .params = cmd_iso_data_path_setup_params,
+};
+#endif /* SHELL_CMD_HELP */
+
+int
+cmd_iso_data_path_setup(int argc, char **argv)
+{
+    struct ble_iso_data_path_setup_params params = { 0 };
+    int rc;
+
+    rc = parse_arg_init(argc - 1, argv + 1);
+    if (rc != 0) {
+        return rc;
+    }
+
+    params.conn_handle = parse_arg_uint16("conn_handle", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'conn_handle' parameter\n");
+        return rc;
+    }
+
+    params.data_path_dir = parse_arg_kv("dir", cmd_iso_data_dir, &rc);
+    if (rc != 0) {
+        console_printf("invalid 'dir' parameter\n");
+        return rc;
+    }
+
+    /* For now, the Data Path ID is set to HCI by default */
+
+    rc = ble_iso_data_path_setup(&params);
+    if (rc != 0) {
+        console_printf("ISO Data Path setup failed (%d)\n", rc);
+        return rc;
+    }
+
+    return 0;
+}
+
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+static const struct shell_param cmd_iso_data_path_remove_params[] = {
+    {"conn_handle", "Connection handle, usage: =<UINT16>"},
+    {"dir", "Data path direction, usage: =[tx|rx]"},
+
+    { NULL, NULL}
+};
+
+const struct shell_cmd_help cmd_iso_data_path_remove_help = {
+    .summary = "Remove ISO Data Path",
+    .usage = NULL,
+    .params = cmd_iso_data_path_remove_params,
+};
+#endif /* SHELL_CMD_HELP */
+
+int
+cmd_iso_data_path_remove(int argc, char **argv)
+{
+    struct ble_iso_data_path_remove_params params = { 0 };
+    int rc;
+
+    rc = parse_arg_init(argc - 1, argv + 1);
+    if (rc != 0) {
+        return rc;
+    }
+
+    params.conn_handle = parse_arg_uint16("conn_handle", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'conn_handle' parameter\n");
+        return rc;
+    }
+
+    params.data_path_dir = parse_arg_kv("dir", cmd_iso_data_dir, &rc);
+    if (rc != 0) {
+        console_printf("invalid 'dir' parameter\n");
+        return rc;
+    }
+
+    rc = ble_iso_data_path_remove(&params);
+    if (rc != 0) {
+        console_printf("ISO Data Path remove failed (%d)\n", rc);
+        return rc;
+    }
+
+    return 0;
+}
+#endif /* BLE_ISO */
diff --git a/apps/btshell/src/cmd_iso.h b/apps/btshell/src/cmd_iso.h
new file mode 100644
index 000000000..c027c0885
--- /dev/null
+++ b/apps/btshell/src/cmd_iso.h
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_CMD_ISO_
+#define H_CMD_ISO_
+
+#include "cmd.h"
+
+extern const struct shell_cmd_help cmd_iso_big_create_help;
+extern const struct shell_cmd_help cmd_iso_big_terminate_help;
+extern const struct shell_cmd_help cmd_iso_big_sync_create_help;
+extern const struct shell_cmd_help cmd_iso_big_sync_terminate_help;
+extern const struct shell_cmd_help cmd_iso_data_path_setup_help;
+extern const struct shell_cmd_help cmd_iso_data_path_remove_help;
+
+int cmd_iso_big_create(int argc, char **argv);
+int cmd_iso_big_terminate(int argc, char **argv);
+int cmd_iso_big_sync_create(int argc, char **argv);
+int cmd_iso_big_sync_terminate(int argc, char **argv);
+int cmd_iso_data_path_setup(int argc, char **argv);
+int cmd_iso_data_path_remove(int argc, char **argv);
+
+#endif /* H_CMD_ISO_ */