Skip to content

Commit 29f8074

Browse files
committed
Refactoring of BLE service discovery : it is now implemented into the classes of the services.
1 parent f90f225 commit 29f8074

10 files changed

Lines changed: 254 additions & 227 deletions

src/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ list(APPEND SOURCE_FILES
369369
components/ble/MusicService.cpp
370370
components/ble/BatteryInformationService.cpp
371371
components/ble/ImmediateAlertService.cpp
372+
components/ble/ServiceDiscovery.cpp
372373
components/firmwarevalidator/FirmwareValidator.cpp
373374
drivers/Cst816s.cpp
374375
FreeRTOS/port.c
@@ -447,6 +448,8 @@ set(INCLUDE_FILES
447448
components/firmwarevalidator/FirmwareValidator.h
448449
components/ble/BatteryInformationService.h
449450
components/ble/ImmediateAlertService.h
451+
components/ble/ServiceDiscovery.h
452+
components/ble/BleClient.h
450453
drivers/Cst816s.h
451454
FreeRTOS/portmacro.h
452455
FreeRTOS/portmacro_cmsis.h

src/components/ble/AlertNotificationClient.cpp

Lines changed: 97 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,143 +3,175 @@
33

44
#include "AlertNotificationClient.h"
55

6-
76
using namespace Pinetime::Controllers;
87
constexpr ble_uuid16_t AlertNotificationClient::ansServiceUuid;
9-
108
constexpr ble_uuid16_t AlertNotificationClient::supportedNewAlertCategoryUuid;
11-
constexpr ble_uuid16_t AlertNotificationClient::supportedUnreadAlertCategoryUuid ;
9+
constexpr ble_uuid16_t AlertNotificationClient::supportedUnreadAlertCategoryUuid;
1210
constexpr ble_uuid16_t AlertNotificationClient::newAlertUuid;
1311
constexpr ble_uuid16_t AlertNotificationClient::unreadAlertStatusUuid;
1412
constexpr 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 &notificationManager) :
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

4575
int 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

77119
int 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

88131
int 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

106154
void 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-
143175
void 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
}

src/components/ble/AlertNotificationClient.h

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,12 @@
33
#include <cstdint>
44
#include <array>
55
#include <host/ble_gap.h>
6+
#include "BleClient.h"
67

78

89
namespace Pinetime {
910
namespace Controllers {
10-
int NewAlertSubcribeCallback(uint16_t conn_handle,
11-
const struct ble_gatt_error *error,
12-
struct ble_gatt_attr *attr,
13-
void *arg);
14-
15-
class AlertNotificationClient {
11+
class AlertNotificationClient : public BleClient {
1612
public:
1713
explicit AlertNotificationClient(Pinetime::System::SystemTask &systemTask,
1814
Pinetime::Controllers::NotificationManager &notificationManager);
@@ -24,14 +20,9 @@ namespace Pinetime {
2420
int OnDescriptorDiscoveryEventCallback(uint16_t connectionHandle, const ble_gatt_error *error,
2521
uint16_t characteristicValueHandle, const ble_gatt_dsc *descriptor);
2622
void OnNotification(ble_gap_event *event);
27-
bool IsDiscovered() const;
28-
uint16_t StartHandle() const;
29-
uint16_t EndHandle() const;
3023
void Reset();
24+
void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override;
3125

32-
static constexpr const ble_uuid16_t &Uuid() { return ansServiceUuid; }
33-
34-
uint16_t NewAlerthandle() const;
3526
private:
3627
static constexpr uint16_t ansServiceId{0x1811};
3728
static constexpr uint16_t supportedNewAlertCategoryId = 0x2a47;
@@ -77,6 +68,9 @@ namespace Pinetime {
7768
bool isDiscovered = false;
7869
Pinetime::System::SystemTask &systemTask;
7970
Pinetime::Controllers::NotificationManager &notificationManager;
71+
std::function<void(uint16_t)> onServiceDiscovered;
72+
bool isCharacteristicDiscovered = false;
73+
bool isDescriptorFound = false;
8074
};
8175
}
8276
}

src/components/ble/BleClient.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
#include <functional>
4+
5+
namespace Pinetime {
6+
namespace Controllers{
7+
class BleClient {
8+
public:
9+
virtual void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) = 0;
10+
};
11+
}
12+
}

0 commit comments

Comments
 (0)