Skip to content
Permalink
Browse files

Improve Zigbee network startup

In some setup the initial network formation fails due interference which
results in 'Not In Network' state. This commit will attempt to reconnect
the network repeadedly.

If the user requests to Leave the network the process is paused until Join
is clicked again.
  • Loading branch information
manup committed Oct 11, 2019
1 parent 30fad8f commit 7699c98d6d939130b62b96938c812b589a2a08cc
Showing with 42 additions and 13 deletions.
  1. +2 −1 database.cpp
  2. +18 −8 de_web_plugin.cpp
  3. +6 −4 de_web_plugin_private.h
  4. +16 −0 rest_configuration.cpp
@@ -963,7 +963,8 @@ static int sqliteLoadConfigCallback(void *user, int ncols, char **colval , char
}
else if (strcmp(colval[0], "rfconnect") == 0)
{
if (!val.isEmpty())
// only reload from database if auto reconnect is disabled
if (!val.isEmpty() && deCONZ::appArgumentNumeric("--auto-connect", 1) == 0)
{
int conn = val.toInt(&ok);
if (ok && ((conn == 0) || (conn == 1)))
@@ -14152,6 +14152,12 @@ void DeRestPlugin::idleTimerFired()

if (!d->isInNetwork())
{
// automatically try reconnect network
if (d->networkState == DeRestPluginPrivate::MaintainNetwork && d->gwRfConnectedExpected)
{
d->networkConnectedBefore = d->gwRfConnectedExpected;
d->startReconnectNetwork(RECONNECT_CHECK_DELAY);
}
return;
}

@@ -16037,11 +16043,6 @@ void DeRestPluginPrivate::pollDatabaseWifiTimerFired()

void DeRestPluginPrivate::restartAppTimerFired()
{
reconnectTimer = new QTimer(this);
reconnectTimer->setSingleShot(true);
connect(reconnectTimer, SIGNAL(timeout()),
this, SLOT(reconnectTimerFired()));

// deCONZ will be restarted after reconnect
genericDisconnectNetwork();
}
@@ -16182,7 +16183,7 @@ void DeRestPluginPrivate::pollNextDevice()
*/
void DeRestPluginPrivate::genericDisconnectNetwork()
{
DBG_Assert(apsCtrl != 0);
DBG_Assert(apsCtrl != nullptr);

if (!apsCtrl)
{
@@ -16225,7 +16226,7 @@ void DeRestPluginPrivate::checkNetworkDisconnected()
}
else
{
DBG_Assert(apsCtrl != 0);
DBG_Assert(apsCtrl != nullptr);
if (apsCtrl)
{
DBG_Printf(DBG_INFO, "disconnect from network failed, try again\n");
@@ -16244,6 +16245,14 @@ void DeRestPluginPrivate::checkNetworkDisconnected()
*/
void DeRestPluginPrivate::startReconnectNetwork(int delay)
{
if (!reconnectTimer)
{
reconnectTimer = new QTimer(this);
reconnectTimer->setSingleShot(true);
connect(reconnectTimer, SIGNAL(timeout()),
this, SLOT(reconnectTimerFired()));
}

networkState = ReconnectNetwork;
DBG_Printf(DBG_INFO_L2, "networkState: CC_ReconnectNetwork\n");
networkReconnectAttempts = NETWORK_ATTEMPS;
@@ -16309,7 +16318,8 @@ void DeRestPluginPrivate::reconnectNetwork()
}
else
{
DBG_Printf(DBG_INFO, "reconnect network failed\n");
DBG_Printf(DBG_INFO, "reconnect network failed, try later\n");
networkState = MaintainNetwork;
}
}

@@ -1018,6 +1018,7 @@ public Q_SLOTS:
void gpDataIndication(const deCONZ::GpDataIndication &ind);
void gpProcessButtonEvent(const deCONZ::GpDataIndication &ind);
void configurationChanged();
void networkStateChangeRequest(bool shouldConnect);
int taskCountForAddress(const deCONZ::Address &address);
void processTasks();
void processGroupTasks();
@@ -1614,14 +1615,15 @@ public Q_SLOTS:
uint8_t channelChangeApsRequestId;

// generic network reconnect state machine
enum networkReconnectState
enum NetworkReconnectState
{
DisconnectingNetwork,
ReconnectNetwork
ReconnectNetwork,
MaintainNetwork
};

QTimer *reconnectTimer;
networkReconnectState networkState;
QTimer *reconnectTimer = nullptr;
NetworkReconnectState networkState = MaintainNetwork;
int networkDisconnectAttempts;
int networkReconnectAttempts;
bool networkConnectedBefore;
@@ -231,6 +231,11 @@ void DeRestPluginPrivate::initConfig()

connect(deCONZ::ApsController::instance(), &deCONZ::ApsController::configurationChanged,
this, &DeRestPluginPrivate::configurationChanged);

#if DECONZ_LIB_VERSION >= 0x010C00
connect(deCONZ::ApsController::instance(), &deCONZ::ApsController::networkStateChangeRequest,
this, &DeRestPluginPrivate::networkStateChangeRequest);
#endif
}

/*! Init timezone. */
@@ -554,6 +559,17 @@ void DeRestPluginPrivate::configurationChanged()
}
}

/*! Network state change request received from deCONZ core (e.g. Join/Leave clicked)
*/
void DeRestPluginPrivate::networkStateChangeRequest(bool shouldConnect)
{
if (gwRfConnectedExpected != shouldConnect)
{
gwRfConnectedExpected = shouldConnect;
queSaveDb(DB_CONFIG, DB_SHORT_SAVE_DELAY);
}
}

/*! Configuration REST API broker.
\param req - request data
\param rsp - response data

0 comments on commit 7699c98

Please sign in to comment.
You can’t perform that action at this time.