[BLE] restarting a discovery

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
user_2112781
Level 4
Level 4
10 likes received 10 likes given 5 likes given

I always get the 8033 (WICED_BT_BUSY) error code when I want to start again a discovery.

At the end of the scan, in the p_scan_result_cback, I try the following:

void scanCallback(wiced_bt_ble_scan_results_t *p_scan_result, uint8_t *p_adv_data)

{

  if (p_scan_result == NULL)

  {

  printf("wiced_bt_ble_get_current_scan_state = %u\n", wiced_bt_ble_get_current_scan_state());

  printf("wiced_bt_ble_scan(START) = %d\n", wiced_bt_ble_scan(BTM_BLE_SCAN_TYPE_HIGH_DUTY, WICED_TRUE, scanCallback));

  }

}

And as expected I get:

wiced_bt_ble_get_current_scan_state = 0

wiced_bt_ble_scan(START) = 8033

So, why can't the device discovery restart if the state is 0 ?

0 Likes
1 Solution
JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

When you attempt to restart a scan, the stack checks for the existence of a non-NULL callback. If one exists it will throw you a WICED_BT_BUSY error. This is what is happening in your code.

You're correct that the scan is stopped by that point in the code, and, as you've seen, the indicator variable is appropriately set. However, until you allow the callback to return, the control block still has a non-NULL value for the callback. You must allow the callback to return--only then is the control block passed a NULL value for the callback, and only then can you restart a new scan.  

Jacob

View solution in original post

8 Replies
JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

When you attempt to restart a scan, the stack checks for the existence of a non-NULL callback. If one exists it will throw you a WICED_BT_BUSY error. This is what is happening in your code.

You're correct that the scan is stopped by that point in the code, and, as you've seen, the indicator variable is appropriately set. However, until you allow the callback to return, the control block still has a non-NULL value for the callback. You must allow the callback to return--only then is the control block passed a NULL value for the callback, and only then can you restart a new scan.  

Jacob

Okay, thank you, it's working if I try to relaunch the scan outside of the callback.

0 Likes

jakewtorres wrote:

When you attempt to restart a scan, the stack checks for the existence of a non-NULL callback. If one exists it will throw you a WICED_BT_BUSY error. This is what is happening in your code.

You're correct that the scan is stopped by that point in the code, and, as you've seen, the indicator variable is appropriately set. However, until you allow the callback to return, the control block still has a non-NULL value for the callback. You must allow the callback to return--only then is the control block passed a NULL value for the callback, and only then can you restart a new scan.  

Jacob

Then the problem is how can you know a scan is done? (so you can restart new scan)

If using wiced_bt_ble_scan() you can get  BTM_BLE_SCAN_STATE_CHANGED_EVT event when status changed.

But if using wiced_bt_ble_observe(), there is no way to know when the scan is done. (unless using polling).

Is this a bug?

0 Likes
Anonymous
Not applicable

I was in the same place, needing to start a new scan as soon as I knew the last one had finished by getting a NULL scan result in the callback to wiced_bt_ble_scan().

My solution was to use wiced_rtos_send_asynchronous_event() to schedule a function that would in turn schedule the next scan.  That way, the control block referred to in earlier comments has a chance to transition the BT stack out of the state where you'd get WICED_BT_BUSY.

There are probably other ways to do it, but I've not had any problems with this so far.

lfogle-weekley wrote:

I was in the same place, needing to start a new scan as soon as I knew the last one had finished by getting a NULL scan result in the callback to wiced_bt_ble_scan().

My solution was to use wiced_rtos_send_asynchronous_event() to schedule a function that would in turn schedule the next scan.  That way, the control block referred to in earlier comments has a chance to transition the BT stack out of the state where you'd get WICED_BT_BUSY.

There are probably other ways to do it, but I've not had any problems with this so far.

Hi lfogle-weekley​,

I'm calling wiced_bt_ble_scan() if got NULL scan result.

It usually works, however I observed sometimes the medium size buf-usage increased after re-scan.

With the time passing, in the end it will run out of buffers. Then device reboot.

Do you hit such issue?

I have concern about using wiced_rtos_send_asynchronous_event() because it can take more time to restart the scan.

Which means it's highly possible to lost some data.

BTW, it's also possible to set duration to 0 then it will scan forever.

However, the problem is I also observe sometimes the scan stop without any event. (It just silently stop working).

0 Likes

axel.lin_1746341 wrote:

BTW, it's also possible to set duration to 0 then it will scan forever.

However, the problem is I also observe sometimes the scan stop without any event. (It just silently stop working).

So I found if ble_scan uses one "large buffer pool" the scan stop working anymore.

The comment says large buffer pool is used by HCI ACL messages.

Why ble scan use "large buffer pool"?

0 Likes
Anonymous
Not applicable

In my case I did not experience exhaustion of the medium sized buffers.

I'm also tolerant of lost data, because I'm just listening to beacons that will re-send their advertisements more frequently than their data will meaningfully change.  Your requirements may be more sensitive than mine in that regard.

I also didn't want to trust scan duration 0, but I no longer remember whether I actually observed the behavior you mention where it silently stops working.

0 Likes