Merge PR #14: deCONZ backend: fix reconnect mechanism and make latest firmware version work
This commit is contained in:
commit
ca57f0a720
Binary file not shown.
@ -67,13 +67,14 @@ public:
|
|||||||
CommandApsDataIndication = 0x17,
|
CommandApsDataIndication = 0x17,
|
||||||
CommandGreenPower = 0x19,
|
CommandGreenPower = 0x19,
|
||||||
CommandMacPoll = 0x1C,
|
CommandMacPoll = 0x1C,
|
||||||
CommandSimplifiedBeacon = 0x1F
|
CommandMacBeacon = 0x1F,
|
||||||
|
CommandUpdateBootloader = 0x21
|
||||||
};
|
};
|
||||||
Q_ENUM(Command)
|
Q_ENUM(Command)
|
||||||
|
|
||||||
enum Parameter {
|
enum Parameter {
|
||||||
ParameterMacAddress = 0x01, // R
|
ParameterMacAddress = 0x01, // R
|
||||||
ParameterPanId = 0x05, // R
|
ParameterPanId = 0x05, // RW
|
||||||
ParameterNetworkAddress = 0x07, // R
|
ParameterNetworkAddress = 0x07, // R
|
||||||
ParameterNetworkExtendedPanId = 0x08, // R
|
ParameterNetworkExtendedPanId = 0x08, // R
|
||||||
ParameterNodeType = 0x09, //RW
|
ParameterNodeType = 0x09, //RW
|
||||||
@ -81,12 +82,15 @@ public:
|
|||||||
ParameterApsExtendedPanId = 0x0B, //RW
|
ParameterApsExtendedPanId = 0x0B, //RW
|
||||||
ParameterTrustCenterAddress = 0x0E, // RW
|
ParameterTrustCenterAddress = 0x0E, // RW
|
||||||
ParameterSecurityMode = 0x10, // RW
|
ParameterSecurityMode = 0x10, // RW
|
||||||
ParameterNetworkKey = 0x18, //W
|
ParameterPredefinedNwkPanId = 0x15, // RW
|
||||||
|
ParameterNetworkKey = 0x18, // RW
|
||||||
|
ParameterLinkKey = 0x19, // RW
|
||||||
ParameterCurrentChannel = 0x1c, // R
|
ParameterCurrentChannel = 0x1c, // R
|
||||||
ParameterPermitJoin = 0x21, // RW
|
ParameterPermitJoin = 0x21, // RW
|
||||||
ParameterProtocolVersion = 0x22, // R
|
ParameterProtocolVersion = 0x22, // R
|
||||||
ParameterNetworkUpdateId = 0x24, // RW
|
ParameterNetworkUpdateId = 0x24, // RW
|
||||||
ParameterWatchdogTtl = 0x26 // RW since protocol version 0x0108
|
ParameterWatchdogTtl = 0x26, // RW since protocol version 0x0108
|
||||||
|
ParameterNetworkFrameCounter = 0x27 // RW
|
||||||
};
|
};
|
||||||
Q_ENUM(Parameter)
|
Q_ENUM(Parameter)
|
||||||
|
|
||||||
|
|||||||
@ -146,6 +146,7 @@ void ZigbeeInterfaceDeconz::onReconnectTimeout()
|
|||||||
if (m_serialPort && !m_serialPort->isOpen()) {
|
if (m_serialPort && !m_serialPort->isOpen()) {
|
||||||
if (!m_serialPort->open(QSerialPort::ReadWrite)) {
|
if (!m_serialPort->open(QSerialPort::ReadWrite)) {
|
||||||
setAvailable(false);
|
setAvailable(false);
|
||||||
|
qCDebug(dcZigbeeInterface()) << "Interface reconnected failed" << m_serialPort->portName() << m_serialPort->baudRate();
|
||||||
m_reconnectTimer->start();
|
m_reconnectTimer->start();
|
||||||
} else {
|
} else {
|
||||||
qCDebug(dcZigbeeInterface()) << "Interface reconnected successfully on" << m_serialPort->portName() << m_serialPort->baudRate();
|
qCDebug(dcZigbeeInterface()) << "Interface reconnected successfully on" << m_serialPort->portName() << m_serialPort->baudRate();
|
||||||
|
|||||||
@ -67,6 +67,29 @@ Deconz::NetworkState ZigbeeBridgeControllerDeconz::networkState() const
|
|||||||
return m_networkState;
|
return m_networkState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeBridgeControllerDeconz::rebootController()
|
||||||
|
{
|
||||||
|
// According to the docs, the watchdog can be used to reboot the device by
|
||||||
|
// setting the watchdog timeout to a small value and let it timeout
|
||||||
|
|
||||||
|
// Reset the timer to prevent interrupting the reboot
|
||||||
|
m_watchdogTimer->start();
|
||||||
|
|
||||||
|
// Write the watchdog to 2 seconds
|
||||||
|
QByteArray parameterData;
|
||||||
|
QDataStream stream(¶meterData, QIODevice::WriteOnly);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
stream << static_cast<quint32>(2);
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = requestWriteParameter(Deconz::ParameterWatchdogTtl, parameterData);
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [reply](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Could initiate reboot controller by writing watchdog parameter." << reply->statusCode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qCDebug(dcZigbeeController()) << "Reboot device requested successfully. The controler is about to reboot...";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestVersion()
|
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestVersion()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -76,7 +99,9 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestVersion()
|
|||||||
stream << static_cast<quint8>(Deconz::CommandVersion);
|
stream << static_cast<quint8>(Deconz::CommandVersion);
|
||||||
stream << static_cast<quint8>(0); // SQN will be generated right before sending
|
stream << static_cast<quint8>(0); // SQN will be generated right before sending
|
||||||
stream << static_cast<quint8>(0); // Reserverd
|
stream << static_cast<quint8>(0); // Reserverd
|
||||||
stream << static_cast<quint16>(5); // Frame length
|
stream << static_cast<quint16>(9); // Frame length
|
||||||
|
stream << static_cast<quint16>(0);
|
||||||
|
stream << static_cast<quint16>(0);
|
||||||
|
|
||||||
return createReply(Deconz::CommandVersion, "Request controller version", message, this);
|
return createReply(Deconz::CommandVersion, "Request controller version", message, this);
|
||||||
}
|
}
|
||||||
@ -214,9 +239,9 @@ void ZigbeeBridgeControllerDeconz::sendNextRequest()
|
|||||||
if (m_currentReply)
|
if (m_currentReply)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// // FIXME: If the controler request queue is full, wait until it's free again
|
// // FIXME: If the controler request queue is full, wait until it's free again
|
||||||
// if (!m_apsFreeSlotsAvailable)
|
// if (!m_apsFreeSlotsAvailable)
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
// Get the next reply, set the sequence number, send the request data over the interface and start waiting
|
// Get the next reply, set the sequence number, send the request data over the interface and start waiting
|
||||||
m_currentReply = m_replyQueue.dequeue();
|
m_currentReply = m_replyQueue.dequeue();
|
||||||
@ -282,12 +307,12 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::createReply(Deconz::Co
|
|||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendDataGroup(quint8 requestId, quint16 groupAddress, quint16 profileId, quint16 clusterId, quint8 sourceEndpoint, const QByteArray &asdu, Zigbee::ZigbeeTxOptions txOptions, quint8 radius)
|
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendDataGroup(quint8 requestId, quint16 groupAddress, quint16 profileId, quint16 clusterId, quint8 sourceEndpoint, const QByteArray &asdu, Zigbee::ZigbeeTxOptions txOptions, quint8 radius)
|
||||||
{
|
{
|
||||||
// quint8 sequenceNumber = generateSequenceNumber();
|
// quint8 sequenceNumber = generateSequenceNumber();
|
||||||
// qCDebug(dcZigbeeController()) << "Request enqueue send data to group" << ZigbeeUtils::convertUint16ToHexString(groupAddress)
|
// qCDebug(dcZigbeeController()) << "Request enqueue send data to group" << ZigbeeUtils::convertUint16ToHexString(groupAddress)
|
||||||
// << "SQN:" << sequenceNumber
|
// << "SQN:" << sequenceNumber
|
||||||
// << static_cast<Zigbee::ZigbeeProfile>(profileId)
|
// << static_cast<Zigbee::ZigbeeProfile>(profileId)
|
||||||
// << ZigbeeUtils::convertUint16ToHexString(clusterId)
|
// << ZigbeeUtils::convertUint16ToHexString(clusterId)
|
||||||
// << ZigbeeUtils::convertByteToHexString(sourceEndpoint);
|
// << ZigbeeUtils::convertByteToHexString(sourceEndpoint);
|
||||||
|
|
||||||
Q_ASSERT_X(asdu.length() <= 127, "ASDU", "ASDU package length has to <= 127 bytes");
|
Q_ASSERT_X(asdu.length() <= 127, "ASDU", "ASDU package length has to <= 127 bytes");
|
||||||
|
|
||||||
@ -321,13 +346,13 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendData
|
|||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendDataShortAddress(quint8 requestId, quint16 shortAddress, quint8 destinationEndpoint, quint16 profileId, quint16 clusterId, quint8 sourceEndpoint, const QByteArray &asdu, Zigbee::ZigbeeTxOptions txOptions, quint8 radius)
|
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendDataShortAddress(quint8 requestId, quint16 shortAddress, quint8 destinationEndpoint, quint16 profileId, quint16 clusterId, quint8 sourceEndpoint, const QByteArray &asdu, Zigbee::ZigbeeTxOptions txOptions, quint8 radius)
|
||||||
{
|
{
|
||||||
// quint8 sequenceNumber = generateSequenceNumber();
|
// quint8 sequenceNumber = generateSequenceNumber();
|
||||||
// qCDebug(dcZigbeeController()) << "Request enqueue send data to short address" << ZigbeeUtils::convertUint16ToHexString(shortAddress)
|
// qCDebug(dcZigbeeController()) << "Request enqueue send data to short address" << ZigbeeUtils::convertUint16ToHexString(shortAddress)
|
||||||
// << "SQN:" << sequenceNumber
|
// << "SQN:" << sequenceNumber
|
||||||
// << ZigbeeUtils::convertByteToHexString(destinationEndpoint)
|
// << ZigbeeUtils::convertByteToHexString(destinationEndpoint)
|
||||||
// << static_cast<Zigbee::ZigbeeProfile>(profileId)
|
// << static_cast<Zigbee::ZigbeeProfile>(profileId)
|
||||||
// << ZigbeeUtils::convertUint16ToHexString(clusterId)
|
// << ZigbeeUtils::convertUint16ToHexString(clusterId)
|
||||||
// << ZigbeeUtils::convertByteToHexString(sourceEndpoint);
|
// << ZigbeeUtils::convertByteToHexString(sourceEndpoint);
|
||||||
|
|
||||||
Q_ASSERT_X(asdu.length() <= 127, "ASDU", "ASDU package length has to <= 127 bytes");
|
Q_ASSERT_X(asdu.length() <= 127, "ASDU", "ASDU package length has to <= 127 bytes");
|
||||||
|
|
||||||
@ -361,12 +386,12 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendData
|
|||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendDataIeeeAddress(quint8 requestId, ZigbeeAddress ieeeAddress, quint8 destinationEndpoint, quint16 profileId, quint16 clusterId, quint8 sourceEndpoint, const QByteArray &asdu, Zigbee::ZigbeeTxOptions txOptions, quint8 radius)
|
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestEnqueueSendDataIeeeAddress(quint8 requestId, ZigbeeAddress ieeeAddress, quint8 destinationEndpoint, quint16 profileId, quint16 clusterId, quint8 sourceEndpoint, const QByteArray &asdu, Zigbee::ZigbeeTxOptions txOptions, quint8 radius)
|
||||||
{
|
{
|
||||||
// quint8 sequenceNumber = generateSequenceNumber();
|
// quint8 sequenceNumber = generateSequenceNumber();
|
||||||
// qCDebug(dcZigbeeController()) << "Request enqueue send data to IEEE address" << ieeeAddress.toString()
|
// qCDebug(dcZigbeeController()) << "Request enqueue send data to IEEE address" << ieeeAddress.toString()
|
||||||
// << "SQN:" << sequenceNumber
|
// << "SQN:" << sequenceNumber
|
||||||
// << ZigbeeUtils::convertByteToHexString(destinationEndpoint)
|
// << ZigbeeUtils::convertByteToHexString(destinationEndpoint)
|
||||||
// << profileId << clusterId
|
// << profileId << clusterId
|
||||||
// << ZigbeeUtils::convertByteToHexString(sourceEndpoint);
|
// << ZigbeeUtils::convertByteToHexString(sourceEndpoint);
|
||||||
|
|
||||||
Q_ASSERT_X(asdu.length() <= 127, "ZigbeeController", "ASDU package length has to be <= 127 bytes");
|
Q_ASSERT_X(asdu.length() <= 127, "ZigbeeController", "ASDU package length has to be <= 127 bytes");
|
||||||
|
|
||||||
@ -418,7 +443,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
<< Deconz::ParameterMacAddress << "finished with error" << replyMacAddress->statusCode();
|
<< Deconz::ParameterMacAddress << "finished with error" << replyMacAddress->statusCode();
|
||||||
|
|
||||||
readNetworkParametersReply->m_statusCode = replyMacAddress->statusCode();
|
readNetworkParametersReply->m_statusCode = replyMacAddress->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QDataStream stream(replyMacAddress->responseData());
|
QDataStream stream(replyMacAddress->responseData());
|
||||||
@ -438,7 +463,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyPanId->sequenceNumber() << replyPanId->command()
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyPanId->sequenceNumber() << replyPanId->command()
|
||||||
<< Deconz::ParameterPanId << "finished with error" << replyPanId->statusCode();
|
<< Deconz::ParameterPanId << "finished with error" << replyPanId->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replyPanId->statusCode();
|
readNetworkParametersReply->m_statusCode = replyPanId->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QDataStream stream(replyPanId->responseData());
|
QDataStream stream(replyPanId->responseData());
|
||||||
@ -458,7 +483,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyShortAddress->sequenceNumber() << replyShortAddress->command() << Deconz::ParameterNetworkAddress
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyShortAddress->sequenceNumber() << replyShortAddress->command() << Deconz::ParameterNetworkAddress
|
||||||
<< "finished with error" << replyShortAddress->statusCode();
|
<< "finished with error" << replyShortAddress->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replyShortAddress->statusCode();
|
readNetworkParametersReply->m_statusCode = replyShortAddress->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,7 +503,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyExtendedPanId->sequenceNumber() << replyExtendedPanId->command()
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyExtendedPanId->sequenceNumber() << replyExtendedPanId->command()
|
||||||
<< Deconz::ParameterNetworkExtendedPanId << "finished with error" << replyExtendedPanId->statusCode();
|
<< Deconz::ParameterNetworkExtendedPanId << "finished with error" << replyExtendedPanId->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replyExtendedPanId->statusCode();
|
readNetworkParametersReply->m_statusCode = replyExtendedPanId->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,7 +523,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyNodeType->sequenceNumber() << replyNodeType->command()
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyNodeType->sequenceNumber() << replyNodeType->command()
|
||||||
<< Deconz::ParameterNodeType << "finished with error" << replyNodeType->statusCode();
|
<< Deconz::ParameterNodeType << "finished with error" << replyNodeType->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replyNodeType->statusCode();
|
readNetworkParametersReply->m_statusCode = replyNodeType->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,7 +544,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyChannelMask->sequenceNumber() << replyChannelMask->command() << Deconz::ParameterChannelMask
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyChannelMask->sequenceNumber() << replyChannelMask->command() << Deconz::ParameterChannelMask
|
||||||
<< "finished with error" << replyChannelMask->statusCode();
|
<< "finished with error" << replyChannelMask->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replyChannelMask->statusCode();
|
readNetworkParametersReply->m_statusCode = replyChannelMask->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,7 +565,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyApsExtendedPanId->sequenceNumber() << replyApsExtendedPanId->command()
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyApsExtendedPanId->sequenceNumber() << replyApsExtendedPanId->command()
|
||||||
<< Deconz::ParameterApsExtendedPanId << "finished with error" << replyApsExtendedPanId->statusCode();
|
<< Deconz::ParameterApsExtendedPanId << "finished with error" << replyApsExtendedPanId->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replyApsExtendedPanId->statusCode();
|
readNetworkParametersReply->m_statusCode = replyApsExtendedPanId->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,7 +586,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyTrustCenterAddress->sequenceNumber() << replyTrustCenterAddress->command()
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyTrustCenterAddress->sequenceNumber() << replyTrustCenterAddress->command()
|
||||||
<< Deconz::ParameterTrustCenterAddress << "finished with error" << replyTrustCenterAddress->statusCode();
|
<< Deconz::ParameterTrustCenterAddress << "finished with error" << replyTrustCenterAddress->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replyTrustCenterAddress->statusCode();
|
readNetworkParametersReply->m_statusCode = replyTrustCenterAddress->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,7 +607,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replySecurityMode->sequenceNumber() << replySecurityMode->command()
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replySecurityMode->sequenceNumber() << replySecurityMode->command()
|
||||||
<< Deconz::ParameterSecurityMode << "finished with error" << replySecurityMode->statusCode();
|
<< Deconz::ParameterSecurityMode << "finished with error" << replySecurityMode->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replySecurityMode->statusCode();
|
readNetworkParametersReply->m_statusCode = replySecurityMode->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,128 +621,158 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
<< static_cast<Deconz::Parameter>(parameter) << "finished successfully";
|
<< static_cast<Deconz::Parameter>(parameter) << "finished successfully";
|
||||||
qCDebug(dcZigbeeController()) << m_networkConfiguration.securityMode;
|
qCDebug(dcZigbeeController()) << m_networkConfiguration.securityMode;
|
||||||
|
|
||||||
// Note: reading the network key returns "InavlidParameter". Might be for security reasons which is good!
|
|
||||||
|
|
||||||
// Read channel
|
// Read predefined new pan id
|
||||||
ZigbeeInterfaceDeconzReply *replyChannel = requestReadParameter(Deconz::ParameterCurrentChannel);
|
ZigbeeInterfaceDeconzReply *replyPredefinedNwkPanId = requestReadParameter(Deconz::ParameterPredefinedNwkPanId);
|
||||||
connect(replyChannel, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyChannel](){
|
connect(replyPredefinedNwkPanId, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyPredefinedNwkPanId](){
|
||||||
if (replyChannel->statusCode() != Deconz::StatusCodeSuccess) {
|
if (replyPredefinedNwkPanId->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyChannel->sequenceNumber() << replyChannel->command() << Deconz::ParameterCurrentChannel
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyPredefinedNwkPanId->sequenceNumber() << replyPredefinedNwkPanId->command()
|
||||||
<< "finished with error" << replyChannel->statusCode();
|
<< Deconz::ParameterSecurityMode << "finished with error" << replyPredefinedNwkPanId->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replyChannel->statusCode();
|
readNetworkParametersReply->m_statusCode = replyPredefinedNwkPanId->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream stream(replyChannel->responseData());
|
QDataStream stream(replyPredefinedNwkPanId->responseData());
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint16 payloadLenght = 0; quint8 parameter = 0; quint8 channel = 0;
|
quint16 payloadLenght = 0; quint8 parameter = 0; quint8 predefinedNwkPanId = 0;
|
||||||
stream >> payloadLenght >> parameter >> channel;
|
stream >> payloadLenght >> parameter >> predefinedNwkPanId;
|
||||||
m_networkConfiguration.currentChannel = channel;
|
|
||||||
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyChannel->sequenceNumber() << replyChannel->command() << static_cast<Deconz::Parameter>(parameter)
|
m_networkConfiguration.predefinedNetworkPanId = static_cast<bool>(predefinedNwkPanId);
|
||||||
<< "finished successfully";
|
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyPredefinedNwkPanId->sequenceNumber() << replyPredefinedNwkPanId->command()
|
||||||
qCDebug(dcZigbeeController()) << "Current channel:" << m_networkConfiguration.currentChannel;
|
<< static_cast<Deconz::Parameter>(parameter) << "finished successfully";
|
||||||
|
qCDebug(dcZigbeeController()) << m_networkConfiguration.predefinedNetworkPanId;
|
||||||
|
|
||||||
|
|
||||||
// Read permit join status
|
// We don't make use of link key for now
|
||||||
ZigbeeInterfaceDeconzReply *replyPermitJoin = requestReadParameter(Deconz::ParameterPermitJoin);
|
|
||||||
connect(replyPermitJoin, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyPermitJoin](){
|
// Note: reading the network key returns "InavlidParameter". Might be for security reasons which is good!
|
||||||
if (replyPermitJoin->statusCode() != Deconz::StatusCodeSuccess) {
|
|
||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyPermitJoin->sequenceNumber() << replyPermitJoin->command()
|
// Read channel
|
||||||
<< Deconz::ParameterPermitJoin << "finished with error" << replyPermitJoin->statusCode();
|
ZigbeeInterfaceDeconzReply *replyChannel = requestReadParameter(Deconz::ParameterCurrentChannel);
|
||||||
readNetworkParametersReply->m_statusCode = replyPermitJoin->statusCode();
|
connect(replyChannel, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyChannel](){
|
||||||
readNetworkParametersReply->finished();
|
if (replyChannel->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyChannel->sequenceNumber() << replyChannel->command() << Deconz::ParameterCurrentChannel
|
||||||
|
<< "finished with error" << replyChannel->statusCode();
|
||||||
|
readNetworkParametersReply->m_statusCode = replyChannel->statusCode();
|
||||||
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream stream(replyPermitJoin->responseData());
|
QDataStream stream(replyChannel->responseData());
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint16 payloadLenght = 0; quint8 parameter = 0;
|
quint16 payloadLenght = 0; quint8 parameter = 0; quint8 channel = 0;
|
||||||
stream >> payloadLenght >> parameter;
|
stream >> payloadLenght >> parameter >> channel;
|
||||||
//m_networkConfiguration.currentChannel = channel;
|
m_networkConfiguration.currentChannel = channel;
|
||||||
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyPermitJoin->sequenceNumber() << replyPermitJoin->command() << static_cast<Deconz::Parameter>(parameter)
|
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyChannel->sequenceNumber() << replyChannel->command() << static_cast<Deconz::Parameter>(parameter)
|
||||||
<< "finished successfully" << ZigbeeUtils::convertByteArrayToHexString(replyPermitJoin->responseData());
|
<< "finished successfully";
|
||||||
|
qCDebug(dcZigbeeController()) << "Current channel:" << m_networkConfiguration.currentChannel;
|
||||||
|
|
||||||
|
|
||||||
// Read protocol version
|
// Read permit join status
|
||||||
ZigbeeInterfaceDeconzReply *replyProtocolVersion = requestReadParameter(Deconz::ParameterProtocolVersion);
|
ZigbeeInterfaceDeconzReply *replyPermitJoin = requestReadParameter(Deconz::ParameterPermitJoin);
|
||||||
connect(replyProtocolVersion, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyProtocolVersion](){
|
connect(replyPermitJoin, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyPermitJoin](){
|
||||||
if (replyProtocolVersion->statusCode() != Deconz::StatusCodeSuccess) {
|
if (replyPermitJoin->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyProtocolVersion->sequenceNumber() << replyProtocolVersion->command()
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyPermitJoin->sequenceNumber() << replyPermitJoin->command()
|
||||||
<< Deconz::ParameterProtocolVersion << "finished with error" << replyProtocolVersion->statusCode();
|
<< Deconz::ParameterPermitJoin << "finished with error" << replyPermitJoin->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = replyProtocolVersion->statusCode();
|
readNetworkParametersReply->m_statusCode = replyPermitJoin->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream stream(replyProtocolVersion->responseData());
|
QDataStream stream(replyPermitJoin->responseData());
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint16 payloadLenght = 0; quint8 parameter = 0; quint16 protocolVersion = 0;
|
quint16 payloadLenght = 0; quint8 parameter = 0;
|
||||||
stream >> payloadLenght >> parameter >> protocolVersion;
|
stream >> payloadLenght >> parameter;
|
||||||
m_networkConfiguration.protocolVersion = protocolVersion;
|
//m_networkConfiguration.currentChannel = channel;
|
||||||
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyProtocolVersion->sequenceNumber() << replyProtocolVersion->command()
|
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyPermitJoin->sequenceNumber() << replyPermitJoin->command() << static_cast<Deconz::Parameter>(parameter)
|
||||||
<< static_cast<Deconz::Parameter>(parameter) << "finished successfully";
|
<< "finished successfully" << ZigbeeUtils::convertByteArrayToHexString(replyPermitJoin->responseData());
|
||||||
qCDebug(dcZigbeeController()) << "Protocol version:" << ZigbeeUtils::convertUint16ToHexString(m_networkConfiguration.protocolVersion);
|
|
||||||
|
|
||||||
// Read network updat id
|
|
||||||
ZigbeeInterfaceDeconzReply *replyNetworkUpdateId = requestReadParameter(Deconz::ParameterNetworkUpdateId);
|
// Read protocol version
|
||||||
connect(replyNetworkUpdateId, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyNetworkUpdateId](){
|
ZigbeeInterfaceDeconzReply *replyProtocolVersion = requestReadParameter(Deconz::ParameterProtocolVersion);
|
||||||
if (replyNetworkUpdateId->statusCode() != Deconz::StatusCodeSuccess) {
|
connect(replyProtocolVersion, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyProtocolVersion](){
|
||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyNetworkUpdateId->sequenceNumber() << replyNetworkUpdateId->command()
|
if (replyProtocolVersion->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
<< Deconz::ParameterNetworkUpdateId << "finished with error" << replyNetworkUpdateId->statusCode();
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyProtocolVersion->sequenceNumber() << replyProtocolVersion->command()
|
||||||
readNetworkParametersReply->m_statusCode = replyNetworkUpdateId->statusCode();
|
<< Deconz::ParameterProtocolVersion << "finished with error" << replyProtocolVersion->statusCode();
|
||||||
readNetworkParametersReply->finished();
|
readNetworkParametersReply->m_statusCode = replyProtocolVersion->statusCode();
|
||||||
|
emit readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream stream(replyNetworkUpdateId->responseData());
|
QDataStream stream(replyProtocolVersion->responseData());
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint16 payloadLenght = 0; quint8 parameter = 0; quint8 networkUpdateId = 0;
|
quint16 payloadLenght = 0; quint8 parameter = 0; quint16 protocolVersion = 0;
|
||||||
stream >> payloadLenght >> parameter >> networkUpdateId;
|
stream >> payloadLenght >> parameter >> protocolVersion;
|
||||||
m_networkConfiguration.networkUpdateId = networkUpdateId;
|
m_networkConfiguration.protocolVersion = protocolVersion;
|
||||||
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyNetworkUpdateId->sequenceNumber() << replyNetworkUpdateId->command()
|
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyProtocolVersion->sequenceNumber() << replyProtocolVersion->command()
|
||||||
<< static_cast<Deconz::Parameter>(parameter) << "finished successfully";
|
<< static_cast<Deconz::Parameter>(parameter) << "finished successfully";
|
||||||
qCDebug(dcZigbeeController()) << "Network update ID:" << m_networkConfiguration.networkUpdateId;
|
qCDebug(dcZigbeeController()) << "Protocol version:" << ZigbeeUtils::convertUint16ToHexString(m_networkConfiguration.protocolVersion);
|
||||||
|
|
||||||
// Make sure the watchdog is available for this version
|
// Read network updat id
|
||||||
if (m_networkConfiguration.protocolVersion < 0x0108) {
|
ZigbeeInterfaceDeconzReply *replyNetworkUpdateId = requestReadParameter(Deconz::ParameterNetworkUpdateId);
|
||||||
qCDebug(dcZigbeeController()) << "The watchdog api is available since protocol version 0x0108. The watchdog is not required for this version";
|
connect(replyNetworkUpdateId, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyNetworkUpdateId](){
|
||||||
m_watchdogTimer->stop();
|
if (replyNetworkUpdateId->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyNetworkUpdateId->sequenceNumber() << replyNetworkUpdateId->command()
|
||||||
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
<< Deconz::ParameterNetworkUpdateId << "finished with error" << replyNetworkUpdateId->statusCode();
|
||||||
emit networkConfigurationParameterChanged(m_networkConfiguration);
|
readNetworkParametersReply->m_statusCode = replyNetworkUpdateId->statusCode();
|
||||||
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
emit readNetworkParametersReply->finished();
|
||||||
readNetworkParametersReply->finished();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the watchdog in any case
|
|
||||||
resetControllerWatchdog();
|
|
||||||
|
|
||||||
// Read watchdog timeout
|
|
||||||
ZigbeeInterfaceDeconzReply *replyWatchdogTimeout = requestReadParameter(Deconz::ParameterWatchdogTtl);
|
|
||||||
connect(replyWatchdogTimeout, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyWatchdogTimeout](){
|
|
||||||
if (replyWatchdogTimeout->statusCode() != Deconz::StatusCodeSuccess) {
|
|
||||||
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyWatchdogTimeout->sequenceNumber() << replyWatchdogTimeout->command()
|
|
||||||
<< Deconz::ParameterWatchdogTtl << "finished with error" << replyWatchdogTimeout->statusCode();
|
|
||||||
readNetworkParametersReply->m_statusCode = replyWatchdogTimeout->statusCode();
|
|
||||||
readNetworkParametersReply->finished();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream stream(replyWatchdogTimeout->responseData());
|
QDataStream stream(replyNetworkUpdateId->responseData());
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint16 payloadLenght = 0; quint8 parameter = 0; quint32 watchdogTimeout = 0;
|
quint16 payloadLenght = 0; quint8 parameter = 0; quint8 networkUpdateId = 0;
|
||||||
stream >> payloadLenght >> parameter >> watchdogTimeout;
|
stream >> payloadLenght >> parameter >> networkUpdateId;
|
||||||
m_networkConfiguration.watchdogTimeout = watchdogTimeout;
|
m_networkConfiguration.networkUpdateId = networkUpdateId;
|
||||||
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyWatchdogTimeout->sequenceNumber() << replyWatchdogTimeout->command()
|
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyNetworkUpdateId->sequenceNumber() << replyNetworkUpdateId->command()
|
||||||
<< static_cast<Deconz::Parameter>(parameter) << "finished successfully";
|
<< static_cast<Deconz::Parameter>(parameter) << "finished successfully";
|
||||||
qCDebug(dcZigbeeController()) << "Watchdog timeout:" << m_networkConfiguration.watchdogTimeout;
|
qCDebug(dcZigbeeController()) << "Network update ID:" << m_networkConfiguration.networkUpdateId;
|
||||||
|
|
||||||
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
// Make sure the watchdog is available for this version
|
||||||
emit networkConfigurationParameterChanged(m_networkConfiguration);
|
if (m_networkConfiguration.protocolVersion < 0x0108) {
|
||||||
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
qCDebug(dcZigbeeController()) << "The watchdog api is available since protocol version 0x0108. The watchdog is not required for this version";
|
||||||
readNetworkParametersReply->finished();
|
m_watchdogTimer->stop();
|
||||||
|
|
||||||
|
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
||||||
|
emit networkConfigurationParameterChanged(m_networkConfiguration);
|
||||||
|
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
||||||
|
emit readNetworkParametersReply->finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the watchdog in any case
|
||||||
|
resetControllerWatchdog();
|
||||||
|
|
||||||
|
// Read watchdog timeout
|
||||||
|
ZigbeeInterfaceDeconzReply *replyWatchdogTimeout = requestReadParameter(Deconz::ParameterWatchdogTtl);
|
||||||
|
connect(replyWatchdogTimeout, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyWatchdogTimeout](){
|
||||||
|
if (replyWatchdogTimeout->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Request" << "SQN:" << replyWatchdogTimeout->sequenceNumber() << replyWatchdogTimeout->command()
|
||||||
|
<< Deconz::ParameterWatchdogTtl << "finished with error" << replyWatchdogTimeout->statusCode();
|
||||||
|
readNetworkParametersReply->m_statusCode = replyWatchdogTimeout->statusCode();
|
||||||
|
emit readNetworkParametersReply->finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream stream(replyWatchdogTimeout->responseData());
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
quint16 payloadLenght = 0; quint8 parameter = 0; quint32 watchdogTimeout = 0;
|
||||||
|
stream >> payloadLenght >> parameter >> watchdogTimeout;
|
||||||
|
m_networkConfiguration.watchdogTimeout = watchdogTimeout;
|
||||||
|
qCDebug(dcZigbeeController()) << "Request" << "SQN:" << replyWatchdogTimeout->sequenceNumber() << replyWatchdogTimeout->command()
|
||||||
|
<< static_cast<Deconz::Parameter>(parameter) << "finished successfully";
|
||||||
|
qCDebug(dcZigbeeController()) << "Watchdog timeout:" << m_networkConfiguration.watchdogTimeout;
|
||||||
|
|
||||||
|
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
||||||
|
emit networkConfigurationParameterChanged(m_networkConfiguration);
|
||||||
|
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
||||||
|
emit readNetworkParametersReply->finished();
|
||||||
|
|
||||||
|
|
||||||
|
// We ignore the frame counter for now, since we let the firmware take control
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -747,6 +802,11 @@ DeconzDeviceState ZigbeeBridgeControllerDeconz::parseDeviceStateFlag(quint8 devi
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeBridgeControllerDeconz::reconnectConrtroller()
|
||||||
|
{
|
||||||
|
m_interface->reconnectController();
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeBridgeControllerDeconz::readDataIndication()
|
void ZigbeeBridgeControllerDeconz::readDataIndication()
|
||||||
{
|
{
|
||||||
if (m_readIndicationReply) {
|
if (m_readIndicationReply) {
|
||||||
@ -812,7 +872,10 @@ void ZigbeeBridgeControllerDeconz::processDeviceState(DeconzDeviceState deviceSt
|
|||||||
if (m_apsFreeSlotsAvailable != deviceState.apsDataRequestFreeSlots) {
|
if (m_apsFreeSlotsAvailable != deviceState.apsDataRequestFreeSlots) {
|
||||||
m_apsFreeSlotsAvailable = deviceState.apsDataRequestFreeSlots;
|
m_apsFreeSlotsAvailable = deviceState.apsDataRequestFreeSlots;
|
||||||
if (!m_apsFreeSlotsAvailable) {
|
if (!m_apsFreeSlotsAvailable) {
|
||||||
qCWarning(dcZigbeeController()) << "The APS request table is full on the device. Cannot send requests until the queue gets processed on the controller.";
|
// Warn only if the network is up
|
||||||
|
if (m_networkState == Deconz::NetworkStateConnected) {
|
||||||
|
qCWarning(dcZigbeeController()) << "The APS request table is full on the device. Cannot send requests until the queue gets processed on the controller.";
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
qCDebug(dcZigbeeController()) << "The APS request table is free again. Sending the next request";
|
qCDebug(dcZigbeeController()) << "The APS request table is free again. Sending the next request";
|
||||||
@ -918,6 +981,18 @@ void ZigbeeBridgeControllerDeconz::processDataConfirm(const QByteArray &data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeBridgeControllerDeconz::processMacPoll(const QByteArray &data)
|
||||||
|
{
|
||||||
|
qCDebug(dcZigbeeController()) << "MAC Poll command received" << ZigbeeUtils::convertByteArrayToHexString(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeBridgeControllerDeconz::processMacBeacon(const QByteArray &data)
|
||||||
|
{
|
||||||
|
qCDebug(dcZigbeeController()) << "Simplified beacon command received" << ZigbeeUtils::convertByteArrayToHexString(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeBridgeControllerDeconz::onInterfaceAvailableChanged(bool available)
|
void ZigbeeBridgeControllerDeconz::onInterfaceAvailableChanged(bool available)
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeController()) << "Interface available changed" << available;
|
qCDebug(dcZigbeeController()) << "Interface available changed" << available;
|
||||||
@ -954,7 +1029,7 @@ void ZigbeeBridgeControllerDeconz::onInterfacePackageReceived(const QByteArray &
|
|||||||
if (m_currentReply && m_currentReply->sequenceNumber() == sequenceNumber && m_currentReply->command() == command) {
|
if (m_currentReply && m_currentReply->sequenceNumber() == sequenceNumber && m_currentReply->command() == command) {
|
||||||
m_currentReply->m_responseData = data;
|
m_currentReply->m_responseData = data;
|
||||||
m_currentReply->m_statusCode = status;
|
m_currentReply->m_statusCode = status;
|
||||||
m_currentReply->finished();
|
emit m_currentReply->finished();
|
||||||
// Note: the current reply will be cleaned up in the finished slot
|
// Note: the current reply will be cleaned up in the finished slot
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -972,13 +1047,11 @@ void ZigbeeBridgeControllerDeconz::onInterfacePackageReceived(const QByteArray &
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Deconz::CommandMacPoll: {
|
case Deconz::CommandMacPoll: {
|
||||||
// FIXME: parse the data and print info
|
processMacPoll(data);
|
||||||
qCDebug(dcZigbeeController()) << "MAC Poll command received" << ZigbeeUtils::convertByteArrayToHexString(data);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Deconz::CommandSimplifiedBeacon: {
|
case Deconz::CommandMacBeacon: {
|
||||||
// FIXME: parse the data and print info
|
processMacBeacon(data);
|
||||||
qCDebug(dcZigbeeController()) << "Simplified beacon command received" << ZigbeeUtils::convertByteArrayToHexString(data);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1046,7 +1119,8 @@ QDebug operator<<(QDebug debug, const DeconzNetworkConfiguration &configuration)
|
|||||||
debug.nospace() << " - Node type:" << configuration.nodeType << "\n";
|
debug.nospace() << " - Node type:" << configuration.nodeType << "\n";
|
||||||
debug.nospace() << " - IEEE address: " << configuration.ieeeAddress.toString() << "\n";
|
debug.nospace() << " - IEEE address: " << configuration.ieeeAddress.toString() << "\n";
|
||||||
debug.nospace() << " - NWK address: " << ZigbeeUtils::convertUint16ToHexString(configuration.shortAddress) << "\n";
|
debug.nospace() << " - NWK address: " << ZigbeeUtils::convertUint16ToHexString(configuration.shortAddress) << "\n";
|
||||||
debug.nospace() << " - PAN ID: " << ZigbeeUtils::convertUint16ToHexString(configuration.panId) << "\n";
|
debug.nospace() << " - PAN ID: " << ZigbeeUtils::convertUint16ToHexString(configuration.panId) << " (" << configuration.panId << ")\n";
|
||||||
|
debug.nospace() << " - Use predefined network PAN ID: " << configuration.predefinedNetworkPanId << "\n";
|
||||||
debug.nospace() << " - Extended PAN ID: " << ZigbeeUtils::convertUint64ToHexString(configuration.extendedPanId) << "\n";
|
debug.nospace() << " - Extended PAN ID: " << ZigbeeUtils::convertUint64ToHexString(configuration.extendedPanId) << "\n";
|
||||||
debug.nospace() << " - APS Extended PAN ID: " << ZigbeeUtils::convertUint64ToHexString(configuration.apsExtendedPanId) << "\n";
|
debug.nospace() << " - APS Extended PAN ID: " << ZigbeeUtils::convertUint64ToHexString(configuration.apsExtendedPanId) << "\n";
|
||||||
debug.nospace() << " - Trust center IEEE address: " << configuration.trustCenterAddress.toString() << "\n";
|
debug.nospace() << " - Trust center IEEE address: " << configuration.trustCenterAddress.toString() << "\n";
|
||||||
|
|||||||
@ -54,6 +54,7 @@ typedef struct DeconzNetworkConfiguration {
|
|||||||
quint64 apsExtendedPanId = 0; // RW
|
quint64 apsExtendedPanId = 0; // RW
|
||||||
ZigbeeAddress trustCenterAddress; // RW
|
ZigbeeAddress trustCenterAddress; // RW
|
||||||
Deconz::SecurityMode securityMode = Deconz::SecurityModeNoMasterButTrustCenterKey; // RW
|
Deconz::SecurityMode securityMode = Deconz::SecurityModeNoMasterButTrustCenterKey; // RW
|
||||||
|
bool predefinedNetworkPanId; // RW
|
||||||
ZigbeeNetworkKey networkKey; // RW
|
ZigbeeNetworkKey networkKey; // RW
|
||||||
quint8 currentChannel = 0; // R
|
quint8 currentChannel = 0; // R
|
||||||
quint16 protocolVersion = 0; // R
|
quint16 protocolVersion = 0; // R
|
||||||
@ -85,6 +86,8 @@ public:
|
|||||||
void setFirmwareVersionString(const QString &firmwareVersion);
|
void setFirmwareVersionString(const QString &firmwareVersion);
|
||||||
|
|
||||||
Deconz::NetworkState networkState() const;
|
Deconz::NetworkState networkState() const;
|
||||||
|
void rebootController();
|
||||||
|
|
||||||
|
|
||||||
// Controllere requests
|
// Controllere requests
|
||||||
ZigbeeInterfaceDeconzReply *requestVersion();
|
ZigbeeInterfaceDeconzReply *requestVersion();
|
||||||
@ -135,12 +138,15 @@ private:
|
|||||||
// Device state helper
|
// Device state helper
|
||||||
DeconzDeviceState parseDeviceStateFlag(quint8 deviceStateFlag);
|
DeconzDeviceState parseDeviceStateFlag(quint8 deviceStateFlag);
|
||||||
|
|
||||||
|
void reconnectConrtroller();
|
||||||
void readDataIndication();
|
void readDataIndication();
|
||||||
void readDataConfirm();
|
void readDataConfirm();
|
||||||
|
|
||||||
void processDeviceState(DeconzDeviceState deviceState);
|
void processDeviceState(DeconzDeviceState deviceState);
|
||||||
void processDataIndication(const QByteArray &data);
|
void processDataIndication(const QByteArray &data);
|
||||||
void processDataConfirm(const QByteArray &data);
|
void processDataConfirm(const QByteArray &data);
|
||||||
|
void processMacPoll(const QByteArray &data);
|
||||||
|
void processMacBeacon(const QByteArray &data);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void networkStateChanged(Deconz::NetworkState networkState);
|
void networkStateChanged(Deconz::NetworkState networkState);
|
||||||
|
|||||||
@ -201,7 +201,8 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
|
|||||||
case CreateNetworkStateWriteConfiguration: {
|
case CreateNetworkStateWriteConfiguration: {
|
||||||
// - Set coordinator
|
// - Set coordinator
|
||||||
// - Set channel mask
|
// - Set channel mask
|
||||||
// - Set APS extended PANID (zero to reset)
|
// - Set predefined network PANID (0: let the firmware pick, 1: use the defined pan id)
|
||||||
|
// - Set NWK PANID
|
||||||
// - Set trust center address (coordinator address)
|
// - Set trust center address (coordinator address)
|
||||||
// - Set security mode
|
// - Set security mode
|
||||||
// - Set network key
|
// - Set network key
|
||||||
@ -236,76 +237,95 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
|
|||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Configured channel mask successfully. SQN:" << reply->sequenceNumber();
|
qCDebug(dcZigbeeNetwork()) << "Configured channel mask successfully. SQN:" << reply->sequenceNumber();
|
||||||
|
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Configure firmware to use predefined network PANID";
|
||||||
QByteArray paramData;
|
QByteArray paramData;
|
||||||
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
||||||
stream << static_cast<quint64>(extendedPanId());
|
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
qCDebug(dcZigbeeNetwork()) << "Configure APS extended PANID" << extendedPanId();
|
stream << static_cast<quint8>(0x01);
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterApsExtendedPanId, paramData);
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterPredefinedNwkPanId, paramData);
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not write parameter. SQN:" << reply->sequenceNumber() << Deconz::ParameterApsExtendedPanId << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Could not write parameter. SQN:" << reply->sequenceNumber() << Deconz::ParameterPredefinedNwkPanId << reply->statusCode();
|
||||||
// FIXME: set an appropriate error
|
// FIXME: set an appropriate error
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << "Configured APS extended PANID successfully. SQN:" << reply->sequenceNumber();
|
qCDebug(dcZigbeeController()) << "Configured firmware to use predefined network PNAID successfully. SQN:" << reply->sequenceNumber();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Configure network PANID" << panId() << ZigbeeUtils::convertUint16ToHexString(panId());
|
||||||
QByteArray paramData;
|
QByteArray paramData;
|
||||||
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << m_controller->networkConfiguration().ieeeAddress.toUInt64();
|
stream << panId();
|
||||||
qCDebug(dcZigbeeNetwork()) << "Configure trust center address" << m_controller->networkConfiguration().ieeeAddress.toString();
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterPanId, paramData);
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterTrustCenterAddress, paramData);
|
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not write parameter. SQN:" << reply->sequenceNumber() << Deconz::ParameterTrustCenterAddress << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Could not write parameter. SQN:" << reply->sequenceNumber() << Deconz::ParameterPanId << reply->statusCode();
|
||||||
// FIXME: set an appropriate error
|
// FIXME: set an appropriate error
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << "Configured trust center address successfully. SQN:" << reply->sequenceNumber();
|
qCDebug(dcZigbeeController()) << "Configured network PANID successfully. SQN:" << reply->sequenceNumber();
|
||||||
|
|
||||||
QByteArray paramData;
|
QByteArray paramData;
|
||||||
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint8>(Deconz::SecurityModeNoMasterButTrustCenterKey);
|
stream << m_controller->networkConfiguration().ieeeAddress.toUInt64();
|
||||||
qCDebug(dcZigbeeNetwork()) << "Configure security mode" << Deconz::SecurityModeNoMasterButTrustCenterKey;
|
qCDebug(dcZigbeeNetwork()) << "Configure trust center address" << m_controller->networkConfiguration().ieeeAddress.toString();
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterSecurityMode, paramData);
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterTrustCenterAddress, paramData);
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not write parameter. SQN:" << reply->sequenceNumber() << Deconz::ParameterSecurityMode << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Could not write parameter. SQN:" << reply->sequenceNumber() << Deconz::ParameterTrustCenterAddress << reply->statusCode();
|
||||||
// FIXME: set an appropriate error
|
// FIXME: set an appropriate error
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << "Configured security mode successfully. SQN:" << reply->sequenceNumber();
|
qCDebug(dcZigbeeController()) << "Configured trust center address successfully. SQN:" << reply->sequenceNumber();
|
||||||
|
|
||||||
|
QByteArray paramData;
|
||||||
qCDebug(dcZigbeeNetwork()) << "Configure network key" << securityConfiguration().networkKey().toString();
|
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterNetworkKey, securityConfiguration().networkKey().toByteArray());
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
stream << static_cast<quint8>(Deconz::SecurityModeNoMasterButTrustCenterKey);
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Configure security mode" << Deconz::SecurityModeNoMasterButTrustCenterKey;
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterSecurityMode, paramData);
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not write parameter. SQN:" << reply->sequenceNumber() << Deconz::ParameterNetworkKey << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Could not write parameter. SQN:" << reply->sequenceNumber() << Deconz::ParameterSecurityMode << reply->statusCode();
|
||||||
// FIXME: set an appropriate error
|
// FIXME: set an appropriate error
|
||||||
// Note: writing the network key fails all the time...
|
return;
|
||||||
//return;
|
|
||||||
} else {
|
|
||||||
qCDebug(dcZigbeeController()) << "Configured network key successfully. SQN:" << reply->sequenceNumber();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-read the configurations
|
qCDebug(dcZigbeeController()) << "Configured security mode successfully. SQN:" << reply->sequenceNumber();
|
||||||
// Read all network parameters
|
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->readNetworkParameters();
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Configure network key" << securityConfiguration().networkKey().toString();
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterNetworkKey, securityConfiguration().networkKey().toByteArray());
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not read network parameters during network start up. SQN:" << reply->sequenceNumber() << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Could not write parameter. SQN:" << reply->sequenceNumber() << Deconz::ParameterNetworkKey << reply->statusCode();
|
||||||
|
// FIXME: set an appropriate error
|
||||||
|
// Note: writing the network key fails all the time...
|
||||||
|
//return;
|
||||||
|
} else {
|
||||||
|
qCDebug(dcZigbeeController()) << "Configured network key successfully. SQN:" << reply->sequenceNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << m_controller->networkConfiguration();
|
// Re-read the configurations
|
||||||
|
// Read all network parameters
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->readNetworkParameters();
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Could not read network parameters during network start up. SQN:" << reply->sequenceNumber() << reply->statusCode();
|
||||||
|
}
|
||||||
|
|
||||||
// Configuration finished, lets start the network
|
qCDebug(dcZigbeeController()) << m_controller->networkConfiguration();
|
||||||
setCreateNetworkState(CreateNetworkStateStartNetwork);
|
|
||||||
|
// Configuration finished, lets start the network
|
||||||
|
setCreateNetworkState(CreateNetworkStateStartNetwork);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -342,10 +362,15 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
|
|||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Reading network parameters finished successfully. SQN:" << reply->sequenceNumber();
|
qCDebug(dcZigbeeNetwork()) << "Reading network parameters finished successfully. SQN:" << reply->sequenceNumber();
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Network running with following configuration:";
|
||||||
|
qCDebug(dcZigbeeNetwork()) << m_controller->networkConfiguration();
|
||||||
|
|
||||||
setPanId(m_controller->networkConfiguration().panId);
|
setPanId(m_controller->networkConfiguration().panId);
|
||||||
setExtendedPanId(m_controller->networkConfiguration().extendedPanId);
|
setExtendedPanId(m_controller->networkConfiguration().extendedPanId);
|
||||||
setChannel(m_controller->networkConfiguration().currentChannel);
|
setChannel(m_controller->networkConfiguration().currentChannel);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setCreateNetworkState(CreateNetworkStateInitializeCoordinatorNode);
|
setCreateNetworkState(CreateNetworkStateInitializeCoordinatorNode);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@ -392,118 +417,147 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
|
|||||||
|
|
||||||
void ZigbeeNetworkDeconz::runNetworkInitProcess()
|
void ZigbeeNetworkDeconz::runNetworkInitProcess()
|
||||||
{
|
{
|
||||||
|
// - Read the network state (until success)
|
||||||
// - Read the firmware version
|
// - Read the firmware version
|
||||||
// - Read the network configuration parameters
|
// - Read the network configuration parameters
|
||||||
// - Read the network state
|
|
||||||
|
|
||||||
// - If network running and we don't have configurations, write them
|
// - If network running and we don't have configurations, write them
|
||||||
// - If network running and configurations match, we are done
|
// - If network running and configurations match, we are done
|
||||||
|
|
||||||
// Read the firmware version
|
// Read the firmware version
|
||||||
qCDebug(dcZigbeeNetwork()) << "Reading current firmware version...";
|
qCDebug(dcZigbeeNetwork()) << "Request current device state...";
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestVersion();
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestDeviceState();
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode();
|
||||||
m_initRetry++;
|
m_initRetry++;
|
||||||
|
if (!m_controller->available()) {
|
||||||
|
m_initRetry = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_initRetry < 10) {
|
if (m_initRetry < 10) {
|
||||||
qCDebug(dcZigbeeNetwork()) << "Retry to initialize network" << m_initRetry << "/ 10";
|
qCDebug(dcZigbeeNetwork()) << "Retry to initialize network" << m_initRetry << "/ 10";
|
||||||
runNetworkInitProcess();
|
runNetworkInitProcess();
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcZigbeeNetwork()) << "Failed to read firmware version after 10 attempts. Giving up";
|
qCWarning(dcZigbeeNetwork()) << "Failed to read device state after 10 attempts. Giving up";
|
||||||
m_controller->disable();
|
m_controller->reconnectConrtroller();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_initRetry = 0;
|
m_initRetry = 0;
|
||||||
qCDebug(dcZigbeeNetwork()) << "Version request finished successfully" << ZigbeeUtils::convertByteArrayToHexString(reply->responseData());
|
|
||||||
// Note: version is an uint32 value, little endian, but we can read the individual bytes in reversed order
|
|
||||||
quint8 majorVersion = static_cast<quint8>(reply->responseData().at(3));
|
|
||||||
quint8 minorVersion = static_cast<quint8>(reply->responseData().at(2));
|
|
||||||
Deconz::Platform platform = static_cast<Deconz::Platform>(reply->responseData().at(1));
|
|
||||||
QString firmwareVersion = QString("%1.%2").arg(majorVersion).arg(minorVersion);
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Firmware version" << firmwareVersion << platform;
|
|
||||||
|
|
||||||
// Read all network parameters
|
// Read all network parameters
|
||||||
qCDebug(dcZigbeeNetwork()) << "Start reading controller network parameters...";
|
qCDebug(dcZigbeeNetwork()) << "Start reading controller network parameters...";
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->readNetworkParameters();
|
ZigbeeInterfaceDeconzReply *reply = m_controller->readNetworkParameters();
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply, firmwareVersion](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not read network parameters during network start up." << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Could not read network parameters during network start up." << reply->statusCode();
|
||||||
// FIXME: set an appropriate error
|
m_initRetry++;
|
||||||
|
if (m_initRetry < 3) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Retry to read network parameters" << m_initRetry << "/ 3";
|
||||||
|
runNetworkInitProcess();
|
||||||
|
} else {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << "Failed to read network parameters after 3 attempts. Giving up";
|
||||||
|
m_controller->reconnectConrtroller();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Reading network parameters finished successfully.";
|
qCDebug(dcZigbeeNetwork()) << "Reading network parameters finished successfully.";
|
||||||
QString protocolVersion = QString("%1.%2").arg(m_controller->networkConfiguration().protocolVersion >> 8 & 0xFF)
|
|
||||||
.arg(m_controller->networkConfiguration().protocolVersion & 0xFF);
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Controller API protocol version" << ZigbeeUtils::convertUint16ToHexString(m_controller->networkConfiguration().protocolVersion) << protocolVersion;
|
|
||||||
|
|
||||||
m_controller->setFirmwareVersionString(QString("%1 - %2").arg(firmwareVersion).arg(protocolVersion));
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << m_controller->networkConfiguration();
|
qCDebug(dcZigbeeNetwork()) << m_controller->networkConfiguration();
|
||||||
qCDebug(dcZigbeeNetwork()) << "Reading current network state";
|
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestDeviceState();
|
m_protocolVersion = QString("%1.%2").arg(m_controller->networkConfiguration().protocolVersion >> 8 & 0xFF)
|
||||||
|
.arg(m_controller->networkConfiguration().protocolVersion & 0xFF);
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Controller API protocol version" << ZigbeeUtils::convertUint16ToHexString(m_controller->networkConfiguration().protocolVersion) << m_protocolVersion;
|
||||||
|
|
||||||
|
// Try read firmware version (changed with firmware 0x26680700)
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Request current firmware version...";
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestVersion();
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
|
QString firmwareVersion;
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not read device state during network start up. SQN:" << reply->sequenceNumber() << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode();
|
||||||
// FIXME: set an appropriate error
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Reading current network state finished successfully." << "SQN:" << reply->sequenceNumber();
|
|
||||||
|
|
||||||
QDataStream stream(reply->responseData());
|
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
|
||||||
quint8 deviceStateFlag = 0;
|
|
||||||
stream >> deviceStateFlag;
|
|
||||||
DeconzDeviceState deviceState = m_controller->parseDeviceStateFlag(deviceStateFlag);
|
|
||||||
qCDebug(dcZigbeeNetwork()) << deviceState;
|
|
||||||
|
|
||||||
// Update the device state in the controller
|
|
||||||
m_controller->processDeviceState(deviceState);
|
|
||||||
|
|
||||||
if (m_createNewNetwork) {
|
|
||||||
// Set offline
|
|
||||||
// Write configurations
|
|
||||||
// Set online
|
|
||||||
// Read configurations
|
|
||||||
// Create and initialize coordinator node
|
|
||||||
// Done. Save network
|
|
||||||
setCreateNetworkState(CreateNetworkStateStopNetwork);
|
|
||||||
} else {
|
} else {
|
||||||
// Get the network state and start the network if required
|
qCDebug(dcZigbeeNetwork()) << "Version request finished successfully" << ZigbeeUtils::convertByteArrayToHexString(reply->responseData());
|
||||||
if (m_controller->networkState() == Deconz::NetworkStateConnected) {
|
// Note: version is an uint32 value, little endian, but we can read the individual bytes in reversed order
|
||||||
qCDebug(dcZigbeeNetwork()) << "The network is already running.";
|
quint8 majorVersion = static_cast<quint8>(reply->responseData().at(3));
|
||||||
m_initializing = false;
|
quint8 minorVersion = static_cast<quint8>(reply->responseData().at(2));
|
||||||
setPermitJoiningEnabled(false);
|
Deconz::Platform platform = static_cast<Deconz::Platform>(reply->responseData().at(1));
|
||||||
// Set the permit joining timeout network configuration parameter
|
m_firmwareVersion = QString("%1.%2").arg(majorVersion).arg(minorVersion);
|
||||||
QByteArray parameterData;
|
qCDebug(dcZigbeeNetwork()) << "Firmware version" << firmwareVersion << platform;
|
||||||
QDataStream stream(¶meterData, QIODevice::WriteOnly);
|
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
|
||||||
stream << static_cast<quint8>(0);
|
|
||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterPermitJoin, parameterData);
|
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
|
||||||
qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode();
|
|
||||||
// FIXME: set an appropriate error
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Set permit join configuration request finished" << reply->statusCode();
|
|
||||||
setState(StateRunning);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else if (m_controller->networkState() == Deconz::NetworkStateOffline) {
|
|
||||||
m_initializing = true;
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "The network is offline. Lets start it";
|
|
||||||
setCreateNetworkState(CreateNetworkStateStartNetwork);
|
|
||||||
} else {
|
|
||||||
// The network is not running yet, lets wait for the state changed
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_firmwareVersion.isEmpty()) {
|
||||||
|
m_controller->setFirmwareVersionString(QString("%1 - %2").arg(m_firmwareVersion).arg(m_protocolVersion));
|
||||||
|
} else {
|
||||||
|
m_controller->setFirmwareVersionString(m_protocolVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Reading current network state";
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestDeviceState();
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Could not read device state during network start up. SQN:" << reply->sequenceNumber() << reply->statusCode();
|
||||||
|
// FIXME: set an appropriate error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Reading current network state finished successfully." << "SQN:" << reply->sequenceNumber();
|
||||||
|
|
||||||
|
QDataStream stream(reply->responseData());
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
quint8 deviceStateFlag = 0;
|
||||||
|
stream >> deviceStateFlag;
|
||||||
|
DeconzDeviceState deviceState = m_controller->parseDeviceStateFlag(deviceStateFlag);
|
||||||
|
qCDebug(dcZigbeeNetwork()) << deviceState;
|
||||||
|
|
||||||
|
// Update the device state in the controller
|
||||||
|
m_controller->processDeviceState(deviceState);
|
||||||
|
|
||||||
|
if (m_createNewNetwork) {
|
||||||
|
// Set offline
|
||||||
|
// Write configurations
|
||||||
|
// Set online
|
||||||
|
// Read configurations
|
||||||
|
// Create and initialize coordinator node
|
||||||
|
// Done. Save network
|
||||||
|
setCreateNetworkState(CreateNetworkStateStopNetwork);
|
||||||
|
} else {
|
||||||
|
// Get the network state and start the network if required
|
||||||
|
if (m_controller->networkState() == Deconz::NetworkStateConnected) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "The network is already running.";
|
||||||
|
m_initializing = false;
|
||||||
|
setPermitJoiningEnabled(false);
|
||||||
|
// Set the permit joining timeout network configuration parameter
|
||||||
|
QByteArray parameterData;
|
||||||
|
QDataStream stream(¶meterData, QIODevice::WriteOnly);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
stream << static_cast<quint8>(0);
|
||||||
|
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterPermitJoin, parameterData);
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode();
|
||||||
|
// FIXME: set an appropriate error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Set permit join configuration request finished" << reply->statusCode();
|
||||||
|
setState(StateRunning);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if (m_controller->networkState() == Deconz::NetworkStateOffline) {
|
||||||
|
m_initializing = true;
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "The network is offline. Lets start it";
|
||||||
|
setCreateNetworkState(CreateNetworkStateStartNetwork);
|
||||||
|
} else {
|
||||||
|
// The network is not running yet, lets wait for the state changed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -516,8 +570,8 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
|||||||
m_createNewNetwork = false;
|
m_createNewNetwork = false;
|
||||||
// Check if we have to create a pan ID and select the channel
|
// Check if we have to create a pan ID and select the channel
|
||||||
if (panId() == 0 || !m_coordinatorNode) {
|
if (panId() == 0 || !m_coordinatorNode) {
|
||||||
qCDebug(dcZigbeeNetwork()) << "Generate new extended PAN ID...";
|
setPanId(ZigbeeUtils::generateRandomPanId());
|
||||||
setExtendedPanId(ZigbeeUtils::generateRandomPanId());
|
qCDebug(dcZigbeeNetwork()) << "Generated new extended PAN ID" << panId() << ZigbeeUtils::convertUint16ToHexString(panId());
|
||||||
m_createNewNetwork = true;
|
m_createNewNetwork = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,8 +620,10 @@ void ZigbeeNetworkDeconz::onPollNetworkStateTimeout()
|
|||||||
m_controller->processDeviceState(m_controller->parseDeviceStateFlag(deviceStateFlag));
|
m_controller->processDeviceState(m_controller->parseDeviceStateFlag(deviceStateFlag));
|
||||||
if (m_controller->networkState() == Deconz::NetworkStateOffline) {
|
if (m_controller->networkState() == Deconz::NetworkStateOffline) {
|
||||||
qCDebug(dcZigbeeNetwork()) << "Network stopped successfully for creation";
|
qCDebug(dcZigbeeNetwork()) << "Network stopped successfully for creation";
|
||||||
// The network is now offline, continue with the state machine
|
// The network is now offline, continue with the state machine in one second (some grace period after network shutdown)
|
||||||
setCreateNetworkState(CreateNetworkStateWriteConfiguration);
|
QTimer::singleShot(1000, this, [=](){
|
||||||
|
setCreateNetworkState(CreateNetworkStateWriteConfiguration);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// Not offline yet, continue poll
|
// Not offline yet, continue poll
|
||||||
m_pollNetworkStateTimer->start();
|
m_pollNetworkStateTimer->start();
|
||||||
@ -672,7 +728,8 @@ void ZigbeeNetworkDeconz::stopNetwork()
|
|||||||
|
|
||||||
void ZigbeeNetworkDeconz::reset()
|
void ZigbeeNetworkDeconz::reset()
|
||||||
{
|
{
|
||||||
// TODO
|
qCDebug(dcZigbeeNetwork()) << "Reboot the controller. The stack will perform a restart.";
|
||||||
|
m_controller->rebootController();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkDeconz::factoryResetNetwork()
|
void ZigbeeNetworkDeconz::factoryResetNetwork()
|
||||||
|
|||||||
@ -65,6 +65,8 @@ private:
|
|||||||
CreateNetworkState m_createState = CreateNetworkStateIdle;
|
CreateNetworkState m_createState = CreateNetworkStateIdle;
|
||||||
bool m_createNewNetwork = false;
|
bool m_createNewNetwork = false;
|
||||||
bool m_initializing = false;
|
bool m_initializing = false;
|
||||||
|
QString m_protocolVersion;
|
||||||
|
QString m_firmwareVersion;
|
||||||
|
|
||||||
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
|
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
|
||||||
|
|
||||||
|
|||||||
@ -290,10 +290,10 @@ QString ZigbeeUtils::profileIdToString(const Zigbee::ZigbeeProfile &profileId)
|
|||||||
return profileName;
|
return profileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 ZigbeeUtils::generateRandomPanId()
|
quint16 ZigbeeUtils::generateRandomPanId()
|
||||||
{
|
{
|
||||||
// Note: the PAN ID has to be between 0x0000 and 0x3fff
|
// Note: the PAN ID has to be between 0x0000 and 0x3fff
|
||||||
return static_cast<quint64>(rand() % (0x3fff - 1) + 1);
|
return static_cast<quint16>(rand() % (0x3fff - 1) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF ZigbeeUtils::convertColorToXY(const QColor &color)
|
QPointF ZigbeeUtils::convertColorToXY(const QColor &color)
|
||||||
|
|||||||
@ -69,7 +69,7 @@ public:
|
|||||||
static QString profileIdToString(const Zigbee::ZigbeeProfile &profileId);
|
static QString profileIdToString(const Zigbee::ZigbeeProfile &profileId);
|
||||||
|
|
||||||
// Generate random data
|
// Generate random data
|
||||||
static quint64 generateRandomPanId();
|
static quint16 generateRandomPanId();
|
||||||
|
|
||||||
|
|
||||||
// Color converter
|
// Color converter
|
||||||
|
|||||||
Reference in New Issue
Block a user