From 24f5fbd48ced94754a17d2016bffedef7f3abbab Mon Sep 17 00:00:00 2001 From: Vyacheslav Chigrin Date: Fri, 29 Nov 2024 00:28:44 +0300 Subject: [PATCH] Add ImmediateAlertClient to support FindMyPhone functionality. --- CMakeLists.txt | 2 + sim/components/ble/ImmediateAlertClient.cpp | 114 ++++++++++++++++++++ sim/components/ble/ImmediateAlertClient.h | 61 +++++++++++ sim/components/ble/NimbleController.cpp | 2 + sim/components/ble/NimbleController.h | 5 + 5 files changed, 184 insertions(+) create mode 100644 sim/components/ble/ImmediateAlertClient.cpp create mode 100644 sim/components/ble/ImmediateAlertClient.h diff --git a/CMakeLists.txt b/CMakeLists.txt index aa848ce..e0776c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,8 @@ target_sources(infinisim PUBLIC sim/components/battery/BatteryController.cpp sim/components/ble/MusicService.h sim/components/ble/MusicService.cpp + sim/components/ble/ImmediateAlertClient.h + sim/components/ble/ImmediateAlertClient.cpp sim/components/ble/NimbleController.h sim/components/ble/NimbleController.cpp sim/components/brightness/BrightnessController.h diff --git a/sim/components/ble/ImmediateAlertClient.cpp b/sim/components/ble/ImmediateAlertClient.cpp new file mode 100644 index 0000000..293d948 --- /dev/null +++ b/sim/components/ble/ImmediateAlertClient.cpp @@ -0,0 +1,114 @@ +#include "components/ble/ImmediateAlertClient.h" +#include +#include +#include "systemtask/SystemTask.h" + +using namespace Pinetime::Controllers; + +constexpr ble_uuid16_t ImmediateAlertClient::immediateAlertClientUuid; +constexpr ble_uuid16_t ImmediateAlertClient::alertLevelCharacteristicUuid; + +// namespace { +// int OnDiscoveryEventCallback(uint16_t conn_handle, const struct ble_gatt_error* error, const struct ble_gatt_svc* service, void* arg) { +// auto client = static_cast(arg); +// return client->OnDiscoveryEvent(conn_handle, error, service); +// } + +// int OnImmediateAlertCharacteristicDiscoveredCallback(uint16_t conn_handle, +// const struct ble_gatt_error* error, +// const struct ble_gatt_chr* chr, +// void* arg) { +// auto client = static_cast(arg); +// return client->OnCharacteristicDiscoveryEvent(conn_handle, error, chr); +// } +// } + +ImmediateAlertClient::ImmediateAlertClient(Pinetime::System::SystemTask& systemTask) + : systemTask {systemTask}, + characteristicDefinition {{ + .uuid = &alertLevelCharacteristicUuid.u, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, + {0}}, + serviceDefinition { + {/* Device Information Service */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &immediateAlertClientUuid.u, + .characteristics = characteristicDefinition}, + {0}, + } { +} + +void ImmediateAlertClient::Init() { +} + +bool ImmediateAlertClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service) { + // if (service == nullptr && error->status == BLE_HS_EDONE) { + // if (isDiscovered) { + // NRF_LOG_INFO("IAS found, starting characteristics discovery"); + + // ble_gattc_disc_all_chrs(connectionHandle, iasStartHandle, iasEndHandle, OnImmediateAlertCharacteristicDiscoveredCallback, this); + // } else { + // NRF_LOG_INFO("IAS not found"); + // onServiceDiscovered(connectionHandle); + // } + // return true; + // } + + // if (service != nullptr && ble_uuid_cmp(&immediateAlertClientUuid.u, &service->uuid.u) == 0) { + // NRF_LOG_INFO("IAS discovered : 0x%x - 0x%x", service->start_handle, service->end_handle); + // isDiscovered = true; + // iasStartHandle = service->start_handle; + // iasEndHandle = service->end_handle; + // } + return false; +} + +int ImmediateAlertClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle, + const ble_gatt_error* error, + const ble_gatt_chr* characteristic) { + + // if (error->status != 0 && error->status != BLE_HS_EDONE) { + // NRF_LOG_INFO("IAS Characteristic discovery ERROR"); + // onServiceDiscovered(conn_handle); + // return 0; + // } + + // if (characteristic == nullptr && error->status == BLE_HS_EDONE) { + // if (!isCharacteristicDiscovered) { + // NRF_LOG_INFO("IAS Characteristic discovery unsuccessful"); + // onServiceDiscovered(conn_handle); + // } + + // return 0; + // } + + // if (characteristic != nullptr && ble_uuid_cmp(&alertLevelCharacteristicUuid.u, &characteristic->uuid.u) == 0) { + // NRF_LOG_INFO("AIS Characteristic discovered : 0x%x", characteristic->val_handle); + // isCharacteristicDiscovered = true; + // alertLevelHandle = characteristic->val_handle; + // } + return 0; +} + +void ImmediateAlertClient::Discover(uint16_t connectionHandle, std::function onServiceDiscovered) { + NRF_LOG_INFO("[IAS] Starting discovery"); + this->onServiceDiscovered = onServiceDiscovered; + // ble_gattc_disc_svc_by_uuid(connectionHandle, &immediateAlertClientUuid.u, OnDiscoveryEventCallback, this); +} + +bool ImmediateAlertClient::sendImmediateAlert(ImmediateAlertClient::Levels level) { + + // auto* om = ble_hs_mbuf_from_flat(&level, 1); + + // uint16_t connectionHandle = systemTask.nimble().connHandle(); + + // if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { + // return false; + // } + + // ble_gattc_write_no_rsp(connectionHandle, alertLevelHandle, om); + // return true; + return false; +} diff --git a/sim/components/ble/ImmediateAlertClient.h b/sim/components/ble/ImmediateAlertClient.h new file mode 100644 index 0000000..b9e8d56 --- /dev/null +++ b/sim/components/ble/ImmediateAlertClient.h @@ -0,0 +1,61 @@ +#pragma once +#define min // workaround: nimble's min/max macros conflict with libstdc++ +#define max +#include +#undef max +#undef min +#include +#include "components/ble/BleClient.h" + +namespace Pinetime { + namespace System { + class SystemTask; + } + + namespace Controllers { + class NotificationManager; + + class ImmediateAlertClient : public BleClient { + public: + enum class Levels : uint8_t { NoAlert = 0, MildAlert = 1, HighAlert = 2 }; + + ImmediateAlertClient(Pinetime::System::SystemTask& systemTask); + void Init(); + + bool OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service); + int OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error* error, const ble_gatt_chr* characteristic); + + bool sendImmediateAlert(Levels level); + + static constexpr const ble_uuid16_t* Uuid() { + return &ImmediateAlertClient::immediateAlertClientUuid; + } + + static constexpr const ble_uuid16_t* AlertLevelCharacteristicUuid() { + return &ImmediateAlertClient::alertLevelCharacteristicUuid; + } + + void Discover(uint16_t connectionHandle, std::function lambda) override; + + private: + Pinetime::System::SystemTask& systemTask; + + static constexpr uint16_t immediateAlertClientId {0x1802}; + static constexpr uint16_t alertLevelId {0x2A06}; + + static constexpr ble_uuid16_t immediateAlertClientUuid {.u {.type = BLE_UUID_TYPE_16}, .value = immediateAlertClientId}; + static constexpr ble_uuid16_t alertLevelCharacteristicUuid {.u {.type = BLE_UUID_TYPE_16}, .value = alertLevelId}; + + bool isDiscovered = false; + uint16_t iasStartHandle; + uint16_t iasEndHandle; + bool isCharacteristicDiscovered = false; + + struct ble_gatt_chr_def characteristicDefinition[3]; + struct ble_gatt_svc_def serviceDefinition[2]; + + uint16_t alertLevelHandle; + std::function onServiceDiscovered; + }; + } +} diff --git a/sim/components/ble/NimbleController.cpp b/sim/components/ble/NimbleController.cpp index fda4155..a015e38 100644 --- a/sim/components/ble/NimbleController.cpp +++ b/sim/components/ble/NimbleController.cpp @@ -45,6 +45,7 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, // currentTimeService {dateTimeController}, musicService {systemTask}, weatherService {dateTimeController}, + iaClient {systemTask}, // batteryInformationService {batteryController}, // immediateAlertService {systemTask, notificationManager}, // heartRateService {systemTask, heartRateController}, @@ -91,6 +92,7 @@ void NimbleController::Init() { musicService.Init(); weatherService.Init(); navService.Init(); + iaClient.Init(); // anService.Init(); // dfuService.Init(); // batteryInformationService.Init(); diff --git a/sim/components/ble/NimbleController.h b/sim/components/ble/NimbleController.h index 8566d1b..a0b7c1a 100644 --- a/sim/components/ble/NimbleController.h +++ b/sim/components/ble/NimbleController.h @@ -16,6 +16,7 @@ //#include "components/ble/DfuService.h" //#include "components/ble/HeartRateService.h" //#include "components/ble/ImmediateAlertService.h" +#include "components/ble/ImmediateAlertClient.h" #include "components/ble/MusicService.h" #include "components/ble/NavigationService.h" //#include "components/ble/ServiceDiscovery.h" @@ -81,6 +82,9 @@ namespace Pinetime { Pinetime::Controllers::SimpleWeatherService& weather() { return weatherService; }; + Pinetime::Controllers::ImmediateAlertClient& immediateAlertClient() { + return iaClient; + }; uint16_t connHandle(); void NotifyBatteryLevel(uint8_t level); @@ -115,6 +119,7 @@ namespace Pinetime { NavigationService navService; // BatteryInformationService batteryInformationService; // ImmediateAlertService immediateAlertService; + ImmediateAlertClient iaClient; // HeartRateService heartRateService; MotionService motionService; // FSService fsService;