diff --git a/libnymea-zigbee/zcl/zigbeecluster.cpp b/libnymea-zigbee/zcl/zigbeecluster.cpp index a74e8d2..280d86e 100644 --- a/libnymea-zigbee/zcl/zigbeecluster.cpp +++ b/libnymea-zigbee/zcl/zigbeecluster.cpp @@ -183,7 +183,7 @@ ZigbeeClusterReply *ZigbeeCluster::executeGlobalCommand(quint8 command, const QB ZigbeeClusterReply *zclReply = createClusterReply(request, frame); ZigbeeNetworkReply *networkReply = m_network->sendRequest(request); - connect(networkReply, &ZigbeeNetworkReply::finished, this, [this, networkReply, zclReply](){ + connect(networkReply, &ZigbeeNetworkReply::finished, zclReply, [this, networkReply, zclReply](){ if (!verifyNetworkError(zclReply, networkReply)) { finishZclReply(zclReply); return; @@ -203,9 +203,12 @@ ZigbeeClusterReply *ZigbeeCluster::executeGlobalCommand(quint8 command, const QB ZigbeeClusterReply *ZigbeeCluster::createClusterReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame frame) { ZigbeeClusterReply *zclReply = new ZigbeeClusterReply(request, frame, this); - connect(zclReply, &ZigbeeClusterReply::finished, zclReply, &ZigbeeClusterReply::deleteLater, Qt::QueuedConnection); zclReply->m_transactionSequenceNumber = frame.header.transactionSequenceNumber; m_pendingReplies.insert(zclReply->transactionSequenceNumber(), zclReply); + connect(zclReply, &ZigbeeClusterReply::finished, this, [this, zclReply](){ + zclReply->deleteLater(); + m_pendingReplies.remove(zclReply->transactionSequenceNumber()); + }, Qt::QueuedConnection); return zclReply; } @@ -237,7 +240,7 @@ ZigbeeClusterReply *ZigbeeCluster::executeClusterCommand(quint8 command, const Q ZigbeeClusterReply *zclReply = createClusterReply(request, frame); qCDebug(dcZigbeeCluster()) << "Executing command" << ZigbeeUtils::convertByteToHexString(command) << ZigbeeUtils::convertByteArrayToHexString(payload); ZigbeeNetworkReply *networkReply = m_network->sendRequest(request); - connect(networkReply, &ZigbeeNetworkReply::finished, this, [this, networkReply, zclReply](){ + connect(networkReply, &ZigbeeNetworkReply::finished, zclReply, [this, networkReply, zclReply](){ if (!verifyNetworkError(zclReply, networkReply)) { finishZclReply(zclReply); return; @@ -282,7 +285,7 @@ ZigbeeClusterReply *ZigbeeCluster::sendClusterServerResponse(quint8 command, qui ZigbeeClusterReply *zclReply = createClusterReply(request, frame); qCDebug(dcZigbeeCluster()) << "Send command response" << ZigbeeUtils::convertByteToHexString(command) << "TSN:" << ZigbeeUtils::convertByteToHexString(transactionSequenceNumber) << ZigbeeUtils::convertByteArrayToHexString(payload); ZigbeeNetworkReply *networkReply = m_network->sendRequest(request); - connect(networkReply, &ZigbeeNetworkReply::finished, this, [this, networkReply, zclReply](){ + connect(networkReply, &ZigbeeNetworkReply::finished, zclReply, [this, networkReply, zclReply](){ if (!verifyNetworkError(zclReply, networkReply)) { finishZclReply(zclReply); return; @@ -328,7 +331,7 @@ ZigbeeClusterReply *ZigbeeCluster::sendDefaultResponse(quint8 transactionSequenc ZigbeeClusterReply *zclReply = createClusterReply(request, frame); qCDebug(dcZigbeeCluster()) << "Send default response" << "TSN:" << ZigbeeUtils::convertByteToHexString(transactionSequenceNumber) << ZigbeeUtils::convertByteArrayToHexString(payload); ZigbeeNetworkReply *networkReply = m_network->sendRequest(request); - connect(networkReply, &ZigbeeNetworkReply::finished, this, [this, networkReply, zclReply](){ + connect(networkReply, &ZigbeeNetworkReply::finished, zclReply, [this, networkReply, zclReply](){ if (!verifyNetworkError(zclReply, networkReply)) { finishZclReply(zclReply); return; @@ -365,6 +368,9 @@ bool ZigbeeCluster::verifyNetworkError(ZigbeeClusterReply *zclReply, ZigbeeNetwo // The request has been transported successfully to he destination, now // wait for the expected indication or check if we already recieved it zclReply->m_apsConfirmReceived = true; + if (!zclReply->m_zclIndicationReceived) { + zclReply->m_timeoutTimer.start(); + } success = true; break; case ZigbeeNetworkReply::ErrorTimeout: @@ -404,7 +410,6 @@ bool ZigbeeCluster::verifyNetworkError(ZigbeeClusterReply *zclReply, ZigbeeNetwo void ZigbeeCluster::finishZclReply(ZigbeeClusterReply *zclReply) { - m_pendingReplies.remove(zclReply->transactionSequenceNumber()); qCDebug(dcZigbeeCluster()) << "ZigbeeClusterReply finished" << zclReply->request() << zclReply->requestFrame() << zclReply->responseFrame(); // FIXME: Set the status emit zclReply->finished(); diff --git a/libnymea-zigbee/zcl/zigbeeclusterreply.cpp b/libnymea-zigbee/zcl/zigbeeclusterreply.cpp index fc36d1b..510b162 100644 --- a/libnymea-zigbee/zcl/zigbeeclusterreply.cpp +++ b/libnymea-zigbee/zcl/zigbeeclusterreply.cpp @@ -27,6 +27,18 @@ #include "zigbeeclusterreply.h" +ZigbeeClusterReply::ZigbeeClusterReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame requestFrame, QObject *parent) : + QObject(parent), + m_request(request), + m_requestFrame(requestFrame) +{ + m_timeoutTimer.setInterval(10000); + connect(&m_timeoutTimer, &QTimer::timeout, this, [this](){ + m_error = ErrorTimeout; + emit finished(); + }); +} + ZigbeeClusterReply::Error ZigbeeClusterReply::error() const { return m_error; @@ -76,11 +88,3 @@ bool ZigbeeClusterReply::isComplete() const { return m_apsConfirmReceived && m_zclIndicationReceived; } - -ZigbeeClusterReply::ZigbeeClusterReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame requestFrame, QObject *parent) : - QObject(parent), - m_request(request), - m_requestFrame(requestFrame) -{ - -} diff --git a/libnymea-zigbee/zcl/zigbeeclusterreply.h b/libnymea-zigbee/zcl/zigbeeclusterreply.h index 9d47d9e..a37c5a3 100644 --- a/libnymea-zigbee/zcl/zigbeeclusterreply.h +++ b/libnymea-zigbee/zcl/zigbeeclusterreply.h @@ -29,6 +29,7 @@ #define ZIGBEECLUSTERREPLY_H #include +#include #include "zigbeenetworkrequest.h" #include "zigbeeclusterlibrary.h" @@ -73,6 +74,8 @@ private: Error m_error = ErrorNoError; + QTimer m_timeoutTimer; + // Request quint8 m_transactionSequenceNumber = 0; ZigbeeNetworkRequest m_request;