diff options
author | Sven Gothel <[email protected]> | 2021-10-19 06:12:02 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2021-10-19 06:12:02 +0200 |
commit | 9507aa383965d5ab05375169b25c119d9258858f (patch) | |
tree | e44fa0044eb03515843b176d276ccffa31bd4d8d | |
parent | 62594a9b9e2b7004f611d01ac98c34d2ed2c96e1 (diff) |
BTDevice/BTGattHandler: Add send[Notification|Indication](..) commands
-rw-r--r-- | api/direct_bt/BTDevice.hpp | 14 | ||||
-rw-r--r-- | api/direct_bt/BTGattHandler.hpp | 14 | ||||
-rw-r--r-- | src/direct_bt/BTDevice.cpp | 19 | ||||
-rw-r--r-- | src/direct_bt/BTGattHandler.cpp | 37 |
4 files changed, 84 insertions, 0 deletions
diff --git a/api/direct_bt/BTDevice.hpp b/api/direct_bt/BTDevice.hpp index f201a31d..6fc0364f 100644 --- a/api/direct_bt/BTDevice.hpp +++ b/api/direct_bt/BTDevice.hpp @@ -1004,6 +1004,20 @@ namespace direct_bt { std::shared_ptr<GattGenericAccessSvc> getGattGenericAccess(); /** + * + * @param value + * @return + */ + bool sendNotification(const uint16_t handle, const jau::TROOctets & value); + + /** + * + * @param value + * @return + */ + bool sendIndication(const uint16_t handle, const jau::TROOctets & value); + + /** * Issues a GATT ping to the device, validating whether it is still reachable. * <p> * This method could be periodically utilized to shorten the underlying OS disconnect period diff --git a/api/direct_bt/BTGattHandler.hpp b/api/direct_bt/BTGattHandler.hpp index 4f3987c9..f86bc25a 100644 --- a/api/direct_bt/BTGattHandler.hpp +++ b/api/direct_bt/BTGattHandler.hpp @@ -489,6 +489,20 @@ namespace direct_bt { bool configNotificationIndication(BTGattDesc & cd, const bool enableNotification, const bool enableIndication); /** + * + * @param value + * @return + */ + bool sendNotification(const uint16_t handle, const jau::TROOctets & value); + + /** + * + * @param value + * @return + */ + bool sendIndication(const uint16_t handle, const jau::TROOctets & value); + + /** * Add the given listener to the list if not already present. * <p> * Returns true if the given listener is not element of the list and has been newly added, diff --git a/src/direct_bt/BTDevice.cpp b/src/direct_bt/BTDevice.cpp index aa078c50..bf96eb94 100644 --- a/src/direct_bt/BTDevice.cpp +++ b/src/direct_bt/BTDevice.cpp @@ -1680,6 +1680,25 @@ BTGattCharRef BTDevice::findGattChar(const jau::uuid_t& service_uuid, const jau return service->findGattChar(char_uuid); } +bool BTDevice::sendNotification(const uint16_t handle, const jau::TROOctets & value) { + std::shared_ptr<BTGattHandler> gh = getGattHandler(); + if( nullptr == gh || !gh->isConnected() ) { + WARN_PRINT("BTDevice::sendNotification: GATTHandler not connected -> disconnected on %s", toString().c_str()); + return false; + } + return gh->sendNotification(handle, value); +} + +bool BTDevice::sendIndication(const uint16_t handle, const jau::TROOctets & value) { + std::shared_ptr<BTGattHandler> gh = getGattHandler(); + if( nullptr == gh || !gh->isConnected() ) { + WARN_PRINT("BTDevice::sendIndication: GATTHandler not connected -> disconnected on %s", toString().c_str()); + return false; + } + return gh->sendIndication(handle, value); +} + + bool BTDevice::pingGATT() noexcept { std::shared_ptr<BTGattHandler> gh = getGattHandler(); if( nullptr == gh || !gh->isConnected() ) { diff --git a/src/direct_bt/BTGattHandler.cpp b/src/direct_bt/BTGattHandler.cpp index d0f7ad69..5836fa2c 100644 --- a/src/direct_bt/BTGattHandler.cpp +++ b/src/direct_bt/BTGattHandler.cpp @@ -1230,6 +1230,43 @@ uint16_t BTGattHandler::exchangeMTUImpl(const uint16_t clientMaxMTU, const int32 return mtu; } +bool BTGattHandler::sendNotification(const uint16_t handle, const jau::TROOctets & value) { + if( GATTRole::Server != role ) { + ERR_PRINT("BTDevice::sendNotification: GATTRole not server"); + return false; + } + if( !hasHandle(handle) ) { + ERR_PRINT("BTDevice::sendNotification: invalid handle %s", jau::to_hexstring(handle).c_str()); + return false; + } + AttHandleValueRcv data(true /* isNotify */, handle, value); + COND_PRINT(env.DEBUG_DATA, "GATT SEND NTF: %s to %s", data.toString().c_str(), toString().c_str()); + send(data); + return true; +} + +bool BTGattHandler::sendIndication(const uint16_t handle, const jau::TROOctets & value) { + if( GATTRole::Server != role ) { + ERR_PRINT("BTDevice::sendIndication: GATTRole not server"); + return false; + } + if( !hasHandle(handle) ) { + ERR_PRINT("BTDevice::sendIndication: invalid handle %s", jau::to_hexstring(handle).c_str()); + return false; + } + AttHandleValueRcv req(false /* isNotify */, handle, value); + std::unique_ptr<const AttPDUMsg> pdu = sendWithReply(req, env.GATT_WRITE_COMMAND_REPLY_TIMEOUT); // valid reply or exception + if( pdu->getOpcode() == AttPDUMsg::Opcode::HANDLE_VALUE_CFM ) { + COND_PRINT(env.DEBUG_DATA, "GATT SENT IND: %s -> %s to/from %s", + req.toString().c_str(), pdu->toString().c_str(), toString().c_str()); + return true; + } else { + WARN_PRINT("GATT SENT IND: Failed, no CFM reply: %s -> %s to/from %s", + req.toString().c_str(), pdu->toString().c_str(), toString().c_str()); + return false; + } +} + BTGattCharRef BTGattHandler::findCharacterisicsByValueHandle(const uint16_t charValueHandle) noexcept { return findCharacterisicsByValueHandle(charValueHandle, services); } |