Add mode selection and improve overall behaviour

This commit is contained in:
Simon Stürz 2018-06-28 20:38:52 +02:00
parent a9d68d231b
commit a88e9a1131
9 changed files with 384 additions and 156 deletions

View File

@ -30,6 +30,10 @@
NetworkManager::NetworkManager(QObject *parent) :
QObject(parent)
{
// Get notification when network-manager appears/disappears on DBus
m_serviceWatcher = new QDBusServiceWatcher(NetworkManagerUtils::networkManagerServiceString(), QDBusConnection::systemBus(), QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, this);
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &NetworkManager::onServiceRegistered);
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &NetworkManager::onServiceUnregistered);
}
@ -229,6 +233,83 @@ bool NetworkManager::enableWireless(bool enabled)
return m_networkManagerInterface->setProperty("WirelessEnabled", enabled);
}
bool NetworkManager::init()
{
if (!m_enabled)
return false;
qCDebug(dcNetworkManager()) << "Initialize network manager";
// Check DBus connection
if (!QDBusConnection::systemBus().isConnected()) {
qCWarning(dcNetworkManager()) << "System DBus not connected. NetworkManagre not available.";
setAvailable(false);
return false;
}
// Create interface
m_networkManagerInterface = new QDBusInterface(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), QDBusConnection::systemBus(), this);
if(!m_networkManagerInterface->isValid()) {
qCWarning(dcNetworkManager()) << "Invalid DBus network manager interface. NetworkManagre not available.";
m_networkManagerInterface->deleteLater();
m_networkManagerInterface = nullptr;
setAvailable(false);
return false;
}
// Init properties
setVersion(m_networkManagerInterface->property("Version").toString());
setState((NetworkManagerState)m_networkManagerInterface->property("State").toUInt());
setConnectivityState((NetworkManagerConnectivityState)m_networkManagerInterface->property("Connectivity").toUInt());
setNetworkingEnabled(m_networkManagerInterface->property("NetworkingEnabled").toBool());
setWirelessEnabled(m_networkManagerInterface->property("WirelessEnabled").toBool());
// Load network devices
loadDevices();
// Create settings
m_networkSettings = new NetworkSettings(this);
// Connect signals
QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "StateChanged", this, SLOT(onStateChanged(uint)));
QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "DeviceAdded", this, SLOT(onDeviceAdded(QDBusObjectPath)));
QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "DeviceRemoved", this, SLOT(onDeviceRemoved(QDBusObjectPath)));
QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "PropertiesChanged", this, SLOT(onPropertiesChanged(QVariantMap)));
setAvailable(true);
qCDebug(dcNetworkManager()) << "Network manager initialized successfully.";
return true;
}
void NetworkManager::deinit()
{
foreach (NetworkDevice *device, m_networkDevices) {
onDeviceRemoved(device->objectPath());
}
m_wiredNetworkDevices.clear();
m_wirelessNetworkDevices.clear();
if (m_networkSettings) {
delete m_networkSettings;
m_networkSettings = nullptr;
}
if (m_networkManagerInterface) {
delete m_networkManagerInterface;
m_networkManagerInterface = nullptr;
}
setVersion(QString());
setState(NetworkManagerStateUnknown);
setConnectivityState(NetworkManagerConnectivityStateUnknown);
setNetworkingEnabled(false);
setWirelessEnabled(false);
setAvailable(false);
qCDebug(dcNetworkManager()) << "Netowkmanager deinitialized successfully.";
}
void NetworkManager::loadDevices()
{
// Get network devices
@ -271,7 +352,7 @@ void NetworkManager::setAvailable(bool available)
if (m_available == available)
return;
qCDebug(dcNetworkManager()) << "Service is now" << (available ? "available" : "unavailable");
qCDebug(dcNetworkManager()) << "The network manager is now" << (available ? "available" : "unavailable");
m_available = available;
emit availableChanged(m_available);
}
@ -319,13 +400,13 @@ void NetworkManager::setState(const NetworkManager::NetworkManagerState &state)
void NetworkManager::onServiceRegistered()
{
qCDebug(dcNetworkManager()) << "DBus service registered and available.";
// TODO: init stuff
init();
}
void NetworkManager::onServiceUnregistered()
{
qCWarning(dcNetworkManager()) << "DBus service unregistered.";
// TODO: deinit stuff
deinit();
}
void NetworkManager::onDeviceAdded(const QDBusObjectPath &deviceObjectPath)
@ -432,84 +513,29 @@ void NetworkManager::onWiredDeviceChanged()
bool NetworkManager::start()
{
// Get notification when network-manager appears/disappears on DBus
m_serviceWatcher = new QDBusServiceWatcher(NetworkManagerUtils::networkManagerServiceString(), QDBusConnection::systemBus(), QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, this);
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &NetworkManager::onServiceRegistered);
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &NetworkManager::onServiceUnregistered);
// We want the networkmanager to run, so enable it
m_enabled = true;
// Check DBus connection
if (!QDBusConnection::systemBus().isConnected()) {
qCWarning(dcNetworkManager()) << "System DBus not connected. NetworkManagre not available.";
m_serviceWatcher->deleteLater();
m_serviceWatcher = nullptr;
return false;
qCDebug(dcNetworkManager()) << "Start the network manager.";
if (m_available) {
qCDebug(dcNetworkManager()) << "Networkmanager already running.";
return true;
}
// Create interface
m_networkManagerInterface = new QDBusInterface(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), QDBusConnection::systemBus(), this);
if(!m_networkManagerInterface->isValid()) {
qCWarning(dcNetworkManager()) << "Invalid DBus network manager interface. NetworkManagre not available.";
m_serviceWatcher->deleteLater();
m_serviceWatcher = nullptr;
m_networkManagerInterface->deleteLater();
m_networkManagerInterface = nullptr;
return false;
}
// Init properties
setVersion(m_networkManagerInterface->property("Version").toString());
setState((NetworkManagerState)m_networkManagerInterface->property("State").toUInt());
setConnectivityState((NetworkManagerConnectivityState)m_networkManagerInterface->property("Connectivity").toUInt());
setNetworkingEnabled(m_networkManagerInterface->property("NetworkingEnabled").toBool());
setWirelessEnabled(m_networkManagerInterface->property("WirelessEnabled").toBool());
// Load network devices
loadDevices();
// Create settings
m_networkSettings = new NetworkSettings(this);
// Connect signals
QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "StateChanged", this, SLOT(onStateChanged(uint)));
QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "DeviceAdded", this, SLOT(onDeviceAdded(QDBusObjectPath)));
QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "DeviceRemoved", this, SLOT(onDeviceRemoved(QDBusObjectPath)));
QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "PropertiesChanged", this, SLOT(onPropertiesChanged(QVariantMap)));
setAvailable(true);
return true;
return init();
}
void NetworkManager::stop()
{
foreach (NetworkDevice *device, m_networkDevices) {
onDeviceRemoved(device->objectPath());
// We want the networkmanager to stop, so disable it
m_enabled = false;
qCDebug(dcNetworkManager()) << "Stop the network manager.";
if (!m_available) {
qCDebug(dcNetworkManager()) << "Networkmanager already stopped.";
return;
}
m_wiredNetworkDevices.clear();
m_wirelessNetworkDevices.clear();
if (m_networkSettings) {
delete m_networkSettings;
m_networkSettings = nullptr;
}
if (m_networkManagerInterface) {
delete m_networkManagerInterface;
m_networkManagerInterface = nullptr;
}
if (m_serviceWatcher) {
delete m_serviceWatcher;
m_serviceWatcher = nullptr;
}
m_version = QString();
m_state = NetworkManagerStateUnknown;
m_connectivityState = NetworkManagerConnectivityStateUnknown;
m_networkingEnabled = false;
m_wirelessEnabled = false;
setAvailable(false);
deinit();
}

View File

@ -118,12 +118,17 @@ private:
QHash<QDBusObjectPath, WiredNetworkDevice *> m_wiredNetworkDevices;
bool m_available = false;
bool m_enabled = false;
QString m_version;
NetworkManagerState m_state = NetworkManagerStateUnknown;
NetworkManagerConnectivityState m_connectivityState = NetworkManagerConnectivityStateUnknown;
bool m_networkingEnabled = false;
bool m_wirelessEnabled = false;
bool init();
void deinit();
void loadDevices();
static QString networkManagerStateToString(const NetworkManagerState &state);

View File

@ -342,7 +342,7 @@ void BluetoothServer::serviceError(const QLowEnergyService::ServiceError &error)
qCWarning(dcBluetoothServer()) << "Service error:" << errorString;
}
void BluetoothServer::start(WirelessNetworkDevice *wirelessDevice)
void BluetoothServer::start()
{
// Check if a user is connected
if (connected()) {
@ -391,26 +391,7 @@ void BluetoothServer::start(WirelessNetworkDevice *wirelessDevice)
// Create services
m_networkService = new NetworkService(m_controller->addService(NetworkService::serviceData(), m_controller), m_controller);
m_wirelessService = new WirelessService(m_controller->addService(WirelessService::serviceData(), m_controller), wirelessDevice, m_controller);
startAdvertising();
}
void BluetoothServer::restartServer()
{
qCDebug(dcBluetoothServer()) << "-------------------------------------";
qCDebug(dcBluetoothServer()) << "Restart bluetooth server";
qCDebug(dcBluetoothServer()) << "-------------------------------------";
if (!m_controller || !m_localDevice) {
qCWarning(dcBluetoothServer()) << "Could not restart server. There is no controller object or local device object.";
return;
}
if (m_controller->state() == QLowEnergyController::AdvertisingState) {
qCDebug(dcBluetoothServer()) << "Stop advertising;";
m_controller->stopAdvertising();
}
m_wirelessService = new WirelessService(m_controller->addService(WirelessService::serviceData(), m_controller), m_controller);
startAdvertising();
}
@ -421,10 +402,23 @@ void BluetoothServer::stop()
m_controller->disconnectFromDevice();
}
if (!m_running)
return;
qCDebug(dcBluetoothServer()) << "-------------------------------------";
qCDebug(dcBluetoothServer()) << "Stopping bluetooth server.";
qCDebug(dcBluetoothServer()) << "-------------------------------------";
if (m_networkService) {
m_networkService->deleteLater();
m_networkService = nullptr;
}
if (m_wirelessService) {
m_wirelessService->deleteLater();
m_wirelessService = nullptr;
}
if (m_controller) {
qCDebug(dcBluetoothServer()) << "Stop advertising.";
m_controller->stopAdvertising();
@ -435,10 +429,11 @@ void BluetoothServer::stop()
if (m_localDevice) {
qCDebug(dcBluetoothServer()) << "Set host mode to connectable.";
m_localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable);
delete m_localDevice;
m_localDevice->deleteLater();
m_localDevice = nullptr;
}
setConnected(false);
setRunning(false);
}
@ -467,3 +462,15 @@ void BluetoothServer::onNetworkManagerStateChanged(const NetworkManager::Network
m_networkService->setNetworkManagerState(state);
}
void BluetoothServer::onWirelessDeviceBitRateChanged(int bitRate)
{
if (m_wirelessService)
m_wirelessService->onWirelessDeviceBitRateChanged(bitRate);
}
void BluetoothServer::onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state)
{
if (m_wirelessService)
m_wirelessService->onWirelessDeviceStateChanged(state);
}

View File

@ -109,8 +109,7 @@ private slots:
void serviceError(const QLowEnergyService::ServiceError &error);
public slots:
void start(WirelessNetworkDevice *wirelessDevice);
void restartServer();
void start();
void stop();
// Network manager
@ -119,6 +118,10 @@ public slots:
void onWirelessNetworkingEnabledChanged(bool enabled);
void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state);
// Wireless device
void onWirelessDeviceBitRateChanged(int bitRate);
void onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state);
};
#endif // BLUETOOTHSERVER_H

View File

@ -30,10 +30,9 @@
#include <QLowEnergyDescriptorData>
#include <QLowEnergyCharacteristicData>
WirelessService::WirelessService(QLowEnergyService *service, WirelessNetworkDevice *wirelessDevice, QObject *parent) :
WirelessService::WirelessService(QLowEnergyService *service, QObject *parent) :
QObject(parent),
m_service(service),
m_device(wirelessDevice),
m_readingInputData(false)
{
qCDebug(dcBluetoothServer()) << "Create WirelessService.";
@ -44,10 +43,6 @@ WirelessService::WirelessService(QLowEnergyService *service, WirelessNetworkDevi
connect(m_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic, QByteArray)), this, SLOT(characteristicWritten(QLowEnergyCharacteristic, QByteArray)));
connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor, QByteArray)), this, SLOT(descriptorWritten(QLowEnergyDescriptor, QByteArray)));
connect(m_service, SIGNAL(error(QLowEnergyService::ServiceError)), this, SLOT(serviceError(QLowEnergyService::ServiceError)));
qCDebug(dcBluetoothServer()) << "WirelessService: Using" << m_device;
connect(m_device, &WirelessNetworkDevice::bitRateChanged, this, &WirelessService::onWirelessDeviceBitRateChanged);
connect(m_device, &WirelessNetworkDevice::stateChanged, this, &WirelessService::onWirelessDeviceStateChanged);
}
QLowEnergyService *WirelessService::service()
@ -99,7 +94,7 @@ WirelessService::WirelessServiceResponse WirelessService::checkWirelessErrors()
return WirelessServiceResponseNetworkManagerNotAvailable;
}
if (!m_device) {
if (!Core::instance()->networkManager()->wirelessAvailable()) {
qCWarning(dcBluetoothServer()) << "WirelessService: There is no wireless device available.";
return WirelessServiceResponseWirelessNotAvailable;
}
@ -203,7 +198,7 @@ void WirelessService::commandGetNetworks(const QVariantMap &request)
}
QVariantList accessPointVariantList;
foreach (WirelessAccessPoint *accessPoint, m_device->accessPoints()) {
foreach (WirelessAccessPoint *accessPoint, Core::instance()->networkManager()->wirelessNetworkDevices().first()->accessPoints()) {
QVariantMap accessPointVariantMap;
accessPointVariantMap.insert("e", accessPoint->ssid());
accessPointVariantMap.insert("m", accessPoint->macAddress());
@ -244,7 +239,7 @@ void WirelessService::commandConnect(const QVariantMap &request)
return;
}
Core::instance()->networkManager()->connectWifi(m_device->interface(), parameters.value("e").toString(), parameters.value("p").toString());
Core::instance()->networkManager()->connectWifi(Core::instance()->networkManager()->wirelessNetworkDevices().first()->interface(), parameters.value("e").toString(), parameters.value("p").toString());
streamData(createResponse(WirelessServiceCommandConnect));
}
@ -260,7 +255,7 @@ void WirelessService::commandDisconnect(const QVariantMap &request)
Q_UNUSED(request)
if (!m_service) {
qCWarning(dcBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid";
qCWarning(dcBluetoothServer()) << "WirelessService: Service not valid";
return;
}
@ -270,7 +265,7 @@ void WirelessService::commandDisconnect(const QVariantMap &request)
return;
}
m_device->disconnectDevice();
Core::instance()->networkManager()->wirelessNetworkDevices().first()->disconnectDevice();
streamData(createResponse(WirelessServiceCommandDisconnect));
}
@ -278,8 +273,10 @@ void WirelessService::commandScan(const QVariantMap &request)
{
Q_UNUSED(request)
qCDebug(dcBluetoothServer()) << "WirelessService: Execute command scan.";
if (!m_service) {
qCWarning(dcBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid";
qCWarning(dcBluetoothServer()) << "WirelessService: Could scan wireless networks. Service not valid";
return;
}
@ -289,16 +286,17 @@ void WirelessService::commandScan(const QVariantMap &request)
return;
}
m_device->scanWirelessNetworks();
Core::instance()->networkManager()->wirelessNetworkDevices().first()->scanWirelessNetworks();
streamData(createResponse(WirelessServiceCommandScan));
}
void WirelessService::commandGetCurrentConnection(const QVariantMap &request)
{
Q_UNUSED(request)
qCDebug(dcBluetoothServer()) << "WirelessService: Execute get current connection.";
if (!m_service) {
qCWarning(dcBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid";
qCWarning(dcBluetoothServer()) << "WirelessService: Service not valid";
return;
}
@ -308,10 +306,12 @@ void WirelessService::commandGetCurrentConnection(const QVariantMap &request)
return;
}
WirelessNetworkDevice *device = Core::instance()->networkManager()->wirelessNetworkDevices().first();
QVariantMap connectionDataMap;
QNetworkInterface wifiInterface = QNetworkInterface::interfaceFromName(m_device->interface());
if (!m_device->activeAccessPoint() || !wifiInterface.isValid() || wifiInterface.addressEntries().isEmpty()) {
qCDebug(dcBluetoothServer()) << "There is currently no access active accesspoint";
QNetworkInterface wifiInterface = QNetworkInterface::interfaceFromName(device->interface());
if (!device->activeAccessPoint() || !wifiInterface.isValid() || wifiInterface.addressEntries().isEmpty()) {
qCDebug(dcBluetoothServer()) << "WirelessService: There is currently no access active accesspoint";
connectionDataMap.insert("e", "");
connectionDataMap.insert("m", "");
connectionDataMap.insert("s", 0);
@ -319,11 +319,11 @@ void WirelessService::commandGetCurrentConnection(const QVariantMap &request)
connectionDataMap.insert("i", "");
} else {
QHostAddress address = wifiInterface.addressEntries().first().ip();
qCDebug(dcBluetoothServer()) << "Current connection:" << m_device->activeAccessPoint() << address.toString();
connectionDataMap.insert("e", m_device->activeAccessPoint()->ssid());
connectionDataMap.insert("m", m_device->activeAccessPoint()->macAddress());
connectionDataMap.insert("s", m_device->activeAccessPoint()->signalStrength());
connectionDataMap.insert("p", (int)m_device->activeAccessPoint()->isProtected());
qCDebug(dcBluetoothServer()) << "WirelessService: Current connection:" << device->activeAccessPoint() << address.toString();
connectionDataMap.insert("e", device->activeAccessPoint()->ssid());
connectionDataMap.insert("m", device->activeAccessPoint()->macAddress());
connectionDataMap.insert("s", device->activeAccessPoint()->signalStrength());
connectionDataMap.insert("p", (int)device->activeAccessPoint()->isProtected());
connectionDataMap.insert("i", address.toString());
}
@ -483,8 +483,6 @@ void WirelessService::onWirelessDeviceBitRateChanged(const int &bitRate)
void WirelessService::onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState &state)
{
qCDebug(dcBluetoothServer()) << "WirelessService: Wireless network device state changed" << state;
if (!m_service) {
qCWarning(dcBluetoothServer()) << "WirelessService: Could not update wireless network device state. Service not valid";
return;
@ -496,5 +494,6 @@ void WirelessService::onWirelessDeviceStateChanged(const NetworkDevice::NetworkD
return;
}
qCDebug(dcBluetoothServer()) << "WirelessService: Notify wireless state changed" << WirelessService::getWirelessNetworkDeviceState(state);
m_service->writeCharacteristic(characteristic, WirelessService::getWirelessNetworkDeviceState(state));
}

View File

@ -61,7 +61,7 @@ public:
};
Q_ENUM(WirelessServiceResponse)
explicit WirelessService(QLowEnergyService *service, WirelessNetworkDevice *wirelessDevice, QObject *parent = 0);
explicit WirelessService(QLowEnergyService *service, QObject *parent = 0);
QLowEnergyService *service();
@ -69,7 +69,6 @@ public:
private:
QLowEnergyService *m_service = nullptr;
WirelessNetworkDevice *m_device = nullptr;
bool m_readingInputData = false;
QByteArray m_inputDataStream;
@ -104,6 +103,7 @@ private slots:
// Commands
void processCommand(const QVariantMap &request);
public slots:
// Wireless network device
void onWirelessDeviceBitRateChanged(const int &bitRate);
void onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState &state);

View File

@ -22,6 +22,8 @@
#include "core.h"
#include "loggingcategories.h"
#include <QTimer>
Core* Core::s_instance = nullptr;
Core *Core::instance()
@ -55,6 +57,16 @@ NymeadService *Core::nymeaService() const
return m_nymeaService;
}
Core::Mode Core::mode() const
{
return m_mode;
}
void Core::setMode(const Core::Mode &mode)
{
m_mode = mode;
}
QString Core::advertiseName() const
{
return m_advertiseName;
@ -75,6 +87,16 @@ void Core::setPlatformName(const QString &name)
m_platformName = name;
}
int Core::advertisingTimeout() const
{
return m_advertisingTimeout;
}
void Core::setAdvertisingTimeout(const int advertisingTimeout)
{
m_advertisingTimeout = advertisingTimeout;
}
bool Core::testingEnabled() const
{
return m_testing;
@ -87,12 +109,29 @@ void Core::setTestingEnabled(bool testing)
void Core::run()
{
// Start the networkmanager service
if (!m_networkManager->available()) {
m_networkManager->start();
} else {
evaluateNetworkManagerState(m_networkManager->state());
// Start the networkmanager
if (!m_networkManager->start()) {
qCWarning(dcApplication()) << "Could not start network manager. Please make sure the networkmanager is available.";
return;
}
switch (m_mode) {
case ModeAlways:
qCDebug(dcApplication()) << "Start the bluetooth service because of \"always\" mode.";
startService();
break;
case ModeStart:
qCDebug(dcApplication()) << "Start the bluetooth service because of \"start\" mode.";
startService();
m_advertisingTimer->start(m_advertisingTimeout * 1000);
break;
case ModeOffline:
evaluateNetworkManagerState(m_networkManager->state());
break;
default:
break;
}
}
Core::Core(QObject *parent) :
@ -103,6 +142,8 @@ Core::Core(QObject *parent) :
connect(m_networkManager, &NetworkManager::stateChanged, this, &Core::onNetworkManagerStateChanged);
connect(m_networkManager, &NetworkManager::networkingEnabledChanged, this, &Core::onNetworkManagerNetworkingEnabledChanged);
connect(m_networkManager, &NetworkManager::wirelessEnabledChanged, this, &Core::onNetworkManagerWirelessEnabledChanged);
connect(m_networkManager, &NetworkManager::wirelessDeviceAdded, this, &Core::onNetworkManagerWirelessDeviceAdded);
connect(m_networkManager, &NetworkManager::wirelessDeviceRemoved, this, &Core::onNetworkManagerWirelessDeviceRemoved);
m_bluetoothServer = new BluetoothServer(this);
connect(m_bluetoothServer, &BluetoothServer::runningChanged, this, &Core::onBluetoothServerRunningChanged);
@ -110,6 +151,11 @@ Core::Core(QObject *parent) :
m_nymeaService = new NymeadService(false, this);
connect(m_nymeaService, &NymeadService::availableChanged, this, &Core::onNymeaServiceAvailableChanged);
m_advertisingTimer = new QTimer(this);
m_advertisingTimer->setSingleShot(true);
connect(m_advertisingTimer, &QTimer::timeout, this, &Core::onAdvertisingTimeout);
}
Core::~Core()
@ -128,20 +174,24 @@ Core::~Core()
}
void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state)
{
if (m_testing && m_networkManager->available()) {
startService();
{
if (m_mode != ModeOffline)
return;
}
switch (state) {
case NetworkManager::NetworkManagerStateConnectedGlobal:
// We are online
stopService();
if (m_bluetoothServer->running() && !m_bluetoothServer->connected()) {
qCDebug(dcApplication()) << "Stop the bluetooth service because of \"offline\" mode.";
stopService();
}
break;
case NetworkManager::NetworkManagerStateConnectedSite:
// We are somehow in the network
stopService();
if (m_bluetoothServer->running() && !m_bluetoothServer->connected()) {
qCDebug(dcApplication()) << "Stop the bluetooth service because of \"offline\" mode.";
stopService();
}
break;
case NetworkManager::NetworkManagerStateUnknown:
@ -149,9 +199,8 @@ void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState
case NetworkManager::NetworkManagerStateDisconnected:
case NetworkManager::NetworkManagerStateConnectedLocal:
// Everything else is not connected, start the service
if (m_networkManager->available())
startService();
qCDebug(dcApplication()) << "Start the bluetooth service because of \"offline\" mode.";
startService();
break;
default:
qCDebug(dcApplication()) << "Ignoring networkmanager state" << state;
@ -172,9 +221,6 @@ void Core::startService()
return;
}
if (m_bluetoothServer->running())
return;
qCDebug(dcApplication()) << "Start service";
// Disable bluetooth on nymea in order to not crash with client connections
@ -184,21 +230,26 @@ void Core::startService()
qCDebug(dcApplication()) << "Start bluetooth service";
m_bluetoothServer->setAdvertiseName(m_advertiseName);
m_bluetoothServer->setMachineId(m_platformName);
m_bluetoothServer->start(m_networkManager->wirelessNetworkDevices().first());
m_bluetoothServer->start();
}
void Core::stopService()
{
if (m_testing) {
return;
}
if (m_bluetoothServer->running())
qCDebug(dcApplication()) << "Stop bluetooth service";
m_bluetoothServer->stop();
}
void Core::onAdvertisingTimeout()
{
if (m_mode != ModeStart)
return;
qCDebug(dcApplication()) << "Advertising timeout. Shutting down the bluetooth server.";
stopService();
}
void Core::onBluetoothServerRunningChanged(bool running)
{
qCDebug(dcApplication()) << "Bluetooth server" << (running ? "started" : "stopped");
@ -206,6 +257,21 @@ void Core::onBluetoothServerRunningChanged(bool running)
if (!running) {
// Enable bluetooth on nymea
m_nymeaService->enableBluetooth(true);
m_advertisingTimer->stop();
switch (m_mode) {
case ModeAlways:
qCDebug(dcApplication()) << "Restart the bluetooth service because of \"always\" mode.";
startService();
break;
case ModeStart:
break;
case ModeOffline:
evaluateNetworkManagerState(m_networkManager->state());
break;
default:
break;
}
}
}
@ -213,13 +279,15 @@ void Core::onBluetoothServerConnectedChanged(bool connected)
{
qCDebug(dcApplication()) << "Bluetooth client" << (connected ? "connected" : "disconnected");
if (connected) {
m_advertisingTimer->stop();
m_bluetoothServer->onNetworkManagerAvailableChanged(m_networkManager->available());
m_bluetoothServer->onNetworkManagerStateChanged(m_networkManager->state());
m_bluetoothServer->onNetworkingEnabledChanged(m_networkManager->networkingEnabled());
m_bluetoothServer->onWirelessNetworkingEnabledChanged(m_networkManager->wirelessEnabled());
} else {
// Restart bluetooth server if a client disconnected
m_bluetoothServer->restartServer();
m_advertisingTimer->stop();
m_bluetoothServer->stop();
}
}
@ -227,13 +295,26 @@ void Core::onNetworkManagerAvailableChanged(const bool &available)
{
if (!available) {
qCWarning(dcApplication()) << "Networkmanager is not available any more.";
stopService();
m_bluetoothServer->onNetworkManagerAvailableChanged(m_networkManager->available());
return;
}
qCDebug(dcApplication()) << "Networkmanager is now available.";
m_bluetoothServer->onNetworkManagerAvailableChanged(available);
evaluateNetworkManagerState(m_networkManager->state());
switch (m_mode) {
case ModeAlways:
qCDebug(dcApplication()) << "Start the bluetooth service because of \"always\" mode.";
startService();
break;
case ModeStart:
break;
case ModeOffline:
evaluateNetworkManagerState(m_networkManager->state());
break;
default:
break;
}
}
void Core::onNetworkManagerNetworkingEnabledChanged(bool enabled)
@ -257,10 +338,44 @@ void Core::onNetworkManagerStateChanged(const NetworkManager::NetworkManagerStat
evaluateNetworkManagerState(state);
}
void Core::onNymeaServiceAvailableChanged(bool available)
void Core::onNetworkManagerWirelessDeviceAdded(WirelessNetworkDevice *wirelessDevice)
{
if (available && m_bluetoothServer->running()) {
// Check if the bluetooth server is running, disable nymea bt functionality in that case
m_nymeaService->enableBluetooth(false);
if (m_wirelessDevice) {
// We already have a wireless device
return;
}
m_wirelessDevice = wirelessDevice;
connect(m_wirelessDevice, &WiredNetworkDevice::stateChanged, this, &Core::onWirelessDeviceStateChanged);
}
void Core::onNetworkManagerWirelessDeviceRemoved(const QString &interface)
{
if (!m_wirelessDevice) {
// Have no wireless device...
return;
}
if (m_wirelessDevice->interface() == interface) {
disconnect(m_wirelessDevice, &WiredNetworkDevice::stateChanged, this, &Core::onWirelessDeviceStateChanged);
m_wirelessDevice = nullptr;
}
}
void Core::onWirelessDeviceBitRateChanged(int bitRate)
{
qCDebug(dcApplication()) << "Wireless device changed bitrate" << bitRate;
m_bluetoothServer->onWirelessDeviceBitRateChanged(bitRate);
}
void Core::onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state)
{
qCDebug(dcApplication()) << state;
m_bluetoothServer->onWirelessDeviceStateChanged(state);
}
void Core::onNymeaServiceAvailableChanged(bool available)
{
if (available)
m_nymeaService->enableBluetooth(!m_bluetoothServer->running());
}

View File

@ -32,6 +32,14 @@ class Core : public QObject
{
Q_OBJECT
public:
enum Mode {
ModeAlways,
ModeOffline,
ModeStart
};
Q_ENUM(Mode)
static Core* instance();
void destroy();
@ -39,12 +47,18 @@ public:
BluetoothServer *bluetoothServer() const;
NymeadService *nymeaService() const;
Mode mode() const;
void setMode(const Mode &mode);
QString advertiseName() const;
void setAdvertiseName(const QString &name);
QString platformName() const;
void setPlatformName(const QString &name);
int advertisingTimeout() const;
void setAdvertisingTimeout(const int advertisingTimeout);
bool testingEnabled() const;
void setTestingEnabled(bool testing);
@ -59,9 +73,15 @@ private:
NetworkManager *m_networkManager = nullptr;
BluetoothServer *m_bluetoothServer = nullptr;
NymeadService *m_nymeaService = nullptr;
WirelessNetworkDevice *m_wirelessDevice = nullptr;
QTimer *m_advertisingTimer = nullptr;
Mode m_mode = ModeOffline;
QString m_advertiseName;
QString m_platformName;
int m_advertisingTimeout = 60;
bool m_testing = false;
void evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state);
@ -70,6 +90,8 @@ private:
void stopService();
private slots:
void onAdvertisingTimeout();
void onBluetoothServerRunningChanged(bool running);
void onBluetoothServerConnectedChanged(bool connected);
@ -77,6 +99,14 @@ private slots:
void onNetworkManagerNetworkingEnabledChanged(bool enabled);
void onNetworkManagerWirelessEnabledChanged(bool enabled);
void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state);
void onNetworkManagerWirelessDeviceAdded(WirelessNetworkDevice *wirelessDevice);
void onNetworkManagerWirelessDeviceRemoved(const QString &interface);
// Wireless device
void onWirelessDeviceBitRateChanged(int bitRate);
void onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state);
void onNymeaServiceAvailableChanged(bool available);

View File

@ -80,13 +80,14 @@ int main(int argc, char *argv[])
Application application(argc, argv);
application.setApplicationName("nymea-networkmanager");
application.setOrganizationName("nymea");
application.setApplicationVersion("0.0.3");
application.setApplicationVersion("0.1.0");
// Command line parser
QCommandLineParser parser;
parser.addHelpOption();
parser.addVersionOption();
parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection.\n\nCopyright %1 2018 Simon Stürz <simon.stuerz@guh.io>").arg(QChar(0xA9)));
parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection." \
"\n\nCopyright %1 2018 Simon Stürz <simon.stuerz@guh.io>").arg(QChar(0xA9)));
QCommandLineOption debugOption(QStringList() << "d" << "debug", "Enable more debug output.");
parser.addOption(debugOption);
@ -99,6 +100,16 @@ int main(int argc, char *argv[])
platformNameOption.setDefaultValue("nymea-box");
parser.addOption(platformNameOption);
QCommandLineOption timeoutOption(QStringList() << "t" << "timeout", "The timeout of the bluetooth server. Minimum value is 10. Default \"60\".", "SECONDS");
timeoutOption.setDefaultValue("60");
parser.addOption(timeoutOption);
QCommandLineOption modeOption(QStringList() << "m" << "mode", "Run the daemon in a specific mode. Default \"offline\".\n\n" \
"- offline: this mode starts the bluetooth server once the device is offline and not connected to any LAN network.\n\n" \
"- always: this mode enables the bluetooth server as long the application is running.\n\n" \
"- start: this mode starts the bluetooth server for 3 minutes on start and shuts down after a connection.\n\n", "offline | always | start");
parser.addOption(modeOption);
QCommandLineOption testingOption(QStringList() << "t" << "testing", "Advertise the bluetoothserver alyways for testing.");
parser.addOption(testingOption);
@ -112,17 +123,49 @@ int main(int argc, char *argv[])
QLoggingCategory::installFilter(loggingCategoryFilter);
bool timeoutValueOk = false;
int timeout = parser.value(timeoutOption).toInt(&timeoutValueOk);
if (!timeoutValueOk) {
qCCritical(dcApplication()) << QString("Invalid timeout value passed: \"%1\". Please pass an integer >= 10").arg(parser.value(timeoutOption));
parser.showHelp(1);
}
if (timeout < 10) {
qCCritical(dcApplication()) << QString("Invalid timeout value passed: \"%1\". The minimal timeout is 10 [s].").arg(parser.value(timeoutOption));
parser.showHelp(1);
}
Core::Mode mode = Core::ModeOffline;
if (parser.isSet(modeOption)) {
if (parser.value(modeOption).toLower() == "offline") {
mode = Core::ModeOffline;
} else if (parser.value(modeOption).toLower() == "always") {
mode = Core::ModeAlways;
} else if (parser.value(modeOption).toLower() == "start") {
mode = Core::ModeStart;
} else {
qCWarning(dcApplication()).noquote() << QString("The given mode \"%1\" does not match the allowed modes.").arg(parser.value(modeOption));
parser.showHelp(1);
}
}
qCDebug(dcApplication()) << "=====================================";
qCDebug(dcApplication()) << "Starting nymea-networkmanager" << application.applicationVersion();
qCDebug(dcApplication()) << "=====================================";
qCDebug(dcApplication()) << "Advertising name:" << parser.value(advertiseNameOption);
qCDebug(dcApplication()) << "Platform name:" << parser.value(platformNameOption);
qCDebug(dcApplication()) << "Testing mode:" << (parser.isSet(testingOption) ? "enabled" : "disabled");
qCDebug(dcApplication()) << "Mode:" << parser.value(modeOption);
qCDebug(dcApplication()) << "Timeout:" << parser.value(timeoutOption);
// Start core
Core::instance()->setMode(mode);
Core::instance()->setAdvertisingTimeout(timeout);
Core::instance()->setAdvertiseName(parser.value(advertiseNameOption));
Core::instance()->setPlatformName(parser.value(platformNameOption));
Core::instance()->setTestingEnabled(parser.isSet(testingOption));
Core::instance()->run();
return application.exec();