From f3728c41bb311f3838dc9c10a2157a16196b4420 Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 27 Sep 2020 20:59:06 +0200 Subject: [PATCH] Add Immediate Alert Service, needed by the "Find Me" profile from BLE spec. --- src/CMakeLists.txt | 2 + src/Components/Ble/ImmediateAlertService.cpp | 76 ++++++++++++++++++++ src/Components/Ble/ImmediateAlertService.h | 46 ++++++++++++ src/Components/Ble/NimbleController.cpp | 4 +- src/Components/Ble/NimbleController.h | 2 + 5 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/Components/Ble/ImmediateAlertService.cpp create mode 100644 src/Components/Ble/ImmediateAlertService.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 57dbe8b9..eee1d61a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -363,6 +363,7 @@ list(APPEND SOURCE_FILES Components/Ble/AlertNotificationService.cpp Components/Ble/MusicService.cpp Components/Ble/BatteryInformationService.cpp + Components/Ble/ImmediateAlertService.cpp Components/FirmwareValidator/FirmwareValidator.cpp drivers/Cst816s.cpp FreeRTOS/port.c @@ -437,6 +438,7 @@ set(INCLUDE_FILES Components/Ble/DfuService.h Components/FirmwareValidator/FirmwareValidator.h Components/Ble/BatteryInformationService.h + Components/Ble/ImmediateAlertService.h drivers/Cst816s.h FreeRTOS/portmacro.h FreeRTOS/portmacro_cmsis.h diff --git a/src/Components/Ble/ImmediateAlertService.cpp b/src/Components/Ble/ImmediateAlertService.cpp new file mode 100644 index 00000000..d2c4cffb --- /dev/null +++ b/src/Components/Ble/ImmediateAlertService.cpp @@ -0,0 +1,76 @@ +#include "ImmediateAlertService.h" +#include +#include "AlertNotificationService.h" + +using namespace Pinetime::Controllers; + +constexpr ble_uuid16_t ImmediateAlertService::immediateAlertServiceUuid; +constexpr ble_uuid16_t ImmediateAlertService::alertLevelUuid; + +namespace { + int AlertLevelCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { + auto *immediateAlertService = static_cast(arg); + return immediateAlertService->OnAlertLevelChanged(conn_handle, attr_handle, ctxt); + } + + const char* ToString(ImmediateAlertService::Levels level) { + switch (level) { + case ImmediateAlertService::Levels::NoAlert: return "Alert : None"; + case ImmediateAlertService::Levels::HighAlert: return "Alert : High"; + case ImmediateAlertService::Levels::MildAlert: return "Alert : Mild"; + default: return ""; + } + } +} + +ImmediateAlertService::ImmediateAlertService(Pinetime::System::SystemTask &systemTask, + Pinetime::Controllers::NotificationManager ¬ificationManager) : + systemTask{systemTask}, + notificationManager{notificationManager}, + characteristicDefinition{ + { + .uuid = (ble_uuid_t *) &alertLevelUuid, + .access_cb = AlertLevelCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + .val_handle = &alertLevelHandle + }, + { + 0 + } + }, + serviceDefinition{ + { + /* Device Information Service */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = (ble_uuid_t *) &immediateAlertServiceUuid, + .characteristics = characteristicDefinition + }, + { + 0 + }, + }{ + +} + +void ImmediateAlertService::Init() { + int res = 0; + res = ble_gatts_count_cfg(serviceDefinition); + ASSERT(res == 0); + + res = ble_gatts_add_svcs(serviceDefinition); + ASSERT(res == 0); +} + +int ImmediateAlertService::OnAlertLevelChanged(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt *context) { + if(attributeHandle == alertLevelHandle) { + if(context->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + auto alertLevel = static_cast(context->om->om_data[0]); + auto* alertString = ToString(alertLevel); + notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, alertString, strlen(alertString)); + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification); + } + } + + return 0; +} \ No newline at end of file diff --git a/src/Components/Ble/ImmediateAlertService.h b/src/Components/Ble/ImmediateAlertService.h new file mode 100644 index 00000000..c42846c4 --- /dev/null +++ b/src/Components/Ble/ImmediateAlertService.h @@ -0,0 +1,46 @@ +#pragma once +#include + +namespace Pinetime { + namespace System { + class SystemTask; + } + namespace Controllers { + class NotificationManager; + class ImmediateAlertService { + public: + enum class Levels : uint8_t { + NoAlert = 0, + MildAlert = 1, + HighAlert = 2 + }; + + ImmediateAlertService(Pinetime::System::SystemTask &systemTask, + Pinetime::Controllers::NotificationManager ¬ificationManager); + void Init(); + int OnAlertLevelChanged(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt *context); + + private: + Pinetime::System::SystemTask& systemTask; + NotificationManager& notificationManager; + + static constexpr uint16_t immediateAlertServiceId {0x1802}; + static constexpr uint16_t alertLevelId {0x2A06}; + + static constexpr ble_uuid16_t immediateAlertServiceUuid { + .u {.type = BLE_UUID_TYPE_16}, + .value = immediateAlertServiceId + }; + + static constexpr ble_uuid16_t alertLevelUuid { + .u {.type = BLE_UUID_TYPE_16}, + .value = alertLevelId + }; + + struct ble_gatt_chr_def characteristicDefinition[3]; + struct ble_gatt_svc_def serviceDefinition[2]; + + uint16_t alertLevelHandle; + }; + } +} diff --git a/src/Components/Ble/NimbleController.cpp b/src/Components/Ble/NimbleController.cpp index a8add0df..b13f9ce3 100644 --- a/src/Components/Ble/NimbleController.cpp +++ b/src/Components/Ble/NimbleController.cpp @@ -39,7 +39,8 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, alertNotificationClient{systemTask, notificationManager}, currentTimeService{dateTimeController}, musicService{systemTask}, - batteryInformationService{batteryController} { + batteryInformationService{batteryController}, + immediateAlertService{systemTask, notificationManager} { } @@ -88,6 +89,7 @@ void NimbleController::Init() { anService.Init(); dfuService.Init(); batteryInformationService.Init(); + immediateAlertService.Init(); int res; res = ble_hs_util_ensure_addr(0); ASSERT(res == 0); diff --git a/src/Components/Ble/NimbleController.h b/src/Components/Ble/NimbleController.h index 2dee8987..89fa4250 100644 --- a/src/Components/Ble/NimbleController.h +++ b/src/Components/Ble/NimbleController.h @@ -9,6 +9,7 @@ #include "CurrentTimeService.h" #include "MusicService.h" #include "BatteryInformationService.h" +#include "ImmediateAlertService.h" #include namespace Pinetime { @@ -59,6 +60,7 @@ namespace Pinetime { CurrentTimeService currentTimeService; MusicService musicService; BatteryInformationService batteryInformationService; + ImmediateAlertService immediateAlertService; uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = 0;