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 /src | |
parent | 62594a9b9e2b7004f611d01ac98c34d2ed2c96e1 (diff) |
BTDevice/BTGattHandler: Add send[Notification|Indication](..) commands
Diffstat (limited to 'src')
-rw-r--r-- | src/direct_bt/BTDevice.cpp | 19 | ||||
-rw-r--r-- | src/direct_bt/BTGattHandler.cpp | 37 |
2 files changed, 56 insertions, 0 deletions
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); } |