mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-11-01 10:06:11 +00:00
feat(nimble): Add host support for Decision Based Advertising Filtering
This commit is contained in:
@@ -2679,6 +2679,17 @@ struct ble_gap_ext_adv_params {
|
||||
/** If enable scan request notification */
|
||||
unsigned int scan_req_notif:1;
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
/** If use ADV_DECISION_IND on the primary advertising channel */
|
||||
unsigned int use_decision_pdus:1;
|
||||
|
||||
/** If include AdvA in the extended header of all decision PDUs */
|
||||
unsigned int decision_include_adv_a:1;
|
||||
|
||||
/** If include ADI in the extended header of all decision PDUs */
|
||||
unsigned int decision_include_adi:1;
|
||||
#endif
|
||||
|
||||
/** Minimum advertising interval in 0.625ms units, if 0 stack use sane
|
||||
* defaults
|
||||
*/
|
||||
@@ -2830,6 +2841,38 @@ int ble_gap_ext_adv_remove(uint8_t instance);
|
||||
*/
|
||||
int ble_gap_ext_adv_clear(void);
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
/**
|
||||
* Set decision data for an advertising set (DBAF).
|
||||
*
|
||||
* @param instance Advertising set handle (0x00-0xEF)
|
||||
* @param decision_type_flags Decision_Type_Flags (bit0 = Resolvable Tag)
|
||||
* @param data Decision data (Resolvable Tag = hash || prand)
|
||||
* @param data_len Length of data, 0-8
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*/
|
||||
int ble_gap_set_decision_data(uint8_t instance, uint8_t decision_type_flags,
|
||||
const uint8_t *data, uint8_t data_len);
|
||||
|
||||
/**
|
||||
* Set decision instructions used when scanning or initiating (DBAF).
|
||||
*
|
||||
* Controller supports at least 8 tests. Test_Flags[0] bit0 must be 1.
|
||||
*
|
||||
* @param num_tests Number of tests (1-8)
|
||||
* @param test_flags Per-test flags (num_tests octets)
|
||||
* @param test_fields Per-test fields (num_tests octets)
|
||||
* @param test_params Per-test parameters (num_tests * 16 octets)
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*/
|
||||
int ble_gap_set_decision_instructions(uint8_t num_tests,
|
||||
const uint8_t *test_flags,
|
||||
const uint8_t *test_fields,
|
||||
const uint8_t *test_params);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Indicates whether an advertisement procedure is currently in progress on
|
||||
* the specified Instance
|
||||
@@ -3478,6 +3521,9 @@ int ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms,
|
||||
* - BLE_HCI_SCAN_FILT_NO_WL_INITA
|
||||
* - BLE_HCI_SCAN_FILT_USE_WL_INITA
|
||||
* - BLE_HCI_SCAN_FILT_MAX
|
||||
* DBAF (Core 6.0) may OR bits 2-3:
|
||||
* - BLE_HCI_SCAN_FILT_DECISION_ALL
|
||||
* - BLE_HCI_SCAN_FILT_DECISION_ONLY
|
||||
* This parameter is ignored unless
|
||||
* @p filter_duplicates is set.
|
||||
* @param limited If limited discovery procedure should be used.
|
||||
@@ -3635,6 +3681,30 @@ int ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handl
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
ble_gap_event_fn *cb, void *cb_arg);
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
/**
|
||||
* Same as ble_gap_connect_with_synced(), with an explicit Initiator_Filter_Policy.
|
||||
*
|
||||
* filter_policy 0 or 1 keeps the historical choice (peer NULL -> Filter Accept
|
||||
* List, otherwise the peer address).
|
||||
*
|
||||
* Policies 2-4 are rejected. Core Vol 4 Part E 7.8.66: when Advertising_Handle
|
||||
* and Subevent are not 0xFF, the controller ignores Initiator_Filter_Policy and
|
||||
* connects to the supplied peer address. Use ble_gap_ext_connect_dbaf() for
|
||||
* DBAF initiator policies.
|
||||
*
|
||||
* @return BLE_HS_EINVAL if filter_policy is greater than 1.
|
||||
*/
|
||||
int ble_gap_connect_with_synced_dbaf(uint8_t own_addr_type,
|
||||
uint8_t advertising_handle, uint8_t subevent,
|
||||
const ble_addr_t *peer_addr, int32_t duration_ms,
|
||||
uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
uint8_t filter_policy, ble_gap_event_fn *cb, void *cb_arg);
|
||||
#endif
|
||||
#endif
|
||||
/**
|
||||
* Initiates an extended connect procedure.
|
||||
@@ -3694,6 +3764,31 @@ int ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
ble_gap_event_fn *cb, void *cb_arg);
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF) && MYNEWT_VAL(BLE_EXT_ADV)
|
||||
/**
|
||||
* Same as ble_gap_ext_connect(), with an explicit Initiator_Filter_Policy.
|
||||
*
|
||||
* Do not add this policy to ble_gap_conn_params. Callers fill that struct
|
||||
* field by field, so a new byte is uninitialized stack garbage.
|
||||
*
|
||||
* filter_policy 0 or 1 keeps the historical choice (peer NULL -> Filter Accept
|
||||
* List, otherwise the peer address). Values 2-4 are the Core 6.0 DBAF policies
|
||||
* (BLE_HCI_CONN_FILT_DECISION_ONLY / FAL_ALL_PDUS / DECISION_AND_FAL).
|
||||
* Peer_Address is ignored by the controller for 2-4 (Vol 4 Part E 7.8.66).
|
||||
*
|
||||
* @return BLE_HS_EINVAL if filter_policy is greater than 4;
|
||||
* BLE_HS_ENOTSUP if filter_policy is 2-4 and the controller does not
|
||||
* support Decision-Based Advertising Filtering (LE feature bit 42).
|
||||
*/
|
||||
int ble_gap_ext_connect_dbaf(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
uint8_t filter_policy,
|
||||
ble_gap_event_fn *cb, void *cb_arg);
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(OPTIMIZE_MULTI_CONN)
|
||||
/**
|
||||
* @brief Enable the optimization of multiple connections.
|
||||
|
||||
+425
-4
@@ -157,6 +157,9 @@ struct ble_gap_connect_reattempt_ctxt {
|
||||
uint8_t phy_mask;
|
||||
struct ble_gap_conn_params conn_params_2m;
|
||||
struct ble_gap_conn_params conn_params_coded;
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
uint8_t dbaf_filter_policy;
|
||||
#endif
|
||||
#endif // MYNEWT_VAL(BLE_EXT_ADV)
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
ble_addr_t periodic_addr;
|
||||
@@ -233,6 +236,10 @@ struct ble_gap_master_state {
|
||||
uint8_t using_wl:1;
|
||||
uint8_t our_addr_type:2;
|
||||
uint8_t cancel:1;
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
/* Effective Initiator_Filter_Policy sent to the controller. */
|
||||
uint8_t filt_policy;
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES)
|
||||
uint8_t synchronized:1;
|
||||
uint8_t timeout_cancel_pending:1;
|
||||
@@ -1693,6 +1700,9 @@ ble_gap_master_reset_state(void)
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES)
|
||||
ble_gap_master.conn.synchronized = 0;
|
||||
ble_gap_master.conn.timeout_cancel_pending = 0;
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
ble_gap_master.conn.filt_policy = BLE_HCI_CONN_FILT_NO_WL;
|
||||
#endif
|
||||
memset(&ble_gap_master.conn.peer_addr, 0,
|
||||
sizeof(ble_gap_master.conn.peer_addr));
|
||||
@@ -1755,6 +1765,16 @@ ble_gap_master_conn_matches_slave_complete(const struct ble_gap_conn_complete *e
|
||||
return false;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
/* Policies 2-4 ignore Peer_Address (Core Vol 4 Part E 7.8.66). Policy 2
|
||||
* does not use the Filter Accept List, so using_wl is false and would
|
||||
* otherwise compare an address the controller will not honor.
|
||||
*/
|
||||
if (ble_gap_master.conn.filt_policy >= BLE_HCI_CONN_FILT_DECISION_ONLY) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
evt_addr.type = evt->peer_addr_type;
|
||||
memcpy(evt_addr.val, evt->peer_addr, BLE_DEV_ADDR_LEN);
|
||||
|
||||
@@ -2027,6 +2047,17 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle)
|
||||
#endif // MYNEWT_VAL(OPTIMIZE_MULTI_CONN)
|
||||
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV)
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
rc = ble_gap_ext_connect_dbaf(ble_conn_reattempt.own_addr_type,
|
||||
(ble_conn_reattempt.peer_addr_present == 1 ? &ble_conn_reattempt.peer_addr : NULL),
|
||||
ble_conn_reattempt.duration_ms, ble_conn_reattempt.phy_mask,
|
||||
ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_1M_MASK ? &ble_conn_reattempt.conn_params_1m : NULL,
|
||||
ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_2M_MASK ? &ble_conn_reattempt.conn_params_2m : NULL,
|
||||
ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_CODED_MASK ? &ble_conn_reattempt.conn_params_coded : NULL,
|
||||
ble_conn_reattempt.dbaf_filter_policy,
|
||||
ble_conn_reattempt.cb,
|
||||
ble_conn_reattempt.cb_arg);
|
||||
#else
|
||||
rc = ble_gap_ext_connect(ble_conn_reattempt.own_addr_type,
|
||||
(ble_conn_reattempt.peer_addr_present == 1 ? &ble_conn_reattempt.peer_addr : NULL),
|
||||
ble_conn_reattempt.duration_ms, ble_conn_reattempt.phy_mask,
|
||||
@@ -2035,6 +2066,7 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle)
|
||||
ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_CODED_MASK ? &ble_conn_reattempt.conn_params_coded : NULL,
|
||||
ble_conn_reattempt.cb,
|
||||
ble_conn_reattempt.cb_arg);
|
||||
#endif
|
||||
#else
|
||||
rc = ble_gap_connect(ble_conn_reattempt.own_addr_type,
|
||||
(ble_conn_reattempt.peer_addr_present == 1 ? &ble_conn_reattempt.peer_addr : NULL),
|
||||
@@ -6198,6 +6230,17 @@ ble_gap_set_ext_adv_params(struct ble_hci_le_set_ext_adv_params_cp *cmd,
|
||||
if (params->include_tx_power) {
|
||||
cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR;
|
||||
}
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
if (params->use_decision_pdus) {
|
||||
cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_USE_DECISION;
|
||||
}
|
||||
if (params->decision_include_adv_a) {
|
||||
cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_DEC_INCL_ADVA;
|
||||
}
|
||||
if (params->decision_include_adi) {
|
||||
cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_DEC_INCL_ADI;
|
||||
}
|
||||
#endif
|
||||
if (params->legacy_pdu) {
|
||||
cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY;
|
||||
|
||||
@@ -6407,13 +6450,37 @@ ble_gap_ext_adv_params_validate(const struct ble_gap_ext_adv_params *params)
|
||||
BLE_HS_LOG(ERROR, "%s rc=%d\n", __func__, BLE_HS_EINVAL);
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
if (params->use_decision_pdus ||
|
||||
params->decision_include_adv_a ||
|
||||
params->decision_include_adi) {
|
||||
BLE_HS_LOG(ERROR, "%s rc=%d\n", __func__, BLE_HS_EINVAL);
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
if ((params->decision_include_adv_a || params->decision_include_adi) &&
|
||||
!params->use_decision_pdus) {
|
||||
BLE_HS_LOG(ERROR, "%s rc=%d\n", __func__, BLE_HS_EINVAL);
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (params->directed) {
|
||||
if (params->scannable && params->connectable) {
|
||||
BLE_HS_LOG(ERROR, "%s rc=%d\n", __func__, BLE_HS_EINVAL);
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
/* Decision PDUs are permitted only for undirected advertising
|
||||
* (Core Spec Vol 6 Part B 2.3.1.11, Table 2.10). */
|
||||
if (params->use_decision_pdus) {
|
||||
BLE_HS_LOG(ERROR, "%s rc=%d\n", __func__, BLE_HS_EINVAL);
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!params->legacy_pdu) {
|
||||
@@ -7190,6 +7257,106 @@ ble_gap_ext_adv_clear(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
int
|
||||
ble_gap_set_decision_data(uint8_t instance, uint8_t decision_type_flags,
|
||||
const uint8_t *data, uint8_t data_len)
|
||||
{
|
||||
uint8_t buf[sizeof(struct ble_hci_le_set_decision_data_cp) +
|
||||
BLE_HCI_DECISION_DATA_MAX_LEN];
|
||||
struct ble_hci_le_set_decision_data_cp *cmd = (void *)buf;
|
||||
uint16_t opcode;
|
||||
uint8_t len;
|
||||
|
||||
if (!ble_hs_is_enabled()) {
|
||||
return BLE_HS_EDISABLED;
|
||||
}
|
||||
|
||||
if ((ble_hs_hci_get_le_supported_feat() & BLE_HS_HCI_LE_FEAT_DBAF) == 0) {
|
||||
return BLE_HS_ENOTSUP;
|
||||
}
|
||||
|
||||
if (instance > 0xEF) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if (data_len > BLE_HCI_DECISION_DATA_MAX_LEN) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if (data_len > 0 && data == NULL) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if ((decision_type_flags & BLE_HCI_DECISION_TYPE_RESOLVABLE_TAG) &&
|
||||
data_len < 6) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
cmd->adv_handle = instance;
|
||||
cmd->decision_type_flags = decision_type_flags;
|
||||
cmd->decision_data_len = data_len;
|
||||
if (data_len > 0) {
|
||||
memcpy(cmd->decision_data, data, data_len);
|
||||
}
|
||||
|
||||
len = sizeof(*cmd) + data_len;
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DECISION_DATA);
|
||||
|
||||
return ble_hs_hci_cmd_tx(opcode, cmd, len, NULL, 0);
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_set_decision_instructions(uint8_t num_tests,
|
||||
const uint8_t *test_flags,
|
||||
const uint8_t *test_fields,
|
||||
const uint8_t *test_params)
|
||||
{
|
||||
uint8_t buf[sizeof(struct ble_hci_le_set_decision_instructions_cp) +
|
||||
BLE_HCI_DECISION_MAX_TESTS * sizeof(struct ble_hci_le_decision_test)];
|
||||
struct ble_hci_le_set_decision_instructions_cp *cmd = (void *)buf;
|
||||
uint16_t opcode;
|
||||
uint8_t i;
|
||||
uint8_t len;
|
||||
|
||||
if (!ble_hs_is_enabled()) {
|
||||
return BLE_HS_EDISABLED;
|
||||
}
|
||||
|
||||
if ((ble_hs_hci_get_le_supported_feat() & BLE_HS_HCI_LE_FEAT_DBAF) == 0) {
|
||||
return BLE_HS_ENOTSUP;
|
||||
}
|
||||
|
||||
if (num_tests == 0 || num_tests > BLE_HCI_DECISION_MAX_TESTS) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if (test_flags == NULL || test_fields == NULL || test_params == NULL) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if ((test_flags[0] & BLE_HCI_DECISION_TEST_FLAGS_NEW_GROUP) == 0) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
cmd->num_tests = num_tests;
|
||||
for (i = 0; i < num_tests; i++) {
|
||||
cmd->tests[i].test_flags = test_flags[i];
|
||||
cmd->tests[i].test_field = test_fields[i];
|
||||
memcpy(cmd->tests[i].test_params,
|
||||
test_params + (i * BLE_HCI_DECISION_TEST_PARAM_LEN),
|
||||
BLE_HCI_DECISION_TEST_PARAM_LEN);
|
||||
}
|
||||
|
||||
len = sizeof(*cmd) + num_tests * sizeof(struct ble_hci_le_decision_test);
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DECISION_INSTRUCTIONS);
|
||||
|
||||
return ble_hs_hci_cmd_tx(opcode, cmd, len, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
static int
|
||||
ble_gap_periodic_adv_params_tx(uint8_t instance,
|
||||
@@ -8476,6 +8643,23 @@ int ble_gap_periodic_adv_sync_subev(uint16_t sync_handle, uint8_t include_tx_pow
|
||||
*****************************************************************************/
|
||||
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
static int
|
||||
ble_gap_ext_scan_filter_policy_valid(uint8_t filter_policy)
|
||||
{
|
||||
/* bits 4-7 reserved (must be 0). */
|
||||
if (filter_policy & 0xF0) {
|
||||
return 0;
|
||||
}
|
||||
/* bits 2-3: 0b00 / 0b01 / 0b11 valid; 0b10 reserved. */
|
||||
if (((filter_policy >> 2) & 0x03) == 0x02) {
|
||||
return 0;
|
||||
}
|
||||
/* bits 0-1: all values 0-3 valid per spec. */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ble_gap_ext_disc_tx_params(uint8_t own_addr_type, uint8_t filter_policy,
|
||||
const struct ble_hs_hci_ext_scan_param *uncoded_params,
|
||||
@@ -8492,10 +8676,25 @@ ble_gap_ext_disc_tx_params(uint8_t own_addr_type, uint8_t filter_policy,
|
||||
}
|
||||
|
||||
/* Check scanner filter policy */
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
if (!ble_gap_ext_scan_filter_policy_valid(filter_policy)) {
|
||||
#else
|
||||
if (filter_policy > BLE_HCI_SCAN_FILT_MAX) {
|
||||
#endif
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
/* Bits 2-3 are Decision-Based Advertising Filtering. A controller without
|
||||
* LE feature bit 42 must not be sent these values (Core Vol 4 Part E
|
||||
* 7.8.64, error 0x11). Values 0-3 keep the historical scan filter policy.
|
||||
*/
|
||||
if ((filter_policy & BLE_HCI_SCAN_FILT_DECISION_MASK) != 0 &&
|
||||
(ble_hs_hci_get_le_supported_feat() & BLE_HS_HCI_LE_FEAT_DBAF) == 0) {
|
||||
return BLE_HS_ENOTSUP;
|
||||
}
|
||||
#endif
|
||||
|
||||
cmd = (void *) buf;
|
||||
params = cmd->scans;
|
||||
|
||||
@@ -9453,6 +9652,53 @@ ble_gap_check_conn_params(uint8_t phy, const struct ble_gap_conn_params *params)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF) && \
|
||||
(MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) || \
|
||||
(MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_ROLE_CENTRAL)))
|
||||
static int
|
||||
ble_gap_dbaf_initiator_filter_policy(const ble_addr_t *peer_addr,
|
||||
uint8_t req_policy,
|
||||
uint8_t *out_policy)
|
||||
{
|
||||
uint8_t policy;
|
||||
|
||||
if (out_policy == NULL) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if (req_policy > BLE_HCI_CONN_FILT_MAX) {
|
||||
*out_policy = BLE_HCI_CONN_FILT_NO_WL;
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
/* Core Vol 4 Part E 7.8.66: policies other than 0x00 and 0x01 require
|
||||
* Decision-Based Advertising Filtering. 0 and 1 keep the historical choice.
|
||||
*/
|
||||
if (req_policy > BLE_HCI_CONN_FILT_USE_WL &&
|
||||
(ble_hs_hci_get_le_supported_feat() & BLE_HS_HCI_LE_FEAT_DBAF) == 0) {
|
||||
*out_policy = BLE_HCI_CONN_FILT_NO_WL;
|
||||
return BLE_HS_ENOTSUP;
|
||||
}
|
||||
|
||||
policy = (peer_addr == NULL) ? BLE_HCI_CONN_FILT_USE_WL :
|
||||
BLE_HCI_CONN_FILT_NO_WL;
|
||||
if (req_policy > BLE_HCI_CONN_FILT_USE_WL) {
|
||||
policy = req_policy;
|
||||
}
|
||||
|
||||
*out_policy = policy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_gap_initiator_policy_uses_fal(uint8_t policy)
|
||||
{
|
||||
return policy == BLE_HCI_CONN_FILT_USE_WL ||
|
||||
policy == BLE_HCI_CONN_FILT_FAL_ALL_PDUS ||
|
||||
policy == BLE_HCI_CONN_FILT_DECISION_AND_FAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES)
|
||||
static int
|
||||
ble_gap_ext_conn_create_conn_synced_tx(uint8_t own_addr_type,
|
||||
@@ -9460,7 +9706,11 @@ ble_gap_ext_conn_create_conn_synced_tx(uint8_t own_addr_type,
|
||||
const ble_addr_t *peer_addr, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params)
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
, uint8_t filter_policy
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct ble_hci_le_ext_create_conn_v2_cp *cmd;
|
||||
struct conn_params *params;
|
||||
@@ -9490,7 +9740,9 @@ ble_gap_ext_conn_create_conn_synced_tx(uint8_t own_addr_type,
|
||||
* peer address type and peer address fields are ignored by the
|
||||
* controller; fill them with dummy values.
|
||||
*/
|
||||
#if !MYNEWT_VAL(BLE_DBAF)
|
||||
cmd->filter_policy = BLE_HCI_CONN_FILT_USE_WL;
|
||||
#endif
|
||||
cmd->peer_addr_type = 0;
|
||||
memset(cmd->peer_addr, 0, sizeof(cmd->peer_addr));
|
||||
} else {
|
||||
@@ -9499,11 +9751,17 @@ ble_gap_ext_conn_create_conn_synced_tx(uint8_t own_addr_type,
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
#if !MYNEWT_VAL(BLE_DBAF)
|
||||
cmd->filter_policy = BLE_HCI_CONN_FILT_NO_WL;
|
||||
#endif
|
||||
cmd->peer_addr_type = peer_addr->type;
|
||||
memcpy(cmd->peer_addr, peer_addr->val, sizeof(cmd->peer_addr));
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
cmd->filter_policy = filter_policy;
|
||||
#endif
|
||||
|
||||
cmd->own_addr_type = own_addr_type;
|
||||
cmd->init_phy_mask = phy_mask & BLE_GAP_LE_PHY_ANY_MASK;
|
||||
|
||||
@@ -9573,6 +9831,17 @@ ble_gap_ext_conn_create_conn_synced_tx(uint8_t own_addr_type,
|
||||
}
|
||||
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
static int
|
||||
ble_gap_connect_with_synced_policy(uint8_t own_addr_type, uint8_t advertising_handle,
|
||||
uint8_t subevent, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
uint8_t dbaf_filter_policy,
|
||||
ble_gap_event_fn *cb, void *cb_arg)
|
||||
#else
|
||||
int
|
||||
ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handle,
|
||||
uint8_t subevent, const ble_addr_t *peer_addr,
|
||||
@@ -9581,8 +9850,12 @@ ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handle,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
ble_gap_event_fn *cb, void *cb_arg)
|
||||
#endif
|
||||
{
|
||||
uint32_t duration_ticks = 0;
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
uint8_t policy;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
STATS_INC(ble_gap_stats, initiate);
|
||||
@@ -9669,6 +9942,16 @@ ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handle,
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
policy = (peer_addr == NULL) ? BLE_HCI_CONN_FILT_USE_WL :
|
||||
BLE_HCI_CONN_FILT_NO_WL;
|
||||
rc = ble_gap_dbaf_initiator_filter_policy(peer_addr, dbaf_filter_policy,
|
||||
&policy);
|
||||
if (rc != 0) {
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* XXX: Verify conn_params. */
|
||||
|
||||
rc = ble_hs_id_use_addr(own_addr_type);
|
||||
@@ -9680,7 +9963,12 @@ ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handle,
|
||||
|
||||
ble_gap_master.cb = cb;
|
||||
ble_gap_master.cb_arg = cb_arg;
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
ble_gap_master.conn.filt_policy = policy;
|
||||
ble_gap_master.conn.using_wl = ble_gap_initiator_policy_uses_fal(policy);
|
||||
#else
|
||||
ble_gap_master.conn.using_wl = peer_addr == NULL;
|
||||
#endif
|
||||
ble_gap_master.conn.our_addr_type = own_addr_type;
|
||||
ble_gap_master.conn.synchronized = 1;
|
||||
if (peer_addr != NULL) {
|
||||
@@ -9694,7 +9982,11 @@ ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handle,
|
||||
|
||||
rc = ble_gap_ext_conn_create_conn_synced_tx(own_addr_type,advertising_handle,subevent, peer_addr, phy_mask,
|
||||
phy_1m_conn_params, phy_2m_conn_params,
|
||||
phy_coded_conn_params);
|
||||
phy_coded_conn_params
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
, policy
|
||||
#endif
|
||||
);
|
||||
if (rc != 0) {
|
||||
ble_gap_master_reset_state();
|
||||
goto done;
|
||||
@@ -9717,6 +10009,48 @@ done:
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
int
|
||||
ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handle,
|
||||
uint8_t subevent, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
ble_gap_event_fn *cb, void *cb_arg)
|
||||
{
|
||||
return ble_gap_connect_with_synced_policy(own_addr_type, advertising_handle,
|
||||
subevent, peer_addr, duration_ms, phy_mask,
|
||||
phy_1m_conn_params, phy_2m_conn_params, phy_coded_conn_params,
|
||||
0, cb, cb_arg);
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_connect_with_synced_dbaf(uint8_t own_addr_type,
|
||||
uint8_t advertising_handle, uint8_t subevent,
|
||||
const ble_addr_t *peer_addr, int32_t duration_ms,
|
||||
uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
uint8_t filter_policy, ble_gap_event_fn *cb, void *cb_arg)
|
||||
{
|
||||
/* Core Vol 4 Part E 7.8.66: Initiator_Filter_Policy is ignored when
|
||||
* Advertising_Handle and Subevent are not 0xFF, so DBAF policies do not
|
||||
* apply. Accepting them would mark the Filter Accept List busy and skip
|
||||
* peer-address matching while the controller still uses Peer_Address.
|
||||
*/
|
||||
if (filter_policy > BLE_HCI_CONN_FILT_USE_WL) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
return ble_gap_connect_with_synced_policy(own_addr_type, advertising_handle,
|
||||
subevent, peer_addr, duration_ms, phy_mask,
|
||||
phy_1m_conn_params, phy_2m_conn_params, phy_coded_conn_params,
|
||||
filter_policy, cb, cb_arg);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV)
|
||||
@@ -9727,7 +10061,11 @@ ble_gap_ext_conn_create_tx(
|
||||
uint8_t own_addr_type, const ble_addr_t *peer_addr, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params)
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
, uint8_t filter_policy
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct ble_hci_le_ext_create_conn_cp *cmd;
|
||||
struct conn_params *params;
|
||||
@@ -9757,7 +10095,9 @@ ble_gap_ext_conn_create_tx(
|
||||
* peer address type and peer address fields are ignored by the
|
||||
* controller; fill them with dummy values.
|
||||
*/
|
||||
#if !MYNEWT_VAL(BLE_DBAF)
|
||||
cmd->filter_policy = BLE_HCI_CONN_FILT_USE_WL;
|
||||
#endif
|
||||
cmd->peer_addr_type = 0;
|
||||
memset(cmd->peer_addr, 0, sizeof(cmd->peer_addr));
|
||||
} else {
|
||||
@@ -9766,11 +10106,17 @@ ble_gap_ext_conn_create_tx(
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
#if !MYNEWT_VAL(BLE_DBAF)
|
||||
cmd->filter_policy = BLE_HCI_CONN_FILT_NO_WL;
|
||||
#endif
|
||||
cmd->peer_addr_type = peer_addr->type;
|
||||
memcpy(cmd->peer_addr, peer_addr->val, sizeof(cmd->peer_addr));
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
cmd->filter_policy = filter_policy;
|
||||
#endif
|
||||
|
||||
cmd->own_addr_type = own_addr_type;
|
||||
cmd->init_phy_mask = phy_mask & BLE_GAP_LE_PHY_ANY_MASK;
|
||||
|
||||
@@ -9941,6 +10287,16 @@ ble_gap_ext_conn_create_tx(
|
||||
* connected;
|
||||
* Other nonzero on error.
|
||||
*/
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
static int
|
||||
ble_gap_ext_connect_policy(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
uint8_t dbaf_filter_policy,
|
||||
ble_gap_event_fn *cb, void *cb_arg)
|
||||
#else
|
||||
int
|
||||
ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms, uint8_t phy_mask,
|
||||
@@ -9948,9 +10304,13 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
ble_gap_event_fn *cb, void *cb_arg)
|
||||
#endif
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_ROLE_CENTRAL)
|
||||
ble_npl_time_t duration_ticks;
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
uint8_t policy;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
STATS_INC(ble_gap_stats, initiate);
|
||||
@@ -10047,6 +10407,16 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
policy = (peer_addr == NULL) ? BLE_HCI_CONN_FILT_USE_WL :
|
||||
BLE_HCI_CONN_FILT_NO_WL;
|
||||
rc = ble_gap_dbaf_initiator_filter_policy(peer_addr, dbaf_filter_policy,
|
||||
&policy);
|
||||
if (rc != 0) {
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* XXX: Verify conn_params. */
|
||||
|
||||
rc = ble_hs_id_use_addr(own_addr_type);
|
||||
@@ -10058,7 +10428,12 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
|
||||
ble_gap_master.cb = cb;
|
||||
ble_gap_master.cb_arg = cb_arg;
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
ble_gap_master.conn.filt_policy = policy;
|
||||
ble_gap_master.conn.using_wl = ble_gap_initiator_policy_uses_fal(policy);
|
||||
#else
|
||||
ble_gap_master.conn.using_wl = peer_addr == NULL;
|
||||
#endif
|
||||
ble_gap_master.conn.our_addr_type = own_addr_type;
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES)
|
||||
ble_gap_master.conn.synchronized = 0;
|
||||
@@ -10085,6 +10460,9 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
|
||||
ble_conn_reattempt.duration_ms = duration_ms;
|
||||
ble_conn_reattempt.phy_mask = phy_mask;
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
ble_conn_reattempt.dbaf_filter_policy = dbaf_filter_policy;
|
||||
#endif
|
||||
|
||||
if (phy_mask & BLE_GAP_LE_PHY_1M_MASK) {
|
||||
memcpy(&ble_conn_reattempt.conn_params_1m,
|
||||
@@ -10111,7 +10489,11 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
|
||||
rc = ble_gap_ext_conn_create_tx(own_addr_type, peer_addr, phy_mask,
|
||||
phy_1m_conn_params, phy_2m_conn_params,
|
||||
phy_coded_conn_params);
|
||||
phy_coded_conn_params
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
, policy
|
||||
#endif
|
||||
);
|
||||
if (rc != 0) {
|
||||
ble_gap_master_reset_state();
|
||||
goto done;
|
||||
@@ -10131,10 +10513,44 @@ done:
|
||||
}
|
||||
return rc;
|
||||
#else
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
(void)dbaf_filter_policy;
|
||||
#endif
|
||||
return BLE_HS_ENOTSUP;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
int
|
||||
ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
ble_gap_event_fn *cb, void *cb_arg)
|
||||
{
|
||||
return ble_gap_ext_connect_policy(own_addr_type, peer_addr, duration_ms,
|
||||
phy_mask, phy_1m_conn_params,
|
||||
phy_2m_conn_params, phy_coded_conn_params,
|
||||
0, cb, cb_arg);
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_ext_connect_dbaf(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
uint8_t filter_policy,
|
||||
ble_gap_event_fn *cb, void *cb_arg)
|
||||
{
|
||||
return ble_gap_ext_connect_policy(own_addr_type, peer_addr, duration_ms,
|
||||
phy_mask, phy_1m_conn_params,
|
||||
phy_2m_conn_params, phy_coded_conn_params,
|
||||
filter_policy, cb, cb_arg);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int
|
||||
@@ -10249,6 +10665,11 @@ ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
ble_gap_master.cb = cb;
|
||||
ble_gap_master.cb_arg = cb_arg;
|
||||
ble_gap_master.conn.using_wl = peer_addr == NULL;
|
||||
#if MYNEWT_VAL(BLE_DBAF)
|
||||
ble_gap_master.conn.filt_policy = (peer_addr == NULL) ?
|
||||
BLE_HCI_CONN_FILT_USE_WL :
|
||||
BLE_HCI_CONN_FILT_NO_WL;
|
||||
#endif
|
||||
ble_gap_master.conn.our_addr_type = own_addr_type;
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES)
|
||||
ble_gap_master.conn.synchronized = 0;
|
||||
|
||||
@@ -1034,6 +1034,11 @@ ble_hs_hci_set_le_supported_feat(uint64_t feat)
|
||||
uint64_t
|
||||
ble_hs_hci_get_le_supported_feat(void)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC)
|
||||
if (!ble_hs_hci_ctx) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return ble_hs_hci_sup_feat;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ struct os_mbuf;
|
||||
#define BLE_HS_HCI_LE_FEAT_CSA2 (0x00004000)
|
||||
#define BLE_HS_HCI_LE_FEAT_POWER_CLASS_1 (0x00008000)
|
||||
#define BLE_HS_HCI_LE_FEAT_MIN_NUM_USED_CHAN (0x00010000)
|
||||
/* Bit 42: Decision-Based Advertising Filtering (Core Vol 6 Part B 4.6). */
|
||||
#define BLE_HS_HCI_LE_FEAT_DBAF (1ULL << 42)
|
||||
|
||||
struct ble_hs_hci_ack {
|
||||
int bha_status; /* A BLE_HS_E<...> error; NOT a naked HCI code. */
|
||||
|
||||
@@ -1318,6 +1318,40 @@ struct ble_hci_le_set_ext_adv_params_v2_cp {
|
||||
uint8_t sec_phy_opt;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* HCI LE Set Decision Data (OCF 0x0080), Core 6.0 Vol 4 Part E 7.8.144 */
|
||||
#define BLE_HCI_OCF_LE_SET_DECISION_DATA (0x0080)
|
||||
#define BLE_HCI_DECISION_DATA_MAX_LEN (8)
|
||||
#define BLE_HCI_DECISION_TYPE_RESOLVABLE_TAG (0x01)
|
||||
struct ble_hci_le_set_decision_data_cp {
|
||||
uint8_t adv_handle;
|
||||
uint8_t decision_type_flags;
|
||||
uint8_t decision_data_len;
|
||||
uint8_t decision_data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* HCI LE Set Decision Instructions (OCF 0x0081), Core 6.0 Vol 4 Part E 7.8.145 */
|
||||
#define BLE_HCI_OCF_LE_SET_DECISION_INSTRUCTIONS (0x0081)
|
||||
#define BLE_HCI_DECISION_MAX_TESTS (8)
|
||||
#define BLE_HCI_DECISION_TEST_PARAM_LEN (16)
|
||||
#define BLE_HCI_DECISION_TEST_FLAGS_NEW_GROUP (0x01)
|
||||
#define BLE_HCI_DECISION_TEST_FLAGS_PASS_IF_OK (0x02)
|
||||
#define BLE_HCI_DECISION_TEST_FLAGS_PASS_IF_FAIL (0x04)
|
||||
#define BLE_HCI_DECISION_TEST_FLAGS_PASS_IF_ABSENT (0x08)
|
||||
#define BLE_HCI_DECISION_TEST_FIELD_RESOLVABLE_TAG (0)
|
||||
#define BLE_HCI_DECISION_TEST_FIELD_ADV_MODE (6)
|
||||
#define BLE_HCI_DECISION_TEST_FIELD_RSSI (7)
|
||||
#define BLE_HCI_DECISION_TEST_FIELD_PATH_LOSS (8)
|
||||
#define BLE_HCI_DECISION_TEST_FIELD_ADVA (9)
|
||||
struct ble_hci_le_decision_test {
|
||||
uint8_t test_flags;
|
||||
uint8_t test_field;
|
||||
uint8_t test_params[BLE_HCI_DECISION_TEST_PARAM_LEN];
|
||||
} __attribute__((packed));
|
||||
struct ble_hci_le_set_decision_instructions_cp {
|
||||
uint8_t num_tests;
|
||||
struct ble_hci_le_decision_test tests[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_SUBEV_DATA (0x0082)
|
||||
struct periodic_adv_subevents {
|
||||
uint8_t subevent;
|
||||
@@ -1816,6 +1850,11 @@ struct ble_hci_vs_set_event_mask_cp {
|
||||
#define BLE_HCI_SCAN_FILT_NO_WL_INITA (2)
|
||||
#define BLE_HCI_SCAN_FILT_USE_WL_INITA (3)
|
||||
#define BLE_HCI_SCAN_FILT_MAX (3)
|
||||
/* Scanning_Filter_Policy bits 2-3 (Core 6.0 DBAF). Combine with bits 0-1. */
|
||||
#define BLE_HCI_SCAN_FILT_DECISION_NONE (0x00)
|
||||
#define BLE_HCI_SCAN_FILT_DECISION_ALL (0x04)
|
||||
#define BLE_HCI_SCAN_FILT_DECISION_ONLY (0x0C)
|
||||
#define BLE_HCI_SCAN_FILT_DECISION_MASK (0x0C)
|
||||
|
||||
/* Whitelist commands */
|
||||
#define BLE_HCI_ADD_WHITE_LIST_LEN (7)
|
||||
@@ -1826,7 +1865,10 @@ struct ble_hci_vs_set_event_mask_cp {
|
||||
#define BLE_HCI_CONN_ITVL (1250) /* usecs */
|
||||
#define BLE_HCI_CONN_FILT_NO_WL (0)
|
||||
#define BLE_HCI_CONN_FILT_USE_WL (1)
|
||||
#define BLE_HCI_CONN_FILT_MAX (1)
|
||||
#define BLE_HCI_CONN_FILT_DECISION_ONLY (2)
|
||||
#define BLE_HCI_CONN_FILT_FAL_ALL_PDUS (3)
|
||||
#define BLE_HCI_CONN_FILT_DECISION_AND_FAL (4)
|
||||
#define BLE_HCI_CONN_FILT_MAX (4)
|
||||
/* Bluetooth Core Spec minimum connection interval (7.5 ms in 1.25 ms units). */
|
||||
#define BLE_HCI_CONN_ITVL_MIN (0x0006)
|
||||
/* Host-side validation floor for connection interval (1.25 ms units). When
|
||||
@@ -1911,7 +1953,15 @@ struct ble_hci_vs_set_event_mask_cp {
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY (0x0010)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV (0x0020)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR (0x0040)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_USE_DECISION (0x0080)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_DEC_INCL_ADVA (0x0100)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_DEC_INCL_ADI (0x0200)
|
||||
/* Properties understood by controllers without DBAF support.
|
||||
* NimBLE LL rejects anything outside this mask (ble_ll_adv.c).
|
||||
*/
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_MASK (0x7F)
|
||||
/* Full Core 6.0 property mask including decision-PDU bits (host-side DBAF). */
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_MASK_DBAF (0x03FF)
|
||||
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND (0x0013)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_LD_DIR (0x0015)
|
||||
|
||||
Reference in New Issue
Block a user