Skip to content

Fix BLE adv timeout; ESP: don't sched handler on adv finish #9395

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

Merged
merged 1 commit into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions ports/espressif/common-hal/_bleio/Adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,6 @@ static int _advertising_event(struct ble_gap_event *event, void *self_in) {
#endif
break;
}
background_callback_add_core(&bleio_background_callback);
return 0;
}

Expand Down Expand Up @@ -559,7 +558,13 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
return rc;
}

bool high_duty_directed = directed_to != NULL && interval <= 3.5 && timeout <= 1.3;
bool high_duty_directed = directed_to != NULL && interval <= 3.5 && timeout <= 1; // Really 1.3, but it's an int

uint32_t timeout_ms = timeout * 1000;
if (timeout_ms == 0) {
timeout_ms = BLE_HS_FOREVER;
}


#if MYNEWT_VAL(BLE_EXT_ADV)
bool extended = advertising_data_len > BLE_ADV_LEGACY_DATA_MAX_LEN ||
Expand Down Expand Up @@ -621,7 +626,7 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
}
}

rc = ble_gap_ext_adv_start(0, timeout / 10, 0);
rc = ble_gap_ext_adv_start(0, timeout_ms, 0);
#else
uint8_t conn_mode = connectable ? BLE_GAP_CONN_MODE_UND : BLE_GAP_CONN_MODE_NON;
if (directed_to != NULL) {
Expand Down Expand Up @@ -650,7 +655,7 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
}
}
rc = ble_gap_adv_start(own_addr_type, directed_to != NULL ? &peer: NULL,
timeout / 10,
timeout_ms,
&adv_params,
_advertising_event, self);
#endif
Expand Down Expand Up @@ -694,11 +699,9 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool
mp_raise_NotImplementedError(NULL);
}

if (!timeout) {
timeout = BLE_HS_FOREVER;
} else if (timeout > INT32_MAX) {
if ((uint64_t)timeout * 1000ll >= BLE_HS_FOREVER) {
mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Timeout is too long: Maximum timeout length is %d seconds"),
INT32_MAX / 1000);
BLE_HS_FOREVER / 1000 - 1);
}

CHECK_NIMBLE_ERROR(_common_hal_bleio_adapter_start_advertising(self, connectable, anonymous, timeout, interval,
Expand Down
21 changes: 12 additions & 9 deletions ports/nordic/common-hal/_bleio/Adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,13 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
common_hal_bleio_adapter_stop_advertising(self);
}

// A zero timeout means unlimited. Do the checking here
// rather than in common_hal_bleio_adapter_start_advertising(), because
// _common_hal_bleio_adapter_start_advertising() is called for BLE workflow with
// a zero (unlimited) timeout.
if (timeout == 0) {
timeout = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
}
uint32_t err_code;
bool extended = advertising_data_len > BLE_GAP_ADV_SET_DATA_SIZE_MAX ||
scan_response_data_len > BLE_GAP_ADV_SET_DATA_SIZE_MAX;
Expand Down Expand Up @@ -871,15 +878,11 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool
// Anonymous mode requires a timeout so that we don't continue to broadcast
// the same data while cycling the MAC address -- otherwise, what's the
// point of randomizing the MAC address?
if (!timeout) {
if (anonymous) {
// The Nordic macro is in units of 10ms. Convert to seconds.
uint32_t adv_timeout_max_secs = UNITS_TO_SEC(BLE_GAP_ADV_TIMEOUT_LIMITED_MAX, UNIT_10_MS);
uint32_t rotate_timeout_max_secs = BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S;
timeout = MIN(adv_timeout_max_secs, rotate_timeout_max_secs);
} else {
timeout = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
}
if (anonymous) {
// The Nordic macro is in units of 10ms. Convert to seconds.
uint32_t adv_timeout_max_secs = UNITS_TO_SEC(BLE_GAP_ADV_TIMEOUT_LIMITED_MAX, UNIT_10_MS);
uint32_t rotate_timeout_max_secs = BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S;
timeout = MIN(adv_timeout_max_secs, rotate_timeout_max_secs);
} else {
if (SEC_TO_UNITS(timeout, UNIT_10_MS) > BLE_GAP_ADV_TIMEOUT_LIMITED_MAX) {
mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Timeout is too long: Maximum timeout length is %d seconds"),
Expand Down
4 changes: 2 additions & 2 deletions supervisor/shared/bluetooth/bluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ static void supervisor_bluetooth_start_advertising(void) {
return;
}
#endif
uint32_t timeout = 0;
float interval = 0.1f;
const uint32_t timeout = 0; // 0 means advertise forever.
const float interval = 0.1f;
int tx_power = 0;
const uint8_t *adv = private_advertising_data;
size_t adv_len = sizeof(private_advertising_data);
Expand Down