diff --git a/libnymea-zigbee/backends/nxp/interface/nxp.h b/libnymea-zigbee/backends/nxp/interface/nxp.h index 213f692..fd5c16e 100644 --- a/libnymea-zigbee/backends/nxp/interface/nxp.h +++ b/libnymea-zigbee/backends/nxp/interface/nxp.h @@ -45,6 +45,13 @@ public: LogLevelDebug = 0x07 }; Q_ENUM(LogLevel) + + + enum KeyType { + KeyTypeGlobalLinkKey = 0x00, + KeyTypeUniqueLinkKey = 0x01 + }; + Q_ENUM(KeyType) }; #endif // NXP_H diff --git a/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.cpp b/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.cpp index b09c89d..34e23c0 100644 --- a/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.cpp +++ b/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.cpp @@ -102,6 +102,37 @@ ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::requestSetChannelMask(quint3 return createReply(Nxp::CommandSetChannelMask, m_sequenceNumber, "Request set channel mask", message, this); } +ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::requestSetSecurityKey(Nxp::KeyType keyType, const ZigbeeNetworkKey &key) +{ + QByteArray message; + bumpSequenceNumber(); + QDataStream stream(&message, QIODevice::WriteOnly); + stream.setByteOrder(QDataStream::LittleEndian); + stream << static_cast(Nxp::CommandSetSecurityKey); + stream << static_cast(m_sequenceNumber); + stream << static_cast(17); // Frame length + stream << static_cast(keyType); + QByteArray keyData = key.toByteArray(); + for (int i = 0; i < 16; i++) { + stream << static_cast(keyData.at(i)); + } + + return createReply(Nxp::CommandSetSecurityKey, m_sequenceNumber, "Request set security key", message, this); +} + +ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::requestStartNetwork() +{ + QByteArray message; + bumpSequenceNumber(); + QDataStream stream(&message, QIODevice::WriteOnly); + stream.setByteOrder(QDataStream::LittleEndian); + stream << static_cast(Nxp::CommandStartNetwork); + stream << static_cast(m_sequenceNumber); + stream << static_cast(0); // Frame length + + return createReply(Nxp::CommandStartNetwork, m_sequenceNumber, "Request start network", message, this); +} + ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::createReply(Nxp::Command command, quint8 sequenceNumber, const QString &requestName, const QByteArray &requestData, QObject *parent) { // Create the reply diff --git a/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.h b/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.h index e3baa7e..a72495b 100644 --- a/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.h +++ b/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.h @@ -40,8 +40,14 @@ public: ZigbeeInterfaceNxpReply *requestControllerState(); ZigbeeInterfaceNxpReply *requestSoftResetController(); ZigbeeInterfaceNxpReply *requestFactoryResetController(); + + // Configure network ZigbeeInterfaceNxpReply *requestSetPanId(quint64 panId); ZigbeeInterfaceNxpReply *requestSetChannelMask(quint32 channelMask); + ZigbeeInterfaceNxpReply *requestSetSecurityKey(Nxp::KeyType keyType, const ZigbeeNetworkKey &key); + + ZigbeeInterfaceNxpReply *requestStartNetwork(); + signals: void controllerStateChanged(ControllerState controllerState); diff --git a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp index 5b217ca..3e8467e 100644 --- a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp +++ b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp @@ -41,7 +41,8 @@ void ZigbeeNetworkNxp::onControllerAvailableChanged(bool available) qCDebug(dcZigbeeNetwork()) << "Controller is" << (available ? "now available" : "not available any more"); if (available) { - reset(); + //reset(); + factoryResetNetwork(); } } @@ -77,6 +78,8 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion(); connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){ qCDebug(dcZigbeeNetwork()) << "Version reply finished" << reply->status(); + //FIXME: error handling + QByteArray payload = reply->responseData(); QDataStream stream(&payload, QIODevice::ReadOnly); stream.setByteOrder(QDataStream::LittleEndian); @@ -91,12 +94,37 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr ZigbeeInterfaceNxpReply *reply = m_controller->requestSetPanId(extendedPanId()); connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){ qCDebug(dcZigbeeNetwork()) << "Set PAN ID reply finished" << reply->status(); + //FIXME: error handling qCDebug(dcZigbeeNetwork()) << "Set channel mask" << channelMask() << ZigbeeUtils::convertUint32ToHexString(channelMask().toUInt32()) << channelMask().toUInt32(); ZigbeeInterfaceNxpReply *reply = m_controller->requestSetChannelMask(channelMask().toUInt32()); - connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [reply](){ + connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){ qCDebug(dcZigbeeNetwork()) << "Set channel mask reply finished" << reply->status(); + //FIXME: error handling + qCDebug(dcZigbeeNetwork()) << "Set global link key" << securityConfiguration().globalTrustCenterLinkKey().toString(); + ZigbeeInterfaceNxpReply *reply = m_controller->requestSetSecurityKey(Nxp::KeyTypeGlobalLinkKey, securityConfiguration().globalTrustCenterLinkKey()); + connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){ + qCDebug(dcZigbeeNetwork()) << "Set global link key" << reply->status(); + //FIXME: error handling + + qCDebug(dcZigbeeNetwork()) << "Set network link key" << securityConfiguration().networkKey().toString(); + ZigbeeInterfaceNxpReply *reply = m_controller->requestSetSecurityKey(Nxp::KeyTypeUniqueLinkKey, securityConfiguration().networkKey()); + connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){ + qCDebug(dcZigbeeNetwork()) << "Set network link key" << reply->status(); + //FIXME: error handling + + qCDebug(dcZigbeeNetwork()) << "Start the network"; + ZigbeeInterfaceNxpReply *reply = m_controller->requestStartNetwork(); + connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){ + qCDebug(dcZigbeeNetwork()) << "Start network" << reply->status(); + //FIXME: error handling + + + + }); + }); + }); }); }); }); diff --git a/zigbee-cli/main.cpp b/zigbee-cli/main.cpp index 5fc2794..47f78d6 100644 --- a/zigbee-cli/main.cpp +++ b/zigbee-cli/main.cpp @@ -1,7 +1,8 @@ #include #include #include - +#include +#include "zigbeenetworkkey.h" #include "zigbeenetworkmanager.h" //static QHash s_loggingFilters; @@ -138,14 +139,21 @@ int main(int argc, char *argv[]) debugLevel = 1; } -// s_loggingFilters.insert("Application", true); -// s_loggingFilters.insert("Zigbee", true); -// s_loggingFilters.insert("ZigbeeController", (debugLevel > 1)); -// s_loggingFilters.insert("ZigbeeInterface", (debugLevel > 2)); -// s_loggingFilters.insert("ZigbeeInterfaceTraffic", (debugLevel > 3)); + // s_loggingFilters.insert("Application", true); + // s_loggingFilters.insert("Zigbee", true); + // s_loggingFilters.insert("ZigbeeController", (debugLevel > 1)); + // s_loggingFilters.insert("ZigbeeInterface", (debugLevel > 2)); + // s_loggingFilters.insert("ZigbeeInterfaceTraffic", (debugLevel > 3)); //QLoggingCategory::installFilter(loggingCategoryFilter); + QLoggingCategory::setFilterRules("*.debug=false\n" + "Zigbee.debug=true\n" + "ZigbeeController.debug=true\n" + "ZigbeeInterface.debug=false\n" + "ZigbeeInterfaceTraffic.debug=false\n" + ); + // Check channel bool channelValueOk = false; int channel = parser.value(channelOption).toInt(&channelValueOk); @@ -172,9 +180,12 @@ int main(int argc, char *argv[]) ZigbeeChannelMask mask; mask.setChannel(Zigbee::ZigbeeChannel13); network->setChannelMask(mask); - network->startNetwork(); - //Core core(parser.value(serialOption), baudrate, channel); + ZigbeeSecurityConfiguration securityConfiguration; + securityConfiguration.setNetworkKey(ZigbeeNetworkKey(QString("2a:59:f4:11:75:bb:64:48:55:c5:23:62:b0:33:ea:33"))); + network->setSecurityConfiguration(securityConfiguration); + + network->startNetwork(); return application.exec(); }