This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Filter on custom manufacturer data with BLE on Zephhyr/NCS

Hello!

I'm working on a project communicationg using two BLE devices (central and peripheral).  On the central side we want to scan and connect to a peripheral that advertises a certain manufacturer data, but I struggle to configure the scan filter on the central side correctly.  I'm using NCS version v1.5.0 on central and peripheral.

I have verified using nRF Connect that our Beacon (peripheral) advertise the manufacturer data we are looking for:



On the central side I have the following scan_init fuction:

static void scan_init(void) {
  int err;

  struct bt_scan_init_param scan_init = {
      .connect_if_match = 1,
      .scan_param = NULL,
      .conn_param = BT_LE_CONN_PARAM_DEFAULT};


  struct bt_scan_manufacturer_data manufacturer_data = {
        .data =  (uint8_t *){0x00, 0x01, 0x02, 0x03},
        .data_len = (uint8_t) 4};

  bt_scan_init(&scan_init);
  bt_scan_cb_register(&scan_cb);

  err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_MANUFACTURER_DATA, &manufacturer_data);
  if (err) {
    printk("Scanning filters cannot be set (err %d)\n", err);
    return;
  }

  err = bt_scan_filter_enable(BT_SCAN_MANUFACTURER_DATA_FILTER, false);
  if (err) {
    printk("Filters cannot be turned on (err %d)\n", err);
  }
}


Is this looking correct? Should the BT_DATA_MANUFACTURER_DATA flag (0xFF) be inclueded in the .data array above?

I have the following prj.conf:

#Bluetooth
CONFIG_BT=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_SMP=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GATT_DM=y
CONFIG_HEAP_MEM_POOL_SIZE=2048

#Custom central scanning
CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_MANUFACTURER_DATA_CNT=1
CONFIG_BT_PRIVACY=y

#Flash settings for storage of security keys
CONFIG_BT_SETTINGS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y


I have the following advertising array on the peripheral side:
#define BT_CUSTOM_DATA 0xfe  // containing custom data

static const struct bt_data ad[] = {
    BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    BT_DATA_BYTES(BT_DATA_MANUFACTURER_DATA, 0x00, 0x01, 0x02, 0x03)
    BT_DATA_BYTES(BT_CUSTOM_DATA, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x01, 0x02),
};


In a different test, I was able to find the peripheral filtering on a custom UUID, but we want to avoid broadcasting this, since it take up a lot of  bytes in a standard BLE advertising frame. Not sure why the manufacturer data filter doesn't  work.

Looking forward to your response.

Parents Reply Children
  • Hi Hakon, colleague of Daniel here, working on the same project.

    When we're filtering based on UUID we successfully enter the scan_filter_match callback on the Central and succeed to initiate a connection. However, when we are trying to filter based on Manufacturer Data (with the settings and code provided above), we simply never witness any device and thus never enter any of the scan callbacks. After scanning is initialized, nothing happens. 

    Looking forward to your response!

    Best regards,

    Jonas Lien

Related