Fix initialization error due to timeout issue and improve debugging
parent
4e8254fcb9
commit
1eed81562a
|
|
@ -68,7 +68,8 @@ public:
|
|||
StatusProtocolError = 0x01,
|
||||
StatusUnknownCommand = 0x02,
|
||||
StatusInvalidCrc = 0x03,
|
||||
StatusStackError = 0x04
|
||||
StatusStackError = 0x04,
|
||||
StatusTimeout = 0xff
|
||||
};
|
||||
Q_ENUM(Status)
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ void ZigbeeInterfaceNxpReply::setFinished()
|
|||
void ZigbeeInterfaceNxpReply::onTimeout()
|
||||
{
|
||||
m_timeout = true;
|
||||
m_status = Nxp::StatusTimeout;
|
||||
|
||||
emit timeout();
|
||||
emit finished();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ private:
|
|||
QByteArray m_requestData;
|
||||
|
||||
// Response content
|
||||
Nxp::Status m_status = Nxp::StatusUnknownCommand; // FIXME
|
||||
Nxp::Status m_status = Nxp::StatusUnknownCommand;
|
||||
QByteArray m_responseData;
|
||||
|
||||
void setFinished();
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::sendRequest(const ZigbeeNetworkRequest &re
|
|||
|
||||
// Enqueu reply and send next one if we have enouth capacity
|
||||
m_replyQueue.enqueue(reply);
|
||||
qCDebug(dcZigbeeNetwork()) << "=== Pending replies count (enqueued)" << m_replyQueue.count();
|
||||
sendNextReply();
|
||||
|
||||
return reply;
|
||||
|
|
@ -181,6 +182,8 @@ void ZigbeeNetworkNxp::sendNextReply()
|
|||
|
||||
|
||||
ZigbeeNetworkReply *reply = m_replyQueue.dequeue();
|
||||
qCDebug(dcZigbeeNetwork()) << "=== Pending replies count (dequeued)" << m_replyQueue.count();
|
||||
|
||||
ZigbeeInterfaceNxpReply *interfaceReply = m_controller->requestSendRequest(reply->request());
|
||||
connect(interfaceReply, &ZigbeeInterfaceNxpReply::finished, reply, [this, reply, interfaceReply](){
|
||||
if (interfaceReply->status() != Nxp::StatusSuccess) {
|
||||
|
|
@ -246,7 +249,6 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::requestSetPermitJoin(quint16 shortAddress,
|
|||
bool ZigbeeNetworkNxp::processVersionReply(ZigbeeInterfaceNxpReply *reply)
|
||||
{
|
||||
qCDebug(dcZigbeeNetwork()) << "Version reply finished" << reply->status();
|
||||
|
||||
if (reply->timendOut()) {
|
||||
m_reconnectCounter++;
|
||||
if (m_reconnectCounter >= 3) {
|
||||
|
|
@ -271,7 +273,9 @@ bool ZigbeeNetworkNxp::processVersionReply(ZigbeeInterfaceNxpReply *reply)
|
|||
qCWarning(dcZigbeeNetwork()) << "Failed to read firmware version. Retry" << m_reconnectCounter << "/ 3";
|
||||
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
|
||||
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
||||
processVersionReply(reply);
|
||||
if (processVersionReply(reply)) {
|
||||
m_controller->refreshControllerState();
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
|
|
@ -436,22 +440,25 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|||
connect(coordinatorNode, &ZigbeeNode::stateChanged, this, [this, coordinatorNode](ZigbeeNode::State state){
|
||||
if (state == ZigbeeNode::StateInitialized) {
|
||||
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
|
||||
// ZigbeeClusterGroups *groupsCluster = coordinatorNode->getEndpoint(0x01)->inputCluster<ZigbeeClusterGroups>(ZigbeeClusterLibrary::ClusterIdGroups);
|
||||
// if (!groupsCluster) {
|
||||
// qCWarning(dcZigbeeNetwork()) << "Failed to get groups cluster from coordinator. The coordinator will not be in default group 0x0000";
|
||||
// setState(StateRunning);
|
||||
// setPermitJoining(0);
|
||||
// return;
|
||||
// }
|
||||
/* Note: this currently has been hardcoded into the firmware. TODO: implement appropriate method for binding coordinator to group
|
||||
|
||||
// ZigbeeClusterReply *reply = groupsCluster->addGroup(0x0000, "Default");
|
||||
// connect(reply, &ZigbeeClusterReply::finished, this, [=](){
|
||||
// if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
|
||||
// qCWarning(dcZigbeeNetwork()) << "Failed to add coordinator to default group 0x0000. The coordinator will not be in default group 0x0000";
|
||||
// }
|
||||
// setState(StateRunning);
|
||||
// setPermitJoining(0);
|
||||
// });
|
||||
ZigbeeClusterGroups *groupsCluster = coordinatorNode->getEndpoint(0x01)->inputCluster<ZigbeeClusterGroups>(ZigbeeClusterLibrary::ClusterIdGroups);
|
||||
if (!groupsCluster) {
|
||||
qCWarning(dcZigbeeNetwork()) << "Failed to get groups cluster from coordinator. The coordinator will not be in default group 0x0000";
|
||||
setState(StateRunning);
|
||||
setPermitJoining(0);
|
||||
return;
|
||||
}
|
||||
|
||||
ZigbeeClusterReply *reply = groupsCluster->addGroup(0x0000, "Default");
|
||||
connect(reply, &ZigbeeClusterReply::finished, this, [=](){
|
||||
if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
|
||||
qCWarning(dcZigbeeNetwork()) << "Failed to add coordinator to default group 0x0000. The coordinator will not be in default group 0x0000";
|
||||
}
|
||||
setState(StateRunning);
|
||||
setPermitJoining(0);
|
||||
});
|
||||
*/
|
||||
|
||||
setState(StateRunning);
|
||||
setPermitJoining(0);
|
||||
|
|
@ -613,8 +620,10 @@ void ZigbeeNetworkNxp::onDeviceAnnounced(quint16 shortAddress, ZigbeeAddress iee
|
|||
setNodeReachable(node, true);
|
||||
return;
|
||||
} else {
|
||||
qCDebug(dcZigbeeNetwork()) << "Already known device announced with different network address. Removing node and reinitialize...";
|
||||
removeNode(node);
|
||||
qCWarning(dcZigbeeNetwork()) << "Already known device announced with different network address. FIXME: update the network address or reinitialize node...";
|
||||
|
||||
|
||||
//removeNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -211,9 +211,10 @@ ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestSimpleDescriptor(quint8 endp
|
|||
return zdoReply;
|
||||
}
|
||||
|
||||
ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestBindShortAddress(quint8 sourceEndpointId, quint16 clusterId, quint16 destinationAddress)
|
||||
ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestBindGroupAddress(quint8 sourceEndpointId, quint16 clusterId, quint16 destinationAddress)
|
||||
{
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Request bind short address from" << m_node << "endpoint" << clusterId << "to" << destinationAddress;
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Request bind group address from" << m_node << "endpoint" << ZigbeeUtils::convertByteToHexString(sourceEndpointId)
|
||||
<< static_cast<ZigbeeClusterLibrary::ClusterId>(clusterId) << "to group" << ZigbeeUtils::convertUint16ToHexString(destinationAddress);
|
||||
|
||||
// Build APS request
|
||||
ZigbeeNetworkRequest request = buildZdoRequest(ZigbeeDeviceProfile::BindRequest);
|
||||
|
|
@ -260,7 +261,9 @@ ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestBindShortAddress(quint8 sour
|
|||
|
||||
ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestBindIeeeAddress(quint8 sourceEndpointId, quint16 clusterId, const ZigbeeAddress &destinationIeeeAddress, quint8 destinationEndpointId)
|
||||
{
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Request bind ieee address from" << m_node << "endpoint" << clusterId << "to" << destinationIeeeAddress.toString() << destinationEndpointId;
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Request bind IEEE address from" << m_node << "endpoint" << ZigbeeUtils::convertByteToHexString(sourceEndpointId)
|
||||
<< static_cast<ZigbeeClusterLibrary::ClusterId>(clusterId) << "to" << destinationIeeeAddress.toString() << "endpoint"
|
||||
<< ZigbeeUtils::convertByteToHexString(destinationEndpointId);
|
||||
|
||||
// Build APS request
|
||||
ZigbeeNetworkRequest request = buildZdoRequest(ZigbeeDeviceProfile::BindRequest);
|
||||
|
|
@ -358,6 +361,49 @@ ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestUnbind(const ZigbeeDevicePro
|
|||
return zdoReply;
|
||||
}
|
||||
|
||||
ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestBindRegister(const ZigbeeAddress &ieeeAddress)
|
||||
{
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Request bind register" << m_node << ieeeAddress.toString();
|
||||
|
||||
// Build APS request
|
||||
ZigbeeNetworkRequest request = buildZdoRequest(ZigbeeDeviceProfile::BindRegisterRequest);
|
||||
|
||||
// Generate a new transaction sequence number for this device object
|
||||
quint8 transactionSequenceNumber = m_transactionSequenceNumber++;
|
||||
|
||||
// Build ZDO frame
|
||||
QByteArray asdu;
|
||||
QDataStream stream(&asdu, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream << transactionSequenceNumber;
|
||||
stream << ieeeAddress.toUInt64();
|
||||
|
||||
// Set the ZDO frame as APS request payload
|
||||
request.setAsdu(asdu);
|
||||
|
||||
// Create the device object reply and wait for the response indication
|
||||
ZigbeeDeviceObjectReply *zdoReply = createZigbeeDeviceObjectReply(request, transactionSequenceNumber);
|
||||
|
||||
// Send the request, on finished read the confirm information
|
||||
ZigbeeNetworkReply *networkReply = m_network->sendRequest(request);
|
||||
connect(networkReply, &ZigbeeNetworkReply::finished, this, [this, networkReply, zdoReply](){
|
||||
if (!verifyNetworkError(zdoReply, networkReply)) {
|
||||
finishZdoReply(zdoReply);
|
||||
return;
|
||||
}
|
||||
|
||||
// The request was successfully sent to the device
|
||||
// Now check if the expected indication response received already
|
||||
if (zdoReply->isComplete()) {
|
||||
finishZdoReply(zdoReply);
|
||||
return;
|
||||
}
|
||||
// We received the confirmation but not yet the indication
|
||||
});
|
||||
|
||||
return zdoReply;
|
||||
}
|
||||
|
||||
ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestMgmtLeaveNetwork(bool rejoin, bool removeChildren)
|
||||
{
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Request management leave network from" << m_node << "rejoin" << rejoin << "remove children" << removeChildren;
|
||||
|
|
@ -442,17 +488,6 @@ ZigbeeDeviceObjectReply *ZigbeeDeviceObject::requestMgmtLqi(quint8 startIndex)
|
|||
// Now check if the expected indication response received already
|
||||
if (zdoReply->isComplete()) {
|
||||
qCDebug(dcZigbeeDeviceObject()) << "Successfully received response for" << static_cast<ZigbeeDeviceProfile::ZdoCommand>(networkReply->request().clusterId());
|
||||
// TODO: pars child table
|
||||
// QByteArray response = zdoReply->responseAdpu().payload;
|
||||
// QDataStream stream(&response, QIODevice::ReadOnly);
|
||||
// stream.setByteOrder(QDataStream::LittleEndian);
|
||||
// quint8 statusValue; quint8 tableEntries; quint8 startIndex;
|
||||
|
||||
// ZigbeeDeviceProfile::Status status;
|
||||
|
||||
|
||||
|
||||
|
||||
finishZdoReply(zdoReply);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,10 +50,10 @@ public:
|
|||
// TODO: implement other device and service discovery methods
|
||||
|
||||
// End device binding
|
||||
ZigbeeDeviceObjectReply *requestBindShortAddress(quint8 sourceEndpointId, quint16 clusterId, quint16 destinationAddress);
|
||||
ZigbeeDeviceObjectReply *requestBindGroupAddress(quint8 sourceEndpointId, quint16 clusterId, quint16 destinationAddress);
|
||||
ZigbeeDeviceObjectReply *requestBindIeeeAddress(quint8 sourceEndpointId, quint16 clusterId, const ZigbeeAddress &destinationIeeeAddress, quint8 destinationEndpointId);
|
||||
|
||||
ZigbeeDeviceObjectReply *requestUnbind(const ZigbeeDeviceProfile::BindingTableListRecord &bindingRecord);
|
||||
ZigbeeDeviceObjectReply *requestBindRegister(const ZigbeeAddress &ieeeAddress);
|
||||
|
||||
// Management request
|
||||
ZigbeeDeviceObjectReply *requestMgmtLeaveNetwork(bool rejoin = false, bool removeChildren = false);
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ ZigbeeDeviceProfile::Adpu ZigbeeDeviceProfile::parseAdpu(const QByteArray &adpu)
|
|||
|
||||
QDebug operator<<(QDebug debug, const ZigbeeDeviceProfile::Adpu &deviceAdpu)
|
||||
{
|
||||
debug.nospace() << "DeviceAdpu(SQN: " << deviceAdpu.transactionSequenceNumber << ", ";
|
||||
debug.nospace() << "DeviceProfileAdpu(SQN: " << deviceAdpu.transactionSequenceNumber << ", ";
|
||||
debug.nospace() << deviceAdpu.status << ", ";
|
||||
debug.nospace() << ZigbeeUtils::convertUint16ToHexString(deviceAdpu.addressOfInterest) << ", ";
|
||||
debug.nospace() << "Payload: " << ZigbeeUtils::convertByteArrayToHexString(deviceAdpu.payload) << ")";
|
||||
|
|
@ -210,12 +210,12 @@ QDebug operator<<(QDebug debug, const ZigbeeDeviceProfile::NodeDescriptor &nodeD
|
|||
debug.nospace() << " Complex descriptor available: " << nodeDescriptor.complexDescriptorAvailable << "\n";
|
||||
debug.nospace() << " User descriptor available: " << nodeDescriptor.userDescriptorAvailable << "\n";
|
||||
debug.nospace() << " " << nodeDescriptor.frequencyBand << "\n";
|
||||
debug.nospace() << " " << nodeDescriptor.macCapabilities;
|
||||
debug.nospace() << " " << nodeDescriptor.macCapabilities << "\n";
|
||||
debug.nospace() << " Manufacturer code: " << ZigbeeUtils::convertUint16ToHexString(nodeDescriptor.manufacturerCode) << "(" << nodeDescriptor.manufacturerCode << ")" << "\n";
|
||||
debug.nospace() << " Maximum buffer size: " << nodeDescriptor.maximumBufferSize << "\n";
|
||||
debug.nospace() << " Maximum RX size: " << nodeDescriptor.maximumRxSize << "\n";
|
||||
debug.nospace() << " Maximum TX size: " << nodeDescriptor.maximumTxSize << "\n";
|
||||
debug.nospace() << " " << nodeDescriptor.serverMask;
|
||||
debug.nospace() << " " << nodeDescriptor.serverMask << "\n";
|
||||
debug.nospace() << " " << nodeDescriptor.descriptorCapabilities;
|
||||
return debug;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -292,7 +292,6 @@ public:
|
|||
static MacCapabilities parseMacCapabilities(quint8 macCapabilitiesFlag);
|
||||
static ServerMask parseServerMask(quint16 serverMaskFlag);
|
||||
static DescriptorCapabilities parseDescriptorCapabilities(quint8 descriptorCapabilitiesFlag);
|
||||
|
||||
static PowerDescriptor parsePowerDescriptor(quint16 powerDescriptorFlag);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -691,8 +691,9 @@ void ZigbeeNetwork::evaluateNodeReachableStates()
|
|||
// Note: sleeping devices should send some message within 6 hours,
|
||||
// otherwise the device might not be reachable any more
|
||||
int msSinceLastSeen = node->lastSeen().msecsTo(QDateTime::currentDateTimeUtc());
|
||||
qCDebug(dcZigbeeNetwork()) << node << "last seen" << QTime::fromMSecsSinceStartOfDay(msSinceLastSeen).toString();
|
||||
if (msSinceLastSeen < 1000*60*60*6) {
|
||||
qCDebug(dcZigbeeNetwork()) << node << "has been seen the last time" << QTime::fromMSecsSinceStartOfDay(msSinceLastSeen).toString() << "ago.";
|
||||
// 6 Hours = 6 * 60 * 60 * 1000 = 21600000 ms
|
||||
if (msSinceLastSeen < 21600000) {
|
||||
setNodeReachable(node, true);
|
||||
} else {
|
||||
setNodeReachable(node, false);
|
||||
|
|
|
|||
Loading…
Reference in New Issue