Advertise fast for at least 30 secs then slow down

On power up, advertise aggressively for at least 30 seconds then switch
to a longer interval to conserve battery life. This fast/slow pattern
is designed to balance connection response time and battery life.

When a disconnect event is received restart the fast/slow pattern.

When a failed connect event is received, restart the fast/slow pattern.

When the screen is activated and ble is not connected, restart the fast/slow pattern.

This pattern is consistent with Apple's BLE developer standards (QA 1931).
This commit is contained in:
James A. Jerkins 2021-09-05 15:53:20 -05:00
parent 4820b2ffe8
commit 22571d4b38
3 changed files with 20 additions and 1 deletions

View file

@ -122,6 +122,15 @@ void NimbleController::StartAdvertising() {
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
/* fast advertise for 30 sec */
if (fastAdvCount < 15) {
adv_params.itvl_min = 32;
adv_params.itvl_max = 47;
fastAdvCount++;
} else {
adv_params.itvl_min = 1636;
adv_params.itvl_max = 1651;
}
fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
fields.uuids128 = &dfuServiceUuid; fields.uuids128 = &dfuServiceUuid;
@ -139,7 +148,7 @@ void NimbleController::StartAdvertising() {
rc = ble_gap_adv_rsp_set_fields(&rsp_fields); rc = ble_gap_adv_rsp_set_fields(&rsp_fields);
ASSERT(rc == 0); ASSERT(rc == 0);
rc = ble_gap_adv_start(addrType, NULL, 5000, &adv_params, GAPEventCallback, this); rc = ble_gap_adv_start(addrType, NULL, 2000, &adv_params, GAPEventCallback, this);
ASSERT(rc == 0); ASSERT(rc == 0);
} }
@ -163,6 +172,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
alertNotificationClient.Reset(); alertNotificationClient.Reset();
connectionHandle = BLE_HS_CONN_HANDLE_NONE; connectionHandle = BLE_HS_CONN_HANDLE_NONE;
bleController.Disconnect(); bleController.Disconnect();
fastAdvCount = 0;
StartAdvertising(); StartAdvertising();
} else { } else {
connectionHandle = event->connect.conn_handle; connectionHandle = event->connect.conn_handle;
@ -181,6 +191,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
alertNotificationClient.Reset(); alertNotificationClient.Reset();
connectionHandle = BLE_HS_CONN_HANDLE_NONE; connectionHandle = BLE_HS_CONN_HANDLE_NONE;
bleController.Disconnect(); bleController.Disconnect();
fastAdvCount = 0;
StartAdvertising(); StartAdvertising();
break; break;

View file

@ -72,6 +72,10 @@ namespace Pinetime {
uint16_t connHandle(); uint16_t connHandle();
void NotifyBatteryLevel(uint8_t level); void NotifyBatteryLevel(uint8_t level);
void RestartFastAdv() {
fastAdvCount = 0;
}
private: private:
static constexpr const char* deviceName = "InfiniTime"; static constexpr const char* deviceName = "InfiniTime";
Pinetime::System::SystemTask& systemTask; Pinetime::System::SystemTask& systemTask;
@ -94,6 +98,7 @@ namespace Pinetime {
uint8_t addrType; // 1 = Random, 0 = PUBLIC uint8_t addrType; // 1 = Random, 0 = PUBLIC
uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE;
uint8_t fastAdvCount = 0;
ble_uuid128_t dfuServiceUuid { ble_uuid128_t dfuServiceUuid {
.u {.type = BLE_UUID_TYPE_128}, .u {.type = BLE_UUID_TYPE_128},

View file

@ -233,6 +233,9 @@ void SystemTask::Work() {
displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel);
heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp);
if (!bleController.IsConnected())
nimbleController.RestartFastAdv();
isSleeping = false; isSleeping = false;
isWakingUp = false; isWakingUp = false;
isDimmed = false; isDimmed = false;