Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3b0389d
Initial plan
Copilot Feb 1, 2026
5e829dd
Add Decision-Based Advertising Filtering infrastructure
Copilot Feb 1, 2026
e8e6bac
Add Decision PDU scanning logic
Copilot Feb 1, 2026
0e4a896
Fix ADV_DECISION_IND length validation in OpenISA
Copilot Feb 1, 2026
cd28fea
Add Decision-Based Filtering support for OpenISA LLL
Copilot Feb 1, 2026
fe7bfcd
Add HCI and ULL layer support for Decision-Based Filtering
Copilot Feb 1, 2026
41006b0
Add HCI event reporting for ADV_DECISION_IND
Copilot Feb 1, 2026
afd4205
Improve documentation for PDU-to-HCI event type mapping
Copilot Feb 1, 2026
f3c7992
Fix comment: clarify decision_ind union member access
Copilot Feb 1, 2026
7c89c06
Add Host stack support for Decision-Based Filtering
Copilot Feb 1, 2026
2b77aed
Refactor filter policy logic to reduce duplication
Copilot Feb 1, 2026
40d7ccf
Add samples and tests for Decision-Based Filtering
Copilot Feb 1, 2026
2952b1e
Fix code review issues in samples and tests
Copilot Feb 1, 2026
3863cdf
Add advertising LLL support for ADV_DECISION_IND PDUs
Copilot Feb 2, 2026
bd8ed07
Remove #ifdef from HCI constants in public header
Copilot Feb 2, 2026
f2cbeb4
Refactor LLL advertising to use IS_ENABLED() macro
Copilot Feb 2, 2026
20a25f7
Add HCI commands and Host API for Decision Data/Instructions
Copilot Feb 2, 2026
831af07
Update samples and tests to use decision data/instructions APIs
Copilot Feb 2, 2026
ca0e1b6
Add Controller HCI command handlers for decision data/instructions
Copilot Feb 2, 2026
78b9aab
Remove conditional compilation from public API header
Copilot Feb 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions include/zephyr/bluetooth/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,28 @@ int bt_le_ext_adv_set_data(struct bt_le_ext_adv *adv,
const struct bt_data *ad, size_t ad_len,
const struct bt_data *sd, size_t sd_len);

/**
* @brief Set decision data for extended advertising.
*
* Set decision data that will be used for decision-based advertising filtering
* as specified in Bluetooth Core Specification v6.2, Vol 4, Part E, Section 7.8.144.
* This data is used by observers with decision-based filtering instructions to
* determine whether to accept advertising PDUs from this advertiser.
*
* The decision data is associated with the advertising set and remains valid
* until the advertising set is deleted or new decision data is set.
*
* @param adv Advertising set object.
* @param data Decision data buffer.
* @param data_len Length of decision data (must be > 0).
*
* @return Zero on success or (negative) error code otherwise.
* @retval -EINVAL Invalid parameters.
* @retval -ENOTSUP Decision-based filtering not supported by controller.
*/
int bt_le_ext_adv_set_decision_data(struct bt_le_ext_adv *adv,
const uint8_t *data, uint8_t data_len);

/**
* @brief Update advertising parameters.
*
Expand Down Expand Up @@ -2350,6 +2372,34 @@ enum bt_le_scan_opt {
* @note Requires @ref BT_LE_SCAN_OPT_CODED.
*/
BT_LE_SCAN_OPT_NO_1M = BIT(3),

/**
* @brief Enable extended scan filtering.
*
* Enables extended scan filtering mode which provides enhanced
* filtering capabilities. Can be combined with
* @ref BT_LE_SCAN_OPT_FILTER_ACCEPT_LIST.
*
* @note Requires controller support for extended scan filtering.
*/
BT_LE_SCAN_OPT_EXTENDED_FILTER = BIT(4),

/**
* @brief Enable decision-based advertising filtering.
*
* Enables decision-based advertising filtering as specified in
* Bluetooth Core Specification v6.2. This allows the controller to
* filter advertising PDUs based on decision criteria. Can be combined
* with @ref BT_LE_SCAN_OPT_FILTER_ACCEPT_LIST and/or
* @ref BT_LE_SCAN_OPT_EXTENDED_FILTER.
*
* When this option is set, the controller will accept ADV_DECISION_IND
* PDUs according to the filter policy.
*
* @note Requires controller support for decision-based advertising
* filtering (CONFIG_BT_CTLR_DECISION_BASED_FILTERING).
*/
BT_LE_SCAN_OPT_DECISION_BASED = BIT(5),
};

enum bt_le_scan_type {
Expand Down Expand Up @@ -2620,6 +2670,28 @@ BUILD_ASSERT(BT_GAP_SCAN_FAST_WINDOW == BT_GAP_SCAN_FAST_INTERVAL_MIN,
*/
int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb);

/**
* @brief Set decision instructions for scanning.
*
* Set decision instructions that will be used to filter advertising PDUs during
* scanning as specified in Bluetooth Core Specification v6.2, Vol 4, Part E,
* Section 7.8.145. These instructions define the criteria for accepting advertising
* PDUs based on the decision data included in the advertisements.
*
* The instructions remain active until new instructions are set or scanning is stopped.
* This function should be called before starting scanning with decision-based filtering
* enabled (BT_LE_SCAN_OPT_DECISION_BASED).
*
* @param instructions Decision instructions buffer.
* @param instructions_len Length of decision instructions (must be > 0).
*
* @return Zero on success or (negative) error code otherwise.
* @retval -EINVAL Invalid parameters.
* @retval -ENOTSUP Decision-based filtering not supported by controller.
*/
int bt_le_scan_set_decision_instructions(const uint8_t *instructions,
uint8_t instructions_len);

/**
* @brief Stop (LE) scanning.
*
Expand Down
30 changes: 30 additions & 0 deletions include/zephyr/bluetooth/hci_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,11 @@ struct bt_hci_cp_le_set_adv_enable {
#define BT_HCI_LE_SCAN_FP_BASIC_FILTER 0x01
#define BT_HCI_LE_SCAN_FP_EXT_NO_FILTER 0x02
#define BT_HCI_LE_SCAN_FP_EXT_FILTER 0x03
/* Decision-Based Advertising Filtering (BT Core Spec v6.2) */
#define BT_HCI_LE_SCAN_FP_DECISION_NO_FILTER 0x04
#define BT_HCI_LE_SCAN_FP_DECISION_FILTER 0x05
#define BT_HCI_LE_SCAN_FP_DECISION_EXT_NO_FILTER 0x06
#define BT_HCI_LE_SCAN_FP_DECISION_EXT_FILTER 0x07

struct bt_hci_cp_le_set_scan_param {
uint8_t scan_type;
Expand Down Expand Up @@ -2991,6 +2996,31 @@ struct bt_hci_op_le_connection_rate_request {

#define BT_HCI_OP_LE_CONNECTION_RATE_REQUEST BT_OP(BT_OGF_LE, 0x00A1) /* 0x20A1 */

/* LE Set Decision Data command (BT Core Spec v6.2, Vol 4, Part E, Section 7.8.144) */
#define BT_HCI_OP_LE_SET_DECISION_DATA BT_OP(BT_OGF_LE, 0x00A3) /* 0x20A3 */

struct bt_hci_cp_le_set_decision_data {
uint8_t adv_handle;
uint8_t data_length;
uint8_t data[0];
} __packed;

struct bt_hci_rp_le_set_decision_data {
uint8_t status;
} __packed;

/* LE Set Decision Instructions command (BT Core Spec v6.2, Vol 4, Part E, Section 7.8.145) */
#define BT_HCI_OP_LE_SET_DECISION_INSTRUCTIONS BT_OP(BT_OGF_LE, 0x00A4) /* 0x20A4 */

struct bt_hci_cp_le_set_decision_instructions {
uint8_t instructions_length;
uint8_t instructions[0];
} __packed;

struct bt_hci_rp_le_set_decision_instructions {
uint8_t status;
} __packed;

/* Event definitions */

#define BT_HCI_EVT_UNKNOWN 0x00
Expand Down
8 changes: 8 additions & 0 deletions samples/bluetooth/broadcaster_decision/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(broadcaster_decision)

target_sources(app PRIVATE src/main.c)
54 changes: 54 additions & 0 deletions samples/bluetooth/broadcaster_decision/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.. _bluetooth_broadcaster_decision:

Bluetooth: Broadcaster with Decision-Based Advertising
#######################################################

Overview
********

This sample demonstrates extended advertising with decision-based advertising
filtering support as specified in Bluetooth Core Specification v6.2, section
4.6.43.

The application starts extended advertising and transmits advertising PDUs
that can be filtered using decision-based filtering on the scanner side.

Requirements
************

* A board with Bluetooth Low Energy support
* Controller support for decision-based advertising filtering
(CONFIG_BT_CTLR_DECISION_BASED_FILTERING)

Building and Running
********************

This sample can be found under
:zephyr_file:`samples/bluetooth/broadcaster_decision` in the Zephyr tree.

Build the sample with the following commands:

.. zephyr-app-commands::
:zephyr-app: samples/bluetooth/broadcaster_decision
:board: <board>
:goals: build flash
:compact:

To observe the advertising with decision-based filtering, run the
:ref:`bluetooth_observer_decision` sample on another device.

Sample Output
=============

When running, the sample will output:

.. code-block:: console

Starting Decision-Based Advertising Broadcaster
Bluetooth initialized
Extended advertising set created
Advertising data set
Extended advertising started
Advertising with decision-based filtering support
Device name: Decision Broadcaster
Manufacturer data: DECISION
8 changes: 8 additions & 0 deletions samples/bluetooth/broadcaster_decision/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CONFIG_BT=y
CONFIG_BT_BROADCASTER=y
CONFIG_BT_EXT_ADV=y
CONFIG_BT_DEVICE_NAME="Decision Broadcaster"
CONFIG_BT_CTLR_DECISION_BASED_FILTERING=y

CONFIG_ASSERT=y
CONFIG_LOG=y
17 changes: 17 additions & 0 deletions samples/bluetooth/broadcaster_decision/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
sample:
description: Bluetooth broadcaster with decision-based advertising filtering
name: Bluetooth broadcaster_decision
common:
tags: bluetooth
filter: dt_compat_enabled("zephyr,bt-hci")
harness: bluetooth
platform_allow:
- native_sim
- qemu_cortex_m3
- nrf52dk/nrf52832
- nrf52840dk/nrf52840
integration_platforms:
- native_sim
tests:
sample.bluetooth.broadcaster_decision:
build_only: true
116 changes: 116 additions & 0 deletions samples/bluetooth/broadcaster_decision/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @file
* @brief Decision-Based Advertising Broadcaster Sample
*
* This sample demonstrates extended advertising with decision-based
* advertising filtering support as specified in Bluetooth Core
* Specification v6.2.
*/

#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/gap.h>
#include <zephyr/bluetooth/hci.h>

#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)

/* Manufacturer ID for sample data */
#define COMPANY_ID 0x05F1 /* Nordic Semiconductor */

static uint8_t mfg_data[] = {
0xF1, 0x05, /* Company ID (little-endian) */
0x44, 0x45, 0x43, 0x49, 0x53, 0x49, 0x4F, 0x4E /* "DECISION" */
};

static const struct bt_data ad[] = {
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)),
};

int main(void)
{
struct bt_le_ext_adv *adv;
struct bt_le_adv_param adv_param = {
.id = BT_ID_DEFAULT,
.sid = 0,
.secondary_max_skip = 0,
.options = BT_LE_ADV_OPT_EXT_ADV,
.interval_min = BT_GAP_ADV_FAST_INT_MIN_2,
.interval_max = BT_GAP_ADV_FAST_INT_MAX_2,
.peer = NULL,
};
int err;

printk("Starting Decision-Based Advertising Broadcaster\n");

/* Initialize Bluetooth */
err = bt_enable(NULL);
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return 0;
}

printk("Bluetooth initialized\n");

/* Create extended advertising set */
err = bt_le_ext_adv_create(&adv_param, NULL, &adv);
if (err) {
printk("Failed to create advertising set (err %d)\n", err);
return 0;
}

printk("Extended advertising set created\n");

/* Set advertising data */
err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0);
if (err) {
printk("Failed to set advertising data (err %d)\n", err);
return 0;
}

printk("Advertising data set\n");

#if defined(CONFIG_BT_CTLR_DECISION_BASED_FILTERING)
/* Set decision data for decision-based filtering */
static const uint8_t decision_data[] = {
0x01, /* Device type: sensor */
0x02, /* Capability: temperature measurement */
0x05, /* Battery level indicator */
0xFF /* Custom application data */
};

err = bt_le_ext_adv_set_decision_data(adv, decision_data, sizeof(decision_data));
if (err) {
printk("Failed to set decision data (err %d)\n", err);
return 0;
}

printk("Decision data set (length: %d bytes)\n", sizeof(decision_data));
#endif /* CONFIG_BT_CTLR_DECISION_BASED_FILTERING */

/* Start extended advertising */
err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
if (err) {
printk("Failed to start extended advertising (err %d)\n", err);
return 0;
}

printk("Extended advertising started\n");
printk("Advertising with decision-based filtering support\n");
printk("Device name: %s\n", DEVICE_NAME);
printk("Manufacturer data: DECISION\n");

/* Keep advertising indefinitely */
while (1) {
k_sleep(K_SECONDS(1));
}

return 0;
}
8 changes: 8 additions & 0 deletions samples/bluetooth/observer_decision/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(observer_decision)

target_sources(app PRIVATE src/main.c)
Loading