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) : NetworkManager::NetworkManager(QObject *parent) :
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); 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() void NetworkManager::loadDevices()
{ {
// Get network devices // Get network devices
@ -271,7 +352,7 @@ void NetworkManager::setAvailable(bool available)
if (m_available == available) if (m_available == available)
return; return;
qCDebug(dcNetworkManager()) << "Service is now" << (available ? "available" : "unavailable"); qCDebug(dcNetworkManager()) << "The network manager is now" << (available ? "available" : "unavailable");
m_available = available; m_available = available;
emit availableChanged(m_available); emit availableChanged(m_available);
} }
@ -319,13 +400,13 @@ void NetworkManager::setState(const NetworkManager::NetworkManagerState &state)
void NetworkManager::onServiceRegistered() void NetworkManager::onServiceRegistered()
{ {
qCDebug(dcNetworkManager()) << "DBus service registered and available."; qCDebug(dcNetworkManager()) << "DBus service registered and available.";
// TODO: init stuff init();
} }
void NetworkManager::onServiceUnregistered() void NetworkManager::onServiceUnregistered()
{ {
qCWarning(dcNetworkManager()) << "DBus service unregistered."; qCWarning(dcNetworkManager()) << "DBus service unregistered.";
// TODO: deinit stuff deinit();
} }
void NetworkManager::onDeviceAdded(const QDBusObjectPath &deviceObjectPath) void NetworkManager::onDeviceAdded(const QDBusObjectPath &deviceObjectPath)
@ -432,84 +513,29 @@ void NetworkManager::onWiredDeviceChanged()
bool NetworkManager::start() bool NetworkManager::start()
{ {
// Get notification when network-manager appears/disappears on DBus // We want the networkmanager to run, so enable it
m_serviceWatcher = new QDBusServiceWatcher(NetworkManagerUtils::networkManagerServiceString(), QDBusConnection::systemBus(), QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, this); m_enabled = true;
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &NetworkManager::onServiceRegistered);
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &NetworkManager::onServiceUnregistered);
// Check DBus connection qCDebug(dcNetworkManager()) << "Start the network manager.";
if (!QDBusConnection::systemBus().isConnected()) { if (m_available) {
qCWarning(dcNetworkManager()) << "System DBus not connected. NetworkManagre not available."; qCDebug(dcNetworkManager()) << "Networkmanager already running.";
m_serviceWatcher->deleteLater(); return true;
m_serviceWatcher = nullptr;
return false;
} }
// Create interface return init();
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;
} }
void NetworkManager::stop() void NetworkManager::stop()
{ {
foreach (NetworkDevice *device, m_networkDevices) { // We want the networkmanager to stop, so disable it
onDeviceRemoved(device->objectPath()); m_enabled = false;
qCDebug(dcNetworkManager()) << "Stop the network manager.";
if (!m_available) {
qCDebug(dcNetworkManager()) << "Networkmanager already stopped.";
return;
} }
m_wiredNetworkDevices.clear(); deinit();
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);
} }

View File

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

View File

@ -342,7 +342,7 @@ void BluetoothServer::serviceError(const QLowEnergyService::ServiceError &error)
qCWarning(dcBluetoothServer()) << "Service error:" << errorString; qCWarning(dcBluetoothServer()) << "Service error:" << errorString;
} }
void BluetoothServer::start(WirelessNetworkDevice *wirelessDevice) void BluetoothServer::start()
{ {
// Check if a user is connected // Check if a user is connected
if (connected()) { if (connected()) {
@ -391,26 +391,7 @@ void BluetoothServer::start(WirelessNetworkDevice *wirelessDevice)
// Create services // Create services
m_networkService = new NetworkService(m_controller->addService(NetworkService::serviceData(), m_controller), m_controller); 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); m_wirelessService = new WirelessService(m_controller->addService(WirelessService::serviceData(), m_controller), 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();
}
startAdvertising(); startAdvertising();
} }
@ -421,10 +402,23 @@ void BluetoothServer::stop()
m_controller->disconnectFromDevice(); m_controller->disconnectFromDevice();
} }
if (!m_running)
return;
qCDebug(dcBluetoothServer()) << "-------------------------------------"; qCDebug(dcBluetoothServer()) << "-------------------------------------";
qCDebug(dcBluetoothServer()) << "Stopping bluetooth server."; qCDebug(dcBluetoothServer()) << "Stopping bluetooth server.";
qCDebug(dcBluetoothServer()) << "-------------------------------------"; qCDebug(dcBluetoothServer()) << "-------------------------------------";
if (m_networkService) {
m_networkService->deleteLater();
m_networkService = nullptr;
}
if (m_wirelessService) {
m_wirelessService->deleteLater();
m_wirelessService = nullptr;
}
if (m_controller) { if (m_controller) {
qCDebug(dcBluetoothServer()) << "Stop advertising."; qCDebug(dcBluetoothServer()) << "Stop advertising.";
m_controller->stopAdvertising(); m_controller->stopAdvertising();
@ -435,10 +429,11 @@ void BluetoothServer::stop()
if (m_localDevice) { if (m_localDevice) {
qCDebug(dcBluetoothServer()) << "Set host mode to connectable."; qCDebug(dcBluetoothServer()) << "Set host mode to connectable.";
m_localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable); m_localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable);
delete m_localDevice; m_localDevice->deleteLater();
m_localDevice = nullptr; m_localDevice = nullptr;
} }
setConnected(false); setConnected(false);
setRunning(false); setRunning(false);
} }
@ -467,3 +462,15 @@ void BluetoothServer::onNetworkManagerStateChanged(const NetworkManager::Network
m_networkService->setNetworkManagerState(state); 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); void serviceError(const QLowEnergyService::ServiceError &error);
public slots: public slots:
void start(WirelessNetworkDevice *wirelessDevice); void start();
void restartServer();
void stop(); void stop();
// Network manager // Network manager
@ -119,6 +118,10 @@ public slots:
void onWirelessNetworkingEnabledChanged(bool enabled); void onWirelessNetworkingEnabledChanged(bool enabled);
void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state); void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state);
// Wireless device
void onWirelessDeviceBitRateChanged(int bitRate);
void onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state);
}; };
#endif // BLUETOOTHSERVER_H #endif // BLUETOOTHSERVER_H

View File

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

View File

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

View File

@ -22,6 +22,8 @@
#include "core.h" #include "core.h"
#include "loggingcategories.h" #include "loggingcategories.h"
#include <QTimer>
Core* Core::s_instance = nullptr; Core* Core::s_instance = nullptr;
Core *Core::instance() Core *Core::instance()
@ -55,6 +57,16 @@ NymeadService *Core::nymeaService() const
return m_nymeaService; 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 QString Core::advertiseName() const
{ {
return m_advertiseName; return m_advertiseName;
@ -75,6 +87,16 @@ void Core::setPlatformName(const QString &name)
m_platformName = name; m_platformName = name;
} }
int Core::advertisingTimeout() const
{
return m_advertisingTimeout;
}
void Core::setAdvertisingTimeout(const int advertisingTimeout)
{
m_advertisingTimeout = advertisingTimeout;
}
bool Core::testingEnabled() const bool Core::testingEnabled() const
{ {
return m_testing; return m_testing;
@ -87,12 +109,29 @@ void Core::setTestingEnabled(bool testing)
void Core::run() void Core::run()
{ {
// Start the networkmanager service // Start the networkmanager
if (!m_networkManager->available()) { if (!m_networkManager->start()) {
m_networkManager->start(); qCWarning(dcApplication()) << "Could not start network manager. Please make sure the networkmanager is available.";
} else { return;
evaluateNetworkManagerState(m_networkManager->state());
} }
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) : Core::Core(QObject *parent) :
@ -103,6 +142,8 @@ Core::Core(QObject *parent) :
connect(m_networkManager, &NetworkManager::stateChanged, this, &Core::onNetworkManagerStateChanged); connect(m_networkManager, &NetworkManager::stateChanged, this, &Core::onNetworkManagerStateChanged);
connect(m_networkManager, &NetworkManager::networkingEnabledChanged, this, &Core::onNetworkManagerNetworkingEnabledChanged); connect(m_networkManager, &NetworkManager::networkingEnabledChanged, this, &Core::onNetworkManagerNetworkingEnabledChanged);
connect(m_networkManager, &NetworkManager::wirelessEnabledChanged, this, &Core::onNetworkManagerWirelessEnabledChanged); 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); m_bluetoothServer = new BluetoothServer(this);
connect(m_bluetoothServer, &BluetoothServer::runningChanged, this, &Core::onBluetoothServerRunningChanged); connect(m_bluetoothServer, &BluetoothServer::runningChanged, this, &Core::onBluetoothServerRunningChanged);
@ -110,6 +151,11 @@ Core::Core(QObject *parent) :
m_nymeaService = new NymeadService(false, this); m_nymeaService = new NymeadService(false, this);
connect(m_nymeaService, &NymeadService::availableChanged, this, &Core::onNymeaServiceAvailableChanged); 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() Core::~Core()
@ -129,19 +175,23 @@ Core::~Core()
void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state) void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state)
{ {
if (m_testing && m_networkManager->available()) { if (m_mode != ModeOffline)
startService();
return; return;
}
switch (state) { switch (state) {
case NetworkManager::NetworkManagerStateConnectedGlobal: case NetworkManager::NetworkManagerStateConnectedGlobal:
// We are online // We are online
stopService(); if (m_bluetoothServer->running() && !m_bluetoothServer->connected()) {
qCDebug(dcApplication()) << "Stop the bluetooth service because of \"offline\" mode.";
stopService();
}
break; break;
case NetworkManager::NetworkManagerStateConnectedSite: case NetworkManager::NetworkManagerStateConnectedSite:
// We are somehow in the network // 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; break;
case NetworkManager::NetworkManagerStateUnknown: case NetworkManager::NetworkManagerStateUnknown:
@ -149,9 +199,8 @@ void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState
case NetworkManager::NetworkManagerStateDisconnected: case NetworkManager::NetworkManagerStateDisconnected:
case NetworkManager::NetworkManagerStateConnectedLocal: case NetworkManager::NetworkManagerStateConnectedLocal:
// Everything else is not connected, start the service // Everything else is not connected, start the service
if (m_networkManager->available()) qCDebug(dcApplication()) << "Start the bluetooth service because of \"offline\" mode.";
startService(); startService();
break; break;
default: default:
qCDebug(dcApplication()) << "Ignoring networkmanager state" << state; qCDebug(dcApplication()) << "Ignoring networkmanager state" << state;
@ -172,9 +221,6 @@ void Core::startService()
return; return;
} }
if (m_bluetoothServer->running())
return;
qCDebug(dcApplication()) << "Start service"; qCDebug(dcApplication()) << "Start service";
// Disable bluetooth on nymea in order to not crash with client connections // Disable bluetooth on nymea in order to not crash with client connections
@ -184,21 +230,26 @@ void Core::startService()
qCDebug(dcApplication()) << "Start bluetooth service"; qCDebug(dcApplication()) << "Start bluetooth service";
m_bluetoothServer->setAdvertiseName(m_advertiseName); m_bluetoothServer->setAdvertiseName(m_advertiseName);
m_bluetoothServer->setMachineId(m_platformName); m_bluetoothServer->setMachineId(m_platformName);
m_bluetoothServer->start(m_networkManager->wirelessNetworkDevices().first()); m_bluetoothServer->start();
} }
void Core::stopService() void Core::stopService()
{ {
if (m_testing) {
return;
}
if (m_bluetoothServer->running()) if (m_bluetoothServer->running())
qCDebug(dcApplication()) << "Stop bluetooth service"; qCDebug(dcApplication()) << "Stop bluetooth service";
m_bluetoothServer->stop(); 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) void Core::onBluetoothServerRunningChanged(bool running)
{ {
qCDebug(dcApplication()) << "Bluetooth server" << (running ? "started" : "stopped"); qCDebug(dcApplication()) << "Bluetooth server" << (running ? "started" : "stopped");
@ -206,6 +257,21 @@ void Core::onBluetoothServerRunningChanged(bool running)
if (!running) { if (!running) {
// Enable bluetooth on nymea // Enable bluetooth on nymea
m_nymeaService->enableBluetooth(true); 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"); qCDebug(dcApplication()) << "Bluetooth client" << (connected ? "connected" : "disconnected");
if (connected) { if (connected) {
m_advertisingTimer->stop();
m_bluetoothServer->onNetworkManagerAvailableChanged(m_networkManager->available()); m_bluetoothServer->onNetworkManagerAvailableChanged(m_networkManager->available());
m_bluetoothServer->onNetworkManagerStateChanged(m_networkManager->state()); m_bluetoothServer->onNetworkManagerStateChanged(m_networkManager->state());
m_bluetoothServer->onNetworkingEnabledChanged(m_networkManager->networkingEnabled()); m_bluetoothServer->onNetworkingEnabledChanged(m_networkManager->networkingEnabled());
m_bluetoothServer->onWirelessNetworkingEnabledChanged(m_networkManager->wirelessEnabled()); m_bluetoothServer->onWirelessNetworkingEnabledChanged(m_networkManager->wirelessEnabled());
} else { } else {
// Restart bluetooth server if a client disconnected m_advertisingTimer->stop();
m_bluetoothServer->restartServer(); m_bluetoothServer->stop();
} }
} }
@ -227,13 +295,26 @@ void Core::onNetworkManagerAvailableChanged(const bool &available)
{ {
if (!available) { if (!available) {
qCWarning(dcApplication()) << "Networkmanager is not available any more."; qCWarning(dcApplication()) << "Networkmanager is not available any more.";
stopService(); m_bluetoothServer->onNetworkManagerAvailableChanged(m_networkManager->available());
return; return;
} }
qCDebug(dcApplication()) << "Networkmanager is now available."; qCDebug(dcApplication()) << "Networkmanager is now available.";
m_bluetoothServer->onNetworkManagerAvailableChanged(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) void Core::onNetworkManagerNetworkingEnabledChanged(bool enabled)
@ -257,10 +338,44 @@ void Core::onNetworkManagerStateChanged(const NetworkManager::NetworkManagerStat
evaluateNetworkManagerState(state); evaluateNetworkManagerState(state);
} }
void Core::onNymeaServiceAvailableChanged(bool available) void Core::onNetworkManagerWirelessDeviceAdded(WirelessNetworkDevice *wirelessDevice)
{ {
if (available && m_bluetoothServer->running()) { if (m_wirelessDevice) {
// Check if the bluetooth server is running, disable nymea bt functionality in that case // We already have a wireless device
m_nymeaService->enableBluetooth(false); 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 Q_OBJECT
public: public:
enum Mode {
ModeAlways,
ModeOffline,
ModeStart
};
Q_ENUM(Mode)
static Core* instance(); static Core* instance();
void destroy(); void destroy();
@ -39,12 +47,18 @@ public:
BluetoothServer *bluetoothServer() const; BluetoothServer *bluetoothServer() const;
NymeadService *nymeaService() const; NymeadService *nymeaService() const;
Mode mode() const;
void setMode(const Mode &mode);
QString advertiseName() const; QString advertiseName() const;
void setAdvertiseName(const QString &name); void setAdvertiseName(const QString &name);
QString platformName() const; QString platformName() const;
void setPlatformName(const QString &name); void setPlatformName(const QString &name);
int advertisingTimeout() const;
void setAdvertisingTimeout(const int advertisingTimeout);
bool testingEnabled() const; bool testingEnabled() const;
void setTestingEnabled(bool testing); void setTestingEnabled(bool testing);
@ -59,9 +73,15 @@ private:
NetworkManager *m_networkManager = nullptr; NetworkManager *m_networkManager = nullptr;
BluetoothServer *m_bluetoothServer = nullptr; BluetoothServer *m_bluetoothServer = nullptr;
NymeadService *m_nymeaService = nullptr; NymeadService *m_nymeaService = nullptr;
WirelessNetworkDevice *m_wirelessDevice = nullptr;
QTimer *m_advertisingTimer = nullptr;
Mode m_mode = ModeOffline;
QString m_advertiseName; QString m_advertiseName;
QString m_platformName; QString m_platformName;
int m_advertisingTimeout = 60;
bool m_testing = false; bool m_testing = false;
void evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state); void evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state);
@ -70,6 +90,8 @@ private:
void stopService(); void stopService();
private slots: private slots:
void onAdvertisingTimeout();
void onBluetoothServerRunningChanged(bool running); void onBluetoothServerRunningChanged(bool running);
void onBluetoothServerConnectedChanged(bool connected); void onBluetoothServerConnectedChanged(bool connected);
@ -77,6 +99,14 @@ private slots:
void onNetworkManagerNetworkingEnabledChanged(bool enabled); void onNetworkManagerNetworkingEnabledChanged(bool enabled);
void onNetworkManagerWirelessEnabledChanged(bool enabled); void onNetworkManagerWirelessEnabledChanged(bool enabled);
void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state); 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); void onNymeaServiceAvailableChanged(bool available);

View File

@ -80,13 +80,14 @@ int main(int argc, char *argv[])
Application application(argc, argv); Application application(argc, argv);
application.setApplicationName("nymea-networkmanager"); application.setApplicationName("nymea-networkmanager");
application.setOrganizationName("nymea"); application.setOrganizationName("nymea");
application.setApplicationVersion("0.0.3"); application.setApplicationVersion("0.1.0");
// Command line parser // Command line parser
QCommandLineParser parser; QCommandLineParser parser;
parser.addHelpOption(); parser.addHelpOption();
parser.addVersionOption(); 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."); QCommandLineOption debugOption(QStringList() << "d" << "debug", "Enable more debug output.");
parser.addOption(debugOption); parser.addOption(debugOption);
@ -99,6 +100,16 @@ int main(int argc, char *argv[])
platformNameOption.setDefaultValue("nymea-box"); platformNameOption.setDefaultValue("nymea-box");
parser.addOption(platformNameOption); 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."); QCommandLineOption testingOption(QStringList() << "t" << "testing", "Advertise the bluetoothserver alyways for testing.");
parser.addOption(testingOption); parser.addOption(testingOption);
@ -112,17 +123,49 @@ int main(int argc, char *argv[])
QLoggingCategory::installFilter(loggingCategoryFilter); 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()) << "=====================================";
qCDebug(dcApplication()) << "Starting nymea-networkmanager" << application.applicationVersion(); qCDebug(dcApplication()) << "Starting nymea-networkmanager" << application.applicationVersion();
qCDebug(dcApplication()) << "====================================="; qCDebug(dcApplication()) << "=====================================";
qCDebug(dcApplication()) << "Advertising name:" << parser.value(advertiseNameOption); qCDebug(dcApplication()) << "Advertising name:" << parser.value(advertiseNameOption);
qCDebug(dcApplication()) << "Platform name:" << parser.value(platformNameOption); 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 // Start core
Core::instance()->setMode(mode);
Core::instance()->setAdvertisingTimeout(timeout);
Core::instance()->setAdvertiseName(parser.value(advertiseNameOption)); Core::instance()->setAdvertiseName(parser.value(advertiseNameOption));
Core::instance()->setPlatformName(parser.value(platformNameOption)); Core::instance()->setPlatformName(parser.value(platformNameOption));
Core::instance()->setTestingEnabled(parser.isSet(testingOption)); Core::instance()->setTestingEnabled(parser.isSet(testingOption));
Core::instance()->run(); Core::instance()->run();
return application.exec(); return application.exec();