From c9cdbb4413844f7ee3aa9aab6a15e91e1033c238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Sun, 5 Apr 2020 22:48:59 +0200 Subject: [PATCH] Start with ADPU creating and prepare first ASP communication --- .../deconz/zigbeebridgecontrollerdeconz.cpp | 166 +++++++++++++++++- .../deconz/zigbeebridgecontrollerdeconz.h | 15 +- .../deconz/zigbeenetworkdeconz.cpp | 40 +++-- libnymea-zigbee/deconz/zigbeenetworkdeconz.h | 2 + libnymea-zigbee/deconz/zigbeenodedeconz.cpp | 34 ++++ libnymea-zigbee/deconz/zigbeenodedeconz.h | 49 ++++++ .../deconz/zigbeenodeendpointdeconz.cpp | 33 ++++ .../deconz/zigbeenodeendpointdeconz.h | 43 +++++ libnymea-zigbee/libnymea-zigbee.pro | 6 + .../nxp/zigbeebridgecontrollernxp.cpp | 2 +- libnymea-zigbee/zigbee.h | 13 +- libnymea-zigbee/zigbeeadpu.cpp | 56 ++++++ libnymea-zigbee/zigbeeadpu.h | 70 ++++++++ 13 files changed, 511 insertions(+), 18 deletions(-) create mode 100644 libnymea-zigbee/deconz/zigbeenodedeconz.cpp create mode 100644 libnymea-zigbee/deconz/zigbeenodedeconz.h create mode 100644 libnymea-zigbee/deconz/zigbeenodeendpointdeconz.cpp create mode 100644 libnymea-zigbee/deconz/zigbeenodeendpointdeconz.h create mode 100644 libnymea-zigbee/zigbeeadpu.cpp create mode 100644 libnymea-zigbee/zigbeeadpu.h diff --git a/libnymea-zigbee/deconz/zigbeebridgecontrollerdeconz.cpp b/libnymea-zigbee/deconz/zigbeebridgecontrollerdeconz.cpp index ef00e9f..b04fed2 100644 --- a/libnymea-zigbee/deconz/zigbeebridgecontrollerdeconz.cpp +++ b/libnymea-zigbee/deconz/zigbeebridgecontrollerdeconz.cpp @@ -60,6 +60,11 @@ void ZigbeeBridgeControllerDeconz::setFirmwareVersionString(const QString &firmw emit firmwareVersionChanged(m_firmwareVersion); } +Deconz::NetworkState ZigbeeBridgeControllerDeconz::networkState() const +{ + return m_networkState; +} + ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestVersion() { quint8 sequenceNumber = generateSequenceNumber(); @@ -195,6 +200,148 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestReadReceivedDat return createReply(Deconz::CommandApsDataIndication, sequenceNumber, this); } +ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestQuerySendDataConfirm() +{ + quint8 sequenceNumber = generateSequenceNumber(); + qCDebug(dcZigbeeController()) << "Request query send data confirm. SQN:" << sequenceNumber; + + QByteArray message; + QDataStream stream(&message, QIODevice::WriteOnly); + stream.setByteOrder(QDataStream::LittleEndian); + stream << static_cast(Deconz::CommandApsDataConfirm); + stream << static_cast(sequenceNumber); + stream << static_cast(0); // Reserverd + stream << static_cast(7); // Frame length + stream << static_cast(0); // Payload length + + m_interface->sendPackage(message); + + return createReply(Deconz::CommandApsDataConfirm, sequenceNumber, this); +} + +ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendDataGroup(quint8 requestId, quint16 groupAddress, quint8 destinationEndpoint, Zigbee::ZigbeeProfile profileId, Zigbee::ClusterId clusterId, quint8 sourceEndpoint, const QByteArray &asdu, quint8 radius) +{ + quint8 sequenceNumber = generateSequenceNumber(); + qCDebug(dcZigbeeController()) << "Request enqueue send data to group" << ZigbeeUtils::convertUint16ToHexString(groupAddress) + << "SQN:" << sequenceNumber + << ZigbeeUtils::convertByteToHexString(destinationEndpoint) + << profileId << clusterId + << ZigbeeUtils::convertByteToHexString(sourceEndpoint); + + Q_ASSERT_X(asdu.length() <= 127, "ASDU", "ASDU package length has to <= 127 bytes"); + + // Note: 15 protocol bytes + asdu package length + quint16 payloadLength = static_cast(15 + asdu.length()); + + QByteArray message; + QDataStream stream(&message, QIODevice::WriteOnly); + stream.setByteOrder(QDataStream::LittleEndian); + stream << static_cast(Deconz::CommandApsDataRequest); + stream << static_cast(sequenceNumber); + stream << static_cast(0); // Reserverd + stream << static_cast(7 + payloadLength); // Frame length + stream << static_cast(payloadLength); + stream << requestId; + stream << static_cast(0); // Flags + stream << static_cast(Zigbee::DestinationAddressModeGroup); + stream << groupAddress << destinationEndpoint; + stream << static_cast(profileId); + stream << static_cast(clusterId); + stream << sourceEndpoint; + stream << static_cast(asdu.length()); + for (int i = 0; i < asdu.length(); i++) { + stream << static_cast(asdu.at(i)); + } + stream << static_cast(0x04); // TX Options: Use ASP ACKs + stream << radius; + + m_interface->sendPackage(message); + + return createReply(Deconz::CommandApsDataRequest, sequenceNumber, this); +} + +ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendDataShortAddress(quint8 requestId, quint16 shortAddress, quint8 destinationEndpoint, Zigbee::ZigbeeProfile profileId, Zigbee::ClusterId clusterId, quint8 sourceEndpoint, const QByteArray &asdu, quint8 radius) +{ + quint8 sequenceNumber = generateSequenceNumber(); + qCDebug(dcZigbeeController()) << "Request enqueue send data to short address" << ZigbeeUtils::convertUint16ToHexString(shortAddress) + << "SQN:" << sequenceNumber + << ZigbeeUtils::convertByteToHexString(destinationEndpoint) + << profileId << clusterId + << ZigbeeUtils::convertByteToHexString(sourceEndpoint); + + Q_ASSERT_X(asdu.length() <= 127, "ASDU", "ASDU package length has to <= 127 bytes"); + + // Note: 15 protocol bytes + asdu package length + quint16 payloadLength = static_cast(15 + asdu.length()); + + QByteArray message; + QDataStream stream(&message, QIODevice::WriteOnly); + stream.setByteOrder(QDataStream::LittleEndian); + stream << static_cast(Deconz::CommandApsDataRequest); + stream << static_cast(sequenceNumber); + stream << static_cast(0); // Reserverd + stream << static_cast(7 + payloadLength); // Frame length + stream << static_cast(payloadLength); + stream << requestId; + stream << static_cast(0); // Flags + stream << static_cast(Zigbee::DestinationAddressModeShortAddress); + stream << shortAddress << destinationEndpoint; + stream << static_cast(profileId); + stream << static_cast(clusterId); + stream << sourceEndpoint; + stream << static_cast(asdu.length()); + for (int i = 0; i < asdu.length(); i++) { + stream << static_cast(asdu.at(i)); + } + stream << static_cast(0x04); // TX Options: Use ASP ACKs + stream << radius; + + m_interface->sendPackage(message); + + return createReply(Deconz::CommandApsDataRequest, sequenceNumber, this); +} + +ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendDataIeeeAddress(quint8 requestId, ZigbeeAddress ieeeAddress, quint8 destinationEndpoint, Zigbee::ZigbeeProfile profileId, Zigbee::ClusterId clusterId, quint8 sourceEndpoint, const QByteArray &asdu, quint8 radius) +{ + quint8 sequenceNumber = generateSequenceNumber(); + qCDebug(dcZigbeeController()) << "Request enqueue send data to IEEE address" << ieeeAddress.toString() + << "SQN:" << sequenceNumber + << ZigbeeUtils::convertByteToHexString(destinationEndpoint) + << profileId << clusterId + << ZigbeeUtils::convertByteToHexString(sourceEndpoint); + + Q_ASSERT_X(asdu.length() <= 127, "ASDU", "ASDU package length has to <= 127 bytes"); + + // Note: 21 protocol bytes + asdu package length + quint16 payloadLength = static_cast(21 + asdu.length()); + + QByteArray message; + QDataStream stream(&message, QIODevice::WriteOnly); + stream.setByteOrder(QDataStream::LittleEndian); + stream << static_cast(Deconz::CommandApsDataRequest); + stream << static_cast(sequenceNumber); + stream << static_cast(0); // Reserverd + stream << static_cast(7 + payloadLength); // Frame length + stream << static_cast(payloadLength); + stream << requestId; + stream << static_cast(0); // Flags + stream << static_cast(Zigbee::DestinationAddressModeIeeeAddress); + stream << ieeeAddress.toUInt64() << destinationEndpoint; + stream << static_cast(profileId); + stream << static_cast(clusterId); + stream << sourceEndpoint; + stream << static_cast(asdu.length()); + for (int i = 0; i < asdu.length(); i++) { + stream << static_cast(asdu.at(i)); + } + stream << static_cast(0x04); // TX Options: Use ASP ACKs + stream << radius; + + m_interface->sendPackage(message); + + return createReply(Deconz::CommandApsDataRequest, sequenceNumber, this); +} + quint8 ZigbeeBridgeControllerDeconz::generateSequenceNumber() { return m_sequenceNumber++; @@ -573,6 +720,20 @@ void ZigbeeBridgeControllerDeconz::processDeviceState(DeconzDeviceState deviceSt << "configuration changed:" << deviceState.configurationChanged << "ASPDE-DATA.request free slots:" << deviceState.aspDataRequestFreeSlots; + if (m_networkState != deviceState.networkState) { + qCDebug(dcZigbeeController()) << "Network state changed" << deviceState.networkState; + m_networkState = deviceState.networkState; + emit networkStateChanged(m_networkState); + } + + if (m_aspFreeSlotsAvailable != deviceState.aspDataRequestFreeSlots) { + m_aspFreeSlotsAvailable = deviceState.aspDataRequestFreeSlots; + + // FIXME: if true, send next asp request + + } + + // Check if we have to fech new data if (deviceState.aspDataConfirm) { ZigbeeInterfaceDeconzReply *reply = requestReadReceivedDataIndication(); @@ -584,7 +745,6 @@ void ZigbeeBridgeControllerDeconz::processDeviceState(DeconzDeviceState deviceSt } // ASP data indication received - QDataStream stream(reply->responseData()); stream.setByteOrder(QDataStream::LittleEndian); quint16 payloadLenght = 0; quint8 deviceStateFlag = 0; quint8 destinationAddressModeFlag = 0; @@ -598,7 +758,7 @@ void ZigbeeBridgeControllerDeconz::processDeviceState(DeconzDeviceState deviceSt if (destinationAddressMode == Zigbee::DestinationAddressModeGroup || destinationAddressMode == Zigbee::DestinationAddressModeShortAddress) stream >> destinationShortAddress; - if (destinationAddressMode == Zigbee::DestinationAddressModeUnicastIeee) + if (destinationAddressMode == Zigbee::DestinationAddressModeIeeeAddress) stream >> destinationIeeeAddress; stream >> destinationEndpoint >> sourceAddressModeFlag; @@ -630,7 +790,7 @@ void ZigbeeBridgeControllerDeconz::processDeviceState(DeconzDeviceState deviceSt if (destinationAddressMode == Zigbee::DestinationAddressModeShortAddress) qCDebug(dcZigbeeController()) << " Destination short address:" << ZigbeeUtils::convertUint16ToHexString(destinationShortAddress); - if (destinationAddressMode == Zigbee::DestinationAddressModeUnicastIeee) + if (destinationAddressMode == Zigbee::DestinationAddressModeIeeeAddress) qCDebug(dcZigbeeController()) << " Destination IEEE address:" << ZigbeeAddress(destinationIeeeAddress).toString(); qCDebug(dcZigbeeController()) << " Destination endpoint" << ZigbeeUtils::convertByteToHexString(destinationEndpoint); diff --git a/libnymea-zigbee/deconz/zigbeebridgecontrollerdeconz.h b/libnymea-zigbee/deconz/zigbeebridgecontrollerdeconz.h index cf99f5b..5833773 100644 --- a/libnymea-zigbee/deconz/zigbeebridgecontrollerdeconz.h +++ b/libnymea-zigbee/deconz/zigbeebridgecontrollerdeconz.h @@ -85,12 +85,21 @@ public: DeconzNetworkConfiguration networkConfiguration() const; void setFirmwareVersionString(const QString &firmwareVersion); + Deconz::NetworkState networkState() const; + ZigbeeInterfaceDeconzReply *requestVersion(); ZigbeeInterfaceDeconzReply *requestDeviceState(); ZigbeeInterfaceDeconzReply *requestReadParameter(Deconz::Parameter parameter); ZigbeeInterfaceDeconzReply *requestWriteParameter(Deconz::Parameter parameter, const QByteArray &data); ZigbeeInterfaceDeconzReply *requestChangeNetworkState(Deconz::NetworkState networkState); + ZigbeeInterfaceDeconzReply *requestReadReceivedDataIndication(Deconz::SourceAddressMode sourceAddressMode = Deconz::SourceAddressModeShortSourceAddress); + ZigbeeInterfaceDeconzReply *requestQuerySendDataConfirm(); + + // Send data + ZigbeeInterfaceDeconzReply *requestEnqueueSendDataGroup(quint8 requestId, quint16 groupAddress, quint8 destinationEndpoint, Zigbee::ZigbeeProfile profileId, Zigbee::ClusterId clusterId, quint8 sourceEndpoint, const QByteArray &asdu, quint8 radius = 0); + ZigbeeInterfaceDeconzReply *requestEnqueueSendDataShortAddress(quint8 requestId, quint16 shortAddress, quint8 destinationEndpoint, Zigbee::ZigbeeProfile profileId, Zigbee::ClusterId clusterId, quint8 sourceEndpoint, const QByteArray &asdu, quint8 radius = 0); + ZigbeeInterfaceDeconzReply *requestEnqueueSendDataIeeeAddress(quint8 requestId, ZigbeeAddress ieeeAddress, quint8 destinationEndpoint, Zigbee::ZigbeeProfile profileId, Zigbee::ClusterId clusterId, quint8 sourceEndpoint, const QByteArray &asdu, quint8 radius = 0); private: @@ -100,8 +109,11 @@ private: int m_watchdogResetTimout = 60; QHash m_pendingReplies; DeconzNetworkConfiguration m_networkConfiguration; + Deconz::NetworkState m_networkState = Deconz::NetworkStateOffline; QTimer *m_watchdogTimer = nullptr; + bool m_aspFreeSlotsAvailable = false; + quint8 generateSequenceNumber(); ZigbeeInterfaceDeconzReply *createReply(Deconz::Command command, quint8 sequenceNumber, QObject *parent); @@ -110,11 +122,12 @@ private: // The data can be fetched from m_networkConfiguration on success. ZigbeeInterfaceDeconzReply *readNetworkParameters(); + // Device state helper DeconzDeviceState parseDeviceStateFlag(quint8 deviceStateFlag); - void processDeviceState(DeconzDeviceState deviceState); signals: + void networkStateChanged(Deconz::NetworkState networkState); void networkConfigurationParameterChanged(const DeconzNetworkConfiguration &networkConfiguration); private slots: diff --git a/libnymea-zigbee/deconz/zigbeenetworkdeconz.cpp b/libnymea-zigbee/deconz/zigbeenetworkdeconz.cpp index 9a3d607..a013b16 100644 --- a/libnymea-zigbee/deconz/zigbeenetworkdeconz.cpp +++ b/libnymea-zigbee/deconz/zigbeenetworkdeconz.cpp @@ -130,32 +130,48 @@ void ZigbeeNetworkDeconz::startNetworkInternally() qCDebug(dcZigbeeNetwork()) << "Read device state finished successfully"; QDataStream stream(reply->responseData()); + stream.setByteOrder(QDataStream::LittleEndian); + quint8 deviceStateFlag = 0; + stream >> deviceStateFlag; + // Update the device state in the controller + m_controller->processDeviceState(m_controller->parseDeviceStateFlag(deviceStateFlag)); + if (m_createNewNetwork) { + // Write the configurations which need to be changed + createNetwork(); + + // Initialize coordinator node + + + } else { + // Get the network state and start the network if required + if (m_controller->networkState() == Deconz::NetworkStateConnected) { + qCDebug(dcZigbeeNetwork()) << "The network is already running."; + setState(StateRunning); + } + + + + + } }); - if (m_createNewNetwork) { - // Write the configurations which need to be changed - // Initialize coordinator node - - - } else { - // Get the network state and start the network if required - - - - } - }); }); } +void ZigbeeNetworkDeconz::createNetwork() +{ + +} + void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available) { qCDebug(dcZigbeeNetwork()) << "Hardware controller is" << (available ? "now available" : "not available"); diff --git a/libnymea-zigbee/deconz/zigbeenetworkdeconz.h b/libnymea-zigbee/deconz/zigbeenetworkdeconz.h index 743a465..a0bd06e 100644 --- a/libnymea-zigbee/deconz/zigbeenetworkdeconz.h +++ b/libnymea-zigbee/deconz/zigbeenetworkdeconz.h @@ -52,6 +52,8 @@ protected: void startNetworkInternally(); + void createNetwork(); + private slots: void onControllerAvailableChanged(bool available); diff --git a/libnymea-zigbee/deconz/zigbeenodedeconz.cpp b/libnymea-zigbee/deconz/zigbeenodedeconz.cpp new file mode 100644 index 0000000..82dc748 --- /dev/null +++ b/libnymea-zigbee/deconz/zigbeenodedeconz.cpp @@ -0,0 +1,34 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 . +* +* 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 "zigbeenodedeconz.h" + +ZigbeeNodeDeconz::ZigbeeNodeDeconz(QObject *parent) : + ZigbeeNode(parent) +{ + +} diff --git a/libnymea-zigbee/deconz/zigbeenodedeconz.h b/libnymea-zigbee/deconz/zigbeenodedeconz.h new file mode 100644 index 0000000..ba3479f --- /dev/null +++ b/libnymea-zigbee/deconz/zigbeenodedeconz.h @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 . +* +* 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 ZIGBEENODEDECONZ_H +#define ZIGBEENODEDECONZ_H + +#include + +#include "zigbee.h" +#include "zigbeenode.h" + +class ZigbeeNodeDeconz : public ZigbeeNode +{ + Q_OBJECT + + friend class ZigbeeNetworkDeconz; + +public: + explicit ZigbeeNodeDeconz(QObject *parent = nullptr); + +signals: + +}; + +#endif // ZIGBEENODEDECONZ_H diff --git a/libnymea-zigbee/deconz/zigbeenodeendpointdeconz.cpp b/libnymea-zigbee/deconz/zigbeenodeendpointdeconz.cpp new file mode 100644 index 0000000..d7f6ba3 --- /dev/null +++ b/libnymea-zigbee/deconz/zigbeenodeendpointdeconz.cpp @@ -0,0 +1,33 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 . +* +* 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 "zigbeenodeendpointdeconz.h" + +ZigbeeNodeEndpointDeconz::ZigbeeNodeEndpointDeconz(QObject *parent) : QObject(parent) +{ + +} diff --git a/libnymea-zigbee/deconz/zigbeenodeendpointdeconz.h b/libnymea-zigbee/deconz/zigbeenodeendpointdeconz.h new file mode 100644 index 0000000..92dd2eb --- /dev/null +++ b/libnymea-zigbee/deconz/zigbeenodeendpointdeconz.h @@ -0,0 +1,43 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 . +* +* 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 ZIGBEENODEENDPOINTDECONZ_H +#define ZIGBEENODEENDPOINTDECONZ_H + +#include + +class ZigbeeNodeEndpointDeconz : public QObject +{ + Q_OBJECT +public: + explicit ZigbeeNodeEndpointDeconz(QObject *parent = nullptr); + +signals: + +}; + +#endif // ZIGBEENODEENDPOINTDECONZ_H diff --git a/libnymea-zigbee/libnymea-zigbee.pro b/libnymea-zigbee/libnymea-zigbee.pro index 9ed1937..a939ddf 100644 --- a/libnymea-zigbee/libnymea-zigbee.pro +++ b/libnymea-zigbee/libnymea-zigbee.pro @@ -8,6 +8,8 @@ SOURCES += \ deconz/interface/zigbeeinterfacedeconzreply.cpp \ deconz/zigbeebridgecontrollerdeconz.cpp \ deconz/zigbeenetworkdeconz.cpp \ + deconz/zigbeenodedeconz.cpp \ + deconz/zigbeenodeendpointdeconz.cpp \ nxp/interface/zigbeeinterface.cpp \ nxp/interface/zigbeeinterfacemessage.cpp \ nxp/interface/zigbeeinterfacerequest.cpp \ @@ -16,6 +18,7 @@ SOURCES += \ nxp/zigbeebridgecontrollernxp.cpp \ nxp/zigbeenodeendpointnxp.cpp \ nxp/zigbeenodenxp.cpp \ + zigbeeadpu.cpp \ zigbeebridgecontroller.cpp \ zigbeechannelmask.cpp \ zigbeecluster.cpp \ @@ -39,6 +42,8 @@ HEADERS += \ deconz/interface/zigbeeinterfacedeconzreply.h \ deconz/zigbeebridgecontrollerdeconz.h \ deconz/zigbeenetworkdeconz.h \ + deconz/zigbeenodedeconz.h \ + deconz/zigbeenodeendpointdeconz.h \ nxp/interface/zigbeeinterface.h \ nxp/interface/zigbeeinterfacemessage.h \ nxp/interface/zigbeeinterfacerequest.h \ @@ -47,6 +52,7 @@ HEADERS += \ nxp/zigbeebridgecontrollernxp.h \ nxp/zigbeenodeendpointnxp.h \ nxp/zigbeenodenxp.h \ + zigbeeadpu.h \ zigbeebridgecontroller.h \ zigbeechannelmask.h \ zigbeecluster.h \ diff --git a/libnymea-zigbee/nxp/zigbeebridgecontrollernxp.cpp b/libnymea-zigbee/nxp/zigbeebridgecontrollernxp.cpp index 38c4a2d..9c933ce 100644 --- a/libnymea-zigbee/nxp/zigbeebridgecontrollernxp.cpp +++ b/libnymea-zigbee/nxp/zigbeebridgecontrollernxp.cpp @@ -516,7 +516,7 @@ ZigbeeInterfaceReply *ZigbeeBridgeControllerNxp::commandBindUnicast(const Zigbee stream << sourceAddress.toUInt64(); stream << sourceEndpoint; stream << clusterId; - stream << static_cast(Zigbee::DestinationAddressModeUnicastIeee); + stream << static_cast(Zigbee::DestinationAddressModeIeeeAddress); stream << destinationAddress.toUInt64(); stream << destinationEndpoint; diff --git a/libnymea-zigbee/zigbee.h b/libnymea-zigbee/zigbee.h index a15faea..e130caf 100644 --- a/libnymea-zigbee/zigbee.h +++ b/libnymea-zigbee/zigbee.h @@ -537,7 +537,7 @@ public: enum DestinationAddressMode { DestinationAddressModeGroup = 0x01, DestinationAddressModeShortAddress = 0x02, - DestinationAddressModeUnicastIeee = 0x03 + DestinationAddressModeIeeeAddress = 0x03 }; Q_ENUM(DestinationAddressMode) @@ -559,6 +559,16 @@ public: }; Q_ENUM(ZigbeeZdpStatus) + enum ZigbeeTxOption { + ZigbeeTxOptionSecurityEnabled = 0x01, + ZigbeeTxOptionUseNetworkKey = 0x02, + ZigbeeTxOptionAckTransmission = 0x04, + ZigbeeTxOptionFragmentationPermitted = 0x08, + ZigbeeTxOptionIncludeExtendedNonceInSecurityFrame = 0x10 + }; + Q_ENUM(ZigbeeTxOption) + Q_DECLARE_FLAGS(ZigbeeTxOptions, ZigbeeTxOption) + enum Manufacturer { // RF4CE PanasonicRF4CE = 0x0001, @@ -1332,5 +1342,6 @@ public: }; Q_DECLARE_OPERATORS_FOR_FLAGS(Zigbee::ZigbeeChannels) +Q_DECLARE_OPERATORS_FOR_FLAGS(Zigbee::ZigbeeTxOptions) #endif // ZIGBEE_H diff --git a/libnymea-zigbee/zigbeeadpu.cpp b/libnymea-zigbee/zigbeeadpu.cpp new file mode 100644 index 0000000..ba0ae30 --- /dev/null +++ b/libnymea-zigbee/zigbeeadpu.cpp @@ -0,0 +1,56 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 . +* +* 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 "zigbeeadpu.h" + +ZigbeeAdpu::ZigbeeAdpu(QObject *parent) : QObject(parent) +{ + +} + +quint8 ZigbeeAdpu::buildFrameControl(ZigbeeAdpu::FrameType frameType, ZigbeeAdpu::DeliveryMode deliveryMode, bool apsAckFormat, bool securitySubField, bool acknowledgementRequest, bool extendedHeaderPresent) +{ + quint8 frameControl = 0; + frameControl &= static_cast(frameType); // Bit 0 - 1 + frameControl &= static_cast(deliveryMode); // Bit 2 - 3 + if (apsAckFormat) + frameControl &= static_cast(0x08); // Bit 4 + + if (securitySubField) + frameControl &= static_cast(0x04); // Bit 5 + + if (securitySubField) + frameControl &= static_cast(0x04); // Bit 6 + + if (acknowledgementRequest) + frameControl &= static_cast(0x02); // Bit 7 + + if (extendedHeaderPresent) + frameControl &= static_cast(0x01); // Bit 8 + + return frameControl; +} diff --git a/libnymea-zigbee/zigbeeadpu.h b/libnymea-zigbee/zigbeeadpu.h new file mode 100644 index 0000000..5929502 --- /dev/null +++ b/libnymea-zigbee/zigbeeadpu.h @@ -0,0 +1,70 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 . +* +* 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 ZIGBEEADPU_H +#define ZIGBEEADPU_H + +#include + +typedef struct FrameControl { + +} FrameControl; + +class ZigbeeAdpu : public QObject +{ + Q_OBJECT +public: + + // Note: zigbee Pro Specification 2.2.5.1 General APDU Frame Format + + /* Frame control */ + enum FrameType { + FrameTypeData = 0x00, + FrameTypeCommand = 0x40, + FrameTypeAck = 0x80, + FrameTypeInterPanAps = 0xC0 + }; + Q_ENUM(FrameType) + + enum DeliveryMode { + DeliveryModeNormalUnicast = 0x00, + DeliveryModeBroadcast = 0x20, + DeliveryModeGroupAddressing = 0x30, + }; + Q_ENUM(DeliveryMode) + + + + explicit ZigbeeAdpu(QObject *parent = nullptr); + + quint8 buildFrameControl(FrameType frameType, DeliveryMode deliveryMode, bool apsAckFormat, bool securitySubField, bool acknowledgementRequest, bool extendedHeaderPresent); + +signals: + +}; + +#endif // ZIGBEEADPU_H