nRF52840DK bt_le scanning with duplicated filter does not work.

Hi everyone,

I am currently working on a BLE scanner application that will scan for surrounding tag beacons for 5 seconds every time (the beacons interval is 1 second)

I am using nRF Connect SDK v2.3.0 

Below are my thread file and config file (all the Zephyr BT libraries were included in the ble header file:

#ifndef _BLE_SCANNER_H_
#define _BLE_SCANNER_H_

#include <stdio.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/controller.h>

#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>
#include <zephyr/types.h>

// Max legnth of advertising payload as defined by the BLE advertising standard
#define MAX_MANUF_DATA_PAYLOAD_LENGTH 26

/** @brief Function that enable the ble API.
 */
void ble_enable(void);

/** @brief Function that disable the ble API.
 */
void ble_disable(void);

/** @brief Function that starts the ble scanner module.
 * @param[in] scan_duration_s   The duration of scanning in seconds. If set to 0, the device will scan indefinitely.
 */
void ble_scan_start(struct bt_le_scan_param scan_param, uint32_t scan_duration_s, bt_le_scan_cb_t cb);

#endif // _BLE_SCANNER_H_

#ifndef _BEACONS_HANDLE_H_
#define _BEACONS_HANDLE_H_

#include "../BLE/ble_scanner.h"

#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>
#include <zephyr/types.h>

#include <sdc.h>

#include <stdio.h>

#define DEFAULT_BEACON_DATA_LENGTH 40
#define BEACON_STACKSIZE       1024
#define BEACON_THREAD_PRIORITY 3

/** @brief BLE Door sensor struct
 */
typedef struct bt_le_beacon_ {
    bt_addr_le_t beacon_addr; // Door sensor address in bt_le_addr format
    uint8_t beacon_data_buf[DEFAULT_BEACON_DATA_LENGTH];   // Pointer to the buffer of the door sensor data
    int8_t beacon_rssi;            // Pointer to door_sensor RSSI
    uint8_t beacon_adv_type;            // pointer to door adv_type
} ble_beacon;

/** @brief Function that configure the ble beacon in the BLE Stack
 * @param[in] beacon_uuid   Tag beacon UUID [2 bytes]
 * @return 0 on success or negative value otherwise
 */
static int16_t config_ble_beacons(uint16_t beacon_uuid);

/** @brief Function that handle the ble door sensor data after done call back
 * @return none
 */
void ble_beacons_handle_thread(void);

#endif // _DOOR_SENSOR_HANDLE_H_

#include "beacons_handle.h"

#include <stdio.h>
#include <string.h>

int beacon_err;                   // Tag beacon error code
uint16_t beacon_callback_counter; // Counter for every success beacon callback
uint8_t total_callback_counter;   // Counter for every scanned devices
uint8_t beacon_callback_flag = 0; // 1 when done callback
static bt_addr_le_t prev_addr;    // Manually keep track on the addr has been found

ble_beacon tag_beacon;
LOG_MODULE_REGISTER(tag_beacon, LOG_LEVEL_DBG);

static struct bt_uuid_16 uuid_whitelist = BT_UUID_INIT_16(0xABFE); // beacon UUID

struct bt_le_scan_param tag_beacon_scan_param = {
    .type = BT_HCI_LE_SCAN_PASSIVE, .options = BT_LE_SCAN_OPT_FILTER_DUPLICATE, .interval = 0x0010, .window = 0x0010, .timeout = 0
};


/** @brief Callback invoked when there is a new BLE scan result available. */
void scan_beacon_cb(const bt_addr_le_t* addr, int8_t rssi, uint8_t adv_type, struct net_buf_simple* buf)
{
    // LOG_INF("\033[96mScanned %d devices!\033[1m\n", ++beacon_callback_counter);
    total_callback_counter++;
    char addr_str[BT_ADDR_LE_STR_LEN];
    bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
    uint16_t uuid_received = (buf->data[8] << 8 | buf->data[9]);
    if (uuid_received != uuid_whitelist.val) {
        // LOG_WRN("Invalid UUID: 0x%04x\n", uuid_received);
        return;
    }
    beacon_callback_counter++;
    LOG_INF("Device found: \033[92m%s\033[0m\tUUID: 0x%04x\tRSSI: %d\n", addr_str, uuid_received, rssi);
    // ble_disable();
}

void ble_beacon_handle_thread(void)
{
    ble_enable();

    ble_scan_start(tag_beacon_scan_param, 4, scan_beacon_cb);
    LOG_INF("Total %d MOKO beacons scanned", beacon_callback_counter);
    LOG_INF("Total %d devices scanned\n", total_callback_counter);

    while (1) {
        k_msleep(10 * 1000);
    }
}

K_THREAD_DEFINE(ble_beacon_ID, BEACON_STACKSIZE, ble_beacon_handle_thread, NULL, NULL, NULL, BEACON_THREAD_PRIORITY, 0, 0);

Config file:

# BLUETOOTH
CONFIG_BT=y
CONFIG_BT_OBSERVER=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_FILTER_ACCEPT_LIST=y
CONFIG_BT_LL_SOFTDEVICE=y

CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1
CONFIG_BT_SCAN=y

CONFIG_BT_LL_SW_SPLIT=y

# SERIAL
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_BOOT_BANNER=y
CONFIG_NEWLIB_LIBC_NANO=n
CONFIG_MINIMAL_LIBC=n

# LOG
CONFIG_LOG=y
CONFIG_LOG_MODE_MINIMAL=n
CONFIG_LOG_MODE_DEFERRED=y
CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=1
CONFIG_LOG_PROCESS_THREAD=y
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=2048

# NEW LIB
CONFIG_NEWLIB_LIBC=y

# Stacks and heaps
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_HEAP_MEM_POOL_SIZE=2048

# PM MANAGER
CONFIG_PM_DEVICE=y

I assume this code will filter out the duplicated addresses. When it callbacks, I also filter out the UUDI another time to make sure I have the exact beacon value. However, as can be seen from the terminal, there are 3 beacons that were called back 3 times in 5 seconds, which means the duplicated filter did not work as I expected.

Please let me know if anything was wrong with my code or my setup or maybe another way to filter out duplicated addresses. Thank you. 

Related