diff options
author | JF002 <JF002@users.noreply.github.com> | 2020-10-30 14:16:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-30 14:16:04 +0100 |
commit | 0e97db1c30748d9893291a27504bb55723f58e7d (patch) | |
tree | 9b410aee92af82099619c56a4d25c9c6b7c99e68 /src/components/ble/AlertNotificationClient.cpp | |
parent | cb9e8815d8bc6ce71fd8e97f3e3dae402658ce1f (diff) | |
parent | 29f8074fcb844cf9668a5bf071e9cffa47299c99 (diff) |
Merge pull request #118 from JF002/improve-ble-connection
Improve ble connection
Diffstat (limited to 'src/components/ble/AlertNotificationClient.cpp')
-rw-r--r-- | src/components/ble/AlertNotificationClient.cpp | 159 |
1 files changed, 106 insertions, 53 deletions
diff --git a/src/components/ble/AlertNotificationClient.cpp b/src/components/ble/AlertNotificationClient.cpp index 40970e0b..abe41099 100644 --- a/src/components/ble/AlertNotificationClient.cpp +++ b/src/components/ble/AlertNotificationClient.cpp @@ -3,84 +3,127 @@ #include "AlertNotificationClient.h" - using namespace Pinetime::Controllers; constexpr ble_uuid16_t AlertNotificationClient::ansServiceUuid; - constexpr ble_uuid16_t AlertNotificationClient::supportedNewAlertCategoryUuid; -constexpr ble_uuid16_t AlertNotificationClient::supportedUnreadAlertCategoryUuid ; +constexpr ble_uuid16_t AlertNotificationClient::supportedUnreadAlertCategoryUuid; constexpr ble_uuid16_t AlertNotificationClient::newAlertUuid; constexpr ble_uuid16_t AlertNotificationClient::unreadAlertStatusUuid; constexpr ble_uuid16_t AlertNotificationClient::controlPointUuid; -int Pinetime::Controllers::NewAlertSubcribeCallback(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) { - auto client = static_cast<AlertNotificationClient*>(arg); - return client->OnNewAlertSubcribe(conn_handle, error, attr); -} +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<AlertNotificationClient *>(arg); + return client->OnDiscoveryEvent(conn_handle, error, service); + } -AlertNotificationClient::AlertNotificationClient(Pinetime::System::SystemTask& systemTask, - Pinetime::Controllers::NotificationManager& notificationManager) : - systemTask{systemTask}, notificationManager{notificationManager}{ + int OnAlertNotificationCharacteristicDiscoveredCallback(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg) { + auto client = static_cast<AlertNotificationClient *>(arg); + return client->OnCharacteristicsDiscoveryEvent(conn_handle, error, chr); + } + + int OnAlertNotificationDescriptorDiscoveryEventCallback(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t chr_val_handle, + const struct ble_gatt_dsc *dsc, + void *arg) { + auto client = static_cast<AlertNotificationClient *>(arg); + return client->OnDescriptorDiscoveryEventCallback(conn_handle, error, chr_val_handle, dsc); + } + + int NewAlertSubcribeCallback(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { + auto client = static_cast<AlertNotificationClient *>(arg); + return client->OnNewAlertSubcribe(conn_handle, error, attr); + } +} +AlertNotificationClient::AlertNotificationClient(Pinetime::System::SystemTask &systemTask, + Pinetime::Controllers::NotificationManager ¬ificationManager) : + systemTask{systemTask}, notificationManager{notificationManager} { } -bool AlertNotificationClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, const ble_gatt_svc *service) { - if(service == nullptr && error->status == BLE_HS_EDONE) { - NRF_LOG_INFO("ANS Discovery complete"); +bool AlertNotificationClient::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("ANS Discovery found, starting characteristics discovery"); + + ble_gattc_disc_all_chrs(connectionHandle, ansStartHandle, ansEndHandle, + OnAlertNotificationCharacteristicDiscoveredCallback, this); + } else { + NRF_LOG_INFO("ANS not found"); + onServiceDiscovered(connectionHandle); + } return true; } - if(service != nullptr && ble_uuid_cmp(((ble_uuid_t*)&ansServiceUuid), &service->uuid.u) == 0) { - NRF_LOG_INFO("ANS discovered : 0x%x", service->start_handle); - ansStartHandle = service->start_handle; - ansEndHandle = service->end_handle; - isDiscovered = true; + if (service != nullptr && ble_uuid_cmp(((ble_uuid_t *) &ansServiceUuid), &service->uuid.u) == 0) { + NRF_LOG_INFO("ANS discovered : 0x%x - 0x%x", service->start_handle, service->end_handle); + ansStartHandle = service->start_handle; + ansEndHandle = service->end_handle; + isDiscovered = true; } return false; } int AlertNotificationClient::OnCharacteristicsDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, - const ble_gatt_chr *characteristic) { - if(error->status != 0 && error->status != BLE_HS_EDONE) { + const ble_gatt_chr *characteristic) { + if (error->status != 0 && error->status != BLE_HS_EDONE) { NRF_LOG_INFO("ANS Characteristic discovery ERROR"); + onServiceDiscovered(connectionHandle); return 0; } - if(characteristic == nullptr && error->status == BLE_HS_EDONE) { + if (characteristic == nullptr && error->status == BLE_HS_EDONE) { NRF_LOG_INFO("ANS Characteristic discovery complete"); + if (isCharacteristicDiscovered) { + ble_gattc_disc_all_dscs(connectionHandle, + newAlertHandle, ansEndHandle, + OnAlertNotificationDescriptorDiscoveryEventCallback, this); + } else + onServiceDiscovered(connectionHandle); } else { - if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&supportedNewAlertCategoryUuid), &characteristic->uuid.u) == 0) { + if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &supportedNewAlertCategoryUuid), &characteristic->uuid.u) == 0) { NRF_LOG_INFO("ANS Characteristic discovered : supportedNewAlertCategoryUuid"); supportedNewAlertCategoryHandle = characteristic->val_handle; - } else if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&supportedUnreadAlertCategoryUuid), &characteristic->uuid.u) == 0) { + } else if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &supportedUnreadAlertCategoryUuid), &characteristic->uuid.u) == 0) { NRF_LOG_INFO("ANS Characteristic discovered : supportedUnreadAlertCategoryUuid"); supportedUnreadAlertCategoryHandle = characteristic->val_handle; - } else if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&newAlertUuid), &characteristic->uuid.u) == 0) { + } else if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &newAlertUuid), &characteristic->uuid.u) == 0) { NRF_LOG_INFO("ANS Characteristic discovered : newAlertUuid"); newAlertHandle = characteristic->val_handle; newAlertDefHandle = characteristic->def_handle; - } else if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&unreadAlertStatusUuid), &characteristic->uuid.u) == 0) { + isCharacteristicDiscovered = true; + } else if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &unreadAlertStatusUuid), &characteristic->uuid.u) == 0) { NRF_LOG_INFO("ANS Characteristic discovered : unreadAlertStatusUuid"); unreadAlertStatusHandle = characteristic->val_handle; - } else if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&controlPointUuid), &characteristic->uuid.u) == 0) { + } else if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &controlPointUuid), &characteristic->uuid.u) == 0) { NRF_LOG_INFO("ANS Characteristic discovered : controlPointUuid"); controlPointHandle = characteristic->val_handle; - }else - NRF_LOG_INFO("ANS Characteristic discovered : 0x%x", characteristic->val_handle); - } + } else NRF_LOG_INFO("ANS Characteristic discovered : 0x%x", characteristic->val_handle); + } return 0; } int AlertNotificationClient::OnNewAlertSubcribe(uint16_t connectionHandle, const ble_gatt_error *error, ble_gatt_attr *attribute) { - if(error->status == 0) { + if (error->status == 0) { NRF_LOG_INFO("ANS New alert subscribe OK"); } else { NRF_LOG_INFO("ANS New alert subscribe ERROR"); } + onServiceDiscovered(connectionHandle); return 0; } @@ -88,35 +131,40 @@ int AlertNotificationClient::OnNewAlertSubcribe(uint16_t connectionHandle, const int AlertNotificationClient::OnDescriptorDiscoveryEventCallback(uint16_t connectionHandle, const ble_gatt_error *error, uint16_t characteristicValueHandle, const ble_gatt_dsc *descriptor) { - if(error->status == 0) { - if(characteristicValueHandle == newAlertHandle && ble_uuid_cmp(((ble_uuid_t*)&newAlertUuid), &descriptor->uuid.u)) { - if(newAlertDescriptorHandle == 0) { + if (error->status == 0) { + if (characteristicValueHandle == newAlertHandle && + ble_uuid_cmp(((ble_uuid_t *) &newAlertUuid), &descriptor->uuid.u)) { + if (newAlertDescriptorHandle == 0) { NRF_LOG_INFO("ANS Descriptor discovered : %d", descriptor->handle); newAlertDescriptorHandle = descriptor->handle; + isDescriptorFound = true; uint8_t value[2]; value[0] = 1; value[1] = 0; ble_gattc_write_flat(connectionHandle, newAlertDescriptorHandle, value, sizeof(value), NewAlertSubcribeCallback, this); } } + } else { + if (!isDescriptorFound) + onServiceDiscovered(connectionHandle); } return 0; } void AlertNotificationClient::OnNotification(ble_gap_event *event) { - if(event->notify_rx.attr_handle == newAlertHandle) { + if (event->notify_rx.attr_handle == newAlertHandle) { constexpr size_t stringTerminatorSize = 1; // end of string '\0' constexpr size_t headerSize = 3; - const auto maxMessageSize {NotificationManager::MaximumMessageSize()}; + const auto maxMessageSize{NotificationManager::MaximumMessageSize()}; const auto maxBufferSize{maxMessageSize + headerSize}; const auto dbgPacketLen = OS_MBUF_PKTLEN(event->notify_rx.om); size_t bufferSize = min(dbgPacketLen + stringTerminatorSize, maxBufferSize); - auto messageSize = min(maxMessageSize, (bufferSize-headerSize)); + auto messageSize = min(maxMessageSize, (bufferSize - headerSize)); NotificationManager::Notification notif; - os_mbuf_copydata(event->notify_rx.om, headerSize, messageSize-1, notif.message.data()); - notif.message[messageSize-1] = '\0'; + os_mbuf_copydata(event->notify_rx.om, headerSize, messageSize - 1, notif.message.data()); + notif.message[messageSize - 1] = '\0'; notif.category = Pinetime::Controllers::NotificationManager::Categories::SimpleAlert; notificationManager.Push(std::move(notif)); @@ -124,18 +172,23 @@ void AlertNotificationClient::OnNotification(ble_gap_event *event) { } } -bool AlertNotificationClient::IsDiscovered() const { - return isDiscovered; -} - -uint16_t AlertNotificationClient::StartHandle() const { - return ansStartHandle; -} - -uint16_t AlertNotificationClient::EndHandle() const { - return ansEndHandle; +void AlertNotificationClient::Reset() { + ansStartHandle = 0; + ansEndHandle = 0; + supportedNewAlertCategoryHandle = 0; + supportedUnreadAlertCategoryHandle = 0; + newAlertHandle = 0; + newAlertDescriptorHandle = 0; + newAlertDefHandle = 0; + unreadAlertStatusHandle = 0; + controlPointHandle = 0; + isDiscovered = false; + isCharacteristicDiscovered = false; + isDescriptorFound = false; } -uint16_t AlertNotificationClient::NewAlerthandle() const { - return newAlertHandle; +void AlertNotificationClient::Discover(uint16_t connectionHandle, std::function<void(uint16_t)> onServiceDiscovered) { + NRF_LOG_INFO("[ANS] Starting discovery"); + this->onServiceDiscovered = onServiceDiscovered; + ble_gattc_disc_svc_by_uuid(connectionHandle, &ansServiceUuid.u, OnDiscoveryEventCallback, this); } |