Stop scanning and start advertising

Hi,

I am developing application on  NRF52840 with Zepyr  2.1.2 SDK, and I found two problems when using the example scan_adv, as follows:

  • Executing bt_le_scan_start in the main function can receive data smoothly, but using function scan_start() can not receive data, the same problem also occurs in bt_le_adv_start().
  • Executing bt_le_scan_stop() still cannot stop scanning.

My codeis as below:

#include <zephyr/types.h>
#include <stddef.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>
#include <zephyr/toolchain.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>

struct bt_le_scan_param scan_param = {
		.type       = BT_HCI_LE_SCAN_PASSIVE,
		.options    = BT_LE_SCAN_OPT_NONE,
		.interval   = BT_GAP_SCAN_FAST_INTERVAL,
		.window     = 0x0010,
	};
const struct device *dev;
int state = 1, adv_state;
int8_t rssi_data [8][8] = {0};
static uint8_t mfg_data[] = { 0xff, 0xff, 0x01 };
static const struct bt_data ad[] = {
	BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 3),
	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME,DEVICE_NAME_LEN)
};


void scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
	   struct net_buf_simple *buf)
{...}

void adv_start(uint8_t mfg){
	mfg_data[2] = mfg;
	int err = bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad), NULL, 0);
	if (err) {
		printk("Advertising failed to start (err %d)\n", err);
		return;
	}
	k_sleep(K_MSEC(400));
}

static void adv_stop(){
	int err = bt_le_adv_stop();
	if (err) {
		printk("Advertising failed to stop (err %d)\n", err);
		return;
	}
	k_sleep(K_MSEC(400));
}
void scan_start(){
	int err = bt_le_scan_start(&scan_param, scan_cb);
		if (err) {
			printk("Starting scanning failed (err %d)\n", err);
			return;
		}
		k_sleep(K_MSEC(400));
}

static void scan_stop(){
	int err = bt_le_scan_stop();
	if (err) {
		printk("Stop scanning failed (err %d)\n", err);
		return;
	}
	k_sleep(K_MSEC(400));
}


void main(void)
{
	int err = bt_enable(NULL);
	if (err) {
		printk("Bluetooth init failed (err %d)\n", err);
		return;
	}
	printk("Bluetooth initialized\n");
	scan_start();

	/*  if not use scan_start()
	*********************************************************
	int err = bt_le_scan_start(&scan_param, scan_cb);
	if (err) {
		printk("Starting scanning failed (err %d)\n", err);
		return;
	}
	k_sleep(K_MSEC(400));
	********************************************************
	*/

	k_sleep(K_MSEC(800));
	//scan_stop();
	int err = bt_le_adv_stop();
	if (err) {
		printk("Advertising failed to stop (err %d)\n", err);
		return;
	}
	k_sleep(K_MSEC(400));
	while(1);
}

Thanks.

Parents
  • Hi,

    I see from your code snippet that you call bt_le_adv_stop() at the end. Is that a typo? If you want to stop scanning, you will have to use bt_le_scan_stop()/scan_stop().

    Best regards,

    Vidar

  • Hi,

    Thank you for your reply, I changed it to bt_le_scan_stop but still have the same problem, is there any way to stop scanning?

    In addition, using function scan_start() still cannot receive data.

    my program is as follows:

    #include <zephyr/types.h>
    #include <stddef.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/sys/util.h>
    #include <zephyr/toolchain.h>
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/hci.h>
    #include <device.h>
    #include <devicetree.h>
    #include <drivers/gpio.h>
    
    struct bt_le_scan_param scan_param = {
    		.type       = BT_HCI_LE_SCAN_PASSIVE,
    		.options    = BT_LE_SCAN_OPT_NONE,
    		.interval   = BT_GAP_SCAN_FAST_INTERVAL,
    		.window     = 0x0010,
    	};
    const struct device *dev;
    int state = 1, adv_state;
    int8_t rssi_data [8][8] = {0};
    static uint8_t mfg_data[] = { 0xff, 0xff, 0x01 };
    static const struct bt_data ad[] = {
    	BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 3),
    	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME,DEVICE_NAME_LEN)
    };
    
    
    void scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
    	   struct net_buf_simple *buf)
    {...}
    
    void adv_start(uint8_t mfg){
    	mfg_data[2] = mfg;
    	int err = bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad), NULL, 0);
    	if (err) {
    		printk("Advertising failed to start (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    }
    
    static void adv_stop(){
    	int err = bt_le_adv_stop();
    	if (err) {
    		printk("Advertising failed to stop (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    }
    void scan_start(){
    	int err = bt_le_scan_start(&scan_param, scan_cb);
    		if (err) {
    			printk("Starting scanning failed (err %d)\n", err);
    			return;
    		}
    		k_sleep(K_MSEC(400));
    }
    
    static void scan_stop(){
    	int err = bt_le_scan_stop();
    	if (err) {
    		printk("Stop scanning failed (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    }
    
    
    void main(void)
    {
    	int err = bt_enable(NULL);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    	printk("Bluetooth initialized\n");
    	scan_start();
    
    	/*  if not use scan_start()
    	*********************************************************
    	int err = bt_le_scan_start(&scan_param, scan_cb);
    	if (err) {
    		printk("Starting scanning failed (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    	********************************************************
    	*/
    
    	k_sleep(K_MSEC(800));
    	//scan_stop();
    	int err = bt_le_scan_stop();
    	if (err) {
    		printk("Stop scanning failed (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    	while(1);
    }

  • Kevin_Liu said:
    I changed it to bt_le_scan_stop but still have the same problem, is there any way to stop scanning?

    Please explain how you determine that it does not stop. Is it because bt_le_scan_stop() returns with an error?

    Kevin_Liu said:
    In addition, using function scan_start() still cannot receive data.

    Does scan_start() report any errors?

    Kevin_Liu said:
    my program is as follows:

    Can you post the updated code please? The snippet you posted will not build because the 'err' variable being defined twice in main() 

  • ...

    I use J-Link RTT Viewer V7.58b as a debugging tool. After the bt_le_scan_stop() function is executed, the scan_cb() function continues to work without error

    Does scan_start() report any errors?

    No error occurs, but scan_cb() function does not send any message

    Can you post the updated code please? The snippet you posted will not build because the 'err' variable being defined twice in main()

    #include <zephyr/types.h>
    #include <stddef.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/sys/util.h>
    #include <zephyr/toolchain.h>
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/hci.h>
    #include <device.h>
    #include <devicetree.h>
    #include <drivers/gpio.h>
    
    struct bt_le_scan_param scan_param = {
    		.type       = BT_HCI_LE_SCAN_PASSIVE,
    		.options    = BT_LE_SCAN_OPT_NONE,
    		.interval   = BT_GAP_SCAN_FAST_INTERVAL,
    		.window     = 0x0010,
    	};
    const struct device *dev;
    int state = 1, adv_state;
    int8_t rssi_data [8][8] = {0};
    static uint8_t mfg_data[] = { 0xff, 0xff, 0x01 };
    static const struct bt_data ad[] = {
    	BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 3),
    	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME,DEVICE_NAME_LEN)
    };
    
    
    void scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
    	   struct net_buf_simple *buf)
    {
    	printk("scan_cb start\n");
    	char data_str[129];
    	bin2hex(buf->data, buf->len, data_str, sizeof(data_str));
    	printk("data_str is : %s\n", data_str);
    }
    
    void adv_start(uint8_t mfg){
    	mfg_data[2] = mfg;
    	int err = bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad), NULL, 0);
    	if (err) {
    		printk("Advertising failed to start (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    }
    
    static void adv_stop(){
    	int err = bt_le_adv_stop();
    	if (err) {
    		printk("Advertising failed to stop (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    }
    void scan_start(){
    	int err = bt_le_scan_start(&scan_param, scan_cb);
    		if (err) {
    			printk("Starting scanning failed (err %d)\n", err);
    			return;
    		}
    		k_sleep(K_MSEC(400));
    }
    
    static void scan_stop(){
    	int err = bt_le_scan_stop();
    	if (err) {
    		printk("Stop scanning failed (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    }
    
    
    void main(void)
    {
    	int err = bt_enable(NULL);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    	printk("Bluetooth initialized\n");
    	scan_start();
    
    	/*  if not use scan_start()
    	*********************************************************
    	err = bt_le_scan_start(&scan_param, scan_cb);
    	if (err) {
    		printk("Starting scanning failed (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    	********************************************************
    	*/
    
    	k_sleep(K_MSEC(800));
    	//scan_stop();
    	err = bt_le_scan_stop();
    	if (err) {
    		printk("Stop scanning failed (err %d)\n", err);
    		return;
    	}
    	k_sleep(K_MSEC(400));
    	while(1);
    }

  • This is what when I run the code you posted now:

    So, it appears to be working as expected?

    Here is the hex file I built with your code if you want to try the same on your board:

    2248.zephyr.hex

Reply Children
No Data
Related