nimble/host: Add initial support for Channel Sounding HCI commands and

events
This commit is contained in:
Magdalena Kasenberg
2024-02-05 16:49:27 +01:00
committed by Rahul Tank
parent 6e6089e62b
commit 5b55424c20
16 changed files with 1718 additions and 1 deletions
+93
View File
@@ -0,0 +1,93 @@
/*
* 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)
#define BLE_CS_EVENT_CS_PROCEDURE_ENABLE_COMPLETE (1)
#define BLE_CS_EVENT_SUBEVET_RESULT (2)
#define BLE_CS_EVENT_SUBEVET_RESULT_CONTINUE (3)
struct cs_step_data {
uint8_t mode;
uint8_t channel;
uint8_t data_len;
uint8_t data[];
} __attribute__((packed));
struct ble_cs_event {
uint8_t type;
union
{
struct
{
uint16_t conn_handle;
uint8_t status;
} procedure_complete;
struct
{
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_step_data steps[];
}subev_result;
struct
{
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_step_data steps[];
}subev_result_continue;
};
};
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
+7
View File
@@ -221,6 +221,10 @@ struct hci_conn_update;
#define BLE_GAP_AUTHORIZE_ACCEPT 1
#define BLE_GAP_AUTHORIZE_REJECT 2
extern int ble_global_status;
/** Connection security state */
struct ble_gap_sec_state {
/** If connection is encrypted */
@@ -4083,6 +4087,9 @@ int ble_gap_read_rem_ver_info(uint16_t conn_handle, uint8_t *version, uint16_t *
int ble_gap_rd_local_resolv_addr(uint8_t peer_addr_type, const ble_addr_t *peer_addr,
uint8_t *out_addr);
int ble_gap_set_host_feat(uint8_t bit_num,uint8_t bit_val);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,139 @@
/**
* 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_SVC_RAS_
#define H_BLE_SVC_RAS_
#define BLE_SVC_RAS_CHR_RANGING_SERVICE_VAL (0x185B)
/** @brief UUID of the RAS Features Characteristic. **/
#define BLE_SVC_RAS_CHR_UUID_FEATURES_VAL (0x2C14)
/** @brief UUID of the Real-time Ranging Data Characteristic. **/
#define BLE_SVC_RAS_CHR_UUID_REALTIME_RD_VAL (0x2C15)
/** @brief UUID of the On-demand Ranging Data Characteristic. **/
#define BLE_SVC_RAS_CHR_UUID_ONDEMAND_RD_VAL (0x2C16)
/** @brief UUID of the RAS Control Point Characteristic. **/
#define BLE_SVC_RAS_CHR_UUID_CP_VAL (0x2C17)
/** @brief UUID of the Ranging Data Ready Characteristic. **/
#define BLE_SVC_RAS_CHR_UUID_RD_READY_VAL (0x2C18)
/** @brief UUID of the Ranging Data Overwritten Characteristic. **/
#define BLE_SVC_RAS_CHR_UUID_RD_OVERWRITTEN_VAL (0x2C19)
#define BLE_RAS_RANGING_HEADER_LEN 4
#define BLE_RAS_SUBEVENT_HEADER_LEN 8
#define BLE_RAS_STEP_MODE_LEN 1
#define BLE_RAS_MAX_SUBEVENTS_PER_PROCEDURE 32
#define BLE_RAS_MAX_STEPS_PER_PROCEDURE 256
#define BLE_RAS_MAX_STEP_DATA_LEN 32
#define BLE_RAS_PROCEDURE_MEM \
(BLE_RAS_RANGING_HEADER_LEN + \
(BLE_RAS_MAX_SUBEVENTS_PER_PROCEDURE * BLE_RAS_SUBEVENT_HEADER_LEN) + \
(BLE_RAS_MAX_STEPS_PER_PROCEDURE * BLE_RAS_STEP_MODE_LEN) + \
(BLE_RAS_MAX_STEPS_PER_PROCEDURE * BLE_RAS_MAX_STEP_DATA_LEN))
/** @brief Ranging Header structure as defined in RAS Specification, Table 3.7. */
struct ras_ranging_header {
/** Ranging Counter is lower 12-bits of CS Procedure_Counter provided by the Core Controller
* (Core Specification, Volume 4, Part E, Section 7.7.65.44).
*/
uint16_t ranging_counter : 12;
/** CS configuration identifier. Range: 0 to 3. */
uint8_t config_id : 4;
/** Transmit power level used for the CS Procedure. Range: -127 to 20. Units: dBm. */
int8_t selected_tx_power;
/** Antenna paths that are reported:
* Bit0: 1 if Antenna Path_1 included; 0 if not.
* Bit1: 1 if Antenna Path_2 included; 0 if not.
* Bit2: 1 if Antenna Path_3 included; 0 if not.
* Bit3: 1 if Antenna Path_4 included; 0 if not.
* Bits 4-7: RFU
*/
uint8_t antenna_paths_mask;
} __packed;
void ble_svc_ras_init(void);
/** @brief Subevent Header structure as defined in RAS Specification, Table 3.8. */
struct ras_subevent_header {
/** Starting ACL connection event count for the results reported in the event */
uint16_t start_acl_conn_event;
/** Frequency compensation value in units of 0.01 ppm (15-bit signed integer).
* Note this value can be BT_HCI_LE_CS_SUBEVENT_RESULT_FREQ_COMPENSATION_NOT_AVAILABLE
* if the role is not the initiator, or the frequency compensation value is unavailable.
*/
uint16_t freq_compensation;
/** Ranging Done Status:
* 0x0: All results complete for the CS Procedure
* 0x1: Partial results with more to follow for the CS procedure
* 0xF: All subsequent CS Procedures aborted
* All other values: RFU
*/
uint8_t ranging_done_status : 4;
/** Subevent Done Status:
* 0x0: All results complete for the CS Subevent
* 0xF: Current CS Subevent aborted.
* All other values: RFU
*/
uint8_t subevent_done_status : 4;
/** Indicates the abort reason when Procedure_Done Status received from the Core Controller
* (Core Specification, Volume 4, Part 4, Section 7.7.65.44) is set to 0xF,
* otherwise the value is set to zero.
* 0x0: Report with no abort
* 0x1: Abort because of local Host or remote request
* 0x2: Abort because filtered channel map has less than 15 channels
* 0x3: Abort because the channel map update instant has passed
* 0xF: Abort because of unspecified reasons
* All other values: RFU
*/
uint8_t ranging_abort_reason : 4;
/** Indicates the abort reason when Subevent_Done_Status received from the Core Controller
* (Core Specification, Volume 4, Part 4, Section 7.7.65.44) is set to 0xF,
* otherwise the default value is set to zero.
* 0x0: Report with no abort
* 0x1: Abort because of local Host or remote request
* 0x2: Abort because no CS_SYNC (mode 0) received
* 0x3: Abort because of scheduling conflicts or limited resources
* 0xF: Abort because of unspecified reasons
* All other values: RFU
*/
uint8_t subevent_abort_reason : 4;
/** Reference power level. Range: -127 to 20. Units: dBm */
int8_t ref_power_level;
/** Number of steps in the CS Subevent for which results are reported.
* If the Subevent is aborted, then the Number Of Steps Reported can be set to zero
*/
uint8_t num_steps_reported;
} __packed;
#endif
+34
View File
@@ -0,0 +1,34 @@
#
# 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: nimble/host/services/bas
pkg.description: Battery Service
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
- ble
- bluetooth
- hid
- nimble
pkg.deps:
- nimble/host
pkg.init:
ble_svc_hid_init: 'MYNEWT_VAL(BLE_SVC_HID_SYSINIT_STAGE)'
@@ -0,0 +1,35 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "host/ble_hs.h"
#include "host/ble_uuid.h"
#include "services/ras/ble_svc_ras.h"
/*RAS control point state */
enum ble_ras_rreq_cp_state {
BLE_RAS_RREQ_CP_STATE_NONE,
BLE_RAS_RREQ_CP_STATE_GET_RD_WRITTEN,
BLE_RAS_RREQ_CP_STATE_ACK_RD_WRITTEN,
};
#define BLE_UUID_RANGING_SERVICE_VAL (0x185B)
/** @brief UUID of the RAS Features Characteristic. **/
#define BLE_UUID_RAS_FEATURES_VAL (0x2C14)
/** @brief UUID of the Real-time Ranging Data Characteristic. **/
#define BLE_UUID_RAS_REALTIME_RD_VAL (0x2C15)
/** @brief UUID of the On-demand Ranging Data Characteristic. **/
#define BLE_UUID_RAS_ONDEMAND_RD_VAL (0x2C16)
/** @brief UUID of the RAS Control Point Characteristic. **/
#define BLE_UUID_RAS_CP_VAL (0x2C17)
/** @brief UUID of the Ranging Data Ready Characteristic. **/
#define BLE_UUID_RAS_RD_READY_VAL (0x2C18)
/** @brief UUID of the Ranging Data Overwritten Characteristic. **/
#define BLE_UUID_RAS_RD_OVERWRITTEN_VAL (0x2C19)
@@ -0,0 +1,206 @@
/*
* 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 <assert.h>
#include <stdio.h>
#include <string.h>
#include "host/ble_hs.h"
#include "host/ble_uuid.h"
#include "services/ras/ble_svc_ras.h"
/* Char values */
static int32_t ble_svc_ras_feat_val;
static uint16_t ble_svc_ras_rd_val;
static uint16_t ble_svc_ras_rd_ov_val;
static uint16_t ble_svc_ras_cp_val
static uint16_t ble_svc_ras_feat_val_handle;
static uint16_t ble_svc_ras_rd_val_handle;
static uint16_t ble_svc_ras_rd_ov_val_handle;
static uint16_t ble_svc_ras_cp_val_handle;
static u_int16_t ble_svc_ras_od_val_handle;
static int
gatt_svr_chr_access_ras_val(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg);
static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
{
/* Service: Ranging Data Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RANGING_SERVICE_VAL),
.characteristics = (struct ble_gatt_chr_def[])
{ {
/* Characteristic: Feature Value */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_FEATURES_VAL),
.access_cb = gatt_svr_chr_access_ras_feature,
.val_handle = &ble_svc_ras_feat_val_handle,
.flags = BLE_GATT_CHR_F_READ|BLE_GATT_CHR_F_READ_ENC,
}, {
/* Characteristic: On demand ranging data */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_ONDEMAND_RD_VAL),
.access_cb = gatt_svr_chr_access_ras_feature,
.val_handle = ble_svc_ras_od_val_handle,
.flags = BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE |BLE_GATT_CHR_F_READ_ENC
,
},{
/* Characteristic: RAS Control Point */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_CP_VAL),
.access_cb = gatt_svr_chr_access_ras_feature,
.val_handle = ble_svc_ras_cp_val_handle,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_INDICATE |BLE_GATT_CHR_F_READ_ENC ,
},{
/* Characteristic: RAS Data Ready */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_RD_READY_VAL),
.access_cb = gatt_svr_chr_access_ras_feature,
.val_handle = ble_svc_ras_rd_val_handle,
.flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC,
},{
/* Characteristic: RAS data overwritten */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_RD_OVERWRITTEN_VAL),
.access_cb = gatt_svr_chr_access_ras_feature,
.val_handle=ble_svc_ras_rd_ov_val_handle,
.flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC,
}, {
0, /* No more characteristics in this service */
},
}
},
{
0, /* No more services */
},
};
static int
gatt_svr_chr_access_ras_val(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
const ble_uuid_t *uuid;
int rc;
switch (ctxt->op) {
case BLE_GATT_ACCESS_OP_READ_CHR:
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
MODLOG_DFLT(INFO, "Characteristic read; conn_handle=%d attr_handle=%d\n",
conn_handle, attr_handle);
} else {
MODLOG_DFLT(INFO, "Characteristic read by NimBLE stack; attr_handle=%d\n",
attr_handle);
}
uuid = ctxt->chr->uuid;
if(uuid == BLE_UUID_RAS_FEATURES_VAL){
if (attr_handle == ras_feat_val_handle) {
rc = os_mbuf_append(ctxt->om,
&ras_feat_val,
sizeof(ras_feat_val));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
}
goto unknown;
case BLE_GATT_ACCESS_OP_WRITE_CHR:
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
MODLOG_DFLT(INFO, "Characteristic write; conn_handle=%d attr_handle=%d",
conn_handle, attr_handle);
} else {
MODLOG_DFLT(INFO, "Characteristic write by NimBLE stack; attr_handle=%d",
attr_handle);
}
uuid = ctxt->chr->uuid;
if (attr_handle == ras_feat_val_handle) {
rc = gatt_svr_write(ctxt->om,
sizeof(ras_feat_val),
sizeof(ras_feat_val),
&ras_feat_val, NULL);
ble_gatts_chr_updated(attr_handle);
MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
"all subscribed peers.\n");
return rc;
}
goto unknown;
default:
goto unknown;
}
unknown:
/* Unknown characteristic/descriptor;
* The NimBLE host should not have called this function;
*/
assert(0);
return BLE_ATT_ERR_UNLIKELY;
}
void
gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
{
char buf[BLE_UUID_STR_LEN];
switch (ctxt->op) {
case BLE_GATT_REGISTER_OP_SVC:
MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
ctxt->svc.handle);
break;
case BLE_GATT_REGISTER_OP_CHR:
MODLOG_DFLT(DEBUG, "registering characteristic %s with "
"def_handle=%d val_handle=%d\n",
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
ctxt->chr.def_handle,
ctxt->chr.val_handle);
break;
case BLE_GATT_REGISTER_OP_DSC:
MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
ctxt->dsc.handle);
break;
default:
assert(0);
break;
}
}
int
gatt_svr_init(void)
{
int rc;
ble_svc_gap_init();
ble_svc_gatt_init();
rc = ble_gatts_count_cfg(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
rc = ble_gatts_add_svcs(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
return 0;
}
+810
View File
@@ -0,0 +1,810 @@
/*
* 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"
#define BT_LE_CS_CHANNEL_BIT_SET_VAL(chmap, bit, val) \
((chmap)[(bit) / 8] = ((chmap)[(bit) / 8] & ~BIT((bit) % 8)) | ((val) << ((bit) % 8)))
static void print_ev_sz(int len ,int sz,int status){
printf("len= %d\n",len);
printf("size = %d\n",sz);
printf("status %d\n",status);
}
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 devices Tx PHY. A 4 bits bitmap. */
uint8_t phy;
/* How many more or fewer of transmit power levels should the remote devices
* 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 void
ble_cs_call_result_cb(const struct ble_hci_ev_le_subev_cs_subevent_result *ev)
{
struct ble_cs_event event;
memset(&event,0,sizeof event);
event.type = BLE_CS_EVENT_SUBEVET_RESULT;
event.subev_result.conn_handle = le16toh(ev->conn_handle);
event.subev_result.config_id = ev->config_id;
event.subev_result.start_acl_conn_event_counter=ev->start_acl_conn_event_counter;
event.subev_result.procedure_counter=ev->procedure_counter;
event.subev_result.frequency_compensation=ev->frequency_compensation;
event.subev_result.reference_power_level=ev->reference_power_level;
event.subev_result.procedure_done_status=ev->procedure_done_status;
event.subev_result.subevent_done_status=ev->subevent_done_status;
event.subev_result.abort_reason=ev->abort_reason;
event.subev_result.num_antenna_paths=ev->num_antenna_paths;
event.subev_result.num_steps_reported=ev->num_steps_reported;
memcpy(event.subev_result.steps,ev->steps,ev->num_steps_reported);
ble_cs_call_event_cb(&event);
}
static void ble_cs_call_result_continue_cb(const struct ble_hci_ev_le_subev_cs_subevent_result_continue *ev){
struct ble_cs_event event;
memset(&event,0,sizeof event);
event.type = BLE_CS_EVENT_SUBEVET_RESULT_CONTINUE;
event.subev_result_continue.conn_handle=le16toh(ev->conn_handle);
event.subev_result_continue.config_id=ev->config_id;
event.subev_result_continue.procedure_done_status=ev->procedure_done_status;
event.subev_result_continue.subevent_done_status=ev->procedure_done_status;
event.subev_result_continue.abort_reason=ev->abort_reason;
event.subev_result_continue.num_antenna_paths=ev->num_antenna_paths;
event.subev_result_continue.num_steps_reported=ev->num_steps_reported;
memcpy(event.subev_result_continue.steps,ev->steps,ev->num_steps_reported);
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)
{
printf("ble_hs_hci_evt_le_cs_rd_rem_supp_cap_complete\n");
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;
printf("ev->startus = %d\n", ev->status);
printf("sizeof(*ev)= %d\n",sizeof(*ev));
printf("len= %d\n",len);
if (len != sizeof(*ev) || ev->status) {
printf("\n BLE_HS_ECONTROLLER\n");
return BLE_HS_ECONTROLLER;
}
BLE_HS_LOG(INFO, "CS capabilities exchanged");
/* TODO: Save the remote capabilities somewhere */
set_cmd.conn_handle = le16toh(ev->conn_handle);
/* Only initiator role is enabled */
printf("ble_global_status %d\n",ble_global_status);
if(ble_global_status==0){
set_cmd.role_enable = 0x01;
}
else{
set_cmd.role_enable = 0x02;
}
/* Use antenna with ID 0x01 */
set_cmd.cs_sync_antenna_selection = 0xFE;
/* Set max TX power to the max supported */
set_cmd.max_tx_power = 20;
rc = ble_cs_set_def_settings(&set_cmd, &set_rsp);
if (rc) {
BLE_HS_LOG(INFO, "Failed to set the default CS settings, err %dt", rc);
return rc;
}
BLE_HS_LOG(INFO, "Set default CS settings ");
/* 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(INFO, "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)
{
printf("ble_hs_hci_evt_le_cs_rd_rem_fae_complete\n");
const struct ble_hci_ev_le_subev_cs_rd_rem_fae_complete *ev = data;
struct ble_cs_create_config_cp cmd;
int rc;
print_ev_sz(len,sizeof(*ev),ev->status);
if (len != sizeof(*ev) || ev->status) {
printf("BLE_HS_ECONTROLLER fae \n");
// 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 = 0x00;
/* Measure phase rotations in main mode */
cmd.main_mode_type = 0x01;
/* Do not use sub mode for now. */
cmd.sub_mode_type = 0x00;
/* 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 = 0x05;
/* 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 = 0x01;
cmd.rtt_type = 0x00;
cmd.cs_sync_phy = 0x01;
// memcpy(cmd.channel_map, (uint8_t[10]) {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 10);
BT_LE_CS_CHANNEL_BIT_SET_VAL(cmd.channel_map, 0, 0);
BT_LE_CS_CHANNEL_BIT_SET_VAL(cmd.channel_map, 1, 0);
BT_LE_CS_CHANNEL_BIT_SET_VAL(cmd.channel_map, 23, 0);
BT_LE_CS_CHANNEL_BIT_SET_VAL(cmd.channel_map, 24, 0);
BT_LE_CS_CHANNEL_BIT_SET_VAL(cmd.channel_map, 25, 0);
BT_LE_CS_CHANNEL_BIT_SET_VAL(cmd.channel_map, 77, 0);
BT_LE_CS_CHANNEL_BIT_SET_VAL(cmd.channel_map, 78, 0);
BT_LE_CS_CHANNEL_BIT_SET_VAL(cmd.channel_map, 79, 0);
cmd.channel_map_repetition = 0x03;
/* 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 = 0x02;
/* 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(INFO, "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)
{
printf("ble_hs_hci_evt_le_cs_sec_enable_complete\n");
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(INFO, "Failed to enable CS security BLE_HS_ECNOTEROLLER");
return BLE_HS_ECONTROLLER;
}
BLE_HS_LOG(INFO, "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(INFO, "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(INFO, "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)
{
printf("ble_hs_hci_evt_le_cs_config_complete\n");
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) {
printf("_cs_config_complete BLE_HS_ECONTROLLER\n");
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(INFO, "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;
}
ble_cs_call_result_cb(ev);
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;
}
ble_cs_call_result_continue_cb(ev);
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);
}
printf("cmd sent succfully\n");
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
+31
View File
@@ -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
+16
View File
@@ -104,6 +104,9 @@
#define BLE_GAP_OP_S_PERIODIC_ADV 2
#define BLE_GAP_OP_SYNC 1
int ble_global_status = 0;
/**
* If an attempt to cancel an active procedure fails, the attempt is retried
* at this rate (ms).
@@ -1210,6 +1213,7 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle)
return rc;
}
ble_global_status=BLE_GAP_ROLE_SLAVE;
if (conn.role == BLE_GAP_ROLE_MASTER) {
/* If there was a connection update in progress, indicate to the
* application that it did not complete.
@@ -1218,6 +1222,8 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle)
entry = ble_gap_update_entry_remove(conn_handle);
ble_hs_unlock();
ble_global_status=BLE_GAP_ROLE_MASTER;
if (entry != NULL) {
ble_gap_update_notify(conn_handle, BLE_ERR_CONN_ESTABLISHMENT);
ble_gap_update_entry_free(entry);
@@ -2955,6 +2961,7 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance)
switch (evt->role) {
case BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER:
ble_global_status=0;
rc = ble_gap_accept_master_conn();
if (rc != 0) {
return rc;
@@ -2962,6 +2969,7 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance)
break;
case BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE:
ble_global_status=1;
rc = ble_gap_accept_slave_conn(instance);
if (rc != 0) {
return rc;
@@ -10037,3 +10045,11 @@ ble_gap_host_check_status(void)
return status;
}
int ble_gap_set_host_feat(uint8_t bit_num,uint8_t bit_val) {
struct ble_hci_le_set_host_feature_cp cmd;
cmd.bit_num=bit_num;
cmd.bit_val=bit_val;
return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
BLE_HCI_OCF_LE_SET_HOST_FEATURE),&cmd, sizeof(cmd), NULL, 0);
}
+15
View File
@@ -48,6 +48,10 @@ static uint16_t ble_adv_list_count;
#define BLE_ADV_LIST_MAX_COUNT 200
#endif
#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");
@@ -224,6 +228,17 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = {
[BLE_HCI_LE_SUBEV_CIS_ESTABLISHED_V2] = ble_hs_hci_evt_le_cis_estab_v2,
#endif /* MYNEWT_VAL(BLE_ISO_CIS_ESTAB_V2) */
#endif /* MYNEWT_VAL(BLE_ISO) */
#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 \
+1 -1
View File
@@ -221,7 +221,6 @@ ble_hs_id_addr(uint8_t id_addr_type, const uint8_t **out_id_addr,
{
const uint8_t *id_addr;
int nrpa;
switch (id_addr_type) {
case BLE_ADDR_PUBLIC:
case BLE_ADDR_PUBLIC_ID:
@@ -314,6 +313,7 @@ ble_hs_id_use_addr(uint8_t own_addr_type)
rc = ble_hs_id_addr_type_usable(own_addr_type);
if (rc != 0) {
printf("usable rc = %d\n",rc);
return rc;
}
+19
View File
@@ -238,6 +238,7 @@ ble_hs_startup_read_bd_addr(void)
}
ble_hs_id_set_pub(rsp.addr);
return 0;
}
@@ -384,6 +385,7 @@ ble_hs_startup_le_set_evmask_tx(void)
}
#endif
<<<<<<< HEAD
#if MYNEWT_VAL(BLE_ISO)
if (version >= BLE_HCI_VER_BCS_5_2) {
/**
@@ -404,6 +406,23 @@ ble_hs_startup_le_set_evmask_tx(void)
}
#endif /* MYNEWT_VAL(BLE_ISO) */
#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,
+303
View File
@@ -1368,6 +1368,180 @@ struct ble_hci_le_set_periodic_adv_params_v2 {
uint8_t num_response_slots;
} __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))
@@ -2378,6 +2552,135 @@ struct ble_hci_ev_le_subev_cis_established_v2 {
#define BLE_HCI_LE_SUBEV_DISCARD_REPORT_EVT 0XF0
#endif // (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
#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;
uint8_t tx_snr_capability;
} __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)
+5
View File
@@ -103,6 +103,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
+4
View File
@@ -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