Directed advertising - peer address

Hello everyone

I am using BLE Peripheral UART and Central UART samples to send data between two nrf5340 dev. kits.

I'm trying to set the directed advertising on the peripheral, so it accepts only connections request from my peer, but I can't find, in which format should i set the address of the central. I tried to change it this way in peripheral main, but it did not connect.

err = bt_le_adv_start(((struct bt_le_adv_param[]) { 
{ .id = BT_ID_DEFAULT, .sid = 0, .secondary_max_skip = 0, 
.options = (BT_LE_ADV_OPT_CONNECTABLE), .interval_min = (0x00a0), 
.interval_max = (0x00f0), .peer = {0xF0,0x33,0x4D,0x3A,0x9F,0x6B}, } }),
ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));

I am also a little bit confused of the Bluetooth LE Device Adress in addr.h library.

/** Bluetooth Device Address */
typedef struct {
	uint8_t  val[BT_ADDR_SIZE];
} bt_addr_t;
/**/

/** Length in bytes of an LE Bluetooth address. Not packed, so no sizeof() */
#define BT_ADDR_LE_SIZE 7
/** Bluetooth LE Device Address */
typedef struct {
	uint8_t      type;
	bt_addr_t a;
} bt_addr_le_t;

What does the variable type mean and in which way should I write the bt_addr_t?

Here is the log from J-Link RTT Viewer

00> [00:00:00.272,583] <inf> fs_nvs: 2 Sectors of 4096 bytes
00> [00:00:00.272,583] <inf> fs_nvs: alloc wra: 0, fc8
00> [00:00:00.272,583] <inf> fs_nvs: data wra: 0, 2c
00> [00:00:00.300,354] <inf> bt_hci_core: No ID address. App must call settings_load()
00> [00:00:00.300,354] <inf> peripheral_uart: Bluetooth initialized
00> [00:00:00.949,981] <inf> peripheral_uart: Connected F0:33:4D:3A:9F:6B (random)
00> [00:00:01.664,978] <wrn> peripheral_uart: Failed to send data over BLE connection

Could please somebody help me or give me any advice?

Sorry for maybe stupid questions, I am just beginner and did not find it anywhere.

Parents
  • Hi,

    Allright, I'll do my best to explain how to do this and as well supply some recommended resources for you to examine if desired. You may step away from the addr.h library and rather take a look at the scanning module for filtering.

    The central_uart sample is set up to connect one peripheral device with the Nordic UART Service (NUS) enabled. Here the central scans for a specific message with a filter that scans for the NUS Service UUID, at line 497. In the Peripheral device, the scan response data is set up with the NUS UUID that the Central device scans for. When the filter matches with a peripheral it connects. This uses the scanning module, which contains various filters that can be used, including a filter that scans for a name instead of the service UUID. If you wanted, you could modify the samples to use this filter instead and connect with a name as illustrated below:

    1) Changes to Central:

    In scan_init() change the filter type from UUID to NAME both places.

    static int scan_init(void)
    {
    	int err;
    	struct bt_scan_init_param scan_init = {
    		.connect_if_match = 1,
    	};
    
    	bt_scan_init(&scan_init);
    	bt_scan_cb_register(&scan_cb);
    
    	// err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, BT_UUID_NUS_SERVICE);
    	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, "Nordic_UART_Service");
    	if (err) {
    		LOG_ERR("Scanning filters cannot be set (err %d)", err);
    		return err;
    	}
    	// err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER, false);
    	err = bt_scan_filter_enable(BT_SCAN_NAME_FILTER, false);
    	if (err) {
    		LOG_ERR("Filters cannot be turned on (err %d)", err);
    		return err;
    	}
    
    	LOG_INF("Scan module initialized");
    	return err;
    }

    2) Changes to Peripheral: 

    From line 73 change the ad and sd data to the following

    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 const struct bt_data sd[] = {
    	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
    };

    3) Optionally

    • Customize the peripheral name in proj.conf in the peripheral sample to something you choose yourself. Remember to also edit the string in 1).

    There are several other ways to make a central only connect to specific peripherals, but this is one of the simplest ways.

    Here are some great resources containing information and how-to-dos for creating a Bluetooth Low Energy application. They might be quite detailed and it might take some time to wrap ones head around it, but they have helped me learning more about the Bluetooth stack we use in nRF Connect SDK. Part 2 in this written guide also contains snippets from central_uart and breaks them down and explains some of the functions for connecting and scanning to peripherals

    These tutorials are written for older version of nRF Connect SDK (v1.3.1 and v1.5.1), but they are still mostly applicable to v1.9.1. There will come a supported BLE fundamentals course at Nordic Academy in some time, so you may register to get notified when it gets published.

    Please feel free to follow up with more questions if you have any regarding this topic and otherwise let me know if this is of any help!

    Kind regards,
    Andreas

Reply
  • Hi,

    Allright, I'll do my best to explain how to do this and as well supply some recommended resources for you to examine if desired. You may step away from the addr.h library and rather take a look at the scanning module for filtering.

    The central_uart sample is set up to connect one peripheral device with the Nordic UART Service (NUS) enabled. Here the central scans for a specific message with a filter that scans for the NUS Service UUID, at line 497. In the Peripheral device, the scan response data is set up with the NUS UUID that the Central device scans for. When the filter matches with a peripheral it connects. This uses the scanning module, which contains various filters that can be used, including a filter that scans for a name instead of the service UUID. If you wanted, you could modify the samples to use this filter instead and connect with a name as illustrated below:

    1) Changes to Central:

    In scan_init() change the filter type from UUID to NAME both places.

    static int scan_init(void)
    {
    	int err;
    	struct bt_scan_init_param scan_init = {
    		.connect_if_match = 1,
    	};
    
    	bt_scan_init(&scan_init);
    	bt_scan_cb_register(&scan_cb);
    
    	// err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, BT_UUID_NUS_SERVICE);
    	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, "Nordic_UART_Service");
    	if (err) {
    		LOG_ERR("Scanning filters cannot be set (err %d)", err);
    		return err;
    	}
    	// err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER, false);
    	err = bt_scan_filter_enable(BT_SCAN_NAME_FILTER, false);
    	if (err) {
    		LOG_ERR("Filters cannot be turned on (err %d)", err);
    		return err;
    	}
    
    	LOG_INF("Scan module initialized");
    	return err;
    }

    2) Changes to Peripheral: 

    From line 73 change the ad and sd data to the following

    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 const struct bt_data sd[] = {
    	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
    };

    3) Optionally

    • Customize the peripheral name in proj.conf in the peripheral sample to something you choose yourself. Remember to also edit the string in 1).

    There are several other ways to make a central only connect to specific peripherals, but this is one of the simplest ways.

    Here are some great resources containing information and how-to-dos for creating a Bluetooth Low Energy application. They might be quite detailed and it might take some time to wrap ones head around it, but they have helped me learning more about the Bluetooth stack we use in nRF Connect SDK. Part 2 in this written guide also contains snippets from central_uart and breaks them down and explains some of the functions for connecting and scanning to peripherals

    These tutorials are written for older version of nRF Connect SDK (v1.3.1 and v1.5.1), but they are still mostly applicable to v1.9.1. There will come a supported BLE fundamentals course at Nordic Academy in some time, so you may register to get notified when it gets published.

    Please feel free to follow up with more questions if you have any regarding this topic and otherwise let me know if this is of any help!

    Kind regards,
    Andreas

Children
No Data
Related