[Bluetooth] filter name

Hello,

I am programming BLE with the nRF52840-DK. [Toolchain Manager: v1.3.0, IDE: Visual Studio Code (VSCode), SDK: ncs v2.6.0 ]


I am trying to use the device name as a filter type.

However, even though DEVICE_NAME(peripheral: "SEONG") and FILTER(central: "SEONGMIN") are not exactly the same, they still get connected.Conversely, DEVICE_NAME(peripheral: "SEONG12") and FILTER(central: "SEONGMIN") do not connect. I am curious to know the reason behind this.

Additionally, I would like to understand the difference between 'BT_SCAN_FILTER_TYPE_NAME' and 'BT_SCAN_FILTER_TYPE_SHORT_NAME'.



prj.conf

#
# Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Enable the UART driver
CONFIG_UART_ASYNC_API=y
CONFIG_NRFX_UARTE0=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

# Enable the BLE stack with GATT Client configuration
CONFIG_BT=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_SMP=y
CONFIG_BT_GATT_CLIENT=y

# Enable the BLE modules from NCS
CONFIG_BT_NUS_CLIENT=y
CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1
CONFIG_BT_GATT_DM=y
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_BT_SCAN_NAME_CNT=5
CONFIG_BT_SCAN_NAME_MAX_LEN=20


# This example requires more stack
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_MAIN_STACK_SIZE=1536

# Enable bonding
CONFIG_BT_SETTINGS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y

# Config logger
CONFIG_LOG=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n
CONFIG_LOG_PRINTK=n

CONFIG_ASSERT=y

central code

int err;
	struct bt_le_scan_param scan_param = { 
		.type = 0x01, //  1: active,  0: passive
 		.options = BT_LE_SCAN_OPT_FILTER_DUPLICATE,
		.interval = 0x0010, // 10ms
		.window = 0x0010, // 10ms
	};
	struct bt_scan_init_param scan_init = {
		.connect_if_match = 1,		
		.scan_param = &scan_param,    
		.conn_param = conn_param  
	};

	bt_scan_init(&scan_init);
	bt_scan_cb_register(&scan_cb);
 
	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, "SEONGMIN"); //scan.c scan.h, nus.h
	if (err) {
		LOG_ERR("Scanning filters cannot be set (err %d)", err);
		return err;
	}

	err = bt_scan_filter_enable(BT_SCAN_NAME_FILTER, false); //scan.c scan.h
	if (err) {
		LOG_ERR("Filters cannot be turned on (err %d)", err);
		return err;
	}

peripheral code

#include <zephyr/bluetooth/conn.h>
#include <zephyr/sys/printk.h>
#include <zephyr/kernel.h>
#include <zephyr/settings/settings.h>
#include <zephyr/logging/log.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <bluetooth/services/nus.h>
#define LOG_MODULE_NAME cho
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#define DEVICE_NAME "SEONG"
//#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN	(sizeof(DEVICE_NAME) - 1)

static struct bt_conn *auth_conn;
static K_SEM_DEFINE(ble_init_ok, 0, 1);
static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};
static const struct bt_data sd[] = {
	BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_NUS_VAL),
};

static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey){
	char addr[BT_ADDR_LE_STR_LEN];
	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	printk("Passkey for %s: %06u", addr, passkey);
}

static void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey){
	char addr[BT_ADDR_LE_STR_LEN];
	auth_conn = bt_conn_ref(conn);
	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	printk("Passkey for %s: %06u", addr, passkey);
	printk("Press Button 1 to confirm, Button 2 to reject.");
}

static void auth_cancel(struct bt_conn *conn){
	char addr[BT_ADDR_LE_STR_LEN];
	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	printk("Pairing cancelled: %s", addr);
}

static struct bt_conn_auth_cb conn_auth_callbacks = {
	.passkey_display = auth_passkey_display,
	.passkey_confirm = auth_passkey_confirm,
	.cancel = auth_cancel,
};

static void pairing_complete(struct bt_conn *conn, bool bonded){
	char addr[BT_ADDR_LE_STR_LEN];
	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	printk("Pairing completed: %s, bonded: %d", addr, bonded);
}

static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason){
	char addr[BT_ADDR_LE_STR_LEN];
	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	printk("Pairing failed conn: %s, reason %d", addr, reason);
}

static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
	.pairing_complete = pairing_complete,
	.pairing_failed = pairing_failed
};

int main(void){
	int err;
	printk("cho >> 240628_advv_peripheral\n");

	err = bt_conn_auth_cb_register(&conn_auth_callbacks);  //success: 0
	printk("bt_conn_auth_cb_register: %d\n",err);

	err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks); //success: 0
	printk("bt_conn_auth_info_cb_register: %d\n",err);

	err = bt_enable(NULL);
	printk("bt_enable\n");
	k_sem_give(&ble_init_ok);
	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();
	}
	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
	printk("bt_le_adv_start: %d\n",err);

}


Parents
  • Hi,

    Filtering is based on the contents of the advertisements. For long device names, typically a shortened name is used. This can be either a predefined name, or is done automatically by shortening the full device name by removing characters from the end.

    What might happen in this instance, is if the full name is SEONGMIN, it may, depending on the size available in the advertising package, be shortened to for instance "SEONG" as a short name for the advertising.

    You can for instance use the nRF Connect for Desktop BLE app, or one of the nRF Connect for smartphone apps, to investigate what contents (including name) appears in the advertising packet for the peripheral device.

    Regards,
    Terje

  • can you explain the exact difference between the 'short name'(BT_SCAN_FILTER_TYPE_SHORT_NAME) and the 'name'(BT_SCAN_FILTER_TYPE_NAME) in filter type?

  • Hi,

    The (full) name (BT_SCAN_FILTER_TYPE_NAME) sets up a filter scanning for full name advertisements.

    This means for instance if the name of the device you are looking for is "MyDevice" and the full name fits in the advertising packet, a filter on "MyDevice" as full name will match the device. If however the device does not have enough space in the advertisement to advertise the full name, and instead it advertises only a short name, then you will not get a match.

    The short name (BT_SCAN_FILTER_TYPE_SHORT_NAME) sets up a filter scanning for short name advertisements.

    This means for instance if the name of the device you are looking for is "MyDevice" and it is advertised as "MyDev" due to that being the available space for advertising a short name in the advertising packet, and the minimum setting for short name length is 5 or higher, then you will get a match.

    Continuing hte same example, if on the other hand you find a device with short name of "MyDevv", you will not get a match, since the beginning of the short name does not match perfectly with what was registered as the device name you were looking for. Likewise, you will not get a match which is too short.

    Regards,
    Terje

  • Hi,

    I also had a similar problem as explained here.
    I am referring to this: However, even though DEVICE_NAME(peripheral: "SEONG") and FILTER(central: "SEONGMIN") are not exactly the same, they still get connected.

    The same thing happens to me. I am using BT_SCAN_FILTER_TYPE_NAME and expecting that the peripheral device will connect only if the full name is matched with the filter.

    However, I have a case where the filter on the central device is set to "PRI", but it will connect to the device that is advertising only "P", so DEVICE_NAME(peripheral: "P") and FILTER(central: "PRI") connect. Why is the behavior like this, and is there a way to avoid it?

    The configuration is similar to the one pasted above, with difference in the two configs:

    CONFIG_BT_SCAN_UUID_CNT=0
    CONFIG_BT_SCAN_NAME_CNT=1

    BR,

    Mihaela

Reply
  • Hi,

    I also had a similar problem as explained here.
    I am referring to this: However, even though DEVICE_NAME(peripheral: "SEONG") and FILTER(central: "SEONGMIN") are not exactly the same, they still get connected.

    The same thing happens to me. I am using BT_SCAN_FILTER_TYPE_NAME and expecting that the peripheral device will connect only if the full name is matched with the filter.

    However, I have a case where the filter on the central device is set to "PRI", but it will connect to the device that is advertising only "P", so DEVICE_NAME(peripheral: "P") and FILTER(central: "PRI") connect. Why is the behavior like this, and is there a way to avoid it?

    The configuration is similar to the one pasted above, with difference in the two configs:

    CONFIG_BT_SCAN_UUID_CNT=0
    CONFIG_BT_SCAN_NAME_CNT=1

    BR,

    Mihaela

Children
Related