Commit 40115f5d authored by Vinayak Kariappa Chettimada's avatar Vinayak Kariappa Chettimada Committed by Carles Cufi
Browse files

samples: Bluetooth: Add Extended Scanning support to Observer sample



Added implementation to Observer sample so that when
Extended Advertising feature is enabled, it can receive
Extended Advertising Reports, and hence receive long AD
data from peer Extended Advertising Broadcaster Multiple
sample.

Signed-off-by: default avatarVinayak Kariappa Chettimada <vich@nordicsemi.no>
parent 4fd7eb21
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
.. _bluetooth-observer-sample:

Bluetooth: Observer
###########################
###################

Overview
********

A simple application demonstrating Bluetooth Low Energy Observer role functionality
The application will periodically scan for devices nearby. If any found,
prints the address of the device and the RSSI value to the UART terminal.
A simple application demonstrating Bluetooth Low Energy Observer role
functionality. The application will periodically scan for devices nearby.
If any found, prints the address of the device, the RSSI value, the Advertising
type, and the Advertising data length to the console.

If the used Bluetooth Low Energy Controller supports Extended Scanning, you may
enable `CONFIG_BT_EXT_ADV` in the project configuration file. Refer to the
project configuration file for further details.

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

* BlueZ running on the host, or
* A board with BLE support
* A board with Bluetooth Low Energy support

Building and Running
********************
@@ -22,4 +26,4 @@ Building and Running
This sample can be found under :zephyr_file:`samples/bluetooth/observer` in the
Zephyr tree.

See :ref:`bluetooth samples section <bluetooth-samples>` for details.
See :ref:`Bluetooth samples section <bluetooth-samples>` for details.
+17 −0
Original line number Diff line number Diff line
CONFIG_BT=y
CONFIG_BT_OBSERVER=y

# Enable Extended Scanning
CONFIG_BT_EXT_ADV=y
CONFIG_BT_EXT_SCAN_BUF_SIZE=1650

# Zephyr Bluetooth LE Controller needs 16 event buffers to generate Extended
# Advertising Report for receiving the complete 1650 bytes of data
CONFIG_BT_BUF_EVT_RX_COUNT=16

# Set maximum scan data length for Extended Scanning in Bluetooth LE Controller
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650

# Increase Zephyr Bluetooth LE Controller Rx buffer to receive complete chain
# of PDUs
CONFIG_BT_CTLR_RX_BUFFERS=9
+6 −1
Original line number Diff line number Diff line
@@ -3,5 +3,10 @@ sample:
tests:
  sample.bluetooth.observer:
    harness: bluetooth
    platform_allow: qemu_cortex_m3 qemu_x86
    platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840
    tags: bluetooth
  sample.bluetooth.observer.extended:
    harness: bluetooth
    extra_args: CONF_FILE="prj_extended.conf"
    platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840
    tags: bluetooth
+76 −4
Original line number Diff line number Diff line
@@ -14,15 +14,83 @@
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>

#define NAME_LEN 30

static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
			 struct net_buf_simple *ad)
{
	char addr_str[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
	printk("Device found: %s (RSSI %d)\n", addr_str, rssi);
	printk("Device found: %s (RSSI %d), type %u, AD data len %u\n",
	       addr_str, rssi, type, ad->len);
}

#if defined(CONFIG_BT_EXT_ADV)
static bool data_cb(struct bt_data *data, void *user_data)
{
	char *name = user_data;
	uint8_t len;

	switch (data->type) {
	case BT_DATA_NAME_SHORTENED:
	case BT_DATA_NAME_COMPLETE:
		len = MIN(data->data_len, NAME_LEN - 1);
		(void)memcpy(name, data->data, len);
		name[len] = '\0';
		return false;
	default:
		return true;
	}
}

static const char *phy2str(uint8_t phy)
{
	switch (phy) {
	case BT_GAP_LE_PHY_NONE: return "No packets";
	case BT_GAP_LE_PHY_1M: return "LE 1M";
	case BT_GAP_LE_PHY_2M: return "LE 2M";
	case BT_GAP_LE_PHY_CODED: return "LE Coded";
	default: return "Unknown";
	}
}

static void scan_recv(const struct bt_le_scan_recv_info *info,
		      struct net_buf_simple *buf)
{
	char le_addr[BT_ADDR_LE_STR_LEN];
	char name[NAME_LEN];
	uint8_t data_status;
	uint16_t data_len;

	(void)memset(name, 0, sizeof(name));

	data_len = buf->len;
	bt_data_parse(buf, data_cb, name);

	data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS(info->adv_props);

	bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
	printk("[DEVICE]: %s, AD evt type %u, Tx Pwr: %i, RSSI %i "
	       "Data status: %u, AD data len: %u Name: %s "
	       "C:%u S:%u D:%u SR:%u E:%u Pri PHY: %s, Sec PHY: %s, "
	       "Interval: 0x%04x (%u ms), SID: %u\n",
	       le_addr, info->adv_type, info->tx_power, info->rssi,
	       data_status, data_len, name,
	       (info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) != 0,
	       (info->adv_props & BT_GAP_ADV_PROP_SCANNABLE) != 0,
	       (info->adv_props & BT_GAP_ADV_PROP_DIRECTED) != 0,
	       (info->adv_props & BT_GAP_ADV_PROP_SCAN_RESPONSE) != 0,
	       (info->adv_props & BT_GAP_ADV_PROP_EXT_ADV) != 0,
	       phy2str(info->primary_phy), phy2str(info->secondary_phy),
	       info->interval, info->interval * 5 / 4, info->sid);
}

static struct bt_le_scan_cb scan_callbacks = {
	.recv = scan_recv,
};
#endif /* CONFIG_BT_EXT_ADV */

void main(void)
{
	struct bt_le_scan_param scan_param = {
@@ -41,13 +109,17 @@ void main(void)
		printk("Bluetooth init failed (err %d)\n", err);
		return;
	}

	printk("Bluetooth initialized\n");

#if defined(CONFIG_BT_EXT_ADV)
	bt_le_scan_cb_register(&scan_callbacks);
	printk("Registered scan callbacks\n");
#endif /* CONFIG_BT_EXT_ADV */

	err = bt_le_scan_start(&scan_param, device_found);
	printk("\n");
	if (err) {
		printk("Starting scanning failed (err %d)\n", err);
		printk("Start scanning failed (err %d)\n", err);
		return;
	}
	printk("Scanning started, exiting %s thread.\n", __func__);
}