apache / apache/mynewt-nimble

Events BLE_GAP_EVENT_DISC_COMPLETE and BLE_GAP_EVENT_ADV_COMPLETE are not received

Open
#823 2 comments 1 reaction 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.