317 lines
11 KiB
C++
317 lines
11 KiB
C++
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
*
|
|
* nymea-zigbee
|
|
* Zigbee integration module for nymea
|
|
*
|
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
|
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
|
*
|
|
* This file is part of nymea-zigbee.
|
|
*
|
|
* nymea-zigbee is free software: you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation, either version 3
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* nymea-zigbee 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 nymea-zigbee. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
#ifndef ZIGBEECLUSTERLIBRARY_H
|
|
#define ZIGBEECLUSTERLIBRARY_H
|
|
|
|
#include <QObject>
|
|
#include <QDebug>
|
|
|
|
#include "zigbee.h"
|
|
#include "zigbeedatatype.h"
|
|
|
|
class ZigbeeClusterLibrary
|
|
{
|
|
Q_GADGET
|
|
public:
|
|
/* General ZCL commans */
|
|
enum Command {
|
|
CommandReadAttributes = 0x00,
|
|
CommandReadAttributesResponse = 0x01,
|
|
CommandWriteAttributes = 0x02,
|
|
CommandWriteAttributesUndivided = 0x03,
|
|
CommandWriteAttributesResponse = 0x04,
|
|
CommandWriteAttributesNoResponse = 0x05,
|
|
CommandConfigureReporting = 0x06,
|
|
CommandConfigureReportingResponse = 0x07,
|
|
CommandReadReportingConfiguration = 0x08,
|
|
CommandReadReportingConfigurationResponse = 0x09,
|
|
CommandReportAttributes = 0x0a,
|
|
CommandDefaultResponse = 0x0b,
|
|
CommandDiscoverAttributes = 0x0c,
|
|
CommandDiscoverAttributesResponse = 0x0d,
|
|
CommandReadAttributesStructured = 0x0e,
|
|
CommandWriteAttributesStructured = 0x0f,
|
|
CommandWriteAttributesStructuredResponse = 0x10,
|
|
CommandDiscoverCommandsReceived = 0x11,
|
|
CommandDiscoverCommandsReceivedResponse = 0x12,
|
|
CommandDiscoverCommandsGenerated = 0x13,
|
|
CommandDiscoverCommandsGeneratedResponse = 0x14,
|
|
CommandDiscoverAttributesExtended = 0x15,
|
|
CommandDiscoverAttributesExtendedResponse = 0x16
|
|
};
|
|
Q_ENUM(Command)
|
|
|
|
enum Status {
|
|
StatusSuccess = 0x00,
|
|
StatusFailure = 0x01,
|
|
StatusNotAuthorized = 0x7e,
|
|
StatusReservedFieldNotZero = 0x7f,
|
|
StatusMalformedCommand = 0x80,
|
|
StatusUnsupportedClusterCommand = 0x81,
|
|
StatusUnsupportedGeneralCommand = 0x82,
|
|
StatusUnsupportedManufacturerClusterCommand = 0x83,
|
|
StatusUnsupportedManufacturerGeneralCommand = 0x84,
|
|
StatusInvalidField = 0x85,
|
|
StatusUnsupportedAttribute = 0x86,
|
|
StatusInvalidValue = 0x87,
|
|
StatusReadOnly = 0x88,
|
|
StatusInsufficientSpace = 0x89,
|
|
StatusDuplicateExists = 0x8a,
|
|
StatusNotFound = 0x8b,
|
|
StatusUnreportableAttribute = 0x8c,
|
|
StatusInvalidDataType = 0x8d,
|
|
StatusInvalidSector = 0x8e,
|
|
StatusWriteOnly = 0x8f,
|
|
StatusInconsistentStartupState = 0x90,
|
|
StatusDefinedOutOfBand = 0x91,
|
|
StatusInconsistent = 0x92,
|
|
StatusActionDenied = 0x93,
|
|
StatusTimeout = 0x94,
|
|
StatusAbort = 0x95,
|
|
StatusInvalidImage = 0x96,
|
|
StatusWaitForData = 0x97,
|
|
StatusNoImageAvailable = 0x98,
|
|
StatusRequireMoreImage = 0x99,
|
|
StatusNotificationPending = 0x9a,
|
|
StatusHardwareFailure = 0xc0,
|
|
StatusSoftwareFailure = 0xc1,
|
|
StatusCalibrationError = 0xc2,
|
|
StatusUnsupportedCluster = 0xc3
|
|
};
|
|
Q_ENUM(Status)
|
|
|
|
enum ClusterId {
|
|
// Basics
|
|
ClusterIdUnknown = 0xffff,
|
|
ClusterIdBasic = 0x0000,
|
|
ClusterIdPowerConfiguration = 0x0001,
|
|
ClusterIdDeviceTemperature = 0x0002,
|
|
ClusterIdIdentify = 0x0003,
|
|
ClusterIdGroups = 0x0004,
|
|
ClusterIdScenes = 0x0005,
|
|
ClusterIdOnOff = 0x0006,
|
|
ClusterIdOnOffConfiguration = 0x0007,
|
|
ClusterIdLevelControl = 0x0008,
|
|
ClusterIdAlarms = 0x0009,
|
|
ClusterIdTime = 0x000A,
|
|
ClusterIdRssiLocation = 0x000B,
|
|
ClusterIdAnalogInput = 0x000C,
|
|
ClusterIdAnalogOutput = 0x000D,
|
|
ClusterIdAnalogValue = 0x000E,
|
|
ClusterIdBinaryInput = 0x000F,
|
|
ClusterIdBinaryOutput = 0x0010,
|
|
ClusterIdBinaryValue = 0x0011,
|
|
ClusterIdMultistateInput = 0x0012,
|
|
ClusterIdMultistateOutput = 0x0013,
|
|
ClusterIdMultistateValue = 0x0014,
|
|
ClusterIdCommissoning = 0x0015,
|
|
|
|
// Over the air uppgrade (OTA)
|
|
ClusterIdOtaUpgrade = 0x0019,
|
|
|
|
// Poll controll
|
|
ClusterIdPollControl = 0x0020,
|
|
|
|
|
|
// Closures
|
|
ClusterIdShadeConfiguration = 0x0100,
|
|
ClusterIdDoorLock = 0x0101,
|
|
ClusterIdWindowCovering = 0x0102,
|
|
|
|
// Heating, Ventilation and Air-Conditioning (HVAC)
|
|
ClusterIdPumpConfigurationControl = 0x0200,
|
|
ClusterIdThermostat = 0x0201,
|
|
ClusterIdFanControl = 0x0202,
|
|
ClusterIdDehumiditationControl = 0x0203,
|
|
ClusterIdThermostatUserControl = 0x0204,
|
|
|
|
// Lighting
|
|
ClusterIdColorControl = 0x0300,
|
|
ClusterIdBallastConfiguration = 0x0301,
|
|
|
|
// Sensing
|
|
ClusterIdIlluminanceMeasurement = 0x0400,
|
|
ClusterIdIlluminanceLevelSensing = 0x0401,
|
|
ClusterIdTemperatureMeasurement = 0x0402,
|
|
ClusterIdPressureMeasurement = 0x0403,
|
|
ClusterIdFlowMeasurement = 0x0404,
|
|
ClusterIdRelativeHumidityMeasurement = 0x0405,
|
|
ClusterIdOccupancySensing = 0x0406,
|
|
|
|
// Security and Safty
|
|
ClusterIdIasZone = 0x0500,
|
|
ClusterIdIasAce = 0x0501,
|
|
ClusterIdIasWd = 0x0502,
|
|
|
|
// Smart energy
|
|
ClusterIdPrice = 0x0700,
|
|
ClusterIdDemandResponseAndLoadControl = 0x0701,
|
|
ClusterIdMetering = 0x0702,
|
|
ClusterIdMessaging = 0x0703,
|
|
ClusterIdTunneling = 0x0704,
|
|
ClusterIdKeyEstablishment = 0x0800,
|
|
|
|
// ZLL
|
|
ClusterIdTouchlinkCommissioning = 0x1000,
|
|
|
|
// NXP Appliances
|
|
ClusterIdApplianceControl = 0x001B,
|
|
ClusterIdApplianceIdentification = 0x0B00,
|
|
ClusterIdApplianceEventsAlerts = 0x0B02,
|
|
ClusterIdApplianceStatistics = 0x0B03,
|
|
|
|
// Electrical Measurement
|
|
ClusterIdElectricalMeasurement = 0x0B04,
|
|
ClusterIdDiagnostics = 0x0B05,
|
|
|
|
// Zigbee green power
|
|
ClusterIdGreenPower = 0x0021,
|
|
|
|
// Manufacturer specific
|
|
ClusterIdManufacturerSpecificPhilips = 0xfc00,
|
|
|
|
};
|
|
Q_ENUM(ClusterId)
|
|
|
|
enum GlobalAttribute {
|
|
GlobalAttributeClusterRevision = 0xfffd,
|
|
GlobalAttributeAttributeReportingStatus = 0xfffe
|
|
};
|
|
Q_ENUM(GlobalAttribute)
|
|
|
|
enum AttributeReportingStatus {
|
|
AttributeReportingStatusPending = 0x00,
|
|
AttributeReportingStatusComplete = 0x01
|
|
};
|
|
Q_ENUM(AttributeReportingStatus)
|
|
|
|
// Frame control field
|
|
enum FrameType {
|
|
FrameTypeGlobal = 0x00,
|
|
FrameTypeClusterSpecific = 0x01
|
|
};
|
|
Q_ENUM(FrameType)
|
|
|
|
enum Direction {
|
|
DirectionClientToServer = 0x00,
|
|
DirectionServerToClient = 0x01
|
|
};
|
|
Q_ENUM(Direction)
|
|
|
|
enum ReportingDirection {
|
|
ReportingDirectionReporting = 0x00,
|
|
ReportingDirectionReceiving = 0x01
|
|
};
|
|
Q_ENUM(ReportingDirection)
|
|
|
|
typedef struct FrameControl {
|
|
FrameType frameType = FrameTypeGlobal;
|
|
bool manufacturerSpecific = false;
|
|
Direction direction = DirectionClientToServer;
|
|
bool disableDefaultResponse = false;
|
|
} FrameControl;
|
|
|
|
typedef struct Header {
|
|
FrameControl frameControl;
|
|
quint16 manufacturerCode = 0;
|
|
quint8 transactionSequenceNumber = 0;
|
|
quint8 command;
|
|
} ZclHeader;
|
|
|
|
typedef struct Frame {
|
|
Header header;
|
|
QByteArray payload;
|
|
} Frame;
|
|
|
|
|
|
// Read attribute
|
|
typedef struct ReadAttributeStatusRecord {
|
|
quint16 attributeId;
|
|
ZigbeeClusterLibrary::Status attributeStatus;
|
|
ZigbeeDataType dataType;
|
|
} ReadAttributeStatusRecord;
|
|
|
|
// Write attribute
|
|
typedef struct WriteAttributeRecord {
|
|
quint16 attributeId;
|
|
Zigbee::DataType dataType;
|
|
QByteArray data;
|
|
} WriteAttributeRecord;
|
|
|
|
// Reporting attributes
|
|
typedef struct AttributeReportingConfiguration {
|
|
ReportingDirection direction = ReportingDirectionReporting;
|
|
quint16 attributeId = 0x0000;
|
|
Zigbee::DataType dataType = Zigbee::NoData;
|
|
quint16 minReportingInterval = 0x0000; // seconds
|
|
quint16 maxReportingInterval = 0x0000; // seconds
|
|
QByteArray reportableChange; // Data depending on the dataType
|
|
quint16 timeoutPeriod = 0x0000; // seconds, only used for direction receiving
|
|
} AttributeReportingConfiguration;
|
|
|
|
// Response of reporting configuration
|
|
typedef struct AttributeReportingStatusRecord {
|
|
ZigbeeClusterLibrary::Status status;
|
|
ReportingDirection direction = ReportingDirectionReporting;
|
|
quint16 attributeId = 0x0000;
|
|
} AttributeReportingStatusRecord;
|
|
|
|
|
|
// General parse/build methods
|
|
static quint8 buildFrameControlByte(const FrameControl &frameControl);
|
|
static FrameControl parseFrameControlByte(quint8 frameControlByte);
|
|
|
|
static QByteArray buildHeader(const Header &header);
|
|
|
|
static QList<ReadAttributeStatusRecord> parseAttributeStatusRecords(const QByteArray &payload);
|
|
|
|
//static QByteArray readAttributeData(const QDataStream &stream, Zigbee::DataType dataType);
|
|
static ZigbeeDataType readDataType(QDataStream *stream, Zigbee::DataType dataType);
|
|
|
|
static Frame parseFrameData(const QByteArray &frameData);
|
|
static QByteArray buildFrame(const Frame &frame);
|
|
|
|
// AttributeReportingConfiguration
|
|
static QByteArray buildAttributeReportingConfiguration(const AttributeReportingConfiguration &reportingConfiguration);
|
|
static QByteArray buildWriteAttributeRecord(const WriteAttributeRecord &writeAttributeRecord);
|
|
// TODO: parseAttributeReportingConfiguration
|
|
|
|
static QList<AttributeReportingStatusRecord> parseAttributeReportingStatusRecords(const QByteArray &payload);
|
|
|
|
};
|
|
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::FrameControl &frameControl);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Header &header);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Frame &frame);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::ReadAttributeStatusRecord &attributeStatusRecord);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::AttributeReportingConfiguration &attributeReportingConfiguration);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::AttributeReportingStatusRecord &attributeReportingStatusRecord);
|
|
|
|
|
|
#endif // ZIGBEECLUSTERLIBRARY_H
|