diff options
| author | Michele Bini <michele.bini@gmail.com> | 2022-04-13 18:53:16 (GMT) |
|---|---|---|
| committer | Michele Bini <michele.bini@gmail.com> | 2022-04-13 18:53:16 (GMT) |
| commit | 531c1172a2357d53b214aaf7b29efee47d9b32e5 (patch) | |
| tree | e9c008f13900e1d3c63332a3bbc305754f8ae35c /src/components/ble/AlertNotificationService.cpp | |
| parent | 27fa6bba08766831fe143fe5ca13767bedcd9072 (diff) | |
Revert "Sans notification (notification manager retained as it seems to be used by the dfu manager)"ultraredux2
This reverts commit 569e6fea41c13f33ad1374bb80ca489aaf4a7037.
Diffstat (limited to 'src/components/ble/AlertNotificationService.cpp')
| -rw-r--r-- | src/components/ble/AlertNotificationService.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/components/ble/AlertNotificationService.cpp b/src/components/ble/AlertNotificationService.cpp new file mode 100644 index 0000000..0481912 --- /dev/null +++ b/src/components/ble/AlertNotificationService.cpp @@ -0,0 +1,124 @@ +#include "components/ble/AlertNotificationService.h" +#include <hal/nrf_rtc.h> +#include <cstring> +#include <algorithm> +#include "components/ble/NotificationManager.h" +#include "systemtask/SystemTask.h" + +using namespace Pinetime::Controllers; + +constexpr ble_uuid16_t AlertNotificationService::ansUuid; +constexpr ble_uuid16_t AlertNotificationService::ansCharUuid; +constexpr ble_uuid128_t AlertNotificationService::notificationEventUuid; + +int AlertNotificationCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { + auto anService = static_cast<AlertNotificationService*>(arg); + return anService->OnAlert(conn_handle, attr_handle, ctxt); +} + +void AlertNotificationService::Init() { + int res; + res = ble_gatts_count_cfg(serviceDefinition); + ASSERT(res == 0); + + res = ble_gatts_add_svcs(serviceDefinition); + ASSERT(res == 0); +} + +AlertNotificationService::AlertNotificationService(System::SystemTask& systemTask, NotificationManager& notificationManager) + : characteristicDefinition {{.uuid = &ansCharUuid.u, .access_cb = AlertNotificationCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE}, + {.uuid = ¬ificationEventUuid.u, + .access_cb = AlertNotificationCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_NOTIFY, + .val_handle = &eventHandle}, + {0}}, + serviceDefinition { + {/* Device Information Service */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &ansUuid.u, + .characteristics = characteristicDefinition}, + {0}, + }, + systemTask {systemTask}, + notificationManager {notificationManager} { +} + +int AlertNotificationService::OnAlert(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) { + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + constexpr size_t stringTerminatorSize = 1; // end of string '\0' + constexpr size_t headerSize = 3; + const auto maxMessageSize {NotificationManager::MaximumMessageSize()}; + const auto maxBufferSize {maxMessageSize + headerSize}; + + // Ignore notifications with empty message + const auto packetLen = OS_MBUF_PKTLEN(ctxt->om); + if (packetLen <= headerSize) { + return 0; + } + + size_t bufferSize = std::min(packetLen + stringTerminatorSize, maxBufferSize); + auto messageSize = std::min(maxMessageSize, (bufferSize - headerSize)); + Categories category; + + NotificationManager::Notification notif; + os_mbuf_copydata(ctxt->om, headerSize, messageSize - 1, notif.message.data()); + os_mbuf_copydata(ctxt->om, 0, 1, &category); + notif.message[messageSize - 1] = '\0'; + notif.size = messageSize; + + // TODO convert all ANS categories to NotificationController categories + switch (category) { + case Categories::Call: + notif.category = Pinetime::Controllers::NotificationManager::Categories::IncomingCall; + break; + default: + notif.category = Pinetime::Controllers::NotificationManager::Categories::SimpleAlert; + break; + } + + auto event = Pinetime::System::Messages::OnNewNotification; + notificationManager.Push(std::move(notif)); + systemTask.PushMessage(event); + } + return 0; +} + +void AlertNotificationService::AcceptIncomingCall() { + auto response = IncomingCallResponses::Answer; + auto* om = ble_hs_mbuf_from_flat(&response, 1); + + uint16_t connectionHandle = systemTask.nimble().connHandle(); + + if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { + return; + } + + ble_gattc_notify_custom(connectionHandle, eventHandle, om); +} + +void AlertNotificationService::RejectIncomingCall() { + auto response = IncomingCallResponses::Reject; + auto* om = ble_hs_mbuf_from_flat(&response, 1); + + uint16_t connectionHandle = systemTask.nimble().connHandle(); + + if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { + return; + } + + ble_gattc_notify_custom(connectionHandle, eventHandle, om); +} + +void AlertNotificationService::MuteIncomingCall() { + auto response = IncomingCallResponses::Mute; + auto* om = ble_hs_mbuf_from_flat(&response, 1); + + uint16_t connectionHandle = systemTask.nimble().connHandle(); + + if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { + return; + } + + ble_gattc_notify_custom(connectionHandle, eventHandle, om); +} |
