Events BLE_GAP_EVENT_DISC_COMPLETE and BLE_GAP_EVENT_ADV_COMPLETE are not received
- Dominant language
- C
- Stars
- 893
- Forks
- 512
- Avg merge
- 13d 31m
- Merged PRs (30d)
- 7
Description
We have integrated nimBLE stack over Linux npl porting. nimble_port_init() and nimble_port_run() are rightly called to initialize the nimBLE stack and to process the ble_npl_event events.
ble_gap_disc() and ble_gap_adv_start() are called with '**duration_ms**' parameter set to non-zero values. So, it is expected that BLE_GAP_EVENT_DISC_COMPLETE and BLE_GAP_EVENT_ADV_COMPLETE events are received after the '**duration_ms**' time elapses. But that doesn't happen and scanning/advertising goes on forever, as if '**duration_ms**' was set to BLE_HS_FOREVER.
When I debugged further I understood that when ble_gap_slave_set_timer() or ble_gap_master_set_timer() is set it would just trigger a timer reset of **1 tick** so immediately there would be a timer expiry and in the timer handler, the actual '**duration_ticks - 1**' would be set in ble_hs_timer_sched(). But, the following condition check seem to have an issue,
if (!ble_npl_callout_is_active(&ble_hs_timer) ||
((ble_npl_stime_t)(abs_time -
ble_npl_callout_get_ticks(&ble_hs_timer))) < 0) {
ble_hs_timer_reset(ticks_from_now);
ble_npl_callout_is_active() this is always **true** and (abs_time - ble_npl_callout_get_ticks(&ble_hs_timer))) **is always greater than 0**. Since, it has just triggered an expiry, the ble_npl_callout_get_ticks() returns the current value which will always be less than abs_time. So, timer is never reset to the correct **duration_ticks**.
I checked the same scenario in btshell where the **mynewt npl** layer is used. Here, the ble_npl_callout_is_active() is always **false**. So the condition turns to be true and timer is reset successfully.
So, this seems to be an issue in linux npl layer.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in the Linux NPL timer path around ble_gap_slave_set_timer(), ble_gap_master_set_timer(), ble_hs_timer_sched(), and ble_npl_callout_is_active(). Reproduce scanning or advertising with a non-zero duration_ms and compare the callout state with btshell using the mynewt NPL layer. Done means the timer is reset for the requested duration and the corresponding DISC_COMPLETE or ADV_COMPLETE event is received.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, linux
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100