Implement command responding over cluster api and implement OTA server for default responses
parent
9381a5dcef
commit
0c6924e3f2
|
|
@ -25,6 +25,7 @@ SOURCES += \
|
|||
zcl/measurement/zigbeeclusteroccupancysensing.cpp \
|
||||
zcl/measurement/zigbeeclusterrelativehumiditymeasurement.cpp \
|
||||
zcl/measurement/zigbeeclustertemperaturemeasurement.cpp \
|
||||
zcl/ota/zigbeeclusterota.cpp \
|
||||
zcl/security/zigbeeclusteriaszone.cpp \
|
||||
zcl/zigbeecluster.cpp \
|
||||
zcl/zigbeeclusterattribute.cpp \
|
||||
|
|
@ -76,6 +77,7 @@ HEADERS += \
|
|||
zcl/measurement/zigbeeclusteroccupancysensing.h \
|
||||
zcl/measurement/zigbeeclusterrelativehumiditymeasurement.h \
|
||||
zcl/measurement/zigbeeclustertemperaturemeasurement.h \
|
||||
zcl/ota/zigbeeclusterota.h \
|
||||
zcl/security/zigbeeclusteriaszone.h \
|
||||
zcl/zigbeecluster.h \
|
||||
zcl/zigbeeclusterattribute.h \
|
||||
|
|
|
|||
|
|
@ -75,12 +75,21 @@ void ZigbeeClusterIdentify::setAttribute(const ZigbeeClusterAttribute &attribute
|
|||
|
||||
void ZigbeeClusterIdentify::processDataIndication(ZigbeeClusterLibrary::Frame frame)
|
||||
{
|
||||
qCDebug(dcZigbeeCluster()) << "Processing cluster frame" << m_node << m_endpoint << this << frame;
|
||||
|
||||
// TODO: implement identify query response
|
||||
Command command = static_cast<Command>(frame.header.command);
|
||||
qCDebug(dcZigbeeCluster()) << "Processing cluster frame" << m_node << m_endpoint << this << frame << command;
|
||||
|
||||
// Increase the tsn for continuouse id increasing on both sides
|
||||
m_transactionSequenceNumber = frame.header.transactionSequenceNumber;
|
||||
|
||||
qCWarning(dcZigbeeCluster()) << "Unhandled ZCL indication in" << m_node << m_endpoint << this << frame;
|
||||
switch (command) {
|
||||
case CommandIdentifyQuery:
|
||||
// We are not identifying, we can ignore the command according to the specs
|
||||
qCDebug(dcZigbeeCluster()) << "Received identify query command. We ignore this request according to specs, since we are not identifying our selfs visually.";
|
||||
break;
|
||||
default:
|
||||
qCWarning(dcZigbeeCluster()) << "Unhandled ZCL indication in" << m_node << m_endpoint << this << frame << command;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ void ZigbeeClusterOnOff::processDataIndication(ZigbeeClusterLibrary::Frame frame
|
|||
if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionClientToServer) {
|
||||
// Read the payload which is
|
||||
Command command = static_cast<Command>(frame.header.command);
|
||||
qCDebug(dcZigbeeCluster()) << "Command sent from" << m_node << m_endpoint << this << command;
|
||||
qCDebug(dcZigbeeCluster()) << "Received" << command << "from" << m_node << m_endpoint << this;
|
||||
switch (command) {
|
||||
case CommandOn:
|
||||
emit commandSent(CommandOn);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "zigbeeclusterota.h"
|
||||
#include "zigbeenetworkreply.h"
|
||||
#include "loggingcategory.h"
|
||||
#include "zigbeenetwork.h"
|
||||
#include "zigbeeutils.h"
|
||||
|
||||
#include <QDataStream>
|
||||
|
||||
ZigbeeClusterOta::ZigbeeClusterOta(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent) :
|
||||
ZigbeeCluster(network, node, endpoint, ZigbeeClusterLibrary::ClusterIdOtaUpgrade, direction, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ZigbeeClusterOta::setAttribute(const ZigbeeClusterAttribute &attribute)
|
||||
{
|
||||
qCDebug(dcZigbeeCluster()) << "Update attribute" << m_node << m_endpoint << this << static_cast<Attribute>(attribute.id()) << attribute.dataType();
|
||||
if (hasAttribute(attribute.id())) {
|
||||
m_attributes[attribute.id()] = attribute;
|
||||
emit attributeChanged(attribute);
|
||||
} else {
|
||||
m_attributes.insert(attribute.id(), attribute);
|
||||
emit attributeChanged(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
ZigbeeClusterOta::FileVersion ZigbeeClusterOta::parseFileVersion(quint32 fileVersionValue)
|
||||
{
|
||||
FileVersion fileVersion;
|
||||
fileVersion.applicationRelease = static_cast<quint8>(fileVersionValue & 0xFF000000);
|
||||
fileVersion.applicationBuild = static_cast<quint8>(fileVersionValue & 0x00FF0000);
|
||||
fileVersion.stackRelease = static_cast<quint8>(fileVersionValue & 0x0000FF00);
|
||||
fileVersion.stackBuild = static_cast<quint8>(fileVersionValue & 0x000000FF);
|
||||
return fileVersion;
|
||||
}
|
||||
|
||||
void ZigbeeClusterOta::processDataIndication(ZigbeeClusterLibrary::Frame frame)
|
||||
{
|
||||
qCDebug(dcZigbeeCluster()) << "Processing cluster frame" << m_node << m_endpoint << this << frame;
|
||||
|
||||
// Increase the tsn for continuouse id increasing on both sides
|
||||
m_transactionSequenceNumber = frame.header.transactionSequenceNumber;
|
||||
|
||||
switch (m_direction) {
|
||||
case Client:
|
||||
if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionClientToServer) {
|
||||
Command command = static_cast<Command>(frame.header.command);
|
||||
qCDebug(dcZigbeeCluster()) << "Received" << command << "from" << m_node << m_endpoint << this;
|
||||
switch (command) {
|
||||
case CommandQueryNextImageRequest: {
|
||||
// Print the image information
|
||||
quint8 fieldControl;
|
||||
quint16 manufacturerCode;
|
||||
quint16 imageType;
|
||||
quint32 currentVersion;
|
||||
quint16 hardwareVersion;
|
||||
|
||||
QDataStream requestStream(&frame.payload, QIODevice::ReadOnly);
|
||||
requestStream.setByteOrder(QDataStream::LittleEndian);
|
||||
requestStream >> fieldControl >> manufacturerCode >> imageType >> currentVersion >> hardwareVersion;
|
||||
qCDebug(dcZigbeeCluster()) << "OTA image request:" << (fieldControl == 0x0000 ? "Hardware version not present" : "Hardware version present");
|
||||
qCDebug(dcZigbeeCluster()) << "OTA image request: Manufacturer code" << ZigbeeUtils::convertUint16ToHexString(manufacturerCode);
|
||||
qCDebug(dcZigbeeCluster()) << "OTA image request: Image type" << ZigbeeUtils::convertUint16ToHexString(imageType);
|
||||
qCDebug(dcZigbeeCluster()) << "OTA image request: Current file version" << ZigbeeUtils::convertUint32ToHexString(currentVersion) << parseFileVersion(currentVersion);
|
||||
qCDebug(dcZigbeeCluster()) << "OTA image request: Hardware version" << hardwareVersion;
|
||||
|
||||
// Respond with no image available until we implement the entire cluster for OTA updates
|
||||
qCDebug(dcZigbeeCluster()) << "OTA mechanism not implemented yet. Tell the node there is no image available.";
|
||||
|
||||
QByteArray payload;
|
||||
QDataStream stream(&payload, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream << static_cast<quint8>(StatuCodeNoImageAvailable);
|
||||
|
||||
ZigbeeClusterReply *reply = sendClusterServerResponse(CommandQueryNextImageResponse, frame.header.transactionSequenceNumber, payload);
|
||||
connect(reply, &ZigbeeClusterReply::finished, this, [](){
|
||||
qCDebug(dcZigbeeCluster()) << "OTA image request response for image query sent successfully to requested node.";
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qCWarning(dcZigbeeCluster()) << "Received command" << command << "which is not implemented yet from" << m_node << m_endpoint << this;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Server:
|
||||
qCWarning(dcZigbeeCluster()) << "Unhandled ZCL indication in" << m_node << m_endpoint << this << frame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QDebug operator<<(QDebug debug, const ZigbeeClusterOta::FileVersion &fileVersion)
|
||||
{
|
||||
debug.nospace().noquote() << "FileVersion(Application Release: " << fileVersion.applicationRelease
|
||||
<< ", Application Build: " << fileVersion.applicationBuild
|
||||
<< ", Stack Release: " << fileVersion.stackRelease
|
||||
<< ", Stack Build: " << fileVersion.stackBuild << ")";
|
||||
return debug.space();
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 ZIGBEECLUSTEROTA_H
|
||||
#define ZIGBEECLUSTEROTA_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "zcl/zigbeecluster.h"
|
||||
#include "zcl/zigbeeclusterreply.h"
|
||||
|
||||
class ZigbeeNode;
|
||||
class ZigbeeNetwork;
|
||||
class ZigbeeNodeEndpoint;
|
||||
class ZigbeeNetworkReply;
|
||||
|
||||
class ZigbeeClusterOta : public ZigbeeCluster
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class ZigbeeNode;
|
||||
friend class ZigbeeNetwork;
|
||||
|
||||
public:
|
||||
enum Attribute {
|
||||
AttributeUpgradeServerId = 0x0000,
|
||||
AttributeFileOffset = 0x0001,
|
||||
AttributeCurrentFileVersion = 0x0002,
|
||||
AttributeCurrentZigbeeStackVersion = 0x0003,
|
||||
AttributeDownloadedFileVersion = 0x0004,
|
||||
AttributeDownloadedZigbeeStackVersion = 0x0005,
|
||||
AttributeImageUpgradeStatus = 0x0006,
|
||||
AttributeManufacturerId = 0x0007,
|
||||
AttributeImageTypeId = 0x0008,
|
||||
AttributeMinimumBockPeriod = 0x0009,
|
||||
AttributeImageStamp = 0x000a
|
||||
};
|
||||
Q_ENUM(Attribute)
|
||||
|
||||
enum Command {
|
||||
CommandImageNotify = 0x00,
|
||||
CommandQueryNextImageRequest = 0x01,
|
||||
CommandQueryNextImageResponse = 0x02,
|
||||
CommandImageBlockRequest = 0x03,
|
||||
CommandImagePageRequest = 0x04,
|
||||
CommandImageBlockResponse = 0x05,
|
||||
CommandUpgradeEndRequest = 0x06,
|
||||
CommandUpgradeEndResponse = 0x07,
|
||||
CommandQueryDeviceSpecificFileRequest = 0x08,
|
||||
CommandQueryDeviceSpecificFileResponse = 0x09
|
||||
};
|
||||
Q_ENUM(Command)
|
||||
|
||||
enum StatusCode {
|
||||
StatuCodeSuccess = 0x00,
|
||||
StatuCodeAbort = 0x95,
|
||||
StatuCodeNotAuthorized = 0x7E,
|
||||
StatuCodeInvalidImage = 0x96,
|
||||
StatuCodeWaitForData = 0x97,
|
||||
StatuCodeNoImageAvailable = 0x98,
|
||||
StatuCodeMalformedCommand = 0x80,
|
||||
StatuCodeUnsupportedClusterCommand = 0x81,
|
||||
StatuCodeRequireMoreImage = 0x99
|
||||
};
|
||||
Q_ENUM(StatusCode)
|
||||
|
||||
typedef struct FileVersion {
|
||||
quint8 applicationRelease;
|
||||
quint8 applicationBuild;
|
||||
quint8 stackRelease;
|
||||
quint8 stackBuild;
|
||||
} FileVersion;
|
||||
|
||||
explicit ZigbeeClusterOta(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void processDataIndication(ZigbeeClusterLibrary::Frame frame) override;
|
||||
|
||||
private:
|
||||
void setAttribute(const ZigbeeClusterAttribute &attribute) override;
|
||||
|
||||
FileVersion parseFileVersion(quint32 fileVersionValue);
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, const ZigbeeClusterOta::FileVersion &fileVersion);
|
||||
|
||||
|
||||
#endif // ZIGBEECLUSTEROTA_H
|
||||
|
|
@ -250,6 +250,50 @@ ZigbeeClusterReply *ZigbeeCluster::executeClusterCommand(quint8 command, const Q
|
|||
return zclReply;
|
||||
}
|
||||
|
||||
ZigbeeClusterReply *ZigbeeCluster::sendClusterServerResponse(quint8 command, quint8 transactionSequenceNumber, const QByteArray &payload)
|
||||
{
|
||||
ZigbeeNetworkRequest request = createGeneralRequest();
|
||||
|
||||
// Build ZCL frame control
|
||||
ZigbeeClusterLibrary::FrameControl frameControl;
|
||||
frameControl.frameType = ZigbeeClusterLibrary::FrameTypeClusterSpecific;
|
||||
frameControl.manufacturerSpecific = false;
|
||||
frameControl.direction = ZigbeeClusterLibrary::DirectionServerToClient;
|
||||
frameControl.disableDefaultResponse = true;
|
||||
|
||||
// Build ZCL header
|
||||
ZigbeeClusterLibrary::Header header;
|
||||
header.frameControl = frameControl;
|
||||
header.command = command;
|
||||
header.transactionSequenceNumber = transactionSequenceNumber;
|
||||
|
||||
// Build ZCL frame
|
||||
ZigbeeClusterLibrary::Frame frame;
|
||||
frame.header = header;
|
||||
frame.payload = payload;
|
||||
|
||||
request.setTxOptions(Zigbee::ZigbeeTxOptions(Zigbee::ZigbeeTxOptionAckTransmission));
|
||||
request.setAsdu(ZigbeeClusterLibrary::buildFrame(frame));
|
||||
|
||||
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](){
|
||||
if (!verifyNetworkError(zclReply, networkReply)) {
|
||||
qCWarning(dcZigbeeClusterLibrary()) << "Failed to send response"
|
||||
<< m_node << networkReply->error()
|
||||
<< networkReply->zigbeeApsStatus();
|
||||
finishZclReply(zclReply);
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: since this is a response to a request, we don't expect any additional indications and the reply is finished
|
||||
finishZclReply(zclReply);
|
||||
});
|
||||
|
||||
return zclReply;
|
||||
}
|
||||
|
||||
ZigbeeNetworkRequest ZigbeeCluster::createGeneralRequest()
|
||||
{
|
||||
// Build the request
|
||||
|
|
@ -261,7 +305,7 @@ ZigbeeNetworkRequest ZigbeeCluster::createGeneralRequest()
|
|||
request.setClusterId(m_clusterId);
|
||||
request.setSourceEndpoint(0x01);
|
||||
request.setDestinationEndpoint(m_endpoint->endpointId());
|
||||
request.setRadius(10);
|
||||
request.setRadius(0);
|
||||
request.setTxOptions(Zigbee::ZigbeeTxOptions(Zigbee::ZigbeeTxOptionAckTransmission));
|
||||
return request;
|
||||
}
|
||||
|
|
@ -320,8 +364,6 @@ void ZigbeeCluster::processDataIndication(ZigbeeClusterLibrary::Frame frame)
|
|||
|
||||
void ZigbeeCluster::processApsDataIndication(const QByteArray &asdu, const ZigbeeClusterLibrary::Frame &frame)
|
||||
{
|
||||
qCDebug(dcZigbeeCluster()) << "Received data indication" << this << frame;
|
||||
|
||||
// Check if this indication is for a pending reply
|
||||
if (m_pendingReplies.contains(frame.header.transactionSequenceNumber)) {
|
||||
ZigbeeClusterReply *reply = m_pendingReplies.value(frame.header.transactionSequenceNumber);
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ protected:
|
|||
// Cluster specific
|
||||
ZigbeeClusterReply *createClusterReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame frame);
|
||||
ZigbeeClusterReply *executeClusterCommand(quint8 command, const QByteArray &payload = QByteArray());
|
||||
|
||||
ZigbeeClusterReply *sendClusterServerResponse(quint8 command, quint8 transactionSequenceNumber, const QByteArray &payload = QByteArray());
|
||||
|
||||
bool verifyNetworkError(ZigbeeClusterReply *zclReply, ZigbeeNetworkReply *networkReply);
|
||||
void finishZclReply(ZigbeeClusterReply *zclReply);
|
||||
|
||||
|
|
|
|||
|
|
@ -581,7 +581,7 @@ void ZigbeeNode::handleZigbeeClusterLibraryIndication(const Zigbee::ApsdeDataInd
|
|||
// Get the endpoint
|
||||
ZigbeeNodeEndpoint *endpoint = getEndpoint(indication.sourceEndpoint);
|
||||
if (!endpoint) {
|
||||
qCWarning(dcZigbeeNetwork()) << "Received a ZCL indication for an unrecognized endpoint. There is no such endpoint on" << this << "Creating the uninitialized endpoint";
|
||||
qCDebug(dcZigbeeNetwork()) << "Received a ZCL indication for an unrecognized endpoint. There is no such endpoint on" << this << "Creating the uninitialized endpoint";
|
||||
// Create the uninitialized endpoint for now and fetch information later
|
||||
endpoint = new ZigbeeNodeEndpoint(m_network, this, indication.sourceEndpoint, this);
|
||||
endpoint->setProfile(static_cast<Zigbee::ZigbeeProfile>(indication.profileId));
|
||||
|
|
|
|||
|
|
@ -207,6 +207,11 @@ ZigbeeCluster *ZigbeeNodeEndpoint::createCluster(ZigbeeClusterLibrary::ClusterId
|
|||
return new ZigbeeClusterIasZone(m_network, m_node, this, direction, this);
|
||||
break;
|
||||
|
||||
// OTA
|
||||
case ZigbeeClusterLibrary::ClusterIdOtaUpgrade:
|
||||
return new ZigbeeClusterOta(m_network, m_node, this, direction, this);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Return a default cluster since we have no special implementation for this cluster, allowing to use generic clusters operations
|
||||
return new ZigbeeCluster(m_network, m_node, this, clusterId, direction, this);
|
||||
|
|
@ -244,7 +249,7 @@ void ZigbeeNodeEndpoint::handleZigbeeClusterLibraryIndication(const Zigbee::Apsd
|
|||
cluster = getOutputCluster(static_cast<ZigbeeClusterLibrary::ClusterId>(indication.clusterId));
|
||||
if (!cluster) {
|
||||
cluster = createCluster(static_cast<ZigbeeClusterLibrary::ClusterId>(indication.clusterId), ZigbeeCluster::Client);
|
||||
qCWarning(dcZigbeeEndpoint()) << "Received a ZCL indication for a cluster which does not exist yet on" << m_node << this << "Creating" << cluster;
|
||||
qCDebug(dcZigbeeEndpoint()) << "Received a ZCL indication for a client cluster which does not exist yet on" << m_node << this << "Creating" << cluster;
|
||||
addOutputCluster(cluster);
|
||||
}
|
||||
break;
|
||||
|
|
@ -253,7 +258,7 @@ void ZigbeeNodeEndpoint::handleZigbeeClusterLibraryIndication(const Zigbee::Apsd
|
|||
cluster = getInputCluster(static_cast<ZigbeeClusterLibrary::ClusterId>(indication.clusterId));
|
||||
if (!cluster) {
|
||||
cluster = createCluster(static_cast<ZigbeeClusterLibrary::ClusterId>(indication.clusterId), ZigbeeCluster::Server);
|
||||
qCWarning(dcZigbeeEndpoint()) << "Received a ZCL indication for a cluster which does not exist yet on" << m_node << this << "Creating" << cluster;
|
||||
qCDebug(dcZigbeeEndpoint()) << "Received a ZCL indication for a server cluster which does not exist yet on" << m_node << this << "Creating" << cluster;
|
||||
addInputCluster(cluster);
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@
|
|||
|
||||
#include "zcl/security/zigbeeclusteriaszone.h"
|
||||
|
||||
#include "zcl/ota/zigbeeclusterota.h"
|
||||
|
||||
class ZigbeeNode;
|
||||
class ZigbeeNetwork;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue