Bluetooth hci_usb Sample Cannot Receive Extended Advertisement With Packet Size > 31 Bytes

Hello, we are trying to receive BLE extended advertisement pakcets from Thingy53 using a nRF52840DK as a HCI controller with a Raspberry Pi 5. I am using a nrf52840dk as a scanner using the zephyr sample hci_usb. Below is my prj.conf

CONFIG_BT=y
CONFIG_BT_HCI_RAW=y
CONFIG_BT_HCI=y
CONFIG_BT_LL_SOFTDEVICE=n
CONFIG_BT_LL_SW_SPLIT=y
CONFIG_BT_EXT_ADV=y
CONFIG_BT_OBSERVER=y
CONFIG_BT_CENTRAL=y

CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_PHY_CODED=y
CONFIG_BT_CTLR_PHY_2M=y

CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PID=0x000B
CONFIG_USB_DEVICE_BLUETOOTH=y
CONFIG_USB_DEVICE_BLUETOOTH_VS_H4=n
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n

# We dont want any console or CDC ACM that may cause BlueZ to not detect hci_usb
CONFIG_SERIAL=n
CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=n

# Workaround: Unable to allocate command buffer when using K_NO_WAIT since
# Host number of completed commands does not follow normal flow control.
CONFIG_BT_BUF_CMD_TX_COUNT=10
This code can be built and flashed successfully to the DK. 

We then use a nrf5340DK as a advertiser running the sample zephyr/samples/bluetooth/extended_adv/advertiser with minor modifications on the advertising data as shown below

/**
 * Copyright (c) 2024 Croxel, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gap.h>

static struct bt_conn *default_conn;

enum bt_sample_adv_evt {
	BT_SAMPLE_EVT_CONNECTED,
	BT_SAMPLE_EVT_DISCONNECTED,
	BT_SAMPLE_EVT_MAX,
};

enum bt_sample_adv_st {
	BT_SAMPLE_ST_ADV,
	BT_SAMPLE_ST_CONNECTED,
};

static ATOMIC_DEFINE(evt_bitmask, BT_SAMPLE_EVT_MAX);

static volatile enum bt_sample_adv_st app_st = BT_SAMPLE_ST_ADV;

static struct k_poll_signal poll_sig = K_POLL_SIGNAL_INITIALIZER(poll_sig);
static struct k_poll_event poll_evt = K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
						K_POLL_MODE_NOTIFY_ONLY, &poll_sig);

static void raise_evt(enum bt_sample_adv_evt evt)
{
	(void)atomic_set_bit(evt_bitmask, evt);
	k_poll_signal_raise(poll_evt.signal, 1);
}

static void connected_cb(struct bt_conn *conn, uint8_t err)
{
	printk("Connected (err 0x%02X)\n", err);

	if (err) {
		return;
	}

	__ASSERT(!default_conn, "Attempting to override existing connection object!");
	default_conn = bt_conn_ref(conn);

	raise_evt(BT_SAMPLE_EVT_CONNECTED);
}

static void disconnected_cb(struct bt_conn *conn, uint8_t reason)
{
	printk("Disconnected (reason 0x%02X)\n", reason);

	__ASSERT(conn == default_conn, "Unexpected disconnected callback");

	bt_conn_unref(default_conn);
	default_conn = NULL;
}

static void recycled_cb(void)
{
	printk("Connection object available from previous conn. Disconnect is complete!\n");
	raise_evt(BT_SAMPLE_EVT_DISCONNECTED);
}

BT_CONN_CB_DEFINE(conn_cb) = {
	.connected = connected_cb,
	.disconnected = disconnected_cb,
	.recycled = recycled_cb,
};

static int start_advertising(struct bt_le_ext_adv *adv)
{
	int err;

	printk("Starting Extended Advertising\n");
	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 err;
}

static uint8_t custom_data[15] = {0};

static const struct bt_data ad[] = {
	BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
	BT_DATA(BT_DATA_MANUFACTURER_DATA, custom_data, sizeof(custom_data))
};

int main(void)
{
	int err;
	struct bt_le_ext_adv *adv;

	printk("Starting Extended Advertising Demo\n");

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

	struct bt_le_adv_param param_ext_adv = {
		.secondary_max_skip = 0,
		.options = (BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_USE_IDENTITY | BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_NO_2M),
		.interval_min = 32,
		.interval_max = 33,
		.peer = NULL, 
	};

	/* Create a non-connectable non-scannable advertising set */
	err = bt_le_ext_adv_create(&param_ext_adv, NULL, &adv);
	if (err) {
		printk("Failed to create advertising set (err %d)\n", err);
		return err;
	}

	/* Set advertising data to have complete local name set */
	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;
	}

	err = start_advertising(adv);
	if (err) {
		return err;
	}

	while (true) {
		k_poll(&poll_evt, 1, K_FOREVER);

		k_poll_signal_reset(poll_evt.signal);
		poll_evt.state = K_POLL_STATE_NOT_READY;

		/* Identify event and act upon if applicable */
		if (atomic_test_and_clear_bit(evt_bitmask, BT_SAMPLE_EVT_CONNECTED) &&
		    app_st == BT_SAMPLE_ST_ADV) {

			printk("Connected state!\n");
			app_st = BT_SAMPLE_ST_CONNECTED;

			printk("Initiating disconnect within 5 seconds...\n");
			k_sleep(K_SECONDS(5));

			bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);

		} else if (atomic_test_and_clear_bit(evt_bitmask, BT_SAMPLE_EVT_DISCONNECTED) &&
			   app_st == BT_SAMPLE_ST_CONNECTED) {

			printk("Disconnected state! Restarting advertising\n");
			app_st = BT_SAMPLE_ST_ADV;
			err = start_advertising(adv);
			if (err) {
				return err;
			}
		}
	}

	return err;
}
We simply created our own advertising parameter to disable 2M PHY and increase the advertisement data with dummy 0s. The communication is working fine with the size of custom_data being smaller than 15, resulting to a packet size <= 31 (legacy adv packet limit). But as soon as we change the size to be bigger than 15, the scanner side cannot pick up anything. This is strange as the maximum packet size supported by ext adv should be 256 bytes if I remember. Below I also attach the btmon report if the size of that array is 15:
> HCI Event: LE Meta Event (0x3e) plen 57                        #467 14.708869
      LE Extended Advertising Report (0x0d)
        Num reports: 1
        Entry 0
          Event type: 0x0001
            Props: 0x0001
              Connectable
            Data status: Complete
          Address type: Random (0x01)
          Address: FC:49:49:27:11:81 (Static)
          Primary PHY: LE 1M
          Secondary PHY: LE 2M
          SID: 0x00
          TX power: 127 dBm
          RSSI: -62 dBm (0xc2)
          Periodic advertising interval: 0.00 msec (0x0000)
          Direct address type: Public (0x00)
          Direct address: 00:00:00:00:00:00 (OUI 00-00-00)
          Data length: 0x1f
        0d 09 74 65 73 74 5f 65 78 74 5f 61 64 76 10 ff  ..test_ext_adv..
        00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ............... 
        Name (complete): test_ext_adv
        Company: Ericsson Technology Licensing (0)
          Data[13]: 00000000000000000000000000
@ MGMT Event: Device Found (0x0012) plen 45                  {0x0001} 14.708889
        LE Address: FC:49:49:27:11:81 (Static)
        RSSI: -62 dBm (0xc2)
        Flags: 0x00000000
        Data length: 31
        Name (complete): test_ext_adv
        Company: Ericsson Technology Licensing (0)
          Data[13]: 00000000000000000000000000
This clearly shows the event is a ext. advertisement, which suggests the basic function of ext. adv. is working. Can anyone suggest any debugging process or potential issues?

Parents
  • After enabling 

    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
    I am able to receive all messages

Reply
  • After enabling 

    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
    I am able to receive all messages

Children
No Data
Related