ref: 0.13.0
src/components/ble/AlertNotificationService.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
#include "AlertNotificationService.h" #include <hal/nrf_rtc.h> #include <cstring> #include <algorithm> #include "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 = (ble_uuid_t *) &ansCharUuid, .access_cb = AlertNotificationCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE }, { .uuid = (ble_uuid_t *) ¬ificationEventUuid, .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 = (ble_uuid_t *) &ansUuid, .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}; const auto dbgPacketLen = OS_MBUF_PKTLEN(ctxt->om); size_t bufferSize = std::min(dbgPacketLen + 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'; // 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::SystemTask::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); } |