Timeout ZCL replies
This is basically the same as #41 does with ZDO replies but for ZCL replies. Working with a z-stack dongle and a Gewiss binary input device a lot of timeouts happen during the device interview. While basic device interview timeouts are caught by the ZDO timeouts, later interview steps like cluster attribute reading run into the same issue with this device and the interview process never finishes.
This commit is contained in:
parent
187278cf7c
commit
b96f9fa98f
@ -183,7 +183,7 @@ ZigbeeClusterReply *ZigbeeCluster::executeGlobalCommand(quint8 command, const QB
|
|||||||
|
|
||||||
ZigbeeClusterReply *zclReply = createClusterReply(request, frame);
|
ZigbeeClusterReply *zclReply = createClusterReply(request, frame);
|
||||||
ZigbeeNetworkReply *networkReply = m_network->sendRequest(request);
|
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)) {
|
if (!verifyNetworkError(zclReply, networkReply)) {
|
||||||
finishZclReply(zclReply);
|
finishZclReply(zclReply);
|
||||||
return;
|
return;
|
||||||
@ -203,9 +203,12 @@ ZigbeeClusterReply *ZigbeeCluster::executeGlobalCommand(quint8 command, const QB
|
|||||||
ZigbeeClusterReply *ZigbeeCluster::createClusterReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame frame)
|
ZigbeeClusterReply *ZigbeeCluster::createClusterReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame frame)
|
||||||
{
|
{
|
||||||
ZigbeeClusterReply *zclReply = new ZigbeeClusterReply(request, frame, this);
|
ZigbeeClusterReply *zclReply = new ZigbeeClusterReply(request, frame, this);
|
||||||
connect(zclReply, &ZigbeeClusterReply::finished, zclReply, &ZigbeeClusterReply::deleteLater, Qt::QueuedConnection);
|
|
||||||
zclReply->m_transactionSequenceNumber = frame.header.transactionSequenceNumber;
|
zclReply->m_transactionSequenceNumber = frame.header.transactionSequenceNumber;
|
||||||
m_pendingReplies.insert(zclReply->transactionSequenceNumber(), zclReply);
|
m_pendingReplies.insert(zclReply->transactionSequenceNumber(), zclReply);
|
||||||
|
connect(zclReply, &ZigbeeClusterReply::finished, this, [this, zclReply](){
|
||||||
|
zclReply->deleteLater();
|
||||||
|
m_pendingReplies.remove(zclReply->transactionSequenceNumber());
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
return zclReply;
|
return zclReply;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +240,7 @@ ZigbeeClusterReply *ZigbeeCluster::executeClusterCommand(quint8 command, const Q
|
|||||||
ZigbeeClusterReply *zclReply = createClusterReply(request, frame);
|
ZigbeeClusterReply *zclReply = createClusterReply(request, frame);
|
||||||
qCDebug(dcZigbeeCluster()) << "Executing command" << ZigbeeUtils::convertByteToHexString(command) << ZigbeeUtils::convertByteArrayToHexString(payload);
|
qCDebug(dcZigbeeCluster()) << "Executing command" << ZigbeeUtils::convertByteToHexString(command) << ZigbeeUtils::convertByteArrayToHexString(payload);
|
||||||
ZigbeeNetworkReply *networkReply = m_network->sendRequest(request);
|
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)) {
|
if (!verifyNetworkError(zclReply, networkReply)) {
|
||||||
finishZclReply(zclReply);
|
finishZclReply(zclReply);
|
||||||
return;
|
return;
|
||||||
@ -282,7 +285,7 @@ ZigbeeClusterReply *ZigbeeCluster::sendClusterServerResponse(quint8 command, qui
|
|||||||
ZigbeeClusterReply *zclReply = createClusterReply(request, frame);
|
ZigbeeClusterReply *zclReply = createClusterReply(request, frame);
|
||||||
qCDebug(dcZigbeeCluster()) << "Send command response" << ZigbeeUtils::convertByteToHexString(command) << "TSN:" << ZigbeeUtils::convertByteToHexString(transactionSequenceNumber) << ZigbeeUtils::convertByteArrayToHexString(payload);
|
qCDebug(dcZigbeeCluster()) << "Send command response" << ZigbeeUtils::convertByteToHexString(command) << "TSN:" << ZigbeeUtils::convertByteToHexString(transactionSequenceNumber) << ZigbeeUtils::convertByteArrayToHexString(payload);
|
||||||
ZigbeeNetworkReply *networkReply = m_network->sendRequest(request);
|
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)) {
|
if (!verifyNetworkError(zclReply, networkReply)) {
|
||||||
finishZclReply(zclReply);
|
finishZclReply(zclReply);
|
||||||
return;
|
return;
|
||||||
@ -328,7 +331,7 @@ ZigbeeClusterReply *ZigbeeCluster::sendDefaultResponse(quint8 transactionSequenc
|
|||||||
ZigbeeClusterReply *zclReply = createClusterReply(request, frame);
|
ZigbeeClusterReply *zclReply = createClusterReply(request, frame);
|
||||||
qCDebug(dcZigbeeCluster()) << "Send default response" << "TSN:" << ZigbeeUtils::convertByteToHexString(transactionSequenceNumber) << ZigbeeUtils::convertByteArrayToHexString(payload);
|
qCDebug(dcZigbeeCluster()) << "Send default response" << "TSN:" << ZigbeeUtils::convertByteToHexString(transactionSequenceNumber) << ZigbeeUtils::convertByteArrayToHexString(payload);
|
||||||
ZigbeeNetworkReply *networkReply = m_network->sendRequest(request);
|
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)) {
|
if (!verifyNetworkError(zclReply, networkReply)) {
|
||||||
finishZclReply(zclReply);
|
finishZclReply(zclReply);
|
||||||
return;
|
return;
|
||||||
@ -365,6 +368,9 @@ bool ZigbeeCluster::verifyNetworkError(ZigbeeClusterReply *zclReply, ZigbeeNetwo
|
|||||||
// The request has been transported successfully to he destination, now
|
// The request has been transported successfully to he destination, now
|
||||||
// wait for the expected indication or check if we already recieved it
|
// wait for the expected indication or check if we already recieved it
|
||||||
zclReply->m_apsConfirmReceived = true;
|
zclReply->m_apsConfirmReceived = true;
|
||||||
|
if (!zclReply->m_zclIndicationReceived) {
|
||||||
|
zclReply->m_timeoutTimer.start();
|
||||||
|
}
|
||||||
success = true;
|
success = true;
|
||||||
break;
|
break;
|
||||||
case ZigbeeNetworkReply::ErrorTimeout:
|
case ZigbeeNetworkReply::ErrorTimeout:
|
||||||
@ -404,7 +410,6 @@ bool ZigbeeCluster::verifyNetworkError(ZigbeeClusterReply *zclReply, ZigbeeNetwo
|
|||||||
|
|
||||||
void ZigbeeCluster::finishZclReply(ZigbeeClusterReply *zclReply)
|
void ZigbeeCluster::finishZclReply(ZigbeeClusterReply *zclReply)
|
||||||
{
|
{
|
||||||
m_pendingReplies.remove(zclReply->transactionSequenceNumber());
|
|
||||||
qCDebug(dcZigbeeCluster()) << "ZigbeeClusterReply finished" << zclReply->request() << zclReply->requestFrame() << zclReply->responseFrame();
|
qCDebug(dcZigbeeCluster()) << "ZigbeeClusterReply finished" << zclReply->request() << zclReply->requestFrame() << zclReply->responseFrame();
|
||||||
// FIXME: Set the status
|
// FIXME: Set the status
|
||||||
emit zclReply->finished();
|
emit zclReply->finished();
|
||||||
|
|||||||
@ -27,6 +27,18 @@
|
|||||||
|
|
||||||
#include "zigbeeclusterreply.h"
|
#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
|
ZigbeeClusterReply::Error ZigbeeClusterReply::error() const
|
||||||
{
|
{
|
||||||
return m_error;
|
return m_error;
|
||||||
@ -76,11 +88,3 @@ bool ZigbeeClusterReply::isComplete() const
|
|||||||
{
|
{
|
||||||
return m_apsConfirmReceived && m_zclIndicationReceived;
|
return m_apsConfirmReceived && m_zclIndicationReceived;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeClusterReply::ZigbeeClusterReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame requestFrame, QObject *parent) :
|
|
||||||
QObject(parent),
|
|
||||||
m_request(request),
|
|
||||||
m_requestFrame(requestFrame)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
#define ZIGBEECLUSTERREPLY_H
|
#define ZIGBEECLUSTERREPLY_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include "zigbeenetworkrequest.h"
|
#include "zigbeenetworkrequest.h"
|
||||||
#include "zigbeeclusterlibrary.h"
|
#include "zigbeeclusterlibrary.h"
|
||||||
@ -73,6 +74,8 @@ private:
|
|||||||
|
|
||||||
Error m_error = ErrorNoError;
|
Error m_error = ErrorNoError;
|
||||||
|
|
||||||
|
QTimer m_timeoutTimer;
|
||||||
|
|
||||||
// Request
|
// Request
|
||||||
quint8 m_transactionSequenceNumber = 0;
|
quint8 m_transactionSequenceNumber = 0;
|
||||||
ZigbeeNetworkRequest m_request;
|
ZigbeeNetworkRequest m_request;
|
||||||
|
|||||||
Reference in New Issue
Block a user