Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return the current tick as when the RF will be fully enabled (when MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME is not defined). #1027

Merged

Conversation

danielgjackson
Copy link
Contributor

@danielgjackson danielgjackson commented Sep 25, 2021

Caveat: I am unfortunately not able to test this change on the current version of NimBLE, but the relevant code seems the identical to the version I know to be affected and fixed by this simple one-line change.

When MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME is not defined in syscfg.h, the function ble_ll_rfmgmt_enable_now() is implemented as a static inline stub in ble_ll_rfmgmt.h.

This stub always returns 0, yet the function should return the "tick at which RF will be fully enabled".

Returning a fixed value, rather than a tick value near to the current system tick, causes overflow issues. For example, in ble_ll_adv_sm_start() (ble_ll_adv.c), this time is retrieved and a delta is calculated to check whether the advertising is trying to start before the RF would be ready:

earliest_start_time = ble_ll_rfmgmt_enable_now();
// [...]
delta = (int32_t)(advsm->adv_sch.start_time - earliest_start_time);
if (delta < 0) {
// [...]

As this is not a tick time near to the current value (but instead, always 0), this calculation will overflow when the system timer is between 0x80000000-0xFFFFFFFF. This causes an incorrect, huge forward adjustment to be applied to the schedule.

The symptom is, for those configurations without MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME who attempt to start advertising within a period of an odd multiple of 18.2 hours (half the 32-bit timer period) since the timer started: the advertising appears to silently fail.

Alternatively, this function implementation could be moved into ble_ll_rfmgmt.c rather than the header; or all uses of ble_ll_rfmgmt_enable_now() could be guarded with #if MYNEWT_VAL(BLE_LL_RFMGMT_ENABLE_TIME) > 0/#endif.

…NEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME is not defined).

When `MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME` is not defined, the existing code always returns 0 as the "tick at which RF will be fully enabled".  However, this causes problems.  For example, in `ble_ll_adv_sm_start()` (ble_ll_adv.c:2743) the calculation of `delta` overflows when the system timer is between 0x80000000 and 0xFFFFFFFF -- causing an incorrect, huge adjustment to be made to the scheduled time, ultimately stopping the advertisements from being sent.
Copy link
Contributor

@andrzej-kaczmarek andrzej-kaczmarek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, thanks!

@andrzej-kaczmarek andrzej-kaczmarek merged commit ba36c80 into apache:master Sep 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants