From be31f417db1937032ae440e1cf68cb2971284713 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sun, 29 Aug 2021 15:50:04 -0500 Subject: WIP Refactor ble advertising Refactor ble advertising based on ble standards and conventions. Changes are based on the bleprph example code, bluetooth docs, and nimble docs. --- src/components/ble/NimbleController.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/components/ble/NimbleController.h') diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 0cfe983c..078d6158 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -101,5 +101,7 @@ namespace Pinetime { ServiceDiscovery serviceDiscovery; }; + + static NimbleController* nptr; } } -- cgit v1.2.3 From c32ba844e04017a3fd31444c384deb3542bd76be Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sat, 4 Sep 2021 15:26:50 -0500 Subject: Linear decrease of advert rate to conserve battery Start advertising aggressively when powered on then slow down linearly over 75 seconds. This will conserve battery by not advertising rapidly the whole time we are seeking a connection. The slowest rate is approximately once every 4.5 seconds to balance responsiveness and battery life. We use a fixed advertising duration of 5 seconds and start with a 62.5 ms advertising interval. Every 5 seconds (the advertising duration) we step up to a larger advertising interval (slower advertising). We continue to increase the advertising interval linearly for 75 seconds from the start of advertising. At 75 seconds we have an advertising interval of 4.44 seconds which we keep until connected. A reboot will restart the sequence. When we receive a disconnect event we restart the sequence with fast advertising and then slow down as described above. Note that we are not using the BLE high duty cycle setting to change the advertising rate. The rate is managed by repeatedly setting the minimum and maximum intervals. The linear rate of decrease and the slowest interval size were determined experimentally by the author. The 5.3 Core spec suggests that you not advertise slower than once every 1.2 seconds to preserve responsiveness but we ignored that suggestion. --- src/components/ble/NimbleController.cpp | 5 +++++ src/components/ble/NimbleController.h | 1 + 2 files changed, 6 insertions(+) (limited to 'src/components/ble/NimbleController.h') diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 8e0fe756..bebca2d3 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -122,6 +122,8 @@ void NimbleController::StartAdvertising() { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + adv_params.itvl_min = advInterval; + adv_params.itvl_max = advInterval + 100; fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; fields.uuids128 = &dfuServiceUuid; @@ -148,6 +150,8 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { case BLE_GAP_EVENT_ADV_COMPLETE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_ADV_COMPLETE"); NRF_LOG_INFO("reason=%d; status=%d", event->adv_complete.reason, event->connect.status); + if (advInterval < 7100) + advInterval += 500; StartAdvertising(); break; @@ -181,6 +185,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); + advInterval = 100; StartAdvertising(); break; diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 078d6158..79761108 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -94,6 +94,7 @@ namespace Pinetime { uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; + uint16_t advInterval = 100; // multiplied by 0.625ms, must be in 32..16384 ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, -- cgit v1.2.3 From 4820b2ffe8be0b8d1abefd307a4c0fe6d4d41a73 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sun, 5 Sep 2021 15:52:01 -0500 Subject: Revert "Linear decrease of advert rate to conserve battery" This reverts commit c32ba844e04017a3fd31444c384deb3542bd76be. --- src/components/ble/NimbleController.cpp | 5 ----- src/components/ble/NimbleController.h | 1 - 2 files changed, 6 deletions(-) (limited to 'src/components/ble/NimbleController.h') diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index bebca2d3..8e0fe756 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -122,8 +122,6 @@ void NimbleController::StartAdvertising() { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; - adv_params.itvl_min = advInterval; - adv_params.itvl_max = advInterval + 100; fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; fields.uuids128 = &dfuServiceUuid; @@ -150,8 +148,6 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { case BLE_GAP_EVENT_ADV_COMPLETE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_ADV_COMPLETE"); NRF_LOG_INFO("reason=%d; status=%d", event->adv_complete.reason, event->connect.status); - if (advInterval < 7100) - advInterval += 500; StartAdvertising(); break; @@ -185,7 +181,6 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); - advInterval = 100; StartAdvertising(); break; diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 79761108..078d6158 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -94,7 +94,6 @@ namespace Pinetime { uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; - uint16_t advInterval = 100; // multiplied by 0.625ms, must be in 32..16384 ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, -- cgit v1.2.3 From 22571d4b384e40d647cd994202956f08ed32d925 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sun, 5 Sep 2021 15:53:20 -0500 Subject: 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). --- src/components/ble/NimbleController.cpp | 13 ++++++++++++- src/components/ble/NimbleController.h | 5 +++++ src/systemtask/SystemTask.cpp | 3 +++ 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'src/components/ble/NimbleController.h') diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 8e0fe756..226f6694 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -122,6 +122,15 @@ void NimbleController::StartAdvertising() { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; 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.uuids128 = &dfuServiceUuid; @@ -139,7 +148,7 @@ void NimbleController::StartAdvertising() { rc = ble_gap_adv_rsp_set_fields(&rsp_fields); 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); } @@ -163,6 +172,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); + fastAdvCount = 0; StartAdvertising(); } else { connectionHandle = event->connect.conn_handle; @@ -181,6 +191,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); + fastAdvCount = 0; StartAdvertising(); break; diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 078d6158..473bb1af 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -72,6 +72,10 @@ namespace Pinetime { uint16_t connHandle(); void NotifyBatteryLevel(uint8_t level); + void RestartFastAdv() { + fastAdvCount = 0; + } + private: static constexpr const char* deviceName = "InfiniTime"; Pinetime::System::SystemTask& systemTask; @@ -94,6 +98,7 @@ namespace Pinetime { uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; + uint8_t fastAdvCount = 0; ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 2dff9254..41f346ae 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -233,6 +233,9 @@ void SystemTask::Work() { displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); + if (!bleController.IsConnected()) + nimbleController.RestartFastAdv(); + isSleeping = false; isWakingUp = false; isDimmed = false; -- cgit v1.2.3