Rework permit join mechanism and remove infinit joining
This commit is contained in:
parent
3d62162f5e
commit
e46630f9e2
@ -46,10 +46,6 @@ ZigbeeNetworkDeconz::ZigbeeNetworkDeconz(const QUuid &networkUuid, QObject *pare
|
|||||||
m_pollNetworkStateTimer->setSingleShot(false);
|
m_pollNetworkStateTimer->setSingleShot(false);
|
||||||
connect(m_pollNetworkStateTimer, &QTimer::timeout, this, &ZigbeeNetworkDeconz::onPollNetworkStateTimeout);
|
connect(m_pollNetworkStateTimer, &QTimer::timeout, this, &ZigbeeNetworkDeconz::onPollNetworkStateTimeout);
|
||||||
|
|
||||||
m_permitJoinRefreshTimer = new QTimer(this);
|
|
||||||
m_permitJoinRefreshTimer->setInterval(250 * 1000);
|
|
||||||
m_permitJoinRefreshTimer->setSingleShot(false);
|
|
||||||
connect(m_permitJoinRefreshTimer, &QTimer::timeout, this, &ZigbeeNetworkDeconz::onPermitJoinRefreshTimout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeBridgeController *ZigbeeNetworkDeconz::bridgeController() const
|
ZigbeeBridgeController *ZigbeeNetworkDeconz::bridgeController() const
|
||||||
@ -95,7 +91,60 @@ ZigbeeNetworkReply *ZigbeeNetworkDeconz::sendRequest(const ZigbeeNetworkRequest
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeNetworkReply *ZigbeeNetworkDeconz::setPermitJoin(quint16 shortAddress, quint8 duration)
|
void ZigbeeNetworkDeconz::setPermitJoining(quint8 duration, quint16 address)
|
||||||
|
{
|
||||||
|
if (duration > 0) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Set permit join for" << duration << "s on" << ZigbeeUtils::convertUint16ToHexString(address);
|
||||||
|
} else {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Disable permit join on"<< ZigbeeUtils::convertUint16ToHexString(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: will be reseted if permit join will not work
|
||||||
|
setPermitJoiningEnabled(duration > 0);
|
||||||
|
setPermitJoiningDuration(duration);
|
||||||
|
setPermitJoiningRemaining(duration);
|
||||||
|
|
||||||
|
// Note: since compliance version >= 21 the value 255 is not any more endless.
|
||||||
|
// We need to refresh the command on timeout repeatedly if the duration is longer than 254 s
|
||||||
|
|
||||||
|
ZigbeeNetworkReply *reply = requestSetPermitJoin(address, duration);
|
||||||
|
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply, duration, address](){
|
||||||
|
if (reply->zigbeeApsStatus() != Zigbee::ZigbeeApsStatusSuccess) {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << "Could not set permit join to" << duration << ZigbeeUtils::convertUint16ToHexString(address) << reply->zigbeeApsStatus();
|
||||||
|
setPermitJoiningEnabled(false);
|
||||||
|
setPermitJoiningDuration(duration);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Permit join request finished successfully";
|
||||||
|
|
||||||
|
setPermitJoiningEnabled(duration > 0);
|
||||||
|
setPermitJoiningDuration(duration);
|
||||||
|
setPermitJoiningRemaining(duration);
|
||||||
|
if (duration > 0) {
|
||||||
|
m_permitJoinTimer->start();
|
||||||
|
} else {
|
||||||
|
m_permitJoinTimer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the permit joining timeout network configuration parameter
|
||||||
|
QByteArray parameterData;
|
||||||
|
QDataStream stream(¶meterData, QIODevice::WriteOnly);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
stream << duration;
|
||||||
|
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterPermitJoin, parameterData);
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [reply](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Set permit join configuration request finished" << reply->statusCode();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeNetworkReply *ZigbeeNetworkDeconz::requestSetPermitJoin(quint16 shortAddress, quint8 duration)
|
||||||
{
|
{
|
||||||
// Get the power descriptor
|
// Get the power descriptor
|
||||||
ZigbeeNetworkRequest request;
|
ZigbeeNetworkRequest request;
|
||||||
@ -305,7 +354,7 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
|
|||||||
m_database->saveNode(m_coordinatorNode);
|
m_database->saveNode(m_coordinatorNode);
|
||||||
m_initializing = false;
|
m_initializing = false;
|
||||||
setState(StateRunning);
|
setState(StateRunning);
|
||||||
setPermitJoiningInternal(false);
|
setPermitJoining(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +367,7 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
|
|||||||
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
|
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
|
||||||
m_initializing = false;
|
m_initializing = false;
|
||||||
setState(StateRunning);
|
setState(StateRunning);
|
||||||
setPermitJoiningInternal(false);
|
setPermitJoining(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -380,67 +429,10 @@ void ZigbeeNetworkDeconz::handleZigbeeClusterLibraryIndication(const Zigbee::Aps
|
|||||||
handleNodeIndication(node, indication);
|
handleNodeIndication(node, indication);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkDeconz::setPermitJoiningInternal(bool permitJoining)
|
|
||||||
{
|
|
||||||
quint8 duration = 0;
|
|
||||||
if (permitJoining == true) {
|
|
||||||
duration = 254;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: since compliance version >= 21 the value 255 is not any more Qt::endless.
|
|
||||||
// we need to refresh the command on timeout
|
|
||||||
|
|
||||||
ZigbeeNetworkReply *reply = setPermitJoin(Zigbee::BroadcastAddressAllRouters, duration);
|
|
||||||
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply, permitJoining, duration](){
|
|
||||||
if (reply->zigbeeApsStatus() != Zigbee::ZigbeeApsStatusSuccess) {
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Could not set permit join to" << duration;
|
|
||||||
if (m_permitJoining != false) {
|
|
||||||
m_permitJoining = false;
|
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Permit join request finished successfully";
|
|
||||||
if (permitJoining) {
|
|
||||||
m_permitJoinRefreshTimer->start();
|
|
||||||
} else {
|
|
||||||
m_permitJoinRefreshTimer->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_permitJoining != permitJoining) {
|
|
||||||
m_permitJoining = permitJoining;
|
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the permit joining timeout network configuration parameter
|
|
||||||
QByteArray parameterData;
|
|
||||||
QDataStream stream(¶meterData, QIODevice::WriteOnly);
|
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
|
||||||
stream << duration;
|
|
||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterPermitJoin, parameterData);
|
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, 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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNetworkDeconz::startNetworkInternally()
|
void ZigbeeNetworkDeconz::startNetworkInternally()
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeNetwork()) << "Start zigbee network internally";
|
qCDebug(dcZigbeeNetwork()) << "Start zigbee network internally";
|
||||||
|
|
||||||
if (!m_database) {
|
|
||||||
QString networkDatabaseFileName = settingsDirectory().absolutePath() + QDir::separator() + QString("zigbee-network-%1.db").arg(networkUuid().toString().remove('{').remove('}'));
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Using ZigBee network database" << QFileInfo(networkDatabaseFileName).fileName();
|
|
||||||
m_database = new ZigbeeNetworkDatabase(this, networkDatabaseFileName, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
||||||
@ -525,7 +517,7 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
|||||||
if (m_controller->networkState() == Deconz::NetworkStateConnected) {
|
if (m_controller->networkState() == Deconz::NetworkStateConnected) {
|
||||||
qCDebug(dcZigbeeNetwork()) << "The network is already running.";
|
qCDebug(dcZigbeeNetwork()) << "The network is already running.";
|
||||||
m_initializing = false;
|
m_initializing = false;
|
||||||
setPermitJoining(false);
|
setPermitJoiningEnabled(false);
|
||||||
// Set the permit joining timeout network configuration parameter
|
// Set the permit joining timeout network configuration parameter
|
||||||
QByteArray parameterData;
|
QByteArray parameterData;
|
||||||
QDataStream stream(¶meterData, QIODevice::WriteOnly);
|
QDataStream stream(¶meterData, QIODevice::WriteOnly);
|
||||||
@ -563,18 +555,11 @@ void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
|
|||||||
qCWarning(dcZigbeeNetwork()) << "Hardware controller is not available any more.";
|
qCWarning(dcZigbeeNetwork()) << "Hardware controller is not available any more.";
|
||||||
setError(ErrorHardwareUnavailable);
|
setError(ErrorHardwareUnavailable);
|
||||||
m_initializing = false;
|
m_initializing = false;
|
||||||
if (m_permitJoining != false) {
|
setPermitJoiningEnabled(false);
|
||||||
m_permitJoining = false;
|
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
}
|
|
||||||
setState(StateOffline);
|
setState(StateOffline);
|
||||||
} else {
|
} else {
|
||||||
m_error = ErrorNoError;
|
m_error = ErrorNoError;
|
||||||
if (m_permitJoining != false) {
|
setPermitJoiningEnabled(false);
|
||||||
m_permitJoining = false;
|
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
}
|
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
setState(StateStarting);
|
setState(StateStarting);
|
||||||
qCDebug(dcZigbeeNetwork()) << "Hardware controller is now available.";
|
qCDebug(dcZigbeeNetwork()) << "Hardware controller is now available.";
|
||||||
startNetworkInternally();
|
startNetworkInternally();
|
||||||
@ -651,11 +636,6 @@ void ZigbeeNetworkDeconz::onPollNetworkStateTimeout()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkDeconz::onPermitJoinRefreshTimout()
|
|
||||||
{
|
|
||||||
setPermitJoiningInternal(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNetworkDeconz::onApsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &confirm)
|
void ZigbeeNetworkDeconz::onApsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &confirm)
|
||||||
{
|
{
|
||||||
ZigbeeNetworkReply *reply = m_pendingReplies.value(confirm.requestId);
|
ZigbeeNetworkReply *reply = m_pendingReplies.value(confirm.requestId);
|
||||||
@ -705,22 +685,17 @@ void ZigbeeNetworkDeconz::startNetwork()
|
|||||||
loadNetwork();
|
loadNetwork();
|
||||||
|
|
||||||
if (!m_controller->enable(serialPortName(), serialBaudrate())) {
|
if (!m_controller->enable(serialPortName(), serialBaudrate())) {
|
||||||
m_permitJoining = false;
|
setPermitJoiningEnabled(false);
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
setState(StateOffline);
|
setState(StateOffline);
|
||||||
setCreateNetworkState(CreateNetworkStateIdle);
|
setCreateNetworkState(CreateNetworkStateIdle);
|
||||||
setError(ErrorHardwareUnavailable);
|
setError(ErrorHardwareUnavailable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_permitJoining != false) {
|
setPermitJoiningEnabled(false);
|
||||||
m_permitJoining = false;
|
m_initializing = true;
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: wait for the controller available signal and start the initialization there
|
// Note: wait for the controller available signal and start the initialization there
|
||||||
|
|
||||||
m_initializing = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkDeconz::stopNetwork()
|
void ZigbeeNetworkDeconz::stopNetwork()
|
||||||
|
|||||||
@ -57,7 +57,7 @@ public:
|
|||||||
// Sending an APSDE-DATA.request, will be finished on APSDE-DATA.confirm
|
// Sending an APSDE-DATA.request, will be finished on APSDE-DATA.confirm
|
||||||
ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) override;
|
ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) override;
|
||||||
|
|
||||||
ZigbeeNetworkReply *setPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe);
|
void setPermitJoining(quint8 duration, quint16 address = Zigbee::BroadcastAddressAllRouters) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZigbeeBridgeControllerDeconz *m_controller = nullptr;
|
ZigbeeBridgeControllerDeconz *m_controller = nullptr;
|
||||||
@ -66,13 +66,13 @@ private:
|
|||||||
bool m_createNewNetwork = false;
|
bool m_createNewNetwork = false;
|
||||||
bool m_initializing = false;
|
bool m_initializing = false;
|
||||||
|
|
||||||
QTimer *m_permitJoinRefreshTimer = nullptr;
|
|
||||||
|
|
||||||
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
|
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
|
||||||
|
|
||||||
QTimer *m_pollNetworkStateTimer = nullptr;
|
QTimer *m_pollNetworkStateTimer = nullptr;
|
||||||
void setCreateNetworkState(CreateNetworkState state);
|
void setCreateNetworkState(CreateNetworkState state);
|
||||||
|
|
||||||
|
ZigbeeNetworkReply *requestSetPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe);
|
||||||
|
|
||||||
// ZDO
|
// ZDO
|
||||||
void handleZigbeeDeviceProfileIndication(const Zigbee::ApsdeDataIndication &indication);
|
void handleZigbeeDeviceProfileIndication(const Zigbee::ApsdeDataIndication &indication);
|
||||||
|
|
||||||
@ -80,13 +80,11 @@ private:
|
|||||||
void handleZigbeeClusterLibraryIndication(const Zigbee::ApsdeDataIndication &indication);
|
void handleZigbeeClusterLibraryIndication(const Zigbee::ApsdeDataIndication &indication);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setPermitJoiningInternal(bool permitJoining) override;
|
|
||||||
void startNetworkInternally();
|
void startNetworkInternally();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onControllerAvailableChanged(bool available);
|
void onControllerAvailableChanged(bool available);
|
||||||
void onPollNetworkStateTimeout();
|
void onPollNetworkStateTimeout();
|
||||||
void onPermitJoinRefreshTimout();
|
|
||||||
|
|
||||||
void onApsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &confirm);
|
void onApsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &confirm);
|
||||||
void onApsDataIndicationReceived(const Zigbee::ApsdeDataIndication &indication);
|
void onApsDataIndicationReceived(const Zigbee::ApsdeDataIndication &indication);
|
||||||
|
|||||||
@ -55,13 +55,6 @@ ZigbeeNetworkNxp::ZigbeeNetworkNxp(const QUuid &networkUuid, QObject *parent) :
|
|||||||
setState(StateUpdating);
|
setState(StateUpdating);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
m_permitJoinRefreshTimer = new QTimer(this);
|
|
||||||
m_permitJoinRefreshTimer->setInterval(250 * 1000);
|
|
||||||
m_permitJoinRefreshTimer->setSingleShot(false);
|
|
||||||
connect(m_permitJoinRefreshTimer, &QTimer::timeout, this, [this](){
|
|
||||||
setPermitJoiningInternal(true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeBridgeController *ZigbeeNetworkNxp::bridgeController() const
|
ZigbeeBridgeController *ZigbeeNetworkNxp::bridgeController() const
|
||||||
@ -118,7 +111,79 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::sendRequest(const ZigbeeNetworkRequest &re
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeNetworkReply *ZigbeeNetworkNxp::setPermitJoin(quint16 shortAddress, quint8 duration)
|
void ZigbeeNetworkNxp::setPermitJoining(quint8 duration, quint16 address)
|
||||||
|
{
|
||||||
|
if (duration > 0) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Set permit join for" << duration << "s on" << ZigbeeUtils::convertUint16ToHexString(address);
|
||||||
|
} else {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Disable permit join on"<< ZigbeeUtils::convertUint16ToHexString(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: will be reseted if permit join will not work
|
||||||
|
setPermitJoiningEnabled(duration > 0);
|
||||||
|
setPermitJoiningDuration(duration);
|
||||||
|
setPermitJoiningRemaining(duration);
|
||||||
|
|
||||||
|
if (address == 0x0000) {
|
||||||
|
// Only the coordinator is allowed to join the network
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Set permit join in the coordinator node only to" << duration << "[s]";
|
||||||
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestSetPermitJoinCoordinator(duration);
|
||||||
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply, duration](){
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Set permit join in the coordinator finished" << reply->status();
|
||||||
|
if (reply->status() != Nxp::StatusSuccess) {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << "Failed to set permit join status in coordinator";
|
||||||
|
setPermitJoiningEnabled(false);
|
||||||
|
setPermitJoiningDuration(duration);
|
||||||
|
} else {
|
||||||
|
setPermitJoiningEnabled(duration > 0);
|
||||||
|
setPermitJoiningDuration(duration);
|
||||||
|
setPermitJoiningRemaining(duration);
|
||||||
|
if (duration > 0) {
|
||||||
|
m_permitJoinTimer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: since compliance version >= 21 the value 255 is not any more endless.
|
||||||
|
// We need to refresh the command on timeout if the duration is longer
|
||||||
|
|
||||||
|
ZigbeeNetworkReply *reply = requestSetPermitJoin(address, duration);
|
||||||
|
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply, duration, address](){
|
||||||
|
if (reply->zigbeeApsStatus() != Zigbee::ZigbeeApsStatusSuccess) {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << "Could not set permit join to" << duration << ZigbeeUtils::convertUint16ToHexString(address) << reply->zigbeeApsStatus();
|
||||||
|
setPermitJoiningEnabled(false);
|
||||||
|
setPermitJoiningDuration(duration);
|
||||||
|
m_permitJoinTimer->stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Permit join request finished successfully";
|
||||||
|
setPermitJoiningEnabled(duration > 0);
|
||||||
|
setPermitJoiningDuration(duration);
|
||||||
|
setPermitJoiningRemaining(duration);
|
||||||
|
if (duration > 0) {
|
||||||
|
m_permitJoinTimer->start();
|
||||||
|
} else {
|
||||||
|
m_permitJoinTimer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address == Zigbee::BroadcastAddressAllRouters || address == 0x0000) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Set permit join in the coordinator node to" << duration << "[s]";
|
||||||
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestSetPermitJoinCoordinator(duration);
|
||||||
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [reply](){
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Set permit join in the coordinator finished" << reply->status();
|
||||||
|
if (reply->status() != Nxp::StatusSuccess) {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << "Failed to set permit join status in coordinator";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeNetworkReply *ZigbeeNetworkNxp::requestSetPermitJoin(quint16 shortAddress, quint8 duration)
|
||||||
{
|
{
|
||||||
// Get the power descriptor
|
// Get the power descriptor
|
||||||
ZigbeeNetworkRequest request;
|
ZigbeeNetworkRequest request;
|
||||||
@ -325,7 +390,7 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done.";
|
qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done.";
|
||||||
m_database->saveNode(m_coordinatorNode);
|
m_database->saveNode(m_coordinatorNode);
|
||||||
setPermitJoiningInternal(false);
|
setPermitJoining(0);
|
||||||
setState(StateRunning);
|
setState(StateRunning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -338,7 +403,7 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|||||||
if (state == ZigbeeNode::StateInitialized) {
|
if (state == ZigbeeNode::StateInitialized) {
|
||||||
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
|
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
|
||||||
setState(StateRunning);
|
setState(StateRunning);
|
||||||
setPermitJoiningInternal(false);
|
setPermitJoining(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -500,62 +565,11 @@ void ZigbeeNetworkNxp::onDeviceAnnounced(quint16 shortAddress, ZigbeeAddress iee
|
|||||||
node->startInitialization();
|
node->startInitialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkNxp::setPermitJoiningInternal(bool permitJoining)
|
|
||||||
{
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Set permit join internal" << permitJoining;
|
|
||||||
|
|
||||||
quint8 duration = 0;
|
|
||||||
if (permitJoining) {
|
|
||||||
duration = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: since compliance version >= 21 the value 255 is not any more Qt::endless.
|
|
||||||
// we need to refresh the command on timeout
|
|
||||||
|
|
||||||
|
|
||||||
ZigbeeNetworkReply *reply = setPermitJoin(Zigbee::BroadcastAddressAllRouters, duration);
|
|
||||||
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply, permitJoining, duration](){
|
|
||||||
if (reply->zigbeeApsStatus() != Zigbee::ZigbeeApsStatusSuccess) {
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Could not set permit join to" << duration;
|
|
||||||
if (m_permitJoining != false) {
|
|
||||||
m_permitJoining = false;
|
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Permit join request finished successfully";
|
|
||||||
if (permitJoining) {
|
|
||||||
m_permitJoinRefreshTimer->start();
|
|
||||||
} else {
|
|
||||||
m_permitJoinRefreshTimer->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_permitJoining != permitJoining) {
|
|
||||||
m_permitJoining = permitJoining;
|
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Set permit join in the coordinator node to" << duration << "[s]";
|
|
||||||
ZigbeeInterfaceNxpReply *reply = m_controller->requestSetPermitJoinCoordinator(duration);
|
|
||||||
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [reply](){
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Set permit join in the coordinator finished" << reply->status();
|
|
||||||
if (reply->status() != Nxp::StatusSuccess) {
|
|
||||||
qCWarning(dcZigbeeNetwork()) << "Failed to set permit join status in coordinator";
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNetworkNxp::startNetwork()
|
void ZigbeeNetworkNxp::startNetwork()
|
||||||
{
|
{
|
||||||
loadNetwork();
|
loadNetwork();
|
||||||
|
|
||||||
if (m_permitJoining != false) {
|
setPermitJoiningEnabled(false);
|
||||||
m_permitJoining = false;
|
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_controller->enable(serialPortName(), serialBaudrate())) {
|
if (!m_controller->enable(serialPortName(), serialBaudrate())) {
|
||||||
setState(StateOffline);
|
setState(StateOffline);
|
||||||
|
|||||||
@ -45,7 +45,8 @@ public:
|
|||||||
ZigbeeBridgeController *bridgeController() const override;
|
ZigbeeBridgeController *bridgeController() const override;
|
||||||
Zigbee::ZigbeeBackendType backendType() const override;
|
Zigbee::ZigbeeBackendType backendType() const override;
|
||||||
ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) override;
|
ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) override;
|
||||||
ZigbeeNetworkReply *setPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe);
|
|
||||||
|
void setPermitJoining(quint8 duration, quint16 address = Zigbee::BroadcastAddressAllRouters) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZigbeeBridgeControllerNxp *m_controller = nullptr;
|
ZigbeeBridgeControllerNxp *m_controller = nullptr;
|
||||||
@ -53,8 +54,6 @@ private:
|
|||||||
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
|
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
|
||||||
int m_reconnectCounter = 0;
|
int m_reconnectCounter = 0;
|
||||||
|
|
||||||
QTimer *m_permitJoinRefreshTimer = nullptr;
|
|
||||||
|
|
||||||
bool processVersionReply(ZigbeeInterfaceNxpReply *reply);
|
bool processVersionReply(ZigbeeInterfaceNxpReply *reply);
|
||||||
|
|
||||||
// ZDO
|
// ZDO
|
||||||
@ -63,6 +62,8 @@ private:
|
|||||||
// ZCL
|
// ZCL
|
||||||
void handleZigbeeClusterLibraryIndication(const Zigbee::ApsdeDataIndication &indication);
|
void handleZigbeeClusterLibraryIndication(const Zigbee::ApsdeDataIndication &indication);
|
||||||
|
|
||||||
|
ZigbeeNetworkReply *requestSetPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onControllerAvailableChanged(bool available);
|
void onControllerAvailableChanged(bool available);
|
||||||
void onControllerStateChanged(ZigbeeBridgeControllerNxp::ControllerState controllerState);
|
void onControllerStateChanged(ZigbeeBridgeControllerNxp::ControllerState controllerState);
|
||||||
@ -73,8 +74,6 @@ private slots:
|
|||||||
|
|
||||||
void onDeviceAnnounced(quint16 shortAddress, ZigbeeAddress ieeeAddress, quint8 macCapabilities);
|
void onDeviceAnnounced(quint16 shortAddress, ZigbeeAddress ieeeAddress, quint8 macCapabilities);
|
||||||
|
|
||||||
protected:
|
|
||||||
void setPermitJoiningInternal(bool permitJoining) override;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|||||||
@ -111,6 +111,6 @@ bool ZigbeeAddress::operator!=(const ZigbeeAddress &other) const
|
|||||||
|
|
||||||
QDebug operator<<(QDebug debug, const ZigbeeAddress &address)
|
QDebug operator<<(QDebug debug, const ZigbeeAddress &address)
|
||||||
{
|
{
|
||||||
debug.nospace() << address.toString();
|
debug << address.toString();
|
||||||
return debug.space();
|
return debug;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,18 @@ ZigbeeNetwork::ZigbeeNetwork(const QUuid &networkUuid, QObject *parent) :
|
|||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_networkUuid(networkUuid)
|
m_networkUuid(networkUuid)
|
||||||
{
|
{
|
||||||
|
m_permitJoinTimer = new QTimer(this);
|
||||||
|
m_permitJoinTimer->setInterval(1000);
|
||||||
|
m_permitJoinTimer->setSingleShot(false);
|
||||||
|
connect(m_permitJoinTimer, &QTimer::timeout, this, [this](){
|
||||||
|
m_permitJoiningRemaining--;
|
||||||
|
if (m_permitJoiningRemaining <= 0) {
|
||||||
|
m_permitJoinTimer->stop();
|
||||||
|
setPermitJoining(0);
|
||||||
|
} else {
|
||||||
|
setPermitJoiningRemaining(m_permitJoiningRemaining);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid ZigbeeNetwork::networkUuid() const
|
QUuid ZigbeeNetwork::networkUuid() const
|
||||||
@ -191,14 +202,51 @@ void ZigbeeNetwork::setSecurityConfiguration(const ZigbeeSecurityConfiguration &
|
|||||||
emit securityConfigurationChanged(m_securityConfiguration);
|
emit securityConfigurationChanged(m_securityConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZigbeeNetwork::permitJoining() const
|
bool ZigbeeNetwork::permitJoiningEnabled() const
|
||||||
{
|
{
|
||||||
return m_permitJoining;
|
return m_permitJoiningEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetwork::setPermitJoining(bool permitJoining)
|
quint8 ZigbeeNetwork::permitJoiningDuration() const
|
||||||
{
|
{
|
||||||
setPermitJoiningInternal(permitJoining);
|
return m_permitJoiningDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 ZigbeeNetwork::permitJoiningRemaining() const
|
||||||
|
{
|
||||||
|
return m_permitJoiningRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setPermitJoiningEnabled(bool permitJoiningEnabled)
|
||||||
|
{
|
||||||
|
if (m_permitJoiningEnabled == permitJoiningEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_permitJoiningEnabled = permitJoiningEnabled;
|
||||||
|
emit permitJoiningEnabledChanged(m_permitJoiningEnabled);
|
||||||
|
|
||||||
|
if (!m_permitJoiningEnabled) {
|
||||||
|
m_permitJoinTimer->stop();
|
||||||
|
setPermitJoiningRemaining(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setPermitJoiningDuration(quint8 duration)
|
||||||
|
{
|
||||||
|
if (m_permitJoiningDuration == duration)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_permitJoiningDuration = duration;
|
||||||
|
emit permitJoinDurationChanged(m_permitJoiningDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setPermitJoiningRemaining(quint8 remaining)
|
||||||
|
{
|
||||||
|
if (m_permitJoiningRemaining == remaining)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_permitJoiningRemaining = remaining;
|
||||||
|
emit permitJoinRemainingChanged(m_permitJoiningRemaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
quint8 ZigbeeNetwork::generateSequenceNumber()
|
quint8 ZigbeeNetwork::generateSequenceNumber()
|
||||||
@ -407,7 +455,7 @@ void ZigbeeNetwork::clearSettings()
|
|||||||
if (!m_database->wipeDatabase()) {
|
if (!m_database->wipeDatabase()) {
|
||||||
qCWarning(dcZigbeeNetwork()) << "Failed to wipe the network database" << m_database->databaseName();
|
qCWarning(dcZigbeeNetwork()) << "Failed to wipe the network database" << m_database->databaseName();
|
||||||
}
|
}
|
||||||
m_database->deleteLater();
|
delete m_database;
|
||||||
m_database = nullptr;
|
m_database = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,6 +465,7 @@ void ZigbeeNetwork::clearSettings()
|
|||||||
setChannel(0);
|
setChannel(0);
|
||||||
setSecurityConfiguration(ZigbeeSecurityConfiguration());
|
setSecurityConfiguration(ZigbeeSecurityConfiguration());
|
||||||
setState(StateUninitialized);
|
setState(StateUninitialized);
|
||||||
|
setPermitJoiningEnabled(false);
|
||||||
m_nodeType = ZigbeeDeviceProfile::NodeTypeCoordinator;
|
m_nodeType = ZigbeeDeviceProfile::NodeTypeCoordinator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,11 +631,11 @@ void ZigbeeNetwork::onNodeClusterAttributeChanged(ZigbeeCluster *cluster, const
|
|||||||
|
|
||||||
QDebug operator<<(QDebug debug, ZigbeeNetwork *network)
|
QDebug operator<<(QDebug debug, ZigbeeNetwork *network)
|
||||||
{
|
{
|
||||||
debug.nospace().noquote() << "ZigbeeNetwork(" << network->macAddress() << ", "
|
debug.nospace().noquote() << "ZigbeeNetwork(" << network->macAddress().toString() << ", "
|
||||||
<< network->networkUuid().toString() << ", "
|
<< network->networkUuid().toString() << ", "
|
||||||
<< network->backendType() << ", "
|
<< network->backendType() << ", "
|
||||||
<< "Channel: " << network->channel() << ", "
|
<< "Channel: " << network->channel() << ", "
|
||||||
<< network->state()
|
<< network->state()
|
||||||
<< ")";
|
<< ") ";
|
||||||
return debug.space();
|
return debug;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,9 +107,10 @@ public:
|
|||||||
ZigbeeSecurityConfiguration securityConfiguration() const;
|
ZigbeeSecurityConfiguration securityConfiguration() const;
|
||||||
void setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration);
|
void setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration);
|
||||||
|
|
||||||
bool permitJoining() const;
|
bool permitJoiningEnabled() const;
|
||||||
void setPermitJoining(bool permitJoining);
|
quint8 permitJoiningDuration() const;
|
||||||
|
quint8 permitJoiningRemaining() const;
|
||||||
|
virtual void setPermitJoining(quint8 duration, quint16 address = Zigbee::BroadcastAddressAllRouters) = 0;
|
||||||
|
|
||||||
quint8 generateSequenceNumber();
|
quint8 generateSequenceNumber();
|
||||||
|
|
||||||
@ -161,13 +162,21 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
Error m_error = ErrorNoError;
|
Error m_error = ErrorNoError;
|
||||||
ZigbeeNode *m_coordinatorNode = nullptr;
|
ZigbeeNode *m_coordinatorNode = nullptr;
|
||||||
bool m_permitJoining = false;
|
|
||||||
ZigbeeSecurityConfiguration m_securityConfiguration;
|
ZigbeeSecurityConfiguration m_securityConfiguration;
|
||||||
ZigbeeNetworkDatabase *m_database = nullptr;
|
ZigbeeNetworkDatabase *m_database = nullptr;
|
||||||
|
|
||||||
ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, QObject *parent);
|
ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, QObject *parent);
|
||||||
ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, quint8 macCapabilities, QObject *parent);
|
ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, quint8 macCapabilities, QObject *parent);
|
||||||
virtual void setPermitJoiningInternal(bool permitJoining) = 0;
|
|
||||||
|
// Permit join
|
||||||
|
QTimer *m_permitJoinTimer = nullptr;
|
||||||
|
bool m_permitJoiningEnabled = false;
|
||||||
|
quint8 m_permitJoiningDuration = 120;
|
||||||
|
quint8 m_permitJoiningRemaining = 0;
|
||||||
|
|
||||||
|
void setPermitJoiningEnabled(bool permitJoiningEnabled);
|
||||||
|
void setPermitJoiningDuration(quint8 duration);
|
||||||
|
void setPermitJoiningRemaining(quint8 remaining);
|
||||||
|
|
||||||
void loadNetwork();
|
void loadNetwork();
|
||||||
void clearSettings();
|
void clearSettings();
|
||||||
@ -208,7 +217,10 @@ signals:
|
|||||||
void nodeAdded(ZigbeeNode *node);
|
void nodeAdded(ZigbeeNode *node);
|
||||||
void nodeRemoved(ZigbeeNode *node);
|
void nodeRemoved(ZigbeeNode *node);
|
||||||
|
|
||||||
void permitJoiningChanged(bool permitJoining);
|
void permitJoiningEnabledChanged(bool permitJoiningEnabled);
|
||||||
|
void permitJoinDurationChanged(quint8 duration);
|
||||||
|
void permitJoinRemainingChanged(quint8 remaining);
|
||||||
|
|
||||||
void errorOccured(Error error);
|
void errorOccured(Error error);
|
||||||
void stateChanged(State state);
|
void stateChanged(State state);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user