Can I only beacon/broadcast scan response data only and not advertisement response data?

Hi,

I want to beacon only scan response data and not advertisement response data. I am using Nrf connect sdk 2.3.0 and Nrf 52840 board for beaconing.

I declared value variable and then passing it in scan response data as shown below:

static uint8_t value[] = { 0xff, 0xff, 0x00 };
static const struct bt_data sd[] = {
    BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
    BT_DATA(BT_DATA_MANUFACTURER_DATA, value, sizeof(value))
};
But, while scanning in nrf Connect Mobile app, I'm not getting any manufacturer data( defined in value) shown for the beacon name. What could be the issue?( I don't want to use bt_data ad[] and want to beacon data through scan response only).
  • Hi helloble,

    How did you setup the advertisement? What version of the nRF Connect Mobile app did you use, and on which OS?

    I tried to modify the ibeacon sample like below and got it to work with nRF Connect Mobile app for Android.

    #include <zephyr/types.h>
    #include <stddef.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/sys/util.h>
    
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/hci.h>
    
    static const struct bt_data ad[] = {
    	BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
    	BT_DATA_BYTES(BT_DATA_MANUFACTURER_DATA, 0x01, 0x02, 0x03) /* Calibrated RSSI @ 1m */
    };
    
    static void bt_ready(int err)
    {
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    
    	printk("Bluetooth initialized\n");
    
    	/* Start advertising */
    	// err = bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad),
    	// 		      NULL, 0);
    	err = bt_le_adv_start(BT_LE_ADV_NCONN, NULL, 0,
    			      ad, ARRAY_SIZE(ad));
    	if (err) {
    		printk("Advertising failed to start (err %d)\n", err);
    		return;
    	}
    }
    
    void main(void)
    {
    	int err;
    
    	printk("Starting Demo\n");
    
    	/* Initialize the Bluetooth Subsystem */
    	err = bt_enable(bt_ready);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    	}
    }
    

    Hieu

  • Hi Hieu,

    I am using Nrf Connect Mobile application version "2.6.5" in iphone iOS. And I am using Nrf SDK 2.3.0 with Visual Studio IDE.

    The advertisement data is as follows:

    I'm giving 0x00 manufacturer data (where <0xFFFF >is the id) as the advertisement data. But I want to get a scan response data for the same. As in, I want some data 0x01 in the scan response data( bt_data sd[]).

    static uint8_t value[] = { 0xff0xff0x00 };
    static uint8_t value1[] = { 0xff, 0xff, 0x01 };
    static const struct bt_data ad[] = {
        BT_DATA(BT_DATA_MANUFACTURER_DATA, value, sizeof(value))
    };
    static const struct bt_data sd[] = {
    // I want to get scan response data
    BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
        BT_DATA(BT_DATA_MANUFACTURER_DATA, value1, sizeof(value1))
    }
    When Implementing above, I am not getting scan response data 0x01 along with advertisement data. I am only getting advertisement data in the mobile app. How do I get the scan response data only? How should I implement that?
     
  • Hi helloble,

    I asked for an iPhone-user colleague to check today, and it seems a problem of the iOS app, rather than the nRF5 device application.

    I have asked internally if this is a limitation in iOS or if we could do better. I will follow-up with you when I receive an answer.

    There might be nothing wrong with your current code. Please see if you can check it on Android.
    For reference, this is the code I use to attempt what you are trying, and it works for me with the nRF Connect app for Android, but not with the nRF Connect app for iOS. Same as before, it is based on the iBeacon sample.

    #include <zephyr/types.h>
    #include <stddef.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/sys/util.h>
    
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/hci.h>
    
    static const struct bt_data ad[] = {
    	// BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
    	BT_DATA_BYTES(BT_DATA_NAME_SHORTENED, 'h', 'i', 'v', 'o'),
    	BT_DATA_BYTES(BT_DATA_MANUFACTURER_DATA, 0x01, 0x02, 0x03)
    };
    
    static const struct bt_data sr[] = {
    	// BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
    	BT_DATA_BYTES(BT_DATA_MANUFACTURER_DATA, 0x01, 0x02, 0x06)
    };
    
    static void bt_ready(int err)
    {
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    
    	printk("Bluetooth initialized\n");
    
    	/* Start advertising */
    	// err = bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad),
    	// 		      NULL, 0);
    	err = bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad),
    			      sr, ARRAY_SIZE(sr));
    	if (err) {
    		printk("Advertising failed to start (err %d)\n", err);
    		return;
    	}
    }
    
    void main(void)
    {
    	int err;
    
    	printk("Starting Demo\n");
    
    	/* Initialize the Bluetooth Subsystem */
    	err = bt_enable(bt_ready);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    	}
    }
    

  • Hi helloble,

    It turns out that on iOS, the platform simply returns the scan result using the API centralManager(_:didDiscover:advertisementData:rssi:), and the application cannot access the raw data to parse it in any particular way.

    Therefore, to properly support iOS application, I recommend you not have Manufacturer Data on both Advertising Data and Scan Response.

Related