aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2021-10-19 06:12:02 +0200
committerSven Gothel <[email protected]>2021-10-19 06:12:02 +0200
commit9507aa383965d5ab05375169b25c119d9258858f (patch)
treee44fa0044eb03515843b176d276ccffa31bd4d8d /src
parent62594a9b9e2b7004f611d01ac98c34d2ed2c96e1 (diff)
BTDevice/BTGattHandler: Add send[Notification|Indication](..) commands
Diffstat (limited to 'src')
-rw-r--r--src/direct_bt/BTDevice.cpp19
-rw-r--r--src/direct_bt/BTGattHandler.cpp37
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);
}