33
44#include " AlertNotificationClient.h"
55
6-
76using namespace Pinetime ::Controllers;
87constexpr ble_uuid16_t AlertNotificationClient::ansServiceUuid;
9-
108constexpr ble_uuid16_t AlertNotificationClient::supportedNewAlertCategoryUuid;
11- constexpr ble_uuid16_t AlertNotificationClient::supportedUnreadAlertCategoryUuid ;
9+ constexpr ble_uuid16_t AlertNotificationClient::supportedUnreadAlertCategoryUuid;
1210constexpr ble_uuid16_t AlertNotificationClient::newAlertUuid;
1311constexpr ble_uuid16_t AlertNotificationClient::unreadAlertStatusUuid;
1412constexpr ble_uuid16_t AlertNotificationClient::controlPointUuid;
1513
16- int Pinetime::Controllers::NewAlertSubcribeCallback (uint16_t conn_handle,
17- const struct ble_gatt_error *error,
18- struct ble_gatt_attr *attr,
19- void *arg) {
20- auto client = static_cast <AlertNotificationClient*>(arg);
21- return client->OnNewAlertSubcribe (conn_handle, error, attr);
22- }
14+ namespace {
15+ int
16+ OnDiscoveryEventCallback (uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *service,
17+ void *arg) {
18+ auto client = static_cast <AlertNotificationClient *>(arg);
19+ return client->OnDiscoveryEvent (conn_handle, error, service);
20+ }
21+
22+ int OnAlertNotificationCharacteristicDiscoveredCallback (uint16_t conn_handle, const struct ble_gatt_error *error,
23+ const struct ble_gatt_chr *chr, void *arg) {
24+ auto client = static_cast <AlertNotificationClient *>(arg);
25+ return client->OnCharacteristicsDiscoveryEvent (conn_handle, error, chr);
26+ }
2327
24- AlertNotificationClient::AlertNotificationClient (Pinetime::System::SystemTask& systemTask,
25- Pinetime::Controllers::NotificationManager& notificationManager) :
26- systemTask{systemTask}, notificationManager{notificationManager}{
28+ int OnAlertNotificationDescriptorDiscoveryEventCallback (uint16_t conn_handle,
29+ const struct ble_gatt_error *error,
30+ uint16_t chr_val_handle,
31+ const struct ble_gatt_dsc *dsc,
32+ void *arg) {
33+ auto client = static_cast <AlertNotificationClient *>(arg);
34+ return client->OnDescriptorDiscoveryEventCallback (conn_handle, error, chr_val_handle, dsc);
35+ }
36+
37+ int NewAlertSubcribeCallback (uint16_t conn_handle,
38+ const struct ble_gatt_error *error,
39+ struct ble_gatt_attr *attr,
40+ void *arg) {
41+ auto client = static_cast <AlertNotificationClient *>(arg);
42+ return client->OnNewAlertSubcribe (conn_handle, error, attr);
43+ }
44+ }
2745
46+ AlertNotificationClient::AlertNotificationClient (Pinetime::System::SystemTask &systemTask,
47+ Pinetime::Controllers::NotificationManager ¬ificationManager) :
48+ systemTask{systemTask}, notificationManager{notificationManager} {
2849}
2950
30- bool AlertNotificationClient::OnDiscoveryEvent (uint16_t connectionHandle, const ble_gatt_error *error, const ble_gatt_svc *service) {
31- if (service == nullptr && error->status == BLE_HS_EDONE) {
32- NRF_LOG_INFO (" ANS Discovery complete" );
51+ bool AlertNotificationClient::OnDiscoveryEvent (uint16_t connectionHandle, const ble_gatt_error *error,
52+ const ble_gatt_svc *service) {
53+ if (service == nullptr && error->status == BLE_HS_EDONE) {
54+ if (isDiscovered) {
55+ NRF_LOG_INFO (" ANS Discovery found, starting characteristics discovery" );
56+
57+ ble_gattc_disc_all_chrs (connectionHandle, ansStartHandle, ansEndHandle,
58+ OnAlertNotificationCharacteristicDiscoveredCallback, this );
59+ } else {
60+ NRF_LOG_INFO (" ANS not found" );
61+ onServiceDiscovered (connectionHandle);
62+ }
3363 return true ;
3464 }
3565
36- if (service != nullptr && ble_uuid_cmp (((ble_uuid_t *) &ansServiceUuid), &service->uuid .u ) == 0 ) {
37- NRF_LOG_INFO (" ANS discovered : 0x%x" , service->start_handle );
38- ansStartHandle = service->start_handle ;
39- ansEndHandle = service->end_handle ;
40- isDiscovered = true ;
66+ if (service != nullptr && ble_uuid_cmp (((ble_uuid_t *) &ansServiceUuid), &service->uuid .u ) == 0 ) {
67+ NRF_LOG_INFO (" ANS discovered : 0x%x - 0x%x " , service->start_handle , service-> end_handle );
68+ ansStartHandle = service->start_handle ;
69+ ansEndHandle = service->end_handle ;
70+ isDiscovered = true ;
4171 }
4272 return false ;
4373}
4474
4575int AlertNotificationClient::OnCharacteristicsDiscoveryEvent (uint16_t connectionHandle, const ble_gatt_error *error,
46- const ble_gatt_chr *characteristic) {
47- if (error->status != 0 && error->status != BLE_HS_EDONE) {
76+ const ble_gatt_chr *characteristic) {
77+ if (error->status != 0 && error->status != BLE_HS_EDONE) {
4878 NRF_LOG_INFO (" ANS Characteristic discovery ERROR" );
79+ onServiceDiscovered (connectionHandle);
4980 return 0 ;
5081 }
5182
52- if (characteristic == nullptr && error->status == BLE_HS_EDONE) {
83+ if (characteristic == nullptr && error->status == BLE_HS_EDONE) {
5384 NRF_LOG_INFO (" ANS Characteristic discovery complete" );
85+ if (isCharacteristicDiscovered) {
86+ ble_gattc_disc_all_dscs (connectionHandle,
87+ newAlertHandle, ansEndHandle,
88+ OnAlertNotificationDescriptorDiscoveryEventCallback, this );
89+ } else
90+ onServiceDiscovered (connectionHandle);
5491 } else {
55- if (characteristic != nullptr && ble_uuid_cmp (((ble_uuid_t *)&supportedNewAlertCategoryUuid), &characteristic->uuid .u ) == 0 ) {
92+ if (characteristic != nullptr &&
93+ ble_uuid_cmp (((ble_uuid_t *) &supportedNewAlertCategoryUuid), &characteristic->uuid .u ) == 0 ) {
5694 NRF_LOG_INFO (" ANS Characteristic discovered : supportedNewAlertCategoryUuid" );
5795 supportedNewAlertCategoryHandle = characteristic->val_handle ;
58- } else if (characteristic != nullptr && ble_uuid_cmp (((ble_uuid_t *)&supportedUnreadAlertCategoryUuid), &characteristic->uuid .u ) == 0 ) {
96+ } else if (characteristic != nullptr &&
97+ ble_uuid_cmp (((ble_uuid_t *) &supportedUnreadAlertCategoryUuid), &characteristic->uuid .u ) == 0 ) {
5998 NRF_LOG_INFO (" ANS Characteristic discovered : supportedUnreadAlertCategoryUuid" );
6099 supportedUnreadAlertCategoryHandle = characteristic->val_handle ;
61- } else if (characteristic != nullptr && ble_uuid_cmp (((ble_uuid_t *)&newAlertUuid), &characteristic->uuid .u ) == 0 ) {
100+ } else if (characteristic != nullptr &&
101+ ble_uuid_cmp (((ble_uuid_t *) &newAlertUuid), &characteristic->uuid .u ) == 0 ) {
62102 NRF_LOG_INFO (" ANS Characteristic discovered : newAlertUuid" );
63103 newAlertHandle = characteristic->val_handle ;
64104 newAlertDefHandle = characteristic->def_handle ;
65- } else if (characteristic != nullptr && ble_uuid_cmp (((ble_uuid_t *)&unreadAlertStatusUuid), &characteristic->uuid .u ) == 0 ) {
105+ isCharacteristicDiscovered = true ;
106+ } else if (characteristic != nullptr &&
107+ ble_uuid_cmp (((ble_uuid_t *) &unreadAlertStatusUuid), &characteristic->uuid .u ) == 0 ) {
66108 NRF_LOG_INFO (" ANS Characteristic discovered : unreadAlertStatusUuid" );
67109 unreadAlertStatusHandle = characteristic->val_handle ;
68- } else if (characteristic != nullptr && ble_uuid_cmp (((ble_uuid_t *)&controlPointUuid), &characteristic->uuid .u ) == 0 ) {
110+ } else if (characteristic != nullptr &&
111+ ble_uuid_cmp (((ble_uuid_t *) &controlPointUuid), &characteristic->uuid .u ) == 0 ) {
69112 NRF_LOG_INFO (" ANS Characteristic discovered : controlPointUuid" );
70113 controlPointHandle = characteristic->val_handle ;
71- }else
72- NRF_LOG_INFO (" ANS Characteristic discovered : 0x%x" , characteristic->val_handle );
73- }
114+ } else NRF_LOG_INFO (" ANS Characteristic discovered : 0x%x" , characteristic->val_handle );
115+ }
74116 return 0 ;
75117}
76118
77119int AlertNotificationClient::OnNewAlertSubcribe (uint16_t connectionHandle, const ble_gatt_error *error,
78120 ble_gatt_attr *attribute) {
79- if (error->status == 0 ) {
121+ if (error->status == 0 ) {
80122 NRF_LOG_INFO (" ANS New alert subscribe OK" );
81123 } else {
82124 NRF_LOG_INFO (" ANS New alert subscribe ERROR" );
83125 }
126+ onServiceDiscovered (connectionHandle);
84127
85128 return 0 ;
86129}
87130
88131int AlertNotificationClient::OnDescriptorDiscoveryEventCallback (uint16_t connectionHandle, const ble_gatt_error *error,
89132 uint16_t characteristicValueHandle,
90133 const ble_gatt_dsc *descriptor) {
91- if (error->status == 0 ) {
92- if (characteristicValueHandle == newAlertHandle && ble_uuid_cmp (((ble_uuid_t *)&newAlertUuid), &descriptor->uuid .u )) {
93- if (newAlertDescriptorHandle == 0 ) {
134+ if (error->status == 0 ) {
135+ if (characteristicValueHandle == newAlertHandle &&
136+ ble_uuid_cmp (((ble_uuid_t *) &newAlertUuid), &descriptor->uuid .u )) {
137+ if (newAlertDescriptorHandle == 0 ) {
94138 NRF_LOG_INFO (" ANS Descriptor discovered : %d" , descriptor->handle );
95139 newAlertDescriptorHandle = descriptor->handle ;
140+ isDescriptorFound = true ;
96141 uint8_t value[2 ];
97142 value[0 ] = 1 ;
98143 value[1 ] = 0 ;
99144 ble_gattc_write_flat (connectionHandle, newAlertDescriptorHandle, value, sizeof (value), NewAlertSubcribeCallback, this );
100145 }
101146 }
147+ } else {
148+ if (!isDescriptorFound)
149+ onServiceDiscovered (connectionHandle);
102150 }
103151 return 0 ;
104152}
105153
106154void AlertNotificationClient::OnNotification (ble_gap_event *event) {
107- if (event->notify_rx .attr_handle == newAlertHandle) {
155+ if (event->notify_rx .attr_handle == newAlertHandle) {
108156 constexpr size_t stringTerminatorSize = 1 ; // end of string '\0'
109157 constexpr size_t headerSize = 3 ;
110- const auto maxMessageSize {NotificationManager::MaximumMessageSize ()};
158+ const auto maxMessageSize{NotificationManager::MaximumMessageSize ()};
111159 const auto maxBufferSize{maxMessageSize + headerSize};
112160
113161 const auto dbgPacketLen = OS_MBUF_PKTLEN (event->notify_rx .om );
114162 size_t bufferSize = min (dbgPacketLen + stringTerminatorSize, maxBufferSize);
115- auto messageSize = min (maxMessageSize, (bufferSize- headerSize));
163+ auto messageSize = min (maxMessageSize, (bufferSize - headerSize));
116164
117165 NotificationManager::Notification notif;
118- os_mbuf_copydata (event->notify_rx .om , headerSize, messageSize- 1 , notif.message .data ());
119- notif.message [messageSize- 1 ] = ' \0 ' ;
166+ os_mbuf_copydata (event->notify_rx .om , headerSize, messageSize - 1 , notif.message .data ());
167+ notif.message [messageSize - 1 ] = ' \0 ' ;
120168 notif.category = Pinetime::Controllers::NotificationManager::Categories::SimpleAlert;
121169 notificationManager.Push (std::move (notif));
122170
123171 systemTask.PushMessage (Pinetime::System::SystemTask::Messages::OnNewNotification);
124172 }
125173}
126174
127- bool AlertNotificationClient::IsDiscovered () const {
128- return isDiscovered;
129- }
130-
131- uint16_t AlertNotificationClient::StartHandle () const {
132- return ansStartHandle;
133- }
134-
135- uint16_t AlertNotificationClient::EndHandle () const {
136- return ansEndHandle;
137- }
138-
139- uint16_t AlertNotificationClient::NewAlerthandle () const {
140- return newAlertHandle;
141- }
142-
143175void AlertNotificationClient::Reset () {
144176 ansStartHandle = 0 ;
145177 ansEndHandle = 0 ;
@@ -151,4 +183,12 @@ void AlertNotificationClient::Reset() {
151183 unreadAlertStatusHandle = 0 ;
152184 controlPointHandle = 0 ;
153185 isDiscovered = false ;
186+ isCharacteristicDiscovered = false ;
187+ isDescriptorFound = false ;
188+ }
189+
190+ void AlertNotificationClient::Discover (uint16_t connectionHandle, std::function<void (uint16_t )> onServiceDiscovered) {
191+ NRF_LOG_INFO (" [ANS] Starting discovery" );
192+ this ->onServiceDiscovered = onServiceDiscovered;
193+ ble_gattc_disc_svc_by_uuid (connectionHandle, &ansServiceUuid.u , OnDiscoveryEventCallback, this );
154194}
0 commit comments