Implement auto setup platform mechanism and add uart serialnumber verification

This commit is contained in:
Simon Stürz 2020-12-18 15:35:57 +01:00
parent e32622dd2f
commit 5ab371afdc
2 changed files with 89 additions and 22 deletions

View File

@ -67,6 +67,22 @@ ZigbeeManager::ZigbeeManager(QObject *parent) :
qCDebug(dcZigbee()) << "Adapter added" << adapter; qCDebug(dcZigbee()) << "Adapter added" << adapter;
m_adapters.append(adapter); m_adapters.append(adapter);
if (m_autoSetupAdapters) {
if (networkExistsForAdapter(uartAdapter)) {
qCDebug(dcZigbee()) << "Auto setup enabled. There is already a network configured for" << uartAdapter;
} else {
qCDebug(dcZigbee()) << "Auto setup enabled. No network for" << uartAdapter << "created yet. Creating network...";
ZigbeeNetwork *network = createPlatformNetwork(uartAdapter.serialPort(), uartAdapter.baudRate(), uartAdapter.zigbeeBackend());
if (!uartAdapter.serialNumber().isEmpty())
network->setSerialNumber(uartAdapter.serialNumber());
addNetwork(network);
network->startNetwork();
}
}
// FIXME: check if serial number available and gets used by a network (adjust serial port if changed) // FIXME: check if serial number available and gets used by a network (adjust serial port if changed)
emit availableAdapterAdded(adapter); emit availableAdapterAdded(adapter);
@ -88,6 +104,23 @@ ZigbeeManager::ZigbeeManager(QObject *parent) :
// Check if we have a zigbee platform configuration and if we have to create the platform network automatically // Check if we have a zigbee platform configuration and if we have to create the platform network automatically
checkPlatformConfiguration(); checkPlatformConfiguration();
// Check if auto setup recognized adapters is enabled
if (m_autoSetupAdapters) {
qCDebug(dcZigbee()) << "Auto setup enabled. Verify existing networks and adapters...";
foreach(const ZigbeeUartAdapter &uartAdapter, m_adapterMonitor->availableAdapters()) {
if (networkExistsForAdapter(uartAdapter)) {
qCDebug(dcZigbee()) << "Network for adapter" << uartAdapter << "already created.";
} else {
qCDebug(dcZigbee()) << "Auto setup enabled and there is no network for" << uartAdapter << "created yet. Creating network...";
ZigbeeNetwork *network = createPlatformNetwork(uartAdapter.serialPort(), uartAdapter.baudRate(), uartAdapter.zigbeeBackend());
if (!uartAdapter.serialNumber().isEmpty())
network->setSerialNumber(uartAdapter.serialNumber());
addNetwork(network);
}
}
}
// Start all loaded networks // Start all loaded networks
foreach (ZigbeeNetwork *network, m_zigbeeNetworks.values()) { foreach (ZigbeeNetwork *network, m_zigbeeNetworks.values()) {
network->startNetwork(); network->startNetwork();
@ -126,20 +159,23 @@ QPair<ZigbeeManager::ZigbeeError, QUuid> ZigbeeManager::createZigbeeNetwork(cons
} }
} }
if (!m_adapters.hasSerialPort(serialPort)) { if (!m_adapters.hasSerialPort(serialPort)) {
qCWarning(dcZigbee()) << "Failed to create a network for" << serialPort << "because the adapter is not available any more"; qCWarning(dcZigbee()) << "Failed to create a network for" << serialPort << "because the adapter is not available any more";
return QPair<ZigbeeManager::ZigbeeError, QUuid>(ZigbeeManager::ZigbeeErrorAdapterNotAvailable, QUuid()); return QPair<ZigbeeManager::ZigbeeError, QUuid>(ZigbeeManager::ZigbeeErrorAdapterNotAvailable, QUuid());
} }
// ZigbeeChannelMask testChannelMask = ZigbeeChannelMask(0); QString serialNumber;
// testChannelMask.setChannel(Zigbee::ZigbeeChannel13); foreach (const ZigbeeAdapter &adapter, m_adapters) {
// qCWarning(dcZigbee()) << "Using test channel mask" << testChannelMask; if (adapter.serialPort() == serialPort && !adapter.serialNumber().isEmpty()) {
serialNumber = adapter.serialNumber();
}
}
ZigbeeNetwork *network = buildNetworkObject(QUuid::createUuid(), backendType); ZigbeeNetwork *network = buildNetworkObject(QUuid::createUuid(), backendType);
network->setChannelMask(channelMask); network->setChannelMask(channelMask);
network->setSerialPortName(serialPort); network->setSerialPortName(serialPort);
network->setSerialBaudrate(baudRate); network->setSerialBaudrate(baudRate);
network->setSerialNumber(serialNumber);
addNetwork(network); addNetwork(network);
qCDebug(dcZigbee()) << "Starting" << network; qCDebug(dcZigbee()) << "Starting" << network;
@ -240,8 +276,9 @@ void ZigbeeManager::saveNetwork(ZigbeeNetwork *network)
settings.setValue("channelMask", network->channelMask().toUInt32()); settings.setValue("channelMask", network->channelMask().toUInt32());
settings.setValue("networkKey", network->securityConfiguration().networkKey().toString()); settings.setValue("networkKey", network->securityConfiguration().networkKey().toString());
settings.setValue("trustCenterLinkKey", network->securityConfiguration().globalTrustCenterLinkKey().toString()); settings.setValue("trustCenterLinkKey", network->securityConfiguration().globalTrustCenterLinkKey().toString());
if (!network->serialNumber().isEmpty()) {
// FIXME: save also the serial number of the port if available. settings.setValue("serialNumber", network->serialNumber());
}
settings.endGroup(); // networkUuid settings.endGroup(); // networkUuid
settings.endGroup(); // ZigbeeNetworks settings.endGroup(); // ZigbeeNetworks
@ -259,6 +296,7 @@ void ZigbeeManager::loadZigbeeNetworks()
QUuid networkUuid = QUuid(networkUuidGroupString); QUuid networkUuid = QUuid(networkUuidGroupString);
QString serialPortName = settings.value("serialPort").toString(); QString serialPortName = settings.value("serialPort").toString();
QString serialNumber = settings.value("serialNumber").toString();
qint32 serialBaudRate = settings.value("baudRate").toInt(); qint32 serialBaudRate = settings.value("baudRate").toInt();
ZigbeeAdapter::ZigbeeBackendType backendType = static_cast<ZigbeeAdapter::ZigbeeBackendType>(settings.value("backendType").toInt()); ZigbeeAdapter::ZigbeeBackendType backendType = static_cast<ZigbeeAdapter::ZigbeeBackendType>(settings.value("backendType").toInt());
quint16 panId = static_cast<quint16>(settings.value("panId", 0).toUInt()); quint16 panId = static_cast<quint16>(settings.value("panId", 0).toUInt());
@ -279,6 +317,7 @@ void ZigbeeManager::loadZigbeeNetworks()
ZigbeeNetwork *network = buildNetworkObject(networkUuid, backendType); ZigbeeNetwork *network = buildNetworkObject(networkUuid, backendType);
network->setSerialPortName(serialPortName); network->setSerialPortName(serialPortName);
network->setSerialBaudrate(serialBaudRate); network->setSerialBaudrate(serialBaudRate);
network->setSerialNumber(serialNumber);
network->setMacAddress(macAddress); network->setMacAddress(macAddress);
network->setPanId(panId); network->setPanId(panId);
network->setChannel(channel); network->setChannel(channel);
@ -304,21 +343,33 @@ void ZigbeeManager::loadZigbeeNetworks()
void ZigbeeManager::checkPlatformConfiguration() void ZigbeeManager::checkPlatformConfiguration()
{ {
/* Example platform configurations /* Example platform configurations
* *
* serialPort=/dev/ttymxc2 * serialPort=/dev/ttymxc2
* baudRate=115200 * baudRate=115200
* backend=nxp * backend=nxp
* * autoSetup=false
* serialPort=/dev/ttyS0 *
* baudRate=38400 * serialPort=/dev/ttyS0
* backend=deconz * baudRate=38400
*/ * backend=deconz
* autoSetup=false
*
* autoSetup=true
*/
QFileInfo platformConfigurationFileInfo(NymeaSettings::settingsPath() + QDir::separator() + "zigbee-platform.conf"); QFileInfo platformConfigurationFileInfo(NymeaSettings::settingsPath() + QDir::separator() + "zigbee-platform.conf");
if (platformConfigurationFileInfo.exists()) { if (platformConfigurationFileInfo.exists()) {
qCDebug(dcZigbee()) << "Found zigbee platform configuration" << platformConfigurationFileInfo.absoluteFilePath(); qCDebug(dcZigbee()) << "Found zigbee platform configuration" << platformConfigurationFileInfo.absoluteFilePath();
QSettings platformSettings(platformConfigurationFileInfo.absoluteFilePath(), QSettings::IniFormat); QSettings platformSettings(platformConfigurationFileInfo.absoluteFilePath(), QSettings::IniFormat);
QString serialPort = platformSettings.value("serialPort").toString(); QString serialPort = platformSettings.value("serialPort").toString();
qint32 baudRate = platformSettings.value("baudRate").toUInt();
QString backendString = platformSettings.value("backend").toString();
m_autoSetupAdapters = platformSettings.value("autoSetup").toBool();
Zigbee::ZigbeeBackendType backenType = Zigbee::ZigbeeBackendTypeNxp;
if (backendString.toLower().contains("deconz")) {
backenType = Zigbee::ZigbeeBackendTypeDeconz;
}
if (serialPort.isEmpty()) { if (serialPort.isEmpty()) {
qCWarning(dcZigbee()) << "The serial port is not specified correctly in the platform configuration file" << platformConfigurationFileInfo.absoluteFilePath() << "The platform based network will not be created."; qCWarning(dcZigbee()) << "The serial port is not specified correctly in the platform configuration file" << platformConfigurationFileInfo.absoluteFilePath() << "The platform based network will not be created.";
return; return;
@ -329,13 +380,6 @@ void ZigbeeManager::checkPlatformConfiguration()
return; return;
} }
qint32 baudRate = platformSettings.value("baudRate").toUInt();
QString backendString = platformSettings.value("backend").toString();
Zigbee::ZigbeeBackendType backenType = Zigbee::ZigbeeBackendTypeNxp;
if (backendString.toLower().contains("deconz")) {
backenType = Zigbee::ZigbeeBackendTypeDeconz;
}
bool alreadyCreated = false; bool alreadyCreated = false;
foreach (ZigbeeNetwork *network, m_zigbeeNetworks.values()) { foreach (ZigbeeNetwork *network, m_zigbeeNetworks.values()) {
if (network->serialPortName() == serialPort && network->serialBaudrate() == baudRate && network->backendType() == backenType) { if (network->serialPortName() == serialPort && network->serialBaudrate() == baudRate && network->backendType() == backenType) {
@ -356,6 +400,27 @@ void ZigbeeManager::checkPlatformConfiguration()
} }
} }
bool ZigbeeManager::networkExistsForAdapter(const ZigbeeUartAdapter &uartAdapter)
{
bool networkCreated = false;
foreach (ZigbeeNetwork *network, m_zigbeeNetworks) {
// Use the serial number if possible as refference
if (!uartAdapter.serialNumber().isEmpty()) {
if (network->serialNumber() == uartAdapter.serialNumber()) {
networkCreated = true;
break;
}
}
// Otherwise check the serial port
if (network->serialPortName() == uartAdapter.serialPort()) {
networkCreated = true;
break;
}
}
return networkCreated;
}
ZigbeeNetwork *ZigbeeManager::createPlatformNetwork(const QString &serialPort, uint baudRate, Zigbee::ZigbeeBackendType backendType, ZigbeeChannelMask channelMask) ZigbeeNetwork *ZigbeeManager::createPlatformNetwork(const QString &serialPort, uint baudRate, Zigbee::ZigbeeBackendType backendType, ZigbeeChannelMask channelMask)
{ {
qCDebug(dcZigbee()) << "Creating platform network on" << serialPort << baudRate << backendType << channelMask; qCDebug(dcZigbee()) << "Creating platform network on" << serialPort << baudRate << backendType << channelMask;

View File

@ -83,10 +83,12 @@ private:
QHash<QUuid, ZigbeeNetwork *> m_zigbeeNetworks; QHash<QUuid, ZigbeeNetwork *> m_zigbeeNetworks;
bool m_available = false; bool m_available = false;
bool m_autoSetupAdapters = false;
void saveNetwork(ZigbeeNetwork *network); void saveNetwork(ZigbeeNetwork *network);
void loadZigbeeNetworks(); void loadZigbeeNetworks();
void checkPlatformConfiguration(); void checkPlatformConfiguration();
bool networkExistsForAdapter(const ZigbeeUartAdapter &uartAdapter);
ZigbeeNetwork *createPlatformNetwork(const QString &serialPort, uint baudRate, Zigbee::ZigbeeBackendType backendType, ZigbeeChannelMask channelMask = ZigbeeChannelMask(ZigbeeChannelMask::ChannelConfigurationAllChannels)); ZigbeeNetwork *createPlatformNetwork(const QString &serialPort, uint baudRate, Zigbee::ZigbeeBackendType backendType, ZigbeeChannelMask channelMask = ZigbeeChannelMask(ZigbeeChannelMask::ChannelConfigurationAllChannels));
ZigbeeNetwork *buildNetworkObject(const QUuid &networkId, ZigbeeAdapter::ZigbeeBackendType backendType); ZigbeeNetwork *buildNetworkObject(const QUuid &networkId, ZigbeeAdapter::ZigbeeBackendType backendType);