diff --git a/libnymea-app/libnymea-app-core.h b/libnymea-app/libnymea-app-core.h index e9a4bbbd..4496fe7a 100644 --- a/libnymea-app/libnymea-app-core.h +++ b/libnymea-app/libnymea-app-core.h @@ -73,6 +73,7 @@ #include "configuration/serverconfigurations.h" #include "configuration/mqttpolicy.h" #include "configuration/mqttpolicies.h" +#include "wifisetup/btwifisetup.h" #include "wifisetup/networkmanagercontroller.h" #include "types/wirelessaccesspoint.h" #include "types/wirelessaccesspoints.h" @@ -270,6 +271,7 @@ void registerQmlTypes() { qmlRegisterType(uri, 1, 0, "TagListModel"); qmlRegisterType(uri, 1, 0, "TagListProxyModel"); + qmlRegisterType(uri, 1, 0, "BtWiFiSetup"); qmlRegisterType(uri, 1, 0, "NetworkManagerController"); qmlRegisterType(uri, 1, 0, "BluetoothDiscovery"); qmlRegisterUncreatableType(uri, 1, 0, "BluetoothDeviceInfo", "Can't create this in QML. Get it from the DeviceInfos."); diff --git a/libnymea-app/libnymea-app.pri b/libnymea-app/libnymea-app.pri index c5141efa..d3a0f5cf 100644 --- a/libnymea-app/libnymea-app.pri +++ b/libnymea-app/libnymea-app.pri @@ -22,6 +22,7 @@ INCLUDEPATH += \ $$top_srcdir/QtZeroConf SOURCES += \ + $$PWD/wifisetup/btwifisetup.cpp \ $${PWD}/configuration/networkmanager.cpp \ $${PWD}/engine.cpp \ $${PWD}/models/barseriesadapter.cpp \ @@ -167,6 +168,7 @@ SOURCES += \ HEADERS += \ + $$PWD/wifisetup/btwifisetup.h \ $${PWD}/configuration/networkmanager.h \ $${PWD}/engine.h \ $${PWD}/models/barseriesadapter.h \ diff --git a/libnymea-app/wifisetup/bluetoothdeviceinfo.cpp b/libnymea-app/wifisetup/bluetoothdeviceinfo.cpp index 762ee42b..850e9f4f 100644 --- a/libnymea-app/wifisetup/bluetoothdeviceinfo.cpp +++ b/libnymea-app/wifisetup/bluetoothdeviceinfo.cpp @@ -41,6 +41,11 @@ BluetoothDeviceInfo::BluetoothDeviceInfo(const QBluetoothDeviceInfo &deviceInfo) m_deviceInfo = deviceInfo; } +BluetoothDeviceInfo::~BluetoothDeviceInfo() +{ + qDebug() << "~BluetoothDeviceInfo"; +} + QString BluetoothDeviceInfo::address() const { #ifdef Q_OS_MAC @@ -62,7 +67,7 @@ bool BluetoothDeviceInfo::isLowEnergy() const return m_deviceInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration; } -QBluetoothDeviceInfo BluetoothDeviceInfo::getBluetoothDeviceInfo() const +QBluetoothDeviceInfo BluetoothDeviceInfo::bluetoothDeviceInfo() const { return m_deviceInfo; } diff --git a/libnymea-app/wifisetup/bluetoothdeviceinfo.h b/libnymea-app/wifisetup/bluetoothdeviceinfo.h index 6eda3a47..f72363d2 100644 --- a/libnymea-app/wifisetup/bluetoothdeviceinfo.h +++ b/libnymea-app/wifisetup/bluetoothdeviceinfo.h @@ -45,12 +45,13 @@ class BluetoothDeviceInfo : public QObject public: BluetoothDeviceInfo(); BluetoothDeviceInfo(const QBluetoothDeviceInfo &deviceInfo); + ~BluetoothDeviceInfo(); QString address() const; QString name() const; bool isLowEnergy() const; - QBluetoothDeviceInfo getBluetoothDeviceInfo() const; + QBluetoothDeviceInfo bluetoothDeviceInfo() const; void setBluetoothDeviceInfo(const QBluetoothDeviceInfo &deviceInfo); signals: diff --git a/libnymea-app/wifisetup/bluetoothdiscovery.cpp b/libnymea-app/wifisetup/bluetoothdiscovery.cpp index 84a3bb07..1e4703e5 100644 --- a/libnymea-app/wifisetup/bluetoothdiscovery.cpp +++ b/libnymea-app/wifisetup/bluetoothdiscovery.cpp @@ -174,34 +174,26 @@ void BluetoothDiscovery::onBluetoothHostModeChanged(const QBluetoothLocalDevice: void BluetoothDiscovery::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo) { - if (!deviceInfo.isValid()) - return; - - BluetoothDeviceInfo *deviceInformation = new BluetoothDeviceInfo(deviceInfo); - bool isLowEnergy = deviceInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration; - - qDebug() << "BluetoothDiscovery: [+]" << deviceInformation->name() << "(" << deviceInformation->address() << ")" << (isLowEnergy ? "LE" : ""); - - if (!isLowEnergy || deviceInformation->name().isEmpty()) { - delete deviceInformation; + if (!deviceInfo.isValid() + || !deviceInfo.coreConfigurations().testFlag(QBluetoothDeviceInfo::LowEnergyCoreConfiguration) + || deviceInfo.name().isEmpty()) { return; } - // Check if we already have added this device info foreach (BluetoothDeviceInfo *di, m_deviceInfos->deviceInfos()) { - if (di->address() == deviceInformation->address()) { - qWarning() << "BluetoothDiscover: device" << deviceInformation->name() << "(" << deviceInformation->address() << ") already added"; - deviceInformation->deleteLater(); + if (di->address() == deviceInfo.address().toString()) { return; } } + BluetoothDeviceInfo *deviceInformation = new BluetoothDeviceInfo(deviceInfo); +// qDebug() << "BluetoothDiscovery: [+]" << deviceInformation->name() << "(" << deviceInformation->address() << ")" << (isLowEnergy ? "LE" : "") << deviceInfo.majorDeviceClass() << deviceInfo.minorDeviceClass() << deviceInfo.serviceClasses(); m_deviceInfos->addBluetoothDeviceInfo(deviceInformation); } void BluetoothDiscovery::discoveryFinished() { - qDebug() << "BluetoothDiscovery: Discovery finished"; + qDebug() << "BluetoothDiscovery: Discovery finished" << m_discoveryEnabled << this; if (m_discoveryEnabled) { qDebug() << "BluetoothDiscovery: Restarting discovery"; m_discoveryAgent->start(); @@ -240,9 +232,9 @@ void BluetoothDiscovery::start() m_discoveryAgent->stop(); } - m_deviceInfos->clearModel(); +// m_deviceInfos->clearModel(); - qDebug() << "BluetoothDiscovery: Start discovering."; + qDebug() << "BluetoothDiscovery: Starting discovery."; m_discoveryAgent->start(); emit discoveringChanged(); } diff --git a/libnymea-app/wifisetup/btwifisetup.cpp b/libnymea-app/wifisetup/btwifisetup.cpp new file mode 100644 index 00000000..47a686dc --- /dev/null +++ b/libnymea-app/wifisetup/btwifisetup.cpp @@ -0,0 +1,302 @@ +#include "btwifisetup.h" +#include "bluetoothdeviceinfo.h" +#include "types/wirelessaccesspoints.h" +#include "types/wirelessaccesspoint.h" + +#include + +static QBluetoothUuid wifiServiceUuid = QBluetoothUuid(QUuid("e081fec0-f757-4449-b9c9-bfa83133f7fc")); +static QBluetoothUuid wifiCommanderCharacteristicUuid = QBluetoothUuid(QUuid("e081fec1-f757-4449-b9c9-bfa83133f7fc")); +static QBluetoothUuid wifiResponseCharacteristicUuid = QBluetoothUuid(QUuid("e081fec2-f757-4449-b9c9-bfa83133f7fc")); +static QBluetoothUuid wifiStatusCharacteristicUuid = QBluetoothUuid(QUuid("e081fec3-f757-4449-b9c9-bfa83133f7fc")); + +static QBluetoothUuid networkServiceUuid = QBluetoothUuid(QUuid("ef6d6610-b8af-49e0-9eca-ab343513641c")); +static QBluetoothUuid networkStatusCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6611-b8af-49e0-9eca-ab343513641c")); +static QBluetoothUuid networkCommanderCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6612-b8af-49e0-9eca-ab343513641c")); +static QBluetoothUuid networkResponseCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6613-b8af-49e0-9eca-ab343513641c")); +static QBluetoothUuid networkingEnabledCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6614-b8af-49e0-9eca-ab343513641c")); +static QBluetoothUuid wirelessEnabledCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6615-b8af-49e0-9eca-ab343513641c")); + +static QBluetoothUuid systemServiceUuid = QBluetoothUuid(QUuid("e081fed0-f757-4449-b9c9-bfa83133f7fc")); +static QBluetoothUuid systemCommanderCharacteristicUuid = QBluetoothUuid(QUuid("e081fed1-f757-4449-b9c9-bfa83133f7fc")); +static QBluetoothUuid systemResponseCharacteristicUuid = QBluetoothUuid(QUuid("e081fed2-f757-4449-b9c9-bfa83133f7fc")); + +BtWiFiSetup::BtWiFiSetup(QObject *parent) : QObject(parent) +{ + m_accessPoints = new WirelessAccessPoints(this); + qRegisterMetaType("const BluetoothDeviceInfo*"); +} + +void BtWiFiSetup::connectToDevice(const BluetoothDeviceInfo *device) +{ + qDebug() << "device" << device; + if (m_btController) { + delete m_btController; + m_status = StatusDisconnected; + emit statusChanged(m_status); + + } + + m_btController = QLowEnergyController::createCentral(device->bluetoothDeviceInfo(), this); + connect(m_btController, &QLowEnergyController::connected, this, [this](){ + qDebug() << "Bluetooth connected"; + m_btController->discoverServices(); + }); + + connect(m_btController, &QLowEnergyController::disconnected, this, [this](){ + qDebug() << "Bluetooth disconnected"; + m_status = StatusDisconnected; + emit statusChanged(m_status); + }); + + typedef void (QLowEnergyController::*errorsSignal)(QLowEnergyController::Error); + connect(m_btController, static_cast(&QLowEnergyController::error), this, [this](QLowEnergyController::Error error){ + qDebug() << "Bluetooth error:" << error; + emit this->error(); + }); + + connect(m_btController, &QLowEnergyController::discoveryFinished, this, [this](){ + qDebug() << "Bluetooth service discovery finished"; + setupServices(); + }); + + m_status = StatusConnectingToBluetooth; + emit statusChanged(m_status); + m_btController->connectToDevice(); +} + +void BtWiFiSetup::connectDeviceToWiFi(const QString &ssid) +{ + if (m_status != StatusConnectedToBluetooth) { + qWarning() << "Cannot connect to wifi in state" << m_status; + } +} + +BtWiFiSetup::Status BtWiFiSetup::status() const +{ + return m_status; +} + +QString BtWiFiSetup::modelNumber() const +{ + return m_modelNumber; +} + +QString BtWiFiSetup::manufacturer() const +{ + return m_manufacturer; +} + +QString BtWiFiSetup::softwareRevision() const +{ + return m_softwareRevision; +} + +QString BtWiFiSetup::firmwareRevision() const +{ + return m_firmwareRevision; +} + +QString BtWiFiSetup::hardwareRevision() const +{ + return m_hardwareRevision; +} + +BtWiFiSetup::NetworkStatus BtWiFiSetup::networkStatus() const +{ + return m_networkStatus; +} + +BtWiFiSetup::WirelessStatus BtWiFiSetup::wirelessStatus() const +{ + return m_wirelessStatus; +} + +bool BtWiFiSetup::networkingEnabled() const +{ + return m_networkingEnabled; +} + +bool BtWiFiSetup::wirelessEnabled() const +{ + return m_wirelessEnabled; +} + +WirelessAccessPoints *BtWiFiSetup::accessPoints() const +{ + return m_accessPoints; +} + +WirelessAccessPoint *BtWiFiSetup::currentConnection() const +{ + return m_currentConnection; +} + +void BtWiFiSetup::setupServices() +{ + m_deviceInformationService = m_btController->createServiceObject(QBluetoothUuid::DeviceInformation, m_btController); + m_networkService = m_btController->createServiceObject(networkServiceUuid, m_btController); + m_wifiService = m_btController->createServiceObject(wifiServiceUuid, m_btController); + m_systemService = m_btController->createServiceObject(systemServiceUuid, m_btController); + + if (!m_wifiService || !m_deviceInformationService || !m_networkService) { + qWarning() << "Required services not found on remote device."; + m_btController->disconnectFromDevice(); + return; + } + + // Device information + connect(m_deviceInformationService, &QLowEnergyService::stateChanged, this, [this](QLowEnergyService::ServiceState state) { + if (state != QLowEnergyService::ServiceDiscovered) + return; + qDebug() << "Device info service discovered"; + m_manufacturer = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::ManufacturerNameString).value()); + emit manufacturerChanged(); + m_modelNumber = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::ModelNumberString).value()); + emit modelNumberChanged(); + m_softwareRevision = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::SoftwareRevisionString).value()); + emit softwareRevisionChanged(); + m_firmwareRevision = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::FirmwareRevisionString).value()); + emit firmwareRevisionChanged(); + m_hardwareRevision = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::HardwareRevisionString).value()); + emit hardwareRevisionChanged(); + }); + m_deviceInformationService->discoverDetails(); + + + // network service + connect(m_networkService, &QLowEnergyService::stateChanged, this, [this](QLowEnergyService::ServiceState state){ + if (state != QLowEnergyService::ServiceDiscovered) + return; + qDebug() << "Network service discovered"; + QLowEnergyCharacteristic networkCharacteristic = m_networkService->characteristic(networkStatusCharacteristicUuid); + QLowEnergyCharacteristic networkingEnabledCharacteristic = m_networkService->characteristic(networkingEnabledCharacteristicUuid); + QLowEnergyCharacteristic wirelessEnabledCharacteristic = m_networkService->characteristic(wirelessEnabledCharacteristicUuid); + if (!networkCharacteristic.isValid() || !networkingEnabledCharacteristic.isValid() || !wirelessEnabledCharacteristic.isValid()) { + qWarning() << "Required characteristics not found on remote device (NetworkService)"; + m_btController->disconnectFromDevice(); + return; + } + // Enable notifications + m_networkService->writeDescriptor(networkCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + m_networkService->writeDescriptor(networkingEnabledCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + m_networkService->writeDescriptor(wirelessEnabledCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + + m_networkStatus = static_cast(networkCharacteristic.value().toHex().toUInt(nullptr, 16)); + emit networkStatusChanged(); + m_networkingEnabled = networkingEnabledCharacteristic.value().toHex().toUInt(nullptr, 16); + emit networkingEnabledChanged(); + m_wirelessEnabled = wirelessEnabledCharacteristic.value().toHex().toUInt(nullptr, 16); + emit wirelessEnabledChanged(); + + }); + connect(m_networkService, &QLowEnergyService::characteristicChanged, this, &BtWiFiSetup::characteristicChanged); + m_networkService->discoverDetails(); + + // Wifi service + connect(m_wifiService, &QLowEnergyService::stateChanged, this, [this](QLowEnergyService::ServiceState state){ + if (state != QLowEnergyService::ServiceDiscovered) + return; + + qDebug() << "Wifi service discovered"; + m_status = StatusConnectedToBluetooth; + emit statusChanged(m_status); + + // Enable notifations + m_wifiService->writeDescriptor(m_wifiService->characteristic(wifiResponseCharacteristicUuid).descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + m_wifiService->writeDescriptor(m_wifiService->characteristic(wifiStatusCharacteristicUuid).descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + + QVariantMap request; + request.insert("c", (int)WirelessServiceCommandGetNetworks); + streamData(request); + }); + connect(m_wifiService, &QLowEnergyService::characteristicChanged, this, &BtWiFiSetup::characteristicChanged); + m_wifiService->discoverDetails(); + + + // System service (optional) + if (m_systemService) { + connect(m_systemService, &QLowEnergyService::stateChanged, this, [this](QLowEnergyService::ServiceState state){ + if (state != QLowEnergyService::ServiceDiscovered) + return; + qDebug() << "System service discovered"; + m_systemService->writeDescriptor(m_systemService->characteristic(systemResponseCharacteristicUuid).descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + + }); + m_systemService->discoverDetails(); + } +} + +void BtWiFiSetup::streamData(const QVariantMap &request) +{ + QLowEnergyCharacteristic characteristic = m_wifiService->characteristic(wifiCommanderCharacteristicUuid); + if (!characteristic.isValid()) { + qWarning() << "WifiSetupManager: WirelessService: Wireless commander characteristic not valid"; + return; + } + + QByteArray data = QJsonDocument::fromVariant(request).toJson(QJsonDocument::Compact) + '\n'; + qDebug() << "WifiSetupManager: WirelessService: Start streaming response data:" << data.count() << "bytes"; + + int sentDataLength = 0; + QByteArray remainingData = data; + while (!remainingData.isEmpty()) { + QByteArray package = remainingData.left(20); + sentDataLength += package.count(); + m_wifiService->writeCharacteristic(characteristic, package); + remainingData = remainingData.remove(0, package.count()); + } + + qDebug() << "WifiSetupManager: WirelessService: Finished streaming request data"; +} + +void BtWiFiSetup::processWiFiPacket(const QVariantMap &data) +{ + WirelessServiceCommand command = static_cast(data.value("c").toInt()); + WirelessServiceResponse responseCode = (WirelessServiceResponse)data.value("r").toInt(); + if (responseCode != WirelessServiceResponseSuccess) { + qWarning() << "Error in wifi command:" << responseCode; + return; + } + + qDebug() << "command reply:" << command; + switch (command) { + case WirelessServiceCommandGetNetworks: + + m_accessPoints->clearModel(); + + foreach (const QVariant &data, data.value("p").toList()) { + WirelessAccessPoint *accessPoint = new WirelessAccessPoint(this); + + accessPoint->setSsid(data.toMap().value("e").toString()); + accessPoint->setMacAddress(data.toMap().value("m").toString()); + accessPoint->setSignalStrength(data.toMap().value("s").toInt()); + accessPoint->setProtected(data.toMap().value("p").toBool()); + accessPoint->setHostAddress(""); + m_accessPoints->addWirelessAccessPoint(accessPoint); + } + } +} + +void BtWiFiSetup::characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &data) +{ + m_inputBuffers[characteristic.uuid()].append(data); + if (m_inputBuffers[characteristic.uuid()].endsWith("\n")) { + QByteArray data = m_inputBuffers.take(characteristic.uuid()); + + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); + if (error.error != QJsonParseError::NoError) { + qWarning() << "Invalid json data received:" << error.errorString() << data; + m_btController->disconnectFromDevice(); + return; + } + + if (characteristic.uuid() == wifiResponseCharacteristicUuid) { + processWiFiPacket(jsonDoc.toVariant().toMap()); + } else { + qWarning() << "Unhandled packet from characteristic" << characteristic.uuid(); + } + + } +} diff --git a/libnymea-app/wifisetup/btwifisetup.h b/libnymea-app/wifisetup/btwifisetup.h new file mode 100644 index 00000000..c4b65989 --- /dev/null +++ b/libnymea-app/wifisetup/btwifisetup.h @@ -0,0 +1,199 @@ +#ifndef BTWIFISETUP_H +#define BTWIFISETUP_H + +#include +#include +#include + +class BluetoothDeviceInfo; +class WirelessAccessPoints; +class WirelessAccessPoint; + +class BtWiFiSetup : public QObject +{ + Q_OBJECT + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + + Q_PROPERTY(QString modelNumber READ modelNumber NOTIFY modelNumberChanged) + Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged) + Q_PROPERTY(QString softwareRevision READ softwareRevision NOTIFY softwareRevisionChanged) + Q_PROPERTY(QString firmwareRevision READ firmwareRevision NOTIFY firmwareRevisionChanged) + Q_PROPERTY(QString hardwareRevision READ hardwareRevision NOTIFY hardwareRevisionChanged) + + Q_PROPERTY(NetworkStatus networkStatus READ networkStatus NOTIFY networkStatusChanged) + Q_PROPERTY(WirelessStatus wirelessStatus READ wirelessStatus NOTIFY wirelessStatusChanged) + Q_PROPERTY(bool networkingEnabled READ networkingEnabled NOTIFY networkingEnabledChanged) + Q_PROPERTY(bool wirelessEnabled READ wirelessEnabled NOTIFY wirelessEnabledChanged) + + Q_PROPERTY(WirelessAccessPoints *accessPoints READ accessPoints CONSTANT) + Q_PROPERTY(WirelessAccessPoint *currentConnection READ currentConnection NOTIFY currentConnectionChanged) + +public: + enum Status { + StatusDisconnected, + StatusConnectingToBluetooth, + StatusConnectedToBluetooth, + StatusConnectingToWiFi, + StatusConnectedToWiFi + }; + Q_ENUM(Status) + + enum WirelessServiceCommand { + WirelessServiceCommandInvalid = -1, + WirelessServiceCommandGetNetworks = 0x00, + WirelessServiceCommandConnect = 0x01, + WirelessServiceCommandConnectHidden = 0x02, + WirelessServiceCommandDisconnect = 0x03, + WirelessServiceCommandScan = 0x04, + WirelessServiceCommandGetCurrentConnection = 0x05 + }; + Q_ENUM(WirelessServiceCommand) + + enum WirelessServiceResponse { + WirelessServiceResponseSuccess = 0x00, + WirelessServiceResponseIvalidCommand = 0x01, + WirelessServiceResponseIvalidParameters = 0x02, + WirelessServiceResponseNetworkManagerNotAvailable = 0x03, + WirelessServiceResponseWirelessNotAvailable = 0x04, + WirelessServiceResponseWirelessNotEnabled = 0x05, + WirelessServiceResponseNetworkingNotEnabled = 0x06, + WirelessServiceResponseUnknownError = 0x07 + }; + Q_ENUM(WirelessServiceResponse) + + enum NetworkServiceCommand { + NetworkServiceCommandInvalid = -1, + NetworkServiceCommandEnableNetworking = 0x00, + NetworkServiceCommandDisableNetworking = 0x01, + NetworkServiceCommandEnableWireless = 0x02, + NetworkServiceCommandDisableWireless = 0x03 + }; + Q_ENUM(NetworkServiceCommand) + + enum NetworkServiceResponse { + NetworkServiceResponseSuccess = 0x00, + NetworkServiceResponseIvalidValue = 0x01, + NetworkServiceResponseNetworkManagerNotAvailable = 0x02, + NetworkServiceResponseWirelessNotAvailable = 0x03, + NetworkServiceResponseUnknownError = 0x04, + }; + Q_ENUM(NetworkServiceResponse) + + enum SystemServiceCommand { + SystemServiceCommandInvalid = -1, + SystemServiceCommandPushAuthentication = 0x00 + }; + Q_ENUM(SystemServiceCommand) + + enum SystemServiceResponse { + SystemServiceResponseSuccess = 0x00, + SystemServiceResponseUnknownError = 0x01, + SystemServiceResponseInvalidCommand = 0x02, + SystemServiceResponseInvalidValue = 0x03, + SystemServiceResponsePushServiceUnavailable = 0x04, + }; + Q_ENUM(SystemServiceResponse) + + enum NetworkStatus { + NetworkStatusUnknown = 0x00, + NetworkStatusAsleep = 0x01, + NetworkStatusDisconnected = 0x02, + NetworkStatusDisconnecting = 0x03, + NetworkStatusConnecting = 0x04, + NetworkStatusLocal = 0x05, + NetworkStatusConnectedSite = 0x06, + NetworkStatusGlobal = 0x07 + }; + Q_ENUM(NetworkStatus) + + enum WirelessStatus { + WirelessStatusUnknown = 0x00, + WirelessStatusUnmanaged = 0x01, + WirelessStatusUnavailable = 0x02, + WirelessStatusDisconnected = 0x03, + WirelessStatusPrepare = 0x04, + WirelessStatusConfig = 0x05, + WirelessStatusNeedAuth = 0x06, + WirelessStatusIpConfig = 0x07, + WirelessStatusIpCheck = 0x08, + WirelessStatusSecondaries = 0x09, + WirelessStatusActivated = 0x0A, + WirelessStatusDeactivating = 0x0B, + WirelessStatusFailed = 0x0C + }; + Q_ENUM(WirelessStatus) + + explicit BtWiFiSetup(QObject *parent = nullptr); + + Q_INVOKABLE void connectToDevice(const BluetoothDeviceInfo *device); + Q_INVOKABLE void connectDeviceToWiFi(const QString &ssid); + + Status status() const; + + QString modelNumber() const; + QString manufacturer() const; + QString softwareRevision() const; + QString firmwareRevision() const; + QString hardwareRevision() const; + + NetworkStatus networkStatus() const; + WirelessStatus wirelessStatus() const; + bool networkingEnabled() const; + bool wirelessEnabled() const; + + WirelessAccessPoints *accessPoints() const; + WirelessAccessPoint *currentConnection() const; + +signals: + void statusChanged(Status status); + void error(); + + void modelNumberChanged(); + void manufacturerChanged(); + void softwareRevisionChanged(); + void firmwareRevisionChanged(); + void hardwareRevisionChanged(); + + void networkStatusChanged(); + void wirelessStatusChanged(); + void networkingEnabledChanged(); + void wirelessEnabledChanged(); + + void currentConnectionChanged(); + +private: + void setupServices(); + void streamData(const QVariantMap &request); + void processWiFiPacket(const QVariantMap &data); + +private slots: + void characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &data); + +private: + Status m_status = StatusDisconnected; + QLowEnergyController *m_btController = nullptr; + + QLowEnergyService *m_deviceInformationService = nullptr; + QLowEnergyService *m_networkService = nullptr; + QLowEnergyService *m_wifiService = nullptr; + QLowEnergyService *m_systemService = nullptr; + + QHash m_inputBuffers; + + QString m_modelNumber; + QString m_manufacturer; + QString m_softwareRevision; + QString m_firmwareRevision; + QString m_hardwareRevision; + + NetworkStatus m_networkStatus = NetworkStatusUnknown; + WirelessStatus m_wirelessStatus = WirelessStatusUnknown; + bool m_networkingEnabled = false; + bool m_wirelessEnabled = false; + + WirelessAccessPoints *m_accessPoints = nullptr; + WirelessAccessPoint *m_currentConnection = nullptr; + +}; + +#endif // BTWIFISETUP_H diff --git a/libnymea-app/wifisetup/networkmanagercontroller.cpp b/libnymea-app/wifisetup/networkmanagercontroller.cpp index 56342f23..9e2943dd 100644 --- a/libnymea-app/wifisetup/networkmanagercontroller.cpp +++ b/libnymea-app/wifisetup/networkmanagercontroller.cpp @@ -71,7 +71,7 @@ void NetworkManagerController::connectDevice() return; } - m_wirelessSetupManager = new WirelessSetupManager(m_bluetoothDeviceInfo->getBluetoothDeviceInfo(), this); + m_wirelessSetupManager = new WirelessSetupManager(m_bluetoothDeviceInfo->bluetoothDeviceInfo(), this); emit managerChanged(); m_wirelessSetupManager->connectDevice();