Introduce binding management and cleaning
This commit is contained in:
parent
61114fc773
commit
e245f7c845
@ -78,12 +78,12 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::sendRequest(const ZigbeeNetworkRequest &re
|
||||
// Send the request, and keep the reply until transposrt, zigbee trasmission and response arrived
|
||||
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply](){
|
||||
if (!m_pendingReplies.values().contains(reply)) {
|
||||
qCWarning(dcZigbeeNetwork()) << "#### Reply finished but not in the pending replies list" << reply;
|
||||
//qCWarning(dcZigbeeNetwork()) << "#### Reply finished but not in the pending replies list" << reply;
|
||||
return;
|
||||
}
|
||||
quint8 requestId = m_pendingReplies.key(reply);
|
||||
m_pendingReplies.remove(requestId);
|
||||
qCWarning(dcZigbeeNetwork()) << "#### Removed network reply" << reply << "ID:" << requestId << "Current reply count" << m_pendingReplies.count();
|
||||
//qCWarning(dcZigbeeNetwork()) << "#### Removed network reply" << reply << "ID:" << requestId << "Current reply count" << m_pendingReplies.count();
|
||||
});
|
||||
|
||||
// Finish the reply right the way if the network is offline
|
||||
@ -110,7 +110,7 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::sendRequest(const ZigbeeNetworkRequest &re
|
||||
quint8 networkRequestId = interfaceReply->responseData().at(0);
|
||||
//qCDebug(dcZigbeeNetwork()) << "Request has network SQN" << networkRequestId;
|
||||
reply->request().setRequestId(networkRequestId);
|
||||
qCWarning(dcZigbeeNetwork()) << "#### Insert network reply" << reply << "ID:" << networkRequestId << "Current reply count" << m_pendingReplies.count();
|
||||
//qCWarning(dcZigbeeNetwork()) << "#### Insert network reply" << reply << "ID:" << networkRequestId << "Current reply count" << m_pendingReplies.count();
|
||||
m_pendingReplies.insert(networkRequestId, reply);
|
||||
// The request has been sent successfully to the device, start the timeout timer now
|
||||
startWaitingReply(reply);
|
||||
@ -550,7 +550,7 @@ void ZigbeeNetworkNxp::onApsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &
|
||||
{
|
||||
ZigbeeNetworkReply *reply = m_pendingReplies.value(confirm.requestId);
|
||||
if (!reply) {
|
||||
qCWarning(dcZigbeeNetwork()) << "Received confirmation but could not find any reply. Ignoring the confirmation";
|
||||
qCDebug(dcZigbeeNetwork()) << "Received confirmation but could not find any reply. Ignoring the confirmation";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -53,6 +53,7 @@ SOURCES += \
|
||||
zigbeenetworkreply.cpp \
|
||||
zigbeenetworkrequest.cpp \
|
||||
zigbeenodeendpoint.cpp \
|
||||
zigbeereply.cpp \
|
||||
zigbeesecurityconfiguration.cpp \
|
||||
zigbeeuartadapter.cpp \
|
||||
zigbeeuartadaptermonitor.cpp \
|
||||
@ -109,6 +110,7 @@ HEADERS += \
|
||||
zigbeenetworkreply.h \
|
||||
zigbeenetworkrequest.h \
|
||||
zigbeenodeendpoint.h \
|
||||
zigbeereply.h \
|
||||
zigbeesecurityconfiguration.h \
|
||||
zigbeeuartadapter.h \
|
||||
zigbeeuartadaptermonitor.h \
|
||||
|
||||
@ -36,6 +36,11 @@ ZigbeeClusterBasic::ZigbeeClusterBasic(ZigbeeNetwork *network, ZigbeeNode *node,
|
||||
|
||||
}
|
||||
|
||||
ZigbeeClusterReply *ZigbeeClusterBasic::resetToFactoryDefaults()
|
||||
{
|
||||
return executeClusterCommand(ZigbeeClusterBasic::CommandResetToFactoryDefaults);
|
||||
}
|
||||
|
||||
void ZigbeeClusterBasic::setAttribute(const ZigbeeClusterAttribute &attribute)
|
||||
{
|
||||
qCDebug(dcZigbeeCluster()) << "Update attribute" << m_node << m_endpoint << this << static_cast<Attribute>(attribute.id()) << attribute.dataType();
|
||||
|
||||
@ -58,6 +58,11 @@ public:
|
||||
};
|
||||
Q_ENUM(Attribute)
|
||||
|
||||
enum Command {
|
||||
CommandResetToFactoryDefaults = 0x00
|
||||
};
|
||||
Q_ENUM(Command)
|
||||
|
||||
// Enum for AttributePowerSource(0x0007)
|
||||
enum AttributePowerSourceValue {
|
||||
AttributePowerSourceValueUnknown = 0x00,
|
||||
@ -199,7 +204,7 @@ public:
|
||||
|
||||
explicit ZigbeeClusterBasic(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
|
||||
|
||||
// TODO: reset all clusters to factory defaults command 0x00, optional
|
||||
ZigbeeClusterReply *resetToFactoryDefaults();
|
||||
|
||||
private:
|
||||
void setAttribute(const ZigbeeClusterAttribute &attribute) override;
|
||||
|
||||
@ -306,6 +306,58 @@ ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestBindIeeeAddress(quint8 sourc
|
||||
return zdoReply;
|
||||
}
|
||||
|
||||
ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestUnbind(const ZigbeeDeviceProfile::BindingTableListRecord &bindingRecord)
|
||||
{
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Request unbind" << m_node << bindingRecord;
|
||||
|
||||
// Build APS request
|
||||
ZigbeeNetworkRequest request = buildZdoRequest(ZigbeeDeviceProfile::UnbindRequest);
|
||||
|
||||
// Generate a new transaction sequence number for this device object
|
||||
quint8 transactionSequenceNumber = m_transactionSequenceNumber++;
|
||||
|
||||
// Build ZDO frame
|
||||
QByteArray asdu;
|
||||
QDataStream stream(&asdu, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream << transactionSequenceNumber;
|
||||
stream << bindingRecord.sourceAddress.toUInt64();
|
||||
stream << bindingRecord.sourceEndpoint;
|
||||
stream << bindingRecord.clusterId;
|
||||
stream << static_cast<quint8>(bindingRecord.destinationAddressMode);
|
||||
if (bindingRecord.destinationAddressMode == Zigbee::DestinationAddressModeGroup) {
|
||||
stream << bindingRecord.destinationAddressShort;
|
||||
} else {
|
||||
stream << bindingRecord.destinationAddress.toUInt64();
|
||||
stream << bindingRecord.destinationEndpoint;
|
||||
}
|
||||
|
||||
// Set the ZDO frame as APS request payload
|
||||
request.setAsdu(asdu);
|
||||
|
||||
// Create the device object reply and wait for the response indication
|
||||
ZigbeeDeviceObjectReply *zdoReply = createZigbeeDeviceObjectReply(request, transactionSequenceNumber);
|
||||
|
||||
// Send the request, on finished read the confirm information
|
||||
ZigbeeNetworkReply *networkReply = m_network->sendRequest(request);
|
||||
connect(networkReply, &ZigbeeNetworkReply::finished, this, [this, networkReply, zdoReply](){
|
||||
if (!verifyNetworkError(zdoReply, networkReply)) {
|
||||
finishZdoReply(zdoReply);
|
||||
return;
|
||||
}
|
||||
|
||||
// The request was successfully sent to the device
|
||||
// Now check if the expected indication response received already
|
||||
if (zdoReply->isComplete()) {
|
||||
finishZdoReply(zdoReply);
|
||||
return;
|
||||
}
|
||||
// We received the confirmation but not yet the indication
|
||||
});
|
||||
|
||||
return zdoReply;
|
||||
}
|
||||
|
||||
ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestMgmtLeaveNetwork(bool rejoin, bool removeChildren)
|
||||
{
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Request management leave network from" << m_node << "rejoin" << rejoin << "remove children" << removeChildren;
|
||||
|
||||
@ -53,6 +53,7 @@ public:
|
||||
ZigbeeDeviceObjectReply *requestBindShortAddress(quint8 sourceEndpointId, quint16 clusterId, quint16 destinationAddress);
|
||||
ZigbeeDeviceObjectReply *requestBindIeeeAddress(quint8 sourceEndpointId, quint16 clusterId, const ZigbeeAddress &destinationIeeeAddress, quint8 destinationEndpointId);
|
||||
|
||||
ZigbeeDeviceObjectReply *requestUnbind(const ZigbeeDeviceProfile::BindingTableListRecord &bindingRecord);
|
||||
|
||||
// Management request
|
||||
ZigbeeDeviceObjectReply *requestMgmtLeaveNetwork(bool rejoin = false, bool removeChildren = false);
|
||||
|
||||
@ -86,6 +86,11 @@ Zigbee::ZigbeeMacLayerStatus ZigbeeDeviceObjectReply::zigbeeMacStatus() const
|
||||
return m_zigbeeMacStatus;
|
||||
}
|
||||
|
||||
ZigbeeDeviceProfile::Status ZigbeeDeviceObjectReply::zigbeeDeviceObjectStatus() const
|
||||
{
|
||||
return m_zigbeeDeviceObjectStatus;
|
||||
}
|
||||
|
||||
ZigbeeNetworkRequest ZigbeeDeviceObjectReply::request() const
|
||||
{
|
||||
return m_request;
|
||||
|
||||
@ -117,6 +117,11 @@ ZigbeeDeviceProfile::PowerDescriptor ZigbeeNode::powerDescriptor() const
|
||||
return m_powerDescriptor;
|
||||
}
|
||||
|
||||
QList<ZigbeeDeviceProfile::BindingTableListRecord> ZigbeeNode::bindingTableRecords() const
|
||||
{
|
||||
return m_bindingTableRecords;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setState(ZigbeeNode::State state)
|
||||
{
|
||||
if (m_state == state)
|
||||
@ -154,22 +159,42 @@ void ZigbeeNode::startInitialization()
|
||||
initNodeDescriptor();
|
||||
}
|
||||
|
||||
void ZigbeeNode::removeAllBindings()
|
||||
ZigbeeReply *ZigbeeNode::removeAllBindings()
|
||||
{
|
||||
ZigbeeReply *reply = new ZigbeeReply(this);
|
||||
|
||||
}
|
||||
|
||||
void ZigbeeNode::readBindingTableEntries()
|
||||
{
|
||||
ZigbeeDeviceObjectReply *reply = deviceObject()->requestMgmtBind();
|
||||
connect(reply, &ZigbeeDeviceObjectReply::finished, this, [=](){
|
||||
if (reply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
|
||||
qCWarning(dcZigbeeNode()) << "Failed to read binding table" << reply->error();
|
||||
ZigbeeReply *readBindingsReply = readBindingTableEntries();
|
||||
connect(readBindingsReply, &ZigbeeReply::finished, reply, [=](){
|
||||
if (readBindingsReply->error()) {
|
||||
qCWarning(dcZigbeeNode()) << "Failed to remove all bindings because the current bindings could not be fetched from node" << this;
|
||||
reply->finishReply(readBindingsReply->error());
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Bind table payload" << ZigbeeUtils::convertByteArrayToHexString(reply->responseData());
|
||||
QByteArray response = reply->responseData();
|
||||
qCDebug(dcZigbeeNode()) << "Current binding table records:";
|
||||
foreach (const ZigbeeDeviceProfile::BindingTableListRecord &binding, m_bindingTableRecords) {
|
||||
qCDebug(dcZigbeeNode()) << binding;
|
||||
}
|
||||
|
||||
// Remove bindings sequentially and finish reply if error occures or all bindings removed
|
||||
removeNextBinding(reply);
|
||||
});
|
||||
return reply;
|
||||
}
|
||||
|
||||
ZigbeeReply *ZigbeeNode::readBindingTableEntries()
|
||||
{
|
||||
ZigbeeReply *reply = new ZigbeeReply(this);
|
||||
ZigbeeDeviceObjectReply *zdoReply = deviceObject()->requestMgmtBind();
|
||||
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, this, [=](){
|
||||
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
|
||||
qCWarning(dcZigbeeNode()) << "Failed to read binding table" << zdoReply->error();
|
||||
reply->finishReply(ZigbeeReply::ErrorZigbeeError);
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Bind table payload" << ZigbeeUtils::convertByteArrayToHexString(zdoReply->responseData());
|
||||
QByteArray response = zdoReply->responseData();
|
||||
QDataStream stream(&response, QIODevice::ReadOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
quint8 sqn; quint8 statusInt; quint8 entriesCount; quint8 startIndex; quint8 bindingTableListCount;
|
||||
@ -177,7 +202,7 @@ void ZigbeeNode::readBindingTableEntries()
|
||||
ZigbeeDeviceProfile::Status status = static_cast<ZigbeeDeviceProfile::Status>(statusInt);
|
||||
qCDebug(dcZigbeeDeviceObject()) << "SQN:" << sqn << status << "entries:" << entriesCount << "index:" << startIndex << "list count:" << bindingTableListCount;
|
||||
|
||||
QList<ZigbeeDeviceProfile::BindingTableListRecord> bindingTableRecords;
|
||||
m_bindingTableRecords.clear();
|
||||
for (int i = 0; i < bindingTableListCount; i++) {
|
||||
quint64 sourceAddress; quint8 addressMode;
|
||||
ZigbeeDeviceProfile::BindingTableListRecord record;
|
||||
@ -198,11 +223,15 @@ void ZigbeeNode::readBindingTableEntries()
|
||||
break;
|
||||
}
|
||||
qCDebug(dcZigbeeDeviceObject()) << record;
|
||||
bindingTableRecords << record;
|
||||
m_bindingTableRecords << record;
|
||||
}
|
||||
|
||||
// TODO: continue reading if there are more entries
|
||||
|
||||
emit bindingTableRecordsChanged();
|
||||
reply->finishReply();
|
||||
});
|
||||
return reply;
|
||||
}
|
||||
|
||||
void ZigbeeNode::initNodeDescriptor()
|
||||
@ -418,6 +447,31 @@ void ZigbeeNode::initEndpoint(quint8 endpointId)
|
||||
});
|
||||
}
|
||||
|
||||
void ZigbeeNode::removeNextBinding(ZigbeeReply *reply)
|
||||
{
|
||||
// If we have no bindings left, finish the given reply
|
||||
if (m_bindingTableRecords.isEmpty()) {
|
||||
reply->finishReply();
|
||||
return;
|
||||
}
|
||||
|
||||
ZigbeeDeviceProfile::BindingTableListRecord record = m_bindingTableRecords.last();
|
||||
ZigbeeDeviceObjectReply *zdoReply = m_deviceObject->requestUnbind(record);
|
||||
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, reply, [=](){
|
||||
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
|
||||
qCWarning(dcZigbeeNode()) << "Failed to remove" << record << zdoReply->error();
|
||||
reply->finishReply(ZigbeeReply::ErrorZigbeeError);
|
||||
return;
|
||||
}
|
||||
|
||||
// Successfully removed
|
||||
m_bindingTableRecords.removeLast();
|
||||
emit bindingTableRecordsChanged();
|
||||
|
||||
removeNextBinding(reply);
|
||||
});
|
||||
}
|
||||
|
||||
void ZigbeeNode::initBasicCluster()
|
||||
{
|
||||
// Get the first endpoint which implements the basic cluster
|
||||
@ -476,7 +530,7 @@ void ZigbeeNode::readManufacturerName(ZigbeeClusterBasic *basicCluster)
|
||||
if (m_requestRetry < 3) {
|
||||
m_requestRetry++;
|
||||
qCDebug(dcZigbeeNode()) << "Retry to read manufacturer name from" << this << basicCluster << m_requestRetry << "/" << "3 attempts.";
|
||||
QTimer::singleShot(1000, this, [=](){readManufacturerName(basicCluster);});
|
||||
QTimer::singleShot(1000, this, [=](){ readManufacturerName(basicCluster); });
|
||||
} else {
|
||||
qCWarning(dcZigbeeNode()) << "Failed to read manufacturer name from" << this << basicCluster << "after 3 attempts. Giving up and continue...";
|
||||
m_requestRetry = 0;
|
||||
@ -535,7 +589,7 @@ void ZigbeeNode::readModelIdentifier(ZigbeeClusterBasic *basicCluster)
|
||||
if (m_requestRetry < 3) {
|
||||
m_requestRetry++;
|
||||
qCDebug(dcZigbeeNode()) << "Retry to read model identifier from" << this << basicCluster << m_requestRetry << "/" << "3 attempts.";
|
||||
QTimer::singleShot(1000, this, [=](){readModelIdentifier(basicCluster);});
|
||||
QTimer::singleShot(1000, this, [=](){ readModelIdentifier(basicCluster); });
|
||||
} else {
|
||||
qCWarning(dcZigbeeNode()) << "Failed to read model identifier from" << this << basicCluster << "after 3 attempts. Giving up and continue...";
|
||||
m_requestRetry = 0;
|
||||
@ -576,7 +630,7 @@ void ZigbeeNode::readSoftwareBuildId(ZigbeeClusterBasic *basicCluster)
|
||||
if (m_requestRetry < 3) {
|
||||
m_requestRetry++;
|
||||
qCDebug(dcZigbeeNode()) << "Retry to read model identifier from" << this << basicCluster << m_requestRetry << "/" << "3 attempts.";
|
||||
QTimer::singleShot(1000, this, [=](){readSoftwareBuildId(basicCluster);});
|
||||
QTimer::singleShot(1000, this, [=](){ readSoftwareBuildId(basicCluster); });
|
||||
} else {
|
||||
qCWarning(dcZigbeeNode()) << "Failed to read model identifier from" << this << basicCluster << "after 3 attempts. Giving up and continue...";
|
||||
m_requestRetry = 0;
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#include <QDateTime>
|
||||
|
||||
#include "zigbee.h"
|
||||
#include "zigbeereply.h"
|
||||
#include "zigbeeaddress.h"
|
||||
#include "zigbeenodeendpoint.h"
|
||||
#include "zdo/zigbeedeviceobject.h"
|
||||
@ -82,11 +83,14 @@ public:
|
||||
QList<ZigbeeDeviceProfile::PowerSource> availablePowerSources() const;
|
||||
ZigbeeDeviceProfile::PowerLevel powerLevel() const;
|
||||
|
||||
// Only available if fetched
|
||||
QList<ZigbeeDeviceProfile::BindingTableListRecord> bindingTableRecords() const;
|
||||
|
||||
// This method starts the node initialization phase (read descriptors and endpoints)
|
||||
void startInitialization();
|
||||
|
||||
void removeAllBindings();
|
||||
void readBindingTableEntries();
|
||||
ZigbeeReply *removeAllBindings();
|
||||
ZigbeeReply *readBindingTableEntries();
|
||||
|
||||
private:
|
||||
ZigbeeNode(ZigbeeNetwork *network, quint16 shortAddress, const ZigbeeAddress &extendedAddress, QObject *parent = nullptr);
|
||||
@ -107,6 +111,8 @@ private:
|
||||
ZigbeeDeviceProfile::MacCapabilities m_macCapabilities;
|
||||
ZigbeeDeviceProfile::PowerDescriptor m_powerDescriptor;
|
||||
|
||||
QList<ZigbeeDeviceProfile::BindingTableListRecord> m_bindingTableRecords;
|
||||
|
||||
void setState(State state);
|
||||
void setReachable(bool reachable);
|
||||
|
||||
@ -118,6 +124,8 @@ private:
|
||||
void initEndpoints();
|
||||
void initEndpoint(quint8 endpointId);
|
||||
|
||||
void removeNextBinding(ZigbeeReply *reply);
|
||||
|
||||
// For convenience and having base information about the first endpoint
|
||||
void initBasicCluster();
|
||||
void readManufacturerName(ZigbeeClusterBasic *basicCluster);
|
||||
@ -132,6 +140,7 @@ signals:
|
||||
void lqiChanged(quint8 lqi);
|
||||
void lastSeenChanged(const QDateTime &lastSeen);
|
||||
void reachableChanged(bool reachable);
|
||||
void bindingTableRecordsChanged();
|
||||
void clusterAdded(ZigbeeCluster *cluster);
|
||||
void clusterAttributeChanged(ZigbeeCluster *cluster, const ZigbeeClusterAttribute &attribute);
|
||||
|
||||
|
||||
45
libnymea-zigbee/zigbeereply.cpp
Normal file
45
libnymea-zigbee/zigbeereply.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea-zigbee.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "zigbeereply.h"
|
||||
|
||||
ZigbeeReply::Error ZigbeeReply::error() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
ZigbeeReply::ZigbeeReply(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ZigbeeReply::finishReply(ZigbeeReply::Error error)
|
||||
{
|
||||
m_error = error;
|
||||
emit finished();
|
||||
deleteLater();
|
||||
}
|
||||
66
libnymea-zigbee/zigbeereply.h
Normal file
66
libnymea-zigbee/zigbeereply.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea-zigbee.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef ZIGBEEREPLY_H
|
||||
#define ZIGBEEREPLY_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "zigbee.h"
|
||||
|
||||
class ZigbeeReply : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class ZigbeeNode;
|
||||
friend class ZigbeeNetwork;
|
||||
friend class ZigbeeNodeEndpoint;
|
||||
|
||||
public:
|
||||
enum Error {
|
||||
ErrorNoError,
|
||||
ErrorTimeout,
|
||||
ErrorInterfaceError,
|
||||
ErrorZigbeeError,
|
||||
ErrorNetworkOffline
|
||||
};
|
||||
Q_ENUM(Error)
|
||||
|
||||
Error error() const;
|
||||
|
||||
protected:
|
||||
explicit ZigbeeReply(QObject *parent = nullptr);
|
||||
|
||||
Error m_error = ErrorNoError;
|
||||
|
||||
void finishReply(Error error = ErrorNoError);
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
};
|
||||
|
||||
#endif // ZIGBEEREPLY_H
|
||||
Reference in New Issue
Block a user