diff --git a/libnymea-app/libnymea-app-core.h b/libnymea-app/libnymea-app-core.h index 4496fe7a..89a9edd9 100644 --- a/libnymea-app/libnymea-app-core.h +++ b/libnymea-app/libnymea-app-core.h @@ -277,7 +277,7 @@ void registerQmlTypes() { qmlRegisterUncreatableType(uri, 1, 0, "BluetoothDeviceInfo", "Can't create this in QML. Get it from the DeviceInfos."); qmlRegisterUncreatableType(uri, 1, 0, "BluetoothDeviceInfos", "Can't create this in QML. Get it from the BluetoothDiscovery."); qmlRegisterUncreatableType(uri, 1, 0, "WirelessSetupManager", "Can't create this in QML. Get it from the NetworkManagerControler."); - qmlRegisterUncreatableType(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the WirelessAccessPoints."); + qmlRegisterUncreatableType(uri, 1, 0, "WirelessAccessPoint", "Can't create this in QML. Get it from the WirelessAccessPoints."); qmlRegisterUncreatableType(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance."); qmlRegisterType(uri, 1, 0, "WirelessAccessPointsProxy"); diff --git a/libnymea-app/wifisetup/btwifisetup.cpp b/libnymea-app/wifisetup/btwifisetup.cpp index 47a686dc..c04837c8 100644 --- a/libnymea-app/wifisetup/btwifisetup.cpp +++ b/libnymea-app/wifisetup/btwifisetup.cpp @@ -52,7 +52,7 @@ void BtWiFiSetup::connectToDevice(const BluetoothDeviceInfo *device) 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(); + emit this->bluetoothConnectionError(); }); connect(m_btController, &QLowEnergyController::discoveryFinished, this, [this](){ @@ -65,11 +65,28 @@ void BtWiFiSetup::connectToDevice(const BluetoothDeviceInfo *device) m_btController->connectToDevice(); } -void BtWiFiSetup::connectDeviceToWiFi(const QString &ssid) +void BtWiFiSetup::disconnectFromDevice() +{ + if (m_btController) { + m_btController->disconnectFromDevice(); + m_btController->deleteLater(); + m_btController = nullptr; + } +} + +void BtWiFiSetup::connectDeviceToWiFi(const QString &ssid, const QString &password) { if (m_status != StatusConnectedToBluetooth) { qWarning() << "Cannot connect to wifi in state" << m_status; } + + QVariantMap request; + request.insert("c", (int)WirelessServiceCommandConnect); + QVariantMap parameters; + parameters.insert("e", ssid); + parameters.insert("p", password); + request.insert("p", parameters); + streamData(request); } BtWiFiSetup::Status BtWiFiSetup::status() const @@ -206,9 +223,7 @@ void BtWiFiSetup::setupServices() 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); + loadNetworks(); }); connect(m_wifiService, &QLowEnergyService::characteristicChanged, this, &BtWiFiSetup::characteristicChanged); m_wifiService->discoverDetails(); @@ -255,7 +270,7 @@ 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; + qWarning() << "Error in wifi command" << command << ":" << responseCode; return; } @@ -275,28 +290,70 @@ void BtWiFiSetup::processWiFiPacket(const QVariantMap &data) accessPoint->setHostAddress(""); m_accessPoints->addWirelessAccessPoint(accessPoint); } + break; + case WirelessServiceCommandConnect: + qDebug() << "Connect call succeeded"; + m_status = StatusConnectingToWiFi; + emit statusChanged(m_status); + break; } } +void BtWiFiSetup::loadNetworks() +{ + QVariantMap request; + request.insert("c", (int)WirelessServiceCommandGetNetworks); + streamData(request); +} + +void BtWiFiSetup::loadCurrentConnection() +{ + QVariantMap request; + request.insert("c", (int)WirelessServiceCommandGetCurrentConnection); + streamData(request); +} + void BtWiFiSetup::characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &data) -{ - m_inputBuffers[characteristic.uuid()].append(data); - if (m_inputBuffers[characteristic.uuid()].endsWith("\n")) { +{ + if (characteristic.uuid() == wifiResponseCharacteristicUuid) { + m_inputBuffers[characteristic.uuid()].append(data); + if (!m_inputBuffers[characteristic.uuid()].endsWith("\n")) { + return; + } 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; + qWarning() << "Invalid json data received:" << error.errorString() << data << "from characteristic:" << characteristic.uuid(); m_btController->disconnectFromDevice(); return; } + processWiFiPacket(jsonDoc.toVariant().toMap()); - if (characteristic.uuid() == wifiResponseCharacteristicUuid) { - processWiFiPacket(jsonDoc.toVariant().toMap()); - } else { - qWarning() << "Unhandled packet from characteristic" << characteristic.uuid(); + } else if (characteristic.uuid() == wifiStatusCharacteristicUuid) { + + m_wirelessStatus = static_cast(data.toHex().toInt(nullptr, 16)); + qDebug() << "Wireless status changed" << m_wirelessStatus; + emit wirelessStatusChanged(); + + if (m_wirelessStatus == WirelessStatusFailed) { + emit wifiSetupError(); + } else if (m_wirelessStatus == WirelessStatusActivated) { + loadCurrentConnection(); } + } else if (characteristic.uuid() == networkStatusCharacteristicUuid) { + m_networkStatus = static_cast(data.toHex().toInt(nullptr, 16)); + qDebug() << "Network status changed:" << m_networkStatus; + if (m_networkStatus == NetworkStatusGlobal) { + m_status = StatusConnectedToWiFi; + emit statusChanged(m_status); + + loadCurrentConnection(); + } + + } else { + qWarning() << "Unhandled packet from characteristic" << characteristic.uuid(); } + } diff --git a/libnymea-app/wifisetup/btwifisetup.h b/libnymea-app/wifisetup/btwifisetup.h index c4b65989..c7fa8607 100644 --- a/libnymea-app/wifisetup/btwifisetup.h +++ b/libnymea-app/wifisetup/btwifisetup.h @@ -126,7 +126,8 @@ public: explicit BtWiFiSetup(QObject *parent = nullptr); Q_INVOKABLE void connectToDevice(const BluetoothDeviceInfo *device); - Q_INVOKABLE void connectDeviceToWiFi(const QString &ssid); + Q_INVOKABLE void disconnectFromDevice(); + Q_INVOKABLE void connectDeviceToWiFi(const QString &ssid, const QString &password); Status status() const; @@ -146,7 +147,8 @@ public: signals: void statusChanged(Status status); - void error(); + void bluetoothConnectionError(); + void wifiSetupError(); void modelNumberChanged(); void manufacturerChanged(); @@ -166,6 +168,9 @@ private: void streamData(const QVariantMap &request); void processWiFiPacket(const QVariantMap &data); + void loadNetworks(); + void loadCurrentConnection(); + private slots: void characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &data);