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

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

commit 58eb4082535d8ca9df62af54de02236b0144622e
Author: Magdalena Kasenberg <magdalena.kasenb...@codecoup.pl>
AuthorDate: Mon Feb 5 16:49:27 2024 +0100

    nimble: host: Add initial support for CS HCI
---
 nimble/host/include/host/ble_cs.h  |  57 +++
 nimble/host/src/ble_cs.c           | 731 +++++++++++++++++++++++++++++++++++++
 nimble/host/src/ble_cs_priv.h      |  31 ++
 nimble/host/src/ble_hs_hci_evt.c   |  13 +
 nimble/host/src/ble_hs_startup.c   |  17 +
 nimble/include/nimble/hci_common.h | 302 +++++++++++++++
 nimble/syscfg.yml                  |   5 +
 nimble/transport/syscfg.yml        |   4 +
 8 files changed, 1160 insertions(+)

diff --git a/nimble/host/include/host/ble_cs.h 
b/nimble/host/include/host/ble_cs.h
new file mode 100644
index 000000000..3abbd11e6
--- /dev/null
+++ b/nimble/host/include/host/ble_cs.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+/* All Channel Sounding APIs are experimental and subject to change at any 
time */
+
+#ifndef H_BLE_CS_
+#define H_BLE_CS_
+#include "syscfg/syscfg.h"
+
+#define BLE_CS_EVENT_CS_PROCEDURE_COMPLETE (0)
+
+struct ble_cs_event {
+    uint8_t type;
+    union
+    {
+        struct
+        {
+            uint16_t conn_handle;
+            uint8_t status;
+        } procedure_complete;
+    };
+    
+};
+
+typedef int ble_cs_event_fn(struct ble_cs_event *event, void *arg);
+
+struct ble_cs_initiator_procedure_start_params {
+    uint16_t conn_handle;
+    ble_cs_event_fn *cb;
+    void *cb_arg;
+};
+
+struct ble_cs_reflector_setup_params {
+    ble_cs_event_fn *cb;
+    void *cb_arg;
+};
+
+int ble_cs_initiator_procedure_start(const struct 
ble_cs_initiator_procedure_start_params *params);
+int ble_cs_initiator_procedure_terminate(uint16_t conn_handle);
+int ble_cs_reflector_setup(struct ble_cs_reflector_setup_params *params);
+#endif
diff --git a/nimble/host/src/ble_cs.c b/nimble/host/src/ble_cs.c
new file mode 100644
index 000000000..cef622206
--- /dev/null
+++ b/nimble/host/src/ble_cs.c
@@ -0,0 +1,731 @@
+/*
+ * 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 <inttypes.h>
+#include "syscfg/syscfg.h"
+#include "ble_hs_mbuf_priv.h"
+
+#if MYNEWT_VAL(BLE_CHANNEL_SOUNDING)
+
+#include "os/os_mbuf.h"
+#include "host/ble_hs_log.h"
+#include "host/ble_hs.h"
+#include "host/ble_cs.h"
+#include "nimble/hci_common.h"
+#include "sys/queue.h"
+#include "ble_hs_hci_priv.h"
+
+struct ble_cs_rd_rem_supp_cap_cp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+struct ble_cs_wr_cached_rem_supp_cap_cp {
+    uint16_t conn_handle;
+    uint8_t num_config_supported;
+    uint16_t max_consecutive_procedures_supported;
+    uint8_t num_antennas_supported;
+    uint8_t max_antenna_paths_supported;
+    uint8_t roles_supported;
+    uint8_t optional_modes_supported;
+    uint8_t rtt_capability;
+    uint8_t rtt_aa_only_n;
+    uint8_t rtt_sounding_n;
+    uint8_t rtt_random_payload_n;
+    uint16_t optional_nadm_sounding_capability;
+    uint16_t optional_nadm_random_capability;
+    uint8_t optional_cs_sync_phys_supported;
+    uint16_t optional_subfeatures_supported;
+    uint16_t optional_t_ip1_times_supported;
+    uint16_t optional_t_ip2_times_supported;
+    uint16_t optional_t_fcs_times_supported;
+    uint16_t optional_t_pm_times_supported;
+    uint8_t t_sw_time_supported;
+} __attribute__((packed));
+struct ble_cs_wr_cached_rem_supp_cap_rp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+struct ble_cs_sec_enable_cp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+struct ble_cs_set_def_settings_cp {
+    uint16_t conn_handle;
+    uint8_t role_enable;
+    uint8_t cs_sync_antenna_selection;
+    uint8_t max_tx_power;
+} __attribute__((packed));
+struct ble_cs_set_def_settings_rp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+struct ble_cs_rd_rem_fae_cp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+struct ble_cs_wr_cached_rem_fae_cp {
+    uint16_t conn_handle;
+    uint8_t remote_fae_table[72];
+} __attribute__((packed));
+struct ble_cs_wr_cached_rem_fae_rp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+struct ble_cs_create_config_cp {
+    uint16_t conn_handle;
+    uint8_t config_id;
+    /* If the config should be created on the remote controller too */
+    uint8_t create_context;
+    /* The main mode to be used in the CS procedures */
+    uint8_t main_mode_type;
+    /* The sub mode to be used in the CS procedures */
+    uint8_t sub_mode_type;
+    /* Minimum/maximum number of CS main mode steps to be executed before
+     * a submode step.
+     */
+    uint8_t min_main_mode_steps;
+    uint8_t max_main_mode_steps;
+    /* The number of main mode steps taken from the end of the last
+     * CS subevent to be repeated at the beginning of the current CS subevent
+     * directly after the last mode 0 step of that event
+     */
+    uint8_t main_mode_repetition;
+    uint8_t mode_0_steps;
+    uint8_t role;
+    uint8_t rtt_type;
+    uint8_t cs_sync_phy;
+    uint8_t channel_map[10];
+    uint8_t channel_map_repetition;
+    uint8_t channel_selection_type;
+    uint8_t ch3c_shape;
+    uint8_t ch3c_jump;
+    uint8_t companion_signal_enable;
+} __attribute__((packed));
+
+struct ble_cs_remove_config_cp {
+    uint16_t conn_handle;
+    uint8_t config_id;
+} __attribute__((packed));
+
+struct ble_cs_set_chan_class_cp {
+    uint8_t channel_classification[10];
+} __attribute__((packed));
+
+struct ble_cs_set_proc_params_cp {
+    uint16_t conn_handle;
+    uint8_t config_id;
+    /* The maximum duration of each CS procedure (time = N × 0.625 ms) */
+    uint16_t max_procedure_len;
+    /* The minimum and maximum number of connection events between
+     * consecutive CS procedures. Ignored if only one CS procedure. */
+    uint16_t min_procedure_interval;
+    uint16_t max_procedure_interval;
+    /* The maximum number of consecutive CS procedures to be scheduled */
+    uint16_t max_procedure_count;
+    /* Minimum/maximum suggested durations for each CS subevent in 
microseconds.
+     * Only 3 bytes meaningful. */
+    uint32_t min_subevent_len;
+    uint32_t max_subevent_len;
+    /* Antenna Configuration Index (ACI) for swithing during phase measuement 
*/
+    uint8_t tone_antenna_config_selection;
+    /* The remote device’s Tx PHY. A 4 bits bitmap. */
+    uint8_t phy;
+    /* How many more or fewer of transmit power levels should the remote 
device’s
+     * Tx PHY use during the CS tones and RTT transmission */
+    uint8_t tx_power_delta;
+    /* Preferred peer-ordered antenna elements to be used by the peer for
+     * the selected antenna configuration (ACI). A 4 bits bitmap. */
+    uint8_t preferred_peer_antenna;
+    /* SNR Output Index (SOI) for SNR control adjustment. */
+    uint8_t snr_control_initiator;
+    uint8_t snr_control_reflector;
+} __attribute__((packed));
+struct ble_cs_set_proc_params_rp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+struct ble_cs_proc_enable_cp {
+    uint16_t conn_handle;
+    uint8_t config_id;
+    uint8_t enable;
+} __attribute__((packed));
+
+struct ble_cs_state {
+    uint8_t op;
+    ble_cs_event_fn *cb;
+    void *cb_arg;
+};
+
+static struct ble_cs_state cs_state;
+
+static int
+ble_cs_call_event_cb(struct ble_cs_event *event)
+{
+    int rc;
+
+    if (cs_state.cb != NULL) {
+        rc = cs_state.cb(event, cs_state.cb_arg);
+    } else {
+        rc = 0;
+    }
+
+    return rc;
+}
+
+static void
+ble_cs_call_procedure_complete_cb(uint16_t conn_handle, uint8_t status)
+{
+    struct ble_cs_event event;
+
+    memset(&event, 0, sizeof event);
+    event.type = BLE_CS_EVENT_CS_PROCEDURE_COMPLETE;
+    event.procedure_complete.conn_handle = conn_handle;
+    event.procedure_complete.status = status;
+    ble_cs_call_event_cb(&event);
+}
+
+static int
+ble_cs_rd_loc_supp_cap(void)
+{
+    int rc;
+    struct ble_hci_le_cs_rd_loc_supp_cap_rp rp;
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_CS_RD_LOC_SUPP_CAP),
+                           NULL, 0, &rp, sizeof(rp));
+
+    rp.max_consecutive_procedures_supported = 
le16toh(rp.max_consecutive_procedures_supported);
+    rp.optional_nadm_sounding_capability = 
le16toh(rp.optional_nadm_sounding_capability);
+    rp.optional_nadm_random_capability = 
le16toh(rp.optional_nadm_random_capability);
+    rp.optional_subfeatures_supported = 
le16toh(rp.optional_subfeatures_supported);
+    rp.optional_t_ip1_times_supported = 
le16toh(rp.optional_t_ip1_times_supported);
+    rp.optional_t_ip2_times_supported = 
le16toh(rp.optional_t_ip2_times_supported);
+    rp.optional_t_fcs_times_supported = 
le16toh(rp.optional_t_fcs_times_supported);
+    rp.optional_t_pm_times_supported = 
le16toh(rp.optional_t_pm_times_supported);
+    (void) rp;
+
+    return rc;
+}
+
+static int
+ble_cs_rd_rem_supp_cap(const struct ble_cs_rd_rem_supp_cap_cp *cmd)
+{
+    struct ble_hci_le_cs_rd_rem_supp_cap_cp cp;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+
+    return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                        BLE_HCI_OCF_LE_CS_RD_REM_SUPP_CAP),
+                             &cp, sizeof(cp), NULL, 0);
+}
+
+static int
+ble_cs_wr_cached_rem_supp_cap(const struct ble_cs_wr_cached_rem_supp_cap_cp 
*cmd,
+                              struct ble_cs_wr_cached_rem_supp_cap_rp *rsp)
+{
+    struct ble_hci_le_cs_wr_cached_rem_supp_cap_cp cp;
+    struct ble_hci_le_cs_wr_cached_rem_supp_cap_rp rp;
+    int rc;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+    cp.num_config_supported = cmd->num_config_supported;
+    cp.max_consecutive_procedures_supported = 
htole16(cmd->max_consecutive_procedures_supported);
+    cp.num_antennas_supported = cmd->num_antennas_supported;
+    cp.max_antenna_paths_supported = cmd->max_antenna_paths_supported;
+    cp.roles_supported = cmd->roles_supported;
+    cp.optional_modes_supported = cmd->optional_modes_supported;
+    cp.rtt_capability = cmd->rtt_capability;
+    cp.rtt_aa_only_n = cmd->rtt_aa_only_n;
+    cp.rtt_sounding_n = cmd->rtt_sounding_n;
+    cp.rtt_random_payload_n = cmd->rtt_random_payload_n;
+    cp.optional_nadm_sounding_capability = 
htole16(cmd->optional_nadm_sounding_capability);
+    cp.optional_nadm_random_capability = 
htole16(cmd->optional_nadm_random_capability);
+    cp.optional_cs_sync_phys_supported = cmd->optional_cs_sync_phys_supported;
+    cp.optional_subfeatures_supported = 
htole16(cmd->optional_subfeatures_supported);
+    cp.optional_t_ip1_times_supported = 
htole16(cmd->optional_t_ip1_times_supported);
+    cp.optional_t_ip2_times_supported = 
htole16(cmd->optional_t_ip2_times_supported);
+    cp.optional_t_fcs_times_supported = 
htole16(cmd->optional_t_fcs_times_supported);
+    cp.optional_t_pm_times_supported = 
htole16(cmd->optional_t_pm_times_supported);
+    cp.t_sw_time_supported = cmd->t_sw_time_supported;
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      
BLE_HCI_OCF_LE_CS_WR_CACHED_REM_SUPP_CAP),
+                           &cp, sizeof(cp), &rp, sizeof(rp));
+
+    rsp->conn_handle = le16toh(rp.conn_handle);
+
+    return rc;
+}
+
+static int
+ble_cs_sec_enable(const struct ble_cs_sec_enable_cp *cmd)
+{
+    struct ble_hci_le_cs_sec_enable_cp cp;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+
+    return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                        BLE_HCI_OCF_LE_CS_SEC_ENABLE),
+                             &cp, sizeof(cp), NULL, 0);
+}
+
+static int
+ble_cs_set_def_settings(const struct ble_cs_set_def_settings_cp *cmd,
+                        struct ble_cs_set_def_settings_rp *rsp)
+{
+    struct ble_hci_le_cs_set_def_settings_cp cp;
+    struct ble_hci_le_cs_set_def_settings_rp rp;
+    int rc;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+    cp.role_enable = cmd->role_enable;
+    cp.cs_sync_antenna_selection = cmd->cs_sync_antenna_selection;
+    cp.max_tx_power = cmd->max_tx_power;
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_CS_SET_DEF_SETTINGS),
+                           &cp, sizeof(cp), &rp, sizeof(rp));
+
+    rsp->conn_handle = le16toh(rp.conn_handle);
+
+    return rc;
+}
+
+static int
+ble_cs_rd_rem_fae(const struct ble_cs_rd_rem_fae_cp *cmd)
+{
+    struct ble_hci_le_cs_rd_rem_fae_cp cp;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+
+    return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                        BLE_HCI_OCF_LE_CS_RD_REM_FAE),
+                             &cp, sizeof(cp), NULL, 0);
+}
+
+static int
+ble_cs_wr_cached_rem_fae(const struct ble_cs_wr_cached_rem_fae_cp *cmd,
+                         struct ble_cs_wr_cached_rem_fae_rp *rsp)
+{
+    struct ble_hci_le_cs_wr_cached_rem_fae_cp cp;
+    struct ble_hci_le_cs_wr_cached_rem_fae_rp rp;
+    int rc;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+    memcpy(cp.remote_fae_table, cmd->remote_fae_table, 72);
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_CS_WR_CACHED_REM_FAE),
+                           &cp, sizeof(cp), &rp, sizeof(rp));
+
+    rsp->conn_handle = le16toh(rp.conn_handle);
+
+    return rc;
+}
+
+static int
+ble_cs_create_config(const struct ble_cs_create_config_cp *cmd)
+{
+    struct ble_hci_le_cs_create_config_cp cp;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+    cp.config_id = cmd->config_id;
+    cp.create_context = cmd->create_context;
+    cp.main_mode_type = cmd->main_mode_type;
+    cp.sub_mode_type = cmd->sub_mode_type;
+    cp.min_main_mode_steps = cmd->min_main_mode_steps;
+    cp.max_main_mode_steps = cmd->max_main_mode_steps;
+    cp.main_mode_repetition = cmd->main_mode_repetition;
+    cp.mode_0_steps = cmd->mode_0_steps;
+    cp.role = cmd->role;
+    cp.rtt_type = cmd->rtt_type;
+    cp.cs_sync_phy = cmd->cs_sync_phy;
+    memcpy(cp.channel_map, cmd->channel_map, 10);
+    cp.channel_map_repetition = cmd->channel_map_repetition;
+    cp.channel_selection_type = cmd->channel_selection_type;
+    cp.ch3c_shape = cmd->ch3c_shape;
+    cp.ch3c_jump = cmd->ch3c_jump;
+    cp.companion_signal_enable = cmd->companion_signal_enable;
+
+    return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                        BLE_HCI_OCF_LE_CS_CREATE_CONFIG),
+                             &cp, sizeof(cp), NULL, 0);
+}
+
+static int
+ble_cs_remove_config(const struct ble_cs_remove_config_cp *cmd)
+{
+    struct ble_hci_le_cs_remove_config_cp cp;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+    cp.config_id = cmd->config_id;
+
+    return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                        BLE_HCI_OCF_LE_CS_REMOVE_CONFIG),
+                             &cp, sizeof(cp), NULL, 0);
+}
+
+static int
+ble_cs_set_chan_class(const struct ble_cs_set_chan_class_cp *cmd)
+{
+    struct ble_hci_le_cs_set_chan_class_cp cp;
+    int rc;
+
+    memcpy(cp.channel_classification, cmd->channel_classification, 10);
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_CS_SET_CHAN_CLASS),
+                           &cp, sizeof(cp), NULL, 0);
+
+    return rc;
+}
+
+static int
+ble_cs_set_proc_params(const struct ble_cs_set_proc_params_cp *cmd,
+                       struct ble_cs_set_proc_params_rp *rsp)
+{
+    struct ble_hci_le_cs_set_proc_params_cp cp;
+    struct ble_hci_le_cs_set_proc_params_rp rp;
+    int rc;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+    cp.config_id = cmd->config_id;
+    cp.max_procedure_len = htole16(cmd->max_procedure_len);
+    cp.min_procedure_interval = htole16(cmd->min_procedure_interval);
+    cp.max_procedure_interval = htole16(cmd->max_procedure_interval);
+    cp.max_procedure_count = htole16(cmd->max_procedure_count);
+    put_le24(cp.min_subevent_len, cmd->min_subevent_len);
+    put_le24(cp.max_subevent_len, cmd->max_subevent_len);
+    cp.tone_antenna_config_selection = cmd->tone_antenna_config_selection;
+    cp.phy = cmd->phy;
+    cp.tx_power_delta = cmd->tx_power_delta;
+    cp.preferred_peer_antenna = cmd->preferred_peer_antenna;
+    cp.snr_control_initiator = cmd->snr_control_initiator;
+    cp.snr_control_reflector = cmd->snr_control_reflector;
+
+    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_CS_SET_PROC_PARAMS),
+                           &cp, sizeof(cp), &rp, sizeof(rp));
+
+    rsp->conn_handle = le16toh(rp.conn_handle);
+
+    return rc;
+}
+
+static int
+ble_cs_proc_enable(const struct ble_cs_proc_enable_cp *cmd)
+{
+    struct ble_hci_le_cs_proc_enable_cp cp;
+
+    cp.conn_handle = htole16(cmd->conn_handle);
+    cp.config_id = cmd->config_id;
+    cp.enable = cmd->enable;
+
+    return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
+                                        BLE_HCI_OCF_LE_CS_PROC_ENABLE),
+                             &cp, sizeof(cp), NULL, 0);
+}
+
+int
+ble_hs_hci_evt_le_cs_rd_rem_supp_cap_complete(uint8_t subevent, const void 
*data,
+                                              unsigned int len)
+{
+    int rc;
+    const struct ble_hci_ev_le_subev_cs_rd_rem_supp_cap_complete *ev = data;
+    struct ble_cs_set_def_settings_cp set_cmd;
+    struct ble_cs_set_def_settings_rp set_rsp;
+    struct ble_cs_rd_rem_fae_cp fae_cmd;
+
+    if (len != sizeof(*ev) || ev->status) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    BLE_HS_LOG(DEBUG, "CS capabilities exchanged");
+
+    /* TODO: Save the remote capabilities somewhere */
+
+    set_cmd.conn_handle = le16toh(ev->conn_handle);
+    /* Only initiator role is enabled */
+    set_cmd.role_enable = 0x01;
+    /* Use antenna with ID 0x01 */
+    set_cmd.cs_sync_antenna_selection = 0x01;
+    /* Set max TX power to the max supported */
+    set_cmd.max_tx_power = 0x7F;
+
+    rc = ble_cs_set_def_settings(&set_cmd, &set_rsp);
+    if (rc) {
+        BLE_HS_LOG(DEBUG, "Failed to set the default CS settings, err %dt", 
rc);
+
+        return rc;
+    }
+
+    /* Read the mode 0 Frequency Actuation Error table */
+    fae_cmd.conn_handle = le16toh(ev->conn_handle);
+    rc = ble_cs_rd_rem_fae(&fae_cmd);
+    if (rc) {
+        BLE_HS_LOG(DEBUG, "Failed to read FAE table");
+    }
+
+    return rc;
+}
+
+int
+ble_hs_hci_evt_le_cs_rd_rem_fae_complete(uint8_t subevent, const void *data,
+                                         unsigned int len)
+{
+    const struct ble_hci_ev_le_subev_cs_rd_rem_fae_complete *ev = data;
+    struct ble_cs_create_config_cp cmd;
+    int rc;
+
+    if (len != sizeof(*ev) || ev->status) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    cmd.conn_handle = le16toh(ev->conn_handle);
+    /* The config will use ID 0x00 */
+    cmd.config_id = 0x00;
+    /* Create the config on the remote controller too */
+    cmd.create_context = 0x01;
+    /* Measure phase rotations in main mode */
+    cmd.main_mode_type = 0x01;
+    /* Do not use sub mode for now. */
+    cmd.sub_mode_type = 0xFF;
+    /* Range from which the number of CS main mode steps to execute
+     * will be randomly selected.
+     */
+    cmd.min_main_mode_steps = 0x02;
+    cmd.max_main_mode_steps = 0x06;
+    /* The number of main mode steps to be repeated at the beginning of
+     * the current CS, irrespectively if there are some overlapping main
+     * mode steps from previous CS subevent or not.
+     */
+    cmd.main_mode_repetition = 0x00;
+    /* Number of CS mode 0 steps to be included at the beginning of
+     * each CS subevent
+     */
+    cmd.mode_0_steps = 0x03;
+    /* Take the Initiator role */
+    cmd.role = 0x00;
+    cmd.rtt_type = 0x01;
+    cmd.cs_sync_phy = 0x01;
+    memcpy(cmd.channel_map, (uint8_t[10]) {0x0a, 0xfa, 0xcf, 0xac, 0xfa, 
0xc0}, 10);
+    cmd.channel_map_repetition = 0x01;
+    /* Use Channel Selection Algorithm #3b */
+    cmd.channel_selection_type = 0x00;
+    /* Ignore these as used only with #3c algorithm */
+    cmd.ch3c_shape = 0x00;
+    cmd.ch3c_jump = 0x00;
+    /* EDLC/ECLD attack protection not supported */
+    cmd.companion_signal_enable = 0x00;
+
+    /* Create CS config */
+    rc = ble_cs_create_config(&cmd);
+    if (rc) {
+        BLE_HS_LOG(DEBUG, "Failed to create CS config");
+    }
+
+    return rc;
+}
+
+int
+ble_hs_hci_evt_le_cs_sec_enable_complete(uint8_t subevent, const void *data,
+                                         unsigned int len)
+{
+    int rc;
+    struct ble_cs_set_proc_params_cp cmd;
+    struct ble_cs_set_proc_params_rp rsp;
+    struct ble_cs_proc_enable_cp enable_cmd;
+    const struct ble_hci_ev_le_subev_cs_sec_enable_complete *ev = data;
+
+    if (len != sizeof(*ev)) {
+        BLE_HS_LOG(DEBUG, "Failed to enable CS security");
+
+        return BLE_HS_ECONTROLLER;
+    }
+
+    BLE_HS_LOG(DEBUG, "CS setup phase completed");
+
+    cmd.conn_handle = le16toh(ev->conn_handle);
+    cmd.config_id = 0x00;
+    /* The maximum duration of each CS procedure (time = N × 0.625 ms) */
+    cmd.max_procedure_len = 8;
+    /* The maximum number of consecutive CS procedures to be scheduled
+     * as part of this measurement
+     */
+    cmd.max_procedure_count = 0x0001;
+    /* The minimum and maximum number of connection events between
+     * consecutive CS procedures. Ignored if only one CS procedure.
+     */
+    cmd.min_procedure_interval = 0x0000;
+    cmd.max_procedure_interval = 0x0000;
+    /* Minimum/maximum suggested durations for each CS subevent in 
microseconds.
+     * 1250us and 5000us selected.
+     */
+    cmd.min_subevent_len = 1250;
+    cmd.max_subevent_len = 5000;
+    /* Use ACI 0 as we have only one antenna on each side */
+    cmd.tone_antenna_config_selection = 0x00;
+    /* Use LE 1M PHY for CS procedures */
+    cmd.phy = 0x01;
+    /* Transmit power delta set to 0x80 means Host does not have a 
recommendation. */
+    cmd.tx_power_delta = 0x80;
+    /* Preferred antenna array elements to use. We have only a single antenna 
here. */
+    cmd.preferred_peer_antenna = 0x01;
+    /* SNR Output Index (SOI) for SNR control adjustment. 0xFF means SNR 
control
+     * is not to be applied.
+     */
+    cmd.snr_control_initiator = 0xff;
+    cmd.snr_control_reflector = 0xff;
+
+    rc = ble_cs_set_proc_params(&cmd, &rsp);
+    if (rc) {
+        BLE_HS_LOG(DEBUG, "Failed to set CS procedure parameters");
+    }
+
+    enable_cmd.conn_handle = le16toh(ev->conn_handle);
+    enable_cmd.config_id = 0x00;
+    enable_cmd.enable = 0x01;
+
+    rc = ble_cs_proc_enable(&enable_cmd);
+    if (rc) {
+        BLE_HS_LOG(DEBUG, "Failed to enable CS procedure");
+    }
+
+    return rc;
+}
+
+int
+ble_hs_hci_evt_le_cs_config_complete(uint8_t subevent, const void *data,
+                                     unsigned int len)
+{
+    int rc;
+    const struct ble_hci_ev_le_subev_cs_config_complete *ev = data;
+    struct ble_cs_sec_enable_cp cmd;
+
+    if (len != sizeof(*ev) || ev->status) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    cmd.conn_handle = le16toh(ev->conn_handle);
+
+    /* Exchange CS security keys */
+    rc = ble_cs_sec_enable(&cmd);
+    if (rc) {
+        BLE_HS_LOG(DEBUG, "Failed to enable CS security");
+        ble_cs_call_procedure_complete_cb(le16toh(ev->conn_handle), 
ev->status);
+    }
+
+    return 0;
+}
+
+int
+ble_hs_hci_evt_le_cs_proc_enable_complete(uint8_t subevent, const void *data,
+                                          unsigned int len)
+{
+    const struct ble_hci_ev_le_subev_cs_proc_enable_complete *ev = data;
+
+    if (len != sizeof(*ev) || ev->status) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    return 0;
+}
+
+int
+ble_hs_hci_evt_le_cs_subevent_result(uint8_t subevent, const void *data,
+                                     unsigned int len)
+{
+    const struct ble_hci_ev_le_subev_cs_subevent_result *ev = data;
+
+    if (len != sizeof(*ev)) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    return 0;
+}
+
+int
+ble_hs_hci_evt_le_cs_subevent_result_continue(uint8_t subevent, const void 
*data,
+                                              unsigned int len)
+{
+    const struct ble_hci_ev_le_subev_cs_subevent_result_continue *ev = data;
+
+    if (len != sizeof(*ev)) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    return 0;
+}
+
+int
+ble_hs_hci_evt_le_cs_test_end_complete(uint8_t subevent, const void *data,
+                                       unsigned int len)
+{
+    const struct ble_hci_ev_le_subev_cs_test_end_complete *ev = data;
+
+    if (len != sizeof(*ev)) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    return 0;
+}
+
+int
+ble_cs_initiator_procedure_start(const struct 
ble_cs_initiator_procedure_start_params *params)
+{
+    struct ble_hci_le_cs_rd_loc_supp_cap_rp rsp;
+    struct ble_cs_rd_rem_supp_cap_cp cmd;
+    int rc;
+
+    /* Channel Sounding setup phase:
+     * 1. Set local default CS settings
+     * 2. Exchange CS capabilities with the remote
+     * 3. Read or write the mode 0 Frequency Actuation Error table
+     * 4. Create CS configurations
+     * 5. Start the CS Security Start procedure
+     */
+
+    cs_state.cb = params->cb;
+    cs_state.cb_arg = params->cb_arg;
+
+    cmd.conn_handle = params->conn_handle;
+    rc = ble_cs_rd_rem_supp_cap(&cmd);
+    if (rc) {
+        BLE_HS_LOG(DEBUG, "Failed to read local supported CS capabilities,"
+                   "err %dt", rc);
+    }
+
+    return rc;
+}
+
+int
+ble_cs_initiator_procedure_terminate(uint16_t conn_handle)
+{
+    return 0;
+}
+
+int
+ble_cs_reflector_setup(struct ble_cs_reflector_setup_params *params)
+{
+    cs_state.cb = params->cb;
+    cs_state.cb_arg = params->cb_arg;
+
+    return 0;
+}
+#endif
diff --git a/nimble/host/src/ble_cs_priv.h b/nimble/host/src/ble_cs_priv.h
new file mode 100644
index 000000000..f02565852
--- /dev/null
+++ b/nimble/host/src/ble_cs_priv.h
@@ -0,0 +1,31 @@
+/*
+ * 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_BLE_CS_PRIV_
+#define H_BLE_CS_PRIV_
+
+int ble_hs_hci_evt_le_cs_rd_rem_supp_cap_complete(uint8_t subevent, const void 
*data, unsigned int len);
+int ble_hs_hci_evt_le_cs_rd_rem_fae_complete(uint8_t subevent, const void 
*data, unsigned int len);
+int ble_hs_hci_evt_le_cs_sec_enable_complete(uint8_t subevent, const void 
*data, unsigned int len);
+int ble_hs_hci_evt_le_cs_config_complete(uint8_t subevent, const void *data, 
unsigned int len);
+int ble_hs_hci_evt_le_cs_proc_enable_complete(uint8_t subevent, const void 
*data, unsigned int len);
+int ble_hs_hci_evt_le_cs_subevent_result(uint8_t subevent, const void *data, 
unsigned int len);
+int ble_hs_hci_evt_le_cs_subevent_result_continue(uint8_t subevent, const void 
*data, unsigned int len);
+int ble_hs_hci_evt_le_cs_test_end_complete(uint8_t subevent, const void *data, 
unsigned int len);
+#endif
diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c
index cc88bfd83..48012f3b4 100644
--- a/nimble/host/src/ble_hs_hci_evt.c
+++ b/nimble/host/src/ble_hs_hci_evt.c
@@ -26,6 +26,9 @@
 #include "host/ble_iso.h"
 #include "ble_hs_priv.h"
 #include "ble_iso_priv.h"
+#if MYNEWT_VAL(BLE_CHANNEL_SOUNDING)
+#include "ble_cs_priv.h"
+#endif
 
 _Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ,
                "struct hci_data_hdr must be 4 bytes");
@@ -163,6 +166,16 @@ static ble_hs_hci_evt_le_fn * const 
ble_hs_hci_evt_le_dispatch[] = {
 #if MYNEWT_VAL(BLE_CONN_SUBRATING)
     [BLE_HCI_LE_SUBEV_SUBRATE_CHANGE] = ble_hs_hci_evt_le_subrate_change,
 #endif
+#if MYNEWT_VAL(BLE_CHANNEL_SOUNDING)
+    [BLE_HCI_LE_SUBEV_CS_RD_REM_SUPP_CAP_COMPLETE] = 
ble_hs_hci_evt_le_cs_rd_rem_supp_cap_complete,
+    [BLE_HCI_LE_SUBEV_CS_RD_REM_FAE_COMPLETE] = 
ble_hs_hci_evt_le_cs_rd_rem_fae_complete,
+    [BLE_HCI_LE_SUBEV_CS_SEC_ENABLE_COMPLETE] = 
ble_hs_hci_evt_le_cs_sec_enable_complete,
+    [BLE_HCI_LE_SUBEV_CS_CONFIG_COMPLETE] = 
ble_hs_hci_evt_le_cs_config_complete,
+    [BLE_HCI_LE_SUBEV_CS_PROC_ENABLE_COMPLETE] = 
ble_hs_hci_evt_le_cs_proc_enable_complete,
+    [BLE_HCI_LE_SUBEV_CS_SUBEVENT_RESULT] = 
ble_hs_hci_evt_le_cs_subevent_result,
+    [BLE_HCI_LE_SUBEV_CS_SUBEVENT_RESULT_CONTINUE] = 
ble_hs_hci_evt_le_cs_subevent_result_continue,
+    [BLE_HCI_LE_SUBEV_CS_TEST_END_COMPLETE] = 
ble_hs_hci_evt_le_cs_test_end_complete,
+#endif
 };
 
 #define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \
diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c
index 827c00d2a..c23579547 100644
--- a/nimble/host/src/ble_hs_startup.c
+++ b/nimble/host/src/ble_hs_startup.c
@@ -314,6 +314,23 @@ ble_hs_startup_le_set_evmask_tx(void)
     }
 #endif
 
+#if MYNEWT_VAL(BLE_CHANNEL_SOUNDING)
+    if (version >= BLE_HCI_VER_BCS_5_4) {
+        /**
+         * Enable the following LE events:
+         * 0x0000080000000000 LE CS Read Remote Supported Capabilities 
Complete event
+         * 0x0000100000000000 LE CS Read Remote FAE Table Complete event
+         * 0x0000200000000000 LE CS Security Enable Complete event
+         * 0x0000400000000000 LE CS Config Complete event
+         * 0x0000800000000000 LE CS Procedure Enable Complete event
+         * 0x0001000000000000 LE CS Subevent Result event
+         * 0x0002000000000000 LE CS Subevent Result Continue event
+         * 0x0004000000000000 LE CS Test End Complete event
+         */
+        mask |= 0x0007f80000000000;
+    }
+#endif
+
     cmd.event_mask = htole64(mask);
 
     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
diff --git a/nimble/include/nimble/hci_common.h 
b/nimble/include/nimble/hci_common.h
index fb74c24aa..aadfa37b5 100644
--- a/nimble/include/nimble/hci_common.h
+++ b/nimble/include/nimble/hci_common.h
@@ -1149,6 +1149,180 @@ struct ble_hci_le_subrate_req_cp {
     uint16_t supervision_tmo;
 } __attribute__((packed));
 
+#define BLE_HCI_OCF_LE_CS_RD_LOC_SUPP_CAP                (0x0089)
+struct ble_hci_le_cs_rd_loc_supp_cap_rp {
+    uint8_t num_config_supported;
+    uint16_t max_consecutive_procedures_supported;
+    uint8_t num_antennas_supported;
+    uint8_t max_antenna_paths_supported;
+    uint8_t roles_supported;
+    uint8_t optional_modes_supported;
+    uint8_t rtt_capability;
+    uint8_t rtt_aa_only_n;
+    uint8_t rtt_sounding_n;
+    uint8_t rtt_random_payload_n;
+    uint16_t optional_nadm_sounding_capability;
+    uint16_t optional_nadm_random_capability;
+    uint8_t optional_cs_sync_phys_supported;
+    uint16_t optional_subfeatures_supported;
+    uint16_t optional_t_ip1_times_supported;
+    uint16_t optional_t_ip2_times_supported;
+    uint16_t optional_t_fcs_times_supported;
+    uint16_t optional_t_pm_times_supported;
+    uint8_t t_sw_time_supported;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_RD_REM_SUPP_CAP                (0x008A)
+struct ble_hci_le_cs_rd_rem_supp_cap_cp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_WR_CACHED_REM_SUPP_CAP         (0x008B)
+struct ble_hci_le_cs_wr_cached_rem_supp_cap_cp {
+    uint16_t conn_handle;
+    uint8_t num_config_supported;
+    uint16_t max_consecutive_procedures_supported;
+    uint8_t num_antennas_supported;
+    uint8_t max_antenna_paths_supported;
+    uint8_t roles_supported;
+    uint8_t optional_modes_supported;
+    uint8_t rtt_capability;
+    uint8_t rtt_aa_only_n;
+    uint8_t rtt_sounding_n;
+    uint8_t rtt_random_payload_n;
+    uint16_t optional_nadm_sounding_capability;
+    uint16_t optional_nadm_random_capability;
+    uint8_t optional_cs_sync_phys_supported;
+    uint16_t optional_subfeatures_supported;
+    uint16_t optional_t_ip1_times_supported;
+    uint16_t optional_t_ip2_times_supported;
+    uint16_t optional_t_fcs_times_supported;
+    uint16_t optional_t_pm_times_supported;
+    uint8_t t_sw_time_supported;
+} __attribute__((packed));
+struct ble_hci_le_cs_wr_cached_rem_supp_cap_rp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_SEC_ENABLE                     (0x008C)
+struct ble_hci_le_cs_sec_enable_cp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_SET_DEF_SETTINGS               (0x008D)
+struct ble_hci_le_cs_set_def_settings_cp {
+    uint16_t conn_handle;
+    uint8_t role_enable;
+    uint8_t cs_sync_antenna_selection;
+    uint8_t max_tx_power;
+} __attribute__((packed));
+struct ble_hci_le_cs_set_def_settings_rp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_RD_REM_FAE                     (0x008E)
+struct ble_hci_le_cs_rd_rem_fae_cp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_WR_CACHED_REM_FAE              (0x008F)
+struct ble_hci_le_cs_wr_cached_rem_fae_cp {
+    uint16_t conn_handle;
+    uint8_t remote_fae_table[72];
+} __attribute__((packed));
+struct ble_hci_le_cs_wr_cached_rem_fae_rp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_CREATE_CONFIG                  (0x0090)
+struct ble_hci_le_cs_create_config_cp {
+    uint16_t conn_handle;
+    uint8_t config_id;
+    uint8_t create_context;
+    uint8_t main_mode_type;
+    uint8_t sub_mode_type;
+    uint8_t min_main_mode_steps;
+    uint8_t max_main_mode_steps;
+    uint8_t main_mode_repetition;
+    uint8_t mode_0_steps;
+    uint8_t role;
+    uint8_t rtt_type;
+    uint8_t cs_sync_phy;
+    uint8_t channel_map[10];
+    uint8_t channel_map_repetition;
+    uint8_t channel_selection_type;
+    uint8_t ch3c_shape;
+    uint8_t ch3c_jump;
+    uint8_t companion_signal_enable;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_REMOVE_CONFIG                  (0x0091)
+struct ble_hci_le_cs_remove_config_cp {
+    uint16_t conn_handle;
+    uint8_t config_id;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_SET_CHAN_CLASS                 (0x0092)
+struct ble_hci_le_cs_set_chan_class_cp {
+    uint8_t channel_classification[10];
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_SET_PROC_PARAMS                (0x0093)
+struct ble_hci_le_cs_set_proc_params_cp {
+    uint16_t conn_handle;
+    uint8_t config_id;
+    uint16_t max_procedure_len;
+    uint16_t min_procedure_interval;
+    uint16_t max_procedure_interval;
+    uint16_t max_procedure_count;
+    uint8_t min_subevent_len[3];
+    uint8_t max_subevent_len[3];
+    uint8_t tone_antenna_config_selection;
+    uint8_t phy;
+    uint8_t tx_power_delta;
+    uint8_t preferred_peer_antenna;
+    uint8_t snr_control_initiator;
+    uint8_t snr_control_reflector;
+} __attribute__((packed));
+struct ble_hci_le_cs_set_proc_params_rp {
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_PROC_ENABLE                    (0x0094)
+struct ble_hci_le_cs_proc_enable_cp {
+    uint16_t conn_handle;
+    uint8_t config_id;
+    uint8_t enable;
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_TEST                           (0x0095)
+struct ble_hci_le_cs_test_cp {
+    uint8_t main_mode_type;
+    uint8_t sub_mode_type;
+    uint8_t main_mode_repetition;
+    uint8_t mode_0_steps;
+    uint8_t role;
+    uint8_t rtt_type;
+    uint8_t cs_sync_phy;
+    uint8_t cs_sync_antenna_selection;
+    uint8_t subevent_len[3];
+    uint16_t subevent_interval;
+    uint8_t transmit_power_level;
+    uint8_t t_ip1_time;
+    uint8_t t_ip2_time;
+    uint8_t t_fcs_time;
+    uint8_t t_pm_time;
+    uint8_t t_sw_time;
+    uint8_t tone_antenna_config_selection;
+    uint8_t companion_signal_enable;
+    uint16_t drbg_nonce;
+    uint16_t override_config;
+    uint8_t override_parameters_length;
+    uint8_t override_parameters_data[];
+} __attribute__((packed));
+
+#define BLE_HCI_OCF_LE_CS_TEST_END                       (0x0096)
+
 /* --- Vendor specific commands (OGF 0x003F) */
 /* Read Random Static Address */
 #define BLE_HCI_OCF_VS_RD_STATIC_ADDR                   
(MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0001))
@@ -1993,6 +2167,134 @@ struct ble_hci_ev_le_subev_subrate_change {
     uint16_t supervision_tmo;
 } __attribute__((packed));
 
+#define BLE_HCI_LE_SUBEV_CS_RD_REM_SUPP_CAP_COMPLETE   (0x2C)
+struct ble_hci_ev_le_subev_cs_rd_rem_supp_cap_complete {
+    uint8_t subev_code;
+    uint8_t status;
+    uint16_t conn_handle;
+    uint8_t num_config_supported;
+    uint16_t max_consecutive_procedures_supported;
+    uint8_t num_antennas_supported;
+    uint8_t max_antenna_paths_supported;
+    uint8_t roles_supported;
+    uint8_t optional_modes_supported;
+    uint8_t rtt_capability;
+    uint8_t rtt_aa_only_n;
+    uint8_t rtt_sounding_n;
+    uint8_t rtt_random_payload_n;
+    uint16_t optional_nadm_sounding_capability;
+    uint16_t optional_nadm_random_capability;
+    uint8_t optional_cs_sync_phys_supported;
+    uint16_t optional_subfeatures_supported;
+    uint16_t optional_t_ip1_times_supported;
+    uint16_t optional_t_ip2_times_supported;
+    uint16_t optional_t_fcs_times_supported;
+    uint16_t optional_t_pm_times_supported;
+    uint8_t t_sw_time_supported;
+} __attribute__((packed));
+
+#define BLE_HCI_LE_SUBEV_CS_RD_REM_FAE_COMPLETE        (0x2D)
+struct ble_hci_ev_le_subev_cs_rd_rem_fae_complete {
+    uint8_t subev_code;
+    uint8_t status;
+    uint16_t conn_handle;
+    uint8_t remote_fae_table[72];
+} __attribute__((packed));
+
+#define BLE_HCI_LE_SUBEV_CS_SEC_ENABLE_COMPLETE        (0x2E)
+struct ble_hci_ev_le_subev_cs_sec_enable_complete {
+    uint8_t subev_code;
+    uint8_t status;
+    uint16_t conn_handle;
+} __attribute__((packed));
+
+#define BLE_HCI_LE_SUBEV_CS_CONFIG_COMPLETE            (0x2F)
+struct ble_hci_ev_le_subev_cs_config_complete {
+    uint8_t subev_code;
+    uint8_t status;
+    uint16_t conn_handle;
+    uint8_t config_id;
+    uint8_t action;
+    uint8_t main_mode_type;
+    uint8_t sub_mode_type;
+    uint8_t min_main_mode_steps;
+    uint8_t max_main_mode_steps;
+    uint8_t main_mode_repetition;
+    uint8_t mode_0_steps;
+    uint8_t role;
+    uint8_t rtt_type;
+    uint8_t cs_sync_phy;
+    uint8_t channel_map[10];
+    uint8_t channel_map_repetition;
+    uint8_t channel_selection_type;
+    uint8_t ch3c_shape;
+    uint8_t ch3c_jump;
+    uint8_t companion_signal_enable;
+    uint8_t t_ip1_time;
+    uint8_t t_ip2_time;
+    uint8_t t_fcs_time;
+    uint8_t t_pm_time;
+} __attribute__((packed));
+
+#define BLE_HCI_LE_SUBEV_CS_PROC_ENABLE_COMPLETE       (0x30)
+struct ble_hci_ev_le_subev_cs_proc_enable_complete {
+    uint8_t subev_code;
+    uint8_t status;
+    uint16_t conn_handle;
+    uint8_t config_id;
+    uint8_t state;
+    uint8_t tone_antenna_config_selection;
+    uint8_t selected_tx_power;
+    uint8_t subevent_len[3];
+    uint8_t subevents_per_event;
+    uint16_t subevent_interval;
+    uint16_t event_interval;
+    uint16_t procedure_interval;
+    uint16_t procedure_count;
+} __attribute__((packed));
+
+#define BLE_HCI_LE_SUBEV_CS_SUBEVENT_RESULT            (0x31)
+struct cs_steps_data {
+    uint8_t mode;
+    uint8_t channel;
+    uint8_t data_len;
+    uint8_t data[];
+} __attribute__((packed));
+struct ble_hci_ev_le_subev_cs_subevent_result {
+    uint8_t subev_code;
+    uint16_t conn_handle;
+    uint8_t config_id;
+    uint16_t start_acl_conn_event_counter;
+    uint16_t procedure_counter;
+    uint16_t frequency_compensation;
+    uint8_t reference_power_level;
+    uint8_t procedure_done_status;
+    uint8_t subevent_done_status;
+    uint8_t abort_reason;
+    uint8_t num_antenna_paths;
+    uint8_t num_steps_reported;
+    struct cs_steps_data steps[];
+} __attribute__((packed));
+
+#define BLE_HCI_LE_SUBEV_CS_SUBEVENT_RESULT_CONTINUE   (0x32)
+struct ble_hci_ev_le_subev_cs_subevent_result_continue {
+    uint8_t subev_code;
+    uint16_t conn_handle;
+    uint8_t config_id;
+    uint8_t procedure_done_status;
+    uint8_t subevent_done_status;
+    uint8_t abort_reason;
+    uint8_t num_antenna_paths;
+    uint8_t num_steps_reported;
+    struct cs_steps_data steps[];
+} __attribute__((packed));
+
+#define BLE_HCI_LE_SUBEV_CS_TEST_END_COMPLETE          (0x33)
+struct ble_hci_ev_le_subev_cs_test_end_complete {
+    uint8_t subev_code;
+    uint8_t status;
+} __attribute__((packed));
+
 /* Data buffer overflow event */
 #define BLE_HCI_EVENT_ACL_BUF_OVERFLOW      (0x01)
 
diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml
index 6264d0bc2..d19702790 100644
--- a/nimble/syscfg.yml
+++ b/nimble/syscfg.yml
@@ -115,6 +115,11 @@ syscfg.defs:
         restrictions:
             - 'BLE_ISO if 1'
 
+    BLE_CHANNEL_SOUNDING:
+        description: >
+            This enables Channel Sounding feature
+        value: 0
+
     BLE_HCI_VS:
         description: >
             Enables support for NimBLE specific vendor HCI commands
diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml
index febe09d40..7e8ea9357 100644
--- a/nimble/transport/syscfg.yml
+++ b/nimble/transport/syscfg.yml
@@ -117,3 +117,7 @@ $import:
 
 syscfg.vals.'BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV':
     BLE_TRANSPORT_EVT_SIZE: 257
+
+syscfg.vals.'BLE_CHANNEL_SOUNDING && !(BLE_EXT_ADV || 
BLE_LL_CFG_FEAT_LL_EXT_ADV)':
+    # A larger buffer is needed to sent the FAE table.
+    BLE_TRANSPORT_EVT_SIZE: 78


Reply via email to