Rework permit join mechanism and remove infinit joining

pull/11/head
Simon Stürz 2020-11-02 15:14:22 +01:00
parent 3d62162f5e
commit e46630f9e2
7 changed files with 223 additions and 176 deletions

View File

@ -46,10 +46,6 @@ ZigbeeNetworkDeconz::ZigbeeNetworkDeconz(const QUuid &networkUuid, QObject *pare
m_pollNetworkStateTimer->setSingleShot(false);
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
@ -95,7 +91,60 @@ ZigbeeNetworkReply *ZigbeeNetworkDeconz::sendRequest(const ZigbeeNetworkRequest
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(&parameterData, 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
ZigbeeNetworkRequest request;
@ -305,7 +354,7 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
m_database->saveNode(m_coordinatorNode);
m_initializing = false;
setState(StateRunning);
setPermitJoiningInternal(false);
setPermitJoining(0);
return;
}
@ -318,7 +367,7 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
m_initializing = false;
setState(StateRunning);
setPermitJoiningInternal(false);
setPermitJoining(0);
return;
}
});
@ -380,67 +429,10 @@ void ZigbeeNetworkDeconz::handleZigbeeClusterLibraryIndication(const Zigbee::Aps
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(&parameterData, 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()
{
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;
// Check if we have to create a pan ID and select the channel
if (panId() == 0 || !m_coordinatorNode) {
@ -525,7 +517,7 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
if (m_controller->networkState() == Deconz::NetworkStateConnected) {
qCDebug(dcZigbeeNetwork()) << "The network is already running.";
m_initializing = false;
setPermitJoining(false);
setPermitJoiningEnabled(false);
// Set the permit joining timeout network configuration parameter
QByteArray parameterData;
QDataStream stream(&parameterData, QIODevice::WriteOnly);
@ -563,18 +555,11 @@ void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
qCWarning(dcZigbeeNetwork()) << "Hardware controller is not available any more.";
setError(ErrorHardwareUnavailable);
m_initializing = false;
if (m_permitJoining != false) {
m_permitJoining = false;
emit permitJoiningChanged(m_permitJoining);
}
setPermitJoiningEnabled(false);
setState(StateOffline);
} else {
m_error = ErrorNoError;
if (m_permitJoining != false) {
m_permitJoining = false;
emit permitJoiningChanged(m_permitJoining);
}
emit permitJoiningChanged(m_permitJoining);
setPermitJoiningEnabled(false);
setState(StateStarting);
qCDebug(dcZigbeeNetwork()) << "Hardware controller is now available.";
startNetworkInternally();
@ -651,11 +636,6 @@ void ZigbeeNetworkDeconz::onPollNetworkStateTimeout()
}
}
void ZigbeeNetworkDeconz::onPermitJoinRefreshTimout()
{
setPermitJoiningInternal(true);
}
void ZigbeeNetworkDeconz::onApsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &confirm)
{
ZigbeeNetworkReply *reply = m_pendingReplies.value(confirm.requestId);
@ -705,22 +685,17 @@ void ZigbeeNetworkDeconz::startNetwork()
loadNetwork();
if (!m_controller->enable(serialPortName(), serialBaudrate())) {
m_permitJoining = false;
emit permitJoiningChanged(m_permitJoining);
setPermitJoiningEnabled(false);
setState(StateOffline);
setCreateNetworkState(CreateNetworkStateIdle);
setError(ErrorHardwareUnavailable);
return;
}
if (m_permitJoining != false) {
m_permitJoining = false;
emit permitJoiningChanged(m_permitJoining);
}
setPermitJoiningEnabled(false);
m_initializing = true;
// Note: wait for the controller available signal and start the initialization there
m_initializing = true;
}
void ZigbeeNetworkDeconz::stopNetwork()

View File

@ -57,7 +57,7 @@ public:
// Sending an APSDE-DATA.request, will be finished on APSDE-DATA.confirm
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:
ZigbeeBridgeControllerDeconz *m_controller = nullptr;
@ -66,13 +66,13 @@ private:
bool m_createNewNetwork = false;
bool m_initializing = false;
QTimer *m_permitJoinRefreshTimer = nullptr;
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
QTimer *m_pollNetworkStateTimer = nullptr;
void setCreateNetworkState(CreateNetworkState state);
ZigbeeNetworkReply *requestSetPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe);
// ZDO
void handleZigbeeDeviceProfileIndication(const Zigbee::ApsdeDataIndication &indication);
@ -80,13 +80,11 @@ private:
void handleZigbeeClusterLibraryIndication(const Zigbee::ApsdeDataIndication &indication);
protected:
void setPermitJoiningInternal(bool permitJoining) override;
void startNetworkInternally();
private slots:
void onControllerAvailableChanged(bool available);
void onPollNetworkStateTimeout();
void onPermitJoinRefreshTimout();
void onApsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &confirm);
void onApsDataIndicationReceived(const Zigbee::ApsdeDataIndication &indication);

View File

@ -55,13 +55,6 @@ ZigbeeNetworkNxp::ZigbeeNetworkNxp(const QUuid &networkUuid, QObject *parent) :
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
@ -118,7 +111,79 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::sendRequest(const ZigbeeNetworkRequest &re
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
ZigbeeNetworkRequest request;
@ -325,7 +390,7 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done.";
m_database->saveNode(m_coordinatorNode);
setPermitJoiningInternal(false);
setPermitJoining(0);
setState(StateRunning);
return;
}
@ -338,7 +403,7 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
if (state == ZigbeeNode::StateInitialized) {
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
setState(StateRunning);
setPermitJoiningInternal(false);
setPermitJoining(0);
return;
}
});
@ -500,62 +565,11 @@ void ZigbeeNetworkNxp::onDeviceAnnounced(quint16 shortAddress, ZigbeeAddress iee
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()
{
loadNetwork();
if (m_permitJoining != false) {
m_permitJoining = false;
emit permitJoiningChanged(m_permitJoining);
}
setPermitJoiningEnabled(false);
if (!m_controller->enable(serialPortName(), serialBaudrate())) {
setState(StateOffline);

View File

@ -45,7 +45,8 @@ public:
ZigbeeBridgeController *bridgeController() const override;
Zigbee::ZigbeeBackendType backendType() const 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:
ZigbeeBridgeControllerNxp *m_controller = nullptr;
@ -53,8 +54,6 @@ private:
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
int m_reconnectCounter = 0;
QTimer *m_permitJoinRefreshTimer = nullptr;
bool processVersionReply(ZigbeeInterfaceNxpReply *reply);
// ZDO
@ -63,6 +62,8 @@ private:
// ZCL
void handleZigbeeClusterLibraryIndication(const Zigbee::ApsdeDataIndication &indication);
ZigbeeNetworkReply *requestSetPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe);
private slots:
void onControllerAvailableChanged(bool available);
void onControllerStateChanged(ZigbeeBridgeControllerNxp::ControllerState controllerState);
@ -73,8 +74,6 @@ private slots:
void onDeviceAnnounced(quint16 shortAddress, ZigbeeAddress ieeeAddress, quint8 macCapabilities);
protected:
void setPermitJoiningInternal(bool permitJoining) override;
signals:

View File

@ -111,6 +111,6 @@ bool ZigbeeAddress::operator!=(const ZigbeeAddress &other) const
QDebug operator<<(QDebug debug, const ZigbeeAddress &address)
{
debug.nospace() << address.toString();
return debug.space();
debug << address.toString();
return debug;
}

View File

@ -38,7 +38,18 @@ ZigbeeNetwork::ZigbeeNetwork(const QUuid &networkUuid, QObject *parent) :
QObject(parent),
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
@ -191,14 +202,51 @@ void ZigbeeNetwork::setSecurityConfiguration(const ZigbeeSecurityConfiguration &
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()
@ -407,7 +455,7 @@ void ZigbeeNetwork::clearSettings()
if (!m_database->wipeDatabase()) {
qCWarning(dcZigbeeNetwork()) << "Failed to wipe the network database" << m_database->databaseName();
}
m_database->deleteLater();
delete m_database;
m_database = nullptr;
}
@ -417,6 +465,7 @@ void ZigbeeNetwork::clearSettings()
setChannel(0);
setSecurityConfiguration(ZigbeeSecurityConfiguration());
setState(StateUninitialized);
setPermitJoiningEnabled(false);
m_nodeType = ZigbeeDeviceProfile::NodeTypeCoordinator;
}
@ -582,11 +631,11 @@ void ZigbeeNetwork::onNodeClusterAttributeChanged(ZigbeeCluster *cluster, const
QDebug operator<<(QDebug debug, ZigbeeNetwork *network)
{
debug.nospace().noquote() << "ZigbeeNetwork(" << network->macAddress() << ", "
debug.nospace().noquote() << "ZigbeeNetwork(" << network->macAddress().toString() << ", "
<< network->networkUuid().toString() << ", "
<< network->backendType() << ", "
<< "Channel: " << network->channel() << ", "
<< network->state()
<< ")";
return debug.space();
<< ") ";
return debug;
}

View File

@ -107,9 +107,10 @@ public:
ZigbeeSecurityConfiguration securityConfiguration() const;
void setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration);
bool permitJoining() const;
void setPermitJoining(bool permitJoining);
bool permitJoiningEnabled() const;
quint8 permitJoiningDuration() const;
quint8 permitJoiningRemaining() const;
virtual void setPermitJoining(quint8 duration, quint16 address = Zigbee::BroadcastAddressAllRouters) = 0;
quint8 generateSequenceNumber();
@ -161,13 +162,21 @@ private:
protected:
Error m_error = ErrorNoError;
ZigbeeNode *m_coordinatorNode = nullptr;
bool m_permitJoining = false;
ZigbeeSecurityConfiguration m_securityConfiguration;
ZigbeeNetworkDatabase *m_database = nullptr;
ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, 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 clearSettings();
@ -208,7 +217,10 @@ signals:
void nodeAdded(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 stateChanged(State state);