Update and fix behaviour of bluetooth LE wifi setup

This commit is contained in:
Simon Stürz 2018-07-03 16:37:47 +02:00
parent e652c16436
commit d2cd4eff59
15 changed files with 662 additions and 250 deletions

View File

@ -37,6 +37,9 @@
#include "models/interfacesproxy.h"
#include "basicconfiguration.h"
#include "wifisetup/networkmanagercontroler.h"
#include "wifisetup/wirelessaccesspoint.h"
#include "wifisetup/wirelessaccesspoints.h"
#include "wifisetup/wirelessaccesspointsproxy.h"
#include "tagsmanager.h"
#include "models/tagsproxymodel.h"
#include "types/tag.h"
@ -155,7 +158,9 @@ void registerQmlTypes() {
qmlRegisterUncreatableType<BluetoothDeviceInfo>(uri, 1, 0, "BluetoothDeviceInfo", "Can't create this in QML. Get it from the DeviceInfos.");
qmlRegisterUncreatableType<BluetoothDeviceInfos>(uri, 1, 0, "BluetoothDeviceInfos", "Can't create this in QML. Get it from the BluetoothDiscovery.");
qmlRegisterUncreatableType<WirelessSetupManager>(uri, 1, 0, "WirelessSetupManager", "Can't create this in QML. Get it from the NetworkManagerControler.");
qmlRegisterUncreatableType<WirelessAccesspoints>(uri, 1, 0, "WirelessAccesspoints", "Can't create this in QML. Get it from the Loop.");
qmlRegisterUncreatableType<WirelessAccessPoint>(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the WirelessAccessPoints.");
qmlRegisterUncreatableType<WirelessAccessPoints>(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance.");
qmlRegisterUncreatableType<WirelessAccessPointsProxy>(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance.");
}

View File

@ -58,8 +58,9 @@ SOURCES += \
wifisetup/networkmanagercontroler.cpp \
models/logsmodelng.cpp \
models/interfacesproxy.cpp \
models/tagsproxymodel.cpp \
tagsmanager.cpp \
models/tagsproxymodel.cpp
wifisetup/wirelessaccesspointsproxy.cpp \
HEADERS += \
engine.h \
@ -105,7 +106,8 @@ HEADERS += \
models/logsmodelng.h \
models/interfacesproxy.h \
tagsmanager.h \
models/tagsproxymodel.h
models/tagsproxymodel.h \
wifisetup/wirelessaccesspointsproxy.h
unix {
target.path = /usr/lib

View File

@ -22,6 +22,8 @@
#include "wirelessaccesspoint.h"
#include <QDebug>
WirelessAccessPoint::WirelessAccessPoint(QObject *parent):
QObject(parent)
{
@ -35,7 +37,11 @@ QString WirelessAccessPoint::ssid() const
void WirelessAccessPoint::setSsid(const QString ssid)
{
if (m_ssid == ssid)
return;
m_ssid = ssid;
emit ssidChanged(m_ssid);
}
QString WirelessAccessPoint::macAddress() const
@ -45,7 +51,25 @@ QString WirelessAccessPoint::macAddress() const
void WirelessAccessPoint::setMacAddress(const QString &macAddress)
{
if (m_macAddress == macAddress)
return;
m_macAddress = macAddress;
emit macAddressChanged(m_macAddress);
}
QString WirelessAccessPoint::hostAddress() const
{
return m_hostAddress;
}
void WirelessAccessPoint::setHostAddress(const QString &hostAddress)
{
if (m_hostAddress == hostAddress)
return;
m_hostAddress = hostAddress;
emit hostAddressChanged(m_hostAddress);
}
int WirelessAccessPoint::signalStrength() const
@ -55,7 +79,11 @@ int WirelessAccessPoint::signalStrength() const
void WirelessAccessPoint::setSignalStrength(const int &signalStrength)
{
if (m_signalStrength == signalStrength)
return;
m_signalStrength = signalStrength;
emit signalStrengthChanged(m_signalStrength);
}
bool WirelessAccessPoint::isProtected() const
@ -65,7 +93,12 @@ bool WirelessAccessPoint::isProtected() const
void WirelessAccessPoint::setProtected(const bool &isProtected)
{
if (m_isProtected == isProtected)
return;
m_isProtected = isProtected;
emit isProtectedChanged(m_isProtected);
}
bool WirelessAccessPoint::selectedNetwork() const
@ -75,5 +108,10 @@ bool WirelessAccessPoint::selectedNetwork() const
void WirelessAccessPoint::setSelectedNetwork(bool selected)
{
if (m_selectedNetwork == selected)
return;
qDebug() << "Selected network changed" << m_ssid << selected;
m_selectedNetwork = selected;
emit selectedNetworkChanged(m_selectedNetwork);
}

View File

@ -29,6 +29,12 @@
class WirelessAccessPoint : public QObject
{
Q_OBJECT
Q_PROPERTY(QString ssid READ ssid NOTIFY ssidChanged)
Q_PROPERTY(QString macAddress READ macAddress NOTIFY macAddressChanged)
Q_PROPERTY(QString hostAddress READ hostAddress NOTIFY hostAddressChanged)
Q_PROPERTY(int signalStrength READ signalStrength NOTIFY signalStrengthChanged)
Q_PROPERTY(bool isProtected READ isProtected NOTIFY isProtectedChanged)
Q_PROPERTY(bool selectedNetwork READ selectedNetwork WRITE setSelectedNetwork NOTIFY selectedNetworkChanged)
public:
WirelessAccessPoint(QObject *parent = 0);
@ -39,6 +45,9 @@ public:
QString macAddress() const;
void setMacAddress(const QString &macAddress);
QString hostAddress() const;
void setHostAddress(const QString &hostAddress);
int signalStrength() const;
void setSignalStrength(const int &signalStrength);
@ -51,10 +60,18 @@ public:
private:
QString m_ssid;
QString m_macAddress;
int m_signalStrength;
bool m_isProtected;
bool m_selectedNetwork;
QString m_hostAddress;
int m_signalStrength = 0;
bool m_isProtected = false;
bool m_selectedNetwork = false;
signals:
void ssidChanged(const QString &ssid);
void macAddressChanged(const QString &macAddress);
void hostAddressChanged(const QString &hostAddress);
void signalStrengthChanged(int signalStrength);
void isProtectedChanged(bool isProtected);
void selectedNetworkChanged(bool selectedNetwork);
};
#endif // WIRELESSACCESSPOINT_H

View File

@ -21,19 +21,21 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "wirelessaccesspoints.h"
#include "wirelessaccesspoint.h"
#include <QDebug>
WirelessAccesspoints::WirelessAccesspoints(QObject *parent) : QAbstractListModel(parent)
WirelessAccessPoints::WirelessAccessPoints(QObject *parent) : QAbstractListModel(parent)
{
}
QList<WirelessAccessPoint *> WirelessAccesspoints::wirelessAccessPoints()
QList<WirelessAccessPoint *> WirelessAccessPoints::wirelessAccessPoints()
{
return m_wirelessAccessPoints;
}
void WirelessAccesspoints::setWirelessAccessPoints(QList<WirelessAccessPoint *> wirelessAccessPoints)
void WirelessAccessPoints::setWirelessAccessPoints(QList<WirelessAccessPoint *> wirelessAccessPoints)
{
beginResetModel();
@ -41,20 +43,19 @@ void WirelessAccesspoints::setWirelessAccessPoints(QList<WirelessAccessPoint *>
qDeleteAll(m_wirelessAccessPoints);
m_wirelessAccessPoints.clear();
qSort(wirelessAccessPoints.begin(), wirelessAccessPoints.end(), signalStrengthLessThan);
m_wirelessAccessPoints = wirelessAccessPoints;
endResetModel();
emit countChanged();
}
int WirelessAccesspoints::rowCount(const QModelIndex &parent) const
int WirelessAccessPoints::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_wirelessAccessPoints.count();
}
QVariant WirelessAccesspoints::data(const QModelIndex &index, int role) const
QVariant WirelessAccessPoints::data(const QModelIndex &index, int role) const
{
if (index.row() < 0 || index.row() >= m_wirelessAccessPoints.count())
return QVariant();
@ -64,7 +65,9 @@ QVariant WirelessAccesspoints::data(const QModelIndex &index, int role) const
return accessPoint->ssid();
} else if (role == WirelessAccesspointRoleMacAddress) {
return accessPoint->macAddress();
} else if (role == WirelessAccesspointRoleSignalStrength) {
} else if (role == WirelessAccesspointRoleHostAddress) {
return accessPoint->hostAddress();
} else if (role == WirelessAccesspointRoleSignalStrength) {
return accessPoint->signalStrength();
} else if (role == WirelessAccesspointRoleProtected) {
return accessPoint->isProtected();
@ -75,22 +78,31 @@ QVariant WirelessAccesspoints::data(const QModelIndex &index, int role) const
return QVariant();
}
int WirelessAccesspoints::count() const
int WirelessAccessPoints::count() const
{
return m_wirelessAccessPoints.count();
}
WirelessAccessPoint *WirelessAccesspoints::get(const QString &ssid) const
WirelessAccessPoint *WirelessAccessPoints::getAccessPoint(const QString &ssid) const
{
foreach (WirelessAccessPoint *accessPoint, m_wirelessAccessPoints) {
if (accessPoint->ssid() == ssid)
return accessPoint;
}
return Q_NULLPTR;
return nullptr;
}
void WirelessAccesspoints::clearModel()
WirelessAccessPoint *WirelessAccessPoints::get(int index)
{
if (index < 0 || index >= m_wirelessAccessPoints.count()) {
return nullptr;
}
return m_wirelessAccessPoints.at(index);
}
void WirelessAccessPoints::clearModel()
{
beginResetModel();
qDeleteAll(m_wirelessAccessPoints);
@ -99,43 +111,59 @@ void WirelessAccesspoints::clearModel()
emit countChanged();
}
void WirelessAccesspoints::setSelectedNetwork(const QString &ssid, const QString &macAdderss)
void WirelessAccessPoints::addWirelessAccessPoint(WirelessAccessPoint *accessPoint)
{
beginResetModel();
accessPoint->setParent(this);
foreach (WirelessAccessPoint *accessPoint, m_wirelessAccessPoints) {
if (accessPoint->ssid() == ssid && accessPoint->macAddress() == macAdderss) {
qDebug() << "Set selected network:" << ssid << macAdderss;
accessPoint->setSelectedNetwork(true);
} else {
accessPoint->setSelectedNetwork(false);
}
}
beginInsertRows(QModelIndex(), m_wirelessAccessPoints.count(), m_wirelessAccessPoints.count());
qDebug() << "WirelessAccessPoints: access point added" << accessPoint->ssid() << accessPoint->macAddress();
m_wirelessAccessPoints.append(accessPoint);
endInsertRows();
// FIXME: find a better way to update network selected and resort the list
QList<WirelessAccessPoint *> wirelessAccessPoints = m_wirelessAccessPoints;
connect(accessPoint, &WirelessAccessPoint::selectedNetworkChanged, this, [accessPoint, this]() {
int idx = m_wirelessAccessPoints.indexOf(accessPoint);
if (idx < 0) return;
emit dataChanged(index(idx), index(idx), {WirelessAccesspointRoleSelectedNetwork});
});
connect(accessPoint, &WirelessAccessPoint::signalStrengthChanged, this, [accessPoint, this]() {
int idx = m_wirelessAccessPoints.indexOf(accessPoint);
if (idx < 0) return;
emit dataChanged(index(idx), index(idx), {WirelessAccesspointRoleSignalStrength});
});
connect(accessPoint, &WirelessAccessPoint::hostAddressChanged, this, [accessPoint, this]() {
int idx = m_wirelessAccessPoints.indexOf(accessPoint);
if (idx < 0) return;
emit dataChanged(index(idx), index(idx), {WirelessAccesspointRoleHostAddress});
});
qSort(wirelessAccessPoints.begin(), wirelessAccessPoints.end(), signalStrengthLessThan);
m_wirelessAccessPoints = wirelessAccessPoints;
endResetModel();
emit countChanged();
}
bool WirelessAccesspoints::signalStrengthLessThan(const WirelessAccessPoint *a, const WirelessAccessPoint *b)
void WirelessAccessPoints::removeWirelessAccessPoint(WirelessAccessPoint *accessPoint)
{
// Keep the selected network on top
if (a->selectedNetwork())
return true;
int index = m_wirelessAccessPoints.indexOf(accessPoint);
beginRemoveRows(QModelIndex(), index, index);
qDebug() << "WirelessAccessPoints: access point removed" << accessPoint->ssid() << accessPoint->macAddress();
m_wirelessAccessPoints.removeAt(index);
endRemoveRows();
return a->signalStrength() > b->signalStrength();
emit countChanged();
}
QHash<int, QByteArray> WirelessAccesspoints::roleNames() const
void WirelessAccessPoints::clearSelectedNetwork()
{
foreach (WirelessAccessPoint *accessPoint, m_wirelessAccessPoints) {
accessPoint->setSelectedNetwork(false);
accessPoint->setHostAddress(QString());
}
}
QHash<int, QByteArray> WirelessAccessPoints::roleNames() const
{
QHash<int, QByteArray> roles;
roles[WirelessAccesspointRoleSsid] = "ssid";
roles[WirelessAccesspointRoleMacAddress] = "macAddress";
roles[WirelessAccesspointRoleHostAddress] = "hostAddress";
roles[WirelessAccesspointRoleSignalStrength] = "signalStrength";
roles[WirelessAccesspointRoleProtected] = "protected";
roles[WirelessAccesspointRoleSelectedNetwork] = "selectedNetwork";

View File

@ -26,22 +26,24 @@
#include <QObject>
#include <QAbstractListModel>
#include "wirelessaccesspoint.h"
class WirelessAccessPoint;
class WirelessAccesspoints : public QAbstractListModel
class WirelessAccessPoints : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
enum BluetoothDeviceInfoRole {
WirelessAccesspointRoleSsid = Qt::DisplayRole,
WirelessAccesspointRoleMacAddress,
WirelessAccesspointRoleHostAddress,
WirelessAccesspointRoleSignalStrength,
WirelessAccesspointRoleProtected,
WirelessAccesspointRoleSelectedNetwork
};
explicit WirelessAccesspoints(QObject *parent = 0);
explicit WirelessAccessPoints(QObject *parent = 0);
QList<WirelessAccessPoint *> wirelessAccessPoints();
void setWirelessAccessPoints(QList<WirelessAccessPoint *> wirelessAccessPoints);
@ -49,14 +51,16 @@ public:
int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
Q_INVOKABLE int count() const;
Q_INVOKABLE WirelessAccessPoint *get(const QString &ssid) const;
int count() const;
Q_INVOKABLE WirelessAccessPoint *getAccessPoint(const QString &ssid) const;
Q_INVOKABLE WirelessAccessPoint *get(int index);
void clearModel();
Q_INVOKABLE void setSelectedNetwork(const QString &ssid, const QString &macAdderss);
void addWirelessAccessPoint(WirelessAccessPoint *accessPoint);
void removeWirelessAccessPoint(WirelessAccessPoint *accessPoint);
static bool signalStrengthLessThan(const WirelessAccessPoint *a, const WirelessAccessPoint *b);
Q_INVOKABLE void clearSelectedNetwork();
signals:
void countChanged();

View File

@ -0,0 +1,83 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2018 Simon Stuerz <simon.stuerz@guh.io> *
* *
* This file is part of nymea:app *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "wirelessaccesspointsproxy.h"
#include "wirelessaccesspoint.h"
#include "wirelessaccesspoints.h"
#include <QDebug>
WirelessAccessPointsProxy::WirelessAccessPointsProxy(QObject *parent) : QSortFilterProxyModel(parent)
{
}
WirelessAccessPoints *WirelessAccessPointsProxy::accessPoints() const
{
return m_accessPoints;
}
void WirelessAccessPointsProxy::setAccessPoints(WirelessAccessPoints *accessPoints)
{
m_accessPoints = accessPoints;
emit accessPointsChanged();
setSourceModel(m_accessPoints);
sort(0);
invalidate();
}
bool WirelessAccessPointsProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
Q_UNUSED(source_parent)
// Filter out the current selected network
// WirelessAccessPoint *accessPoint = m_accessPoints->get(source_row);
// // Filter out selected network
// if (accessPoint->selectedNetwork())
// return false;
return true;
}
bool WirelessAccessPointsProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
WirelessAccessPoint *leftAccessPoint = m_accessPoints->get(left.row());
WirelessAccessPoint *rightAccessPoint = m_accessPoints->get(right.row());
if (leftAccessPoint->selectedNetwork())
return true;
return leftAccessPoint->signalStrength() > rightAccessPoint->signalStrength();
}
WirelessAccessPoint *WirelessAccessPointsProxy::get(int index) const
{
return m_accessPoints->get(mapToSource(this->index(index, 0)).row());
}
void WirelessAccessPointsProxy::invokeSort()
{
sort(0);
invalidate();
}

View File

@ -0,0 +1,60 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2018 Simon Stuerz <simon.stuerz@guh.io> *
* *
* This file is part of nymea:app *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef WIRELESSACCESSPOINTSPROXY_H
#define WIRELESSACCESSPOINTSPROXY_H
#include <QObject>
#include <QSortFilterProxyModel>
class WirelessAccessPoint;
class WirelessAccessPoints;
class WirelessAccessPointsProxy : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit WirelessAccessPointsProxy(QObject *parent = nullptr);
WirelessAccessPoints *accessPoints() const;
void setAccessPoints(WirelessAccessPoints *accessPoints);
Q_INVOKABLE WirelessAccessPoint* get(int index) const;
Q_INVOKABLE void invokeSort();
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
private:
WirelessAccessPoints *m_accessPoints = nullptr;
signals:
void accessPointsChanged();
public slots:
};
#endif // WIRELESSACCESSPOINTSPROXY_H

View File

@ -21,6 +21,9 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "wirelesssetupmanager.h"
#include "wirelessaccesspoint.h"
#include "wirelessaccesspoints.h"
#include "wirelessaccesspointsproxy.h"
#include <QJsonDocument>
@ -43,8 +46,10 @@ static QBluetoothUuid systemResponseCharacteristicUuid = QBluetoothUuid(QUuid("
WirelessSetupManager::WirelessSetupManager(const QBluetoothDeviceInfo &deviceInfo, QObject *parent) :
BluetoothDevice(deviceInfo, parent),
m_accessPoints(new WirelessAccesspoints(this))
m_accessPoints(new WirelessAccessPoints(this)),
m_accessPointsProxy(new WirelessAccessPointsProxy(this))
{
m_accessPointsProxy->setAccessPoints(m_accessPoints);
connect(this, &WirelessSetupManager::connectedChanged, this, &WirelessSetupManager::onConnectedChanged);
connect(this, &WirelessSetupManager::serviceDiscoveryFinished, this, &WirelessSetupManager::onServiceDiscoveryFinished);
@ -110,11 +115,16 @@ bool WirelessSetupManager::wirelessEnabled() const
return m_wirelessEnabled;
}
WirelessAccesspoints *WirelessSetupManager::accessPoints()
WirelessAccessPoints *WirelessSetupManager::accessPoints()
{
return m_accessPoints;
}
WirelessAccessPointsProxy *WirelessSetupManager::accessPointsProxy()
{
return m_accessPointsProxy;
}
void WirelessSetupManager::reloadData()
{
loadNetworks();
@ -327,6 +337,10 @@ void WirelessSetupManager::checkInitialized()
&& m_wifiService->state() == QLowEnergyService::ServiceDiscovered;
}
if (initialized && m_wirelessEnabled && m_networkingEnabled) {
loadNetworks();
}
setInitialized(initialized);
}
@ -418,6 +432,10 @@ void WirelessSetupManager::setNetworkingEnabled(bool networkingEnabled)
qDebug() << "WifiSetupManager: Networking enabled changed" << networkingEnabled;
m_networkingEnabled = networkingEnabled;
emit networkingEnabledChanged();
if (!m_networkingEnabled)
m_accessPoints->clearModel();
}
void WirelessSetupManager::setWirelessEnabled(bool wirelessEnabled)
@ -428,6 +446,10 @@ void WirelessSetupManager::setWirelessEnabled(bool wirelessEnabled)
qDebug() << "WifiSetupManager: Wireless enabled changed" << wirelessEnabled;
m_wirelessEnabled = wirelessEnabled;
emit wirelessEnabledChanged();
if (!m_wirelessEnabled)
m_accessPoints->clearModel();
}
void WirelessSetupManager::streamData(const QVariantMap &request)
@ -538,6 +560,22 @@ void WirelessSetupManager::processWifiResponse(const QVariantMap &response)
}
m_accessPointsVariantList = response.value("p").toList();
m_accessPoints->clearModel();
foreach (const QVariant &accessPointVariant, m_accessPointsVariantList) {
QVariantMap accessPointVariantMap = accessPointVariant.toMap();
WirelessAccessPoint *accessPoint = new WirelessAccessPoint(this);
accessPoint->setSsid(accessPointVariantMap.value("e").toString());
accessPoint->setMacAddress(accessPointVariantMap.value("m").toString());
accessPoint->setSignalStrength(accessPointVariantMap.value("s").toInt());
accessPoint->setProtected(accessPointVariantMap.value("p").toBool());
accessPoint->setSelectedNetwork(false);
accessPoint->setHostAddress("");
m_accessPoints->addWirelessAccessPoint(accessPoint);
}
m_accessPointsProxy->setAccessPoints(m_accessPoints);
loadCurrentConnection();
break;
@ -556,19 +594,19 @@ void WirelessSetupManager::processWifiResponse(const QVariantMap &response)
qDebug() << "Current network connection" << response;
QVariantMap currentConnection = response.value("p").toMap();;
QList<WirelessAccessPoint *> accessPointsList;
foreach (const QVariant &accessPointVariant, m_accessPointsVariantList) {
QVariantMap accessPointVariantMap = accessPointVariant.toMap();
WirelessAccessPoint *accessPoint = new WirelessAccessPoint(this);
accessPoint->setSsid(accessPointVariantMap.value("e").toString());
accessPoint->setMacAddress(accessPointVariantMap.value("m").toString());
accessPoint->setSignalStrength(accessPointVariantMap.value("s").toInt());
accessPoint->setProtected(accessPointVariantMap.value("p").toBool());
accessPointsList.append(accessPoint);
// Find current network
QString macAddress = currentConnection.value("m").toString();
foreach (WirelessAccessPoint *accessPoint, m_accessPoints->wirelessAccessPoints()) {
if (accessPoint->macAddress() == macAddress) {
// Set the current network
accessPoint->setSelectedNetwork(true);
accessPoint->setHostAddress(currentConnection.value("i").toString());
} else {
accessPoint->setSelectedNetwork(false);
accessPoint->setHostAddress(QString());
}
}
m_accessPoints->setWirelessAccessPoints(accessPointsList);
m_accessPoints->setSelectedNetwork(currentConnection.value("e").toString(), currentConnection.value("m").toString());
break;
}
default:
@ -720,9 +758,9 @@ void WirelessSetupManager::onServiceDiscoveryFinished()
qWarning() << "WifiSetupManager: Could not create system service. Looks like this networkmanager has not implemented that.";
//controller()->disconnectFromDevice();
} else {
connect(m_systemService, &QLowEnergyService::stateChanged, this, &WirelessSetupManager::onWifiServiceStateChanged);
connect(m_systemService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onWifiServiceCharacteristicChanged);
connect(m_systemService, &QLowEnergyService::characteristicRead, this, &WirelessSetupManager::onWifiServiceReadFinished);
connect(m_systemService, &QLowEnergyService::stateChanged, this, &WirelessSetupManager::onSystemServiceStateChanged);
connect(m_systemService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onSystemServiceCharacteristicChanged);
connect(m_systemService, &QLowEnergyService::characteristicRead, this, &WirelessSetupManager::onSystemServiceReadFinished);
if (m_systemService->state() == QLowEnergyService::DiscoveryRequired)
m_systemService->discoverDetails();
@ -782,24 +820,43 @@ void WirelessSetupManager::onNetworkServiceStateChanged(const QLowEnergyService:
}
QLowEnergyCharacteristic networkCharacteristic = m_netwokService->characteristic(networkStatusCharacteristicUuid);
if (!networkCharacteristic.isValid()) {
qWarning() << "Invalud networking status characteristic";
return;
}
QLowEnergyCharacteristic networkingEnabledCharacteristic = m_netwokService->characteristic(networkingEnabledCharacteristicUuid);
if (!networkingEnabledCharacteristic.isValid()) {
qWarning() << "Invalud networking enabled characteristic";
return;
}
QLowEnergyCharacteristic wirelessEnabledCharacteristic = m_netwokService->characteristic(wirelessEnabledCharacteristicUuid);
if (!wirelessEnabledCharacteristic.isValid()) {
qWarning() << "Invalud wireless enabled characteristic";
return;
}
// Enable notifications
qDebug() << "Enable notifications of network service";
m_netwokService->writeDescriptor(networkCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100"));
m_netwokService->writeDescriptor(networkingEnabledCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100"));
m_netwokService->writeDescriptor(wirelessEnabledCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100"));
setStatusText("Connected and ready");
setWorking(false);
// Done with discovery
setNetworkStatus(m_netwokService->characteristic(networkStatusCharacteristicUuid).value().toHex().toUInt(0, 16));
setNetworkingEnabled((bool)m_netwokService->characteristic(networkingEnabledCharacteristicUuid).value().toHex().toUInt(0, 16));
setWirelessEnabled((bool)m_netwokService->characteristic(wirelessEnabledCharacteristicUuid).value().toHex().toUInt(0, 16));
setNetworkStatus(networkCharacteristic.value().toHex().toUInt(0, 16));
setNetworkingEnabled((bool)networkingEnabledCharacteristic.value().toHex().toUInt(0, 16));
setWirelessEnabled((bool)wirelessEnabledCharacteristic.value().toHex().toUInt(0, 16));
checkInitialized();
}
void WirelessSetupManager::onNetworkServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
if (characteristic.uuid() == networkStatusCharacteristicUuid) {
qDebug() << "Network status changed:" << value;
setNetworkStatus(value.toHex().toUInt(0, 16));
@ -831,8 +888,19 @@ void WirelessSetupManager::onNetworkServiceCharacteristicChanged(const QLowEnerg
m_inputDataStream.clear();
m_readingResponse = false;
return;
}
} else if (characteristic.uuid() == networkingEnabledCharacteristicUuid) {
qDebug() << "Networking enabled changed" << (bool)value.toHex().toUInt(0, 16);
setNetworkingEnabled((bool)value.toHex().toUInt(0, 16));
return;
} else if (characteristic.uuid() == wirelessEnabledCharacteristicUuid) {
qDebug() << "Wireless enabled changed" << (bool)value.toHex().toUInt(0, 16);
setWirelessEnabled((bool)value.toHex().toUInt(0, 16));
return;
}
qWarning() << "Bluetooth: Unhandled service characteristic changed" << characteristic.uuid() << value;
}
void WirelessSetupManager::onNetworkServiceReadFinished(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
@ -860,6 +928,7 @@ void WirelessSetupManager::onWifiServiceStateChanged(const QLowEnergyService::Se
m_wifiService->writeDescriptor(m_wifiService->characteristic(wifiStatusCharacteristicUuid).descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100"));
setWirelessStatus(m_wifiService->characteristic(wifiStatusCharacteristicUuid).value().toHex().toUInt(0, 16));
m_accessPointsProxy->invokeSort();
checkInitialized();
}
@ -896,6 +965,7 @@ void WirelessSetupManager::onWifiServiceCharacteristicChanged(const QLowEnergyCh
m_inputDataStream.clear();
m_readingResponse = false;
}
return;
}
if (characteristic.uuid() == wifiStatusCharacteristicUuid) {
@ -904,25 +974,7 @@ void WirelessSetupManager::onWifiServiceCharacteristicChanged(const QLowEnergyCh
return;
}
if (characteristic.uuid() == networkStatusCharacteristicUuid) {
qDebug() << "Network status changed:" << value.toHex().toUInt(0, 16);
setNetworkStatus(value.toHex().toUInt(0, 16));
return;
}
if (characteristic.uuid() == networkingEnabledCharacteristicUuid) {
qDebug() << "Networking enabled changed" << (bool)value.toHex().toUInt(0, 16);
setNetworkingEnabled((bool)value.toHex().toUInt(0, 16));
return;
}
if (characteristic.uuid() == wirelessEnabledCharacteristicUuid) {
qDebug() << "Wireless enabled changed" << (bool)value.toHex().toUInt(0, 16);
setWirelessEnabled((bool)value.toHex().toUInt(0, 16));
return;
}
qDebug() << "Bluetooth: Unhandled service characteristic changed" << characteristic.uuid() << value;
qWarning() << "Bluetooth: Unhandled service characteristic changed" << characteristic.uuid() << value;
}

View File

@ -27,16 +27,21 @@
#include <QBluetoothDeviceInfo>
#include "bluetoothdevice.h"
#include "wirelessaccesspoints.h"
class WirelessAccessPoint;
class WirelessAccessPoints;
class WirelessAccessPointsProxy;
class WirelessSetupManager : public BluetoothDevice
{
Q_OBJECT
Q_PROPERTY(bool working READ working NOTIFY workingChanged)
Q_PROPERTY(bool initializing READ initializing NOTIFY initializingChanged)
Q_PROPERTY(bool initialized READ initialized NOTIFY initializedChanged)
Q_PROPERTY(WirelessAccesspoints *accessPoints READ accessPoints CONSTANT)
Q_PROPERTY(WirelessAccessPoints *accessPoints READ accessPoints CONSTANT)
Q_PROPERTY(WirelessAccessPointsProxy *accessPointsProxy READ accessPointsProxy CONSTANT)
Q_PROPERTY(QString modelNumber READ modelNumber NOTIFY modelNumberChanged)
Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged)
@ -154,7 +159,8 @@ public:
bool networkingEnabled() const;
bool wirelessEnabled() const;
WirelessAccesspoints *accessPoints();
WirelessAccessPoints *accessPoints();
WirelessAccessPointsProxy *accessPointsProxy();
void reloadData();
@ -174,7 +180,8 @@ private:
QLowEnergyService *m_wifiService = nullptr;
QLowEnergyService *m_systemService = nullptr;
WirelessAccesspoints *m_accessPoints = nullptr;
WirelessAccessPoints *m_accessPoints = nullptr;
WirelessAccessPointsProxy *m_accessPointsProxy = nullptr;
QString m_modelNumber;
QString m_manufacturer;
@ -189,10 +196,10 @@ private:
bool m_initialized = false;
bool m_initializing = false;
NetworkStatus m_networkStatus;
WirelessStatus m_wirelessStatus;
NetworkStatus m_networkStatus = NetworkStatusUnknown;
WirelessStatus m_wirelessStatus = WirelessStatusUnknown;
bool m_readingResponse;
bool m_readingResponse = false;
QByteArray m_inputDataStream;
QString m_ssid;

View File

@ -140,7 +140,6 @@
<file>ui/images/bluetooth.svg</file>
<file>ui/images/refresh.svg</file>
<file>ui/WirelessControlerPage.qml</file>
<file>ui/BluetoothLoadingPage.qml</file>
<file>ui/images/nm-signal-00.svg</file>
<file>ui/images/nm-signal-00-secure.svg</file>
<file>ui/images/nm-signal-25.svg</file>

View File

@ -11,10 +11,10 @@ Page {
text: qsTr("Bluetooth discovery")
onBackPressed: pageStack.pop()
// HeaderButton {
// imageSource: Qt.resolvedUrl("images/refresh.svg")
// onClicked: Engine.bluetoothDiscovery.start()
// }
HeaderButton {
imageSource: Qt.resolvedUrl("images/refresh.svg")
onClicked: Engine.bluetoothDiscovery.start()
}
}
@ -34,7 +34,7 @@ Page {
function setupDevice(name, btAddress) {
shouldDiscover = false;
Engine.bluetoothDiscovery.stop()
pageStack.push(Qt.resolvedUrl("BluetoothLoadingPage.qml"), { name: name, address: btAddress } )
pageStack.push(connectingPageComponent, { name: name, address: btAddress } )
}
ColumnLayout {
@ -170,4 +170,65 @@ Page {
}
}
}
Component {
id: connectingPageComponent
Page {
id: root
header: GuhHeader {
text: qsTr("Establish bluetooth connection")
onBackPressed: pageStack.pop()
}
property string name
property string address
NetworkManagerControler {
id: networkManger
name: root.name
address: root.address
Component.onCompleted: networkManger.connectDevice()
}
Connections {
target: networkManger.manager
onInitializedChanged: {
if (networkManger.manager.initialized) {
pageStack.push(Qt.resolvedUrl("WirelessControlerPage.qml"), { name: root.name, address: root.address, networkManger: networkManger } )
} else {
pageStack.pop()
}
}
onConnectedChanged: {
if (!networkManger.manager.connected) {
pageStack.pop()
}
}
}
ColumnLayout {
anchors.centerIn: parent
BusyIndicator {
Layout.alignment: Qt.AlignHCenter
running: true
}
Label {
id: workingMessage
Layout.alignment: Qt.AlignHCenter
text: networkManger.manager.statusText
}
Label {
id: initializingMessage
Layout.alignment: Qt.AlignHCenter
text: networkManger.manager.initializing ? qsTr("Initialize services...") : ""
}
}
}
}
}

View File

@ -1,64 +0,0 @@
import QtQuick 2.4
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.2
import "components"
import Nymea 1.0
Page {
id: root
header: GuhHeader {
text: qsTr("Establish bluetooth connection")
onBackPressed: pageStack.pop()
}
property string name
property string address
NetworkManagerControler {
id: networkManger
name: root.name
address: root.address
Component.onCompleted: networkManger.connectDevice()
}
Connections {
target: networkManger.manager
onInitializedChanged: {
if (networkManger.manager.initialized) {
pageStack.push(Qt.resolvedUrl("WirelessControlerPage.qml"), { name: root.name, address: root.address, networkManger: networkManger } )
} else {
pageStack.pop()
}
}
onConnectedChanged: {
if (!networkManger.manager.connected) {
pageStack.pop()
}
}
}
ColumnLayout {
anchors.centerIn: parent
BusyIndicator {
Layout.alignment: Qt.AlignHCenter
running: true
}
Label {
id: workingMessage
Layout.alignment: Qt.AlignHCenter
text: networkManger.manager.statusText
}
Label {
id: initializingMessage
Layout.alignment: Qt.AlignHCenter
text: networkManger.manager.initializing ? qsTr("Initialize services...") : ""
}
}
}

View File

@ -117,7 +117,7 @@ Page {
}
}
MenuSeparator {}
MenuSeparator { }
IconMenuItem {
iconSource: "../images/stock_application.svg"
@ -154,7 +154,7 @@ Page {
}
}
ThinDivider {}
ThinDivider { }
ListView {
Layout.fillWidth: true

View File

@ -18,6 +18,16 @@ Page {
pageStack.pop()
pageStack.pop()
}
HeaderButton {
imageSource: Qt.resolvedUrl("images/refresh.svg")
onClicked: networkManger.manager.loadNetworks()
}
HeaderButton {
imageSource: Qt.resolvedUrl("images/settings.svg")
onClicked: pageStack.push(settingsPage)
}
}
Connections {
@ -32,18 +42,72 @@ Page {
onWirelessStatusChanged: {
switch(networkManger.manager.wirelessStatus) {
case WirelessSetupManager.WirelessStatusDisconnected:
networkManger.manager.accessPoints.setSelectedNetwork("", "")
//networkManger.manager.loadCurrentConnection()
networkManger.manager.accessPoints.clearSelectedNetwork()
break;
case WirelessSetupManager.WirelessStatusActivated:
networkManger.manager.loadCurrentConnection()
break;
default:
break;
}
}
}
Timer {
id: loadNetworksTimer
interval: networkManger.manager.accessPoints.count === 0 ? 1000 : 5000
running: networkManger.manager.networkingEnabled && networkManger.manager.wirelessEnabled
repeat: true
onTriggered: {
networkManger.manager.loadNetworks()
function getWirelessStatusString() {
switch (networkManger.manager.wirelessStatus) {
case WirelessSetupManager.WirelessStatusUnknown:
return qsTr("Unknown status.");
case WirelessSetupManager.WirelessStatusUnmanaged:
return qsTr("Network unmanaged.");
case WirelessSetupManager.WirelessStatusUnavailable:
return qsTr("Network unavailable.");
case WirelessSetupManager.WirelessStatusDisconnected:
return qsTr("Disconnected.");
case WirelessSetupManager.WirelessStatusPrepare:
return qsTr("Prepare connection...");
case WirelessSetupManager.WirelessStatusConfig:
return qsTr("Configure network...");
case WirelessSetupManager.WirelessStatusNeedAuth:
return qsTr("Authentication needed");
case WirelessSetupManager.WirelessStatusIpConfig:
return qsTr("Configuration IP...");
case WirelessSetupManager.WirelessStatusIpCheck:
return qsTr("Check IP...");
case WirelessSetupManager.WirelessStatusSecondaries:
return qsTr("Secondaries...");
case WirelessSetupManager.WirelessStatusActivated:
return qsTr("Network connected.");
case WirelessSetupManager.WirelessStatusDeactivating:
return qsTr("Network disconnecting...");
case WirelessSetupManager.WirelessStatusFailed:
return qsTr("Network connection failed.");
default:
return "???";
}
}
function getNetworkStatusString() {
switch (networkManger.manager.networkStatus) {
case WirelessSetupManager.NetworkStatusUnknown:
return qsTr("Unknown status.");
case WirelessSetupManager.NetworkStatusAsleep:
return qsTr("Asleep.");
case WirelessSetupManager.NetworkStatusDisconnected:
return qsTr("Disconnected.");
case WirelessSetupManager.NetworkStatusDisconnecting:
return qsTr("Disconnecting...");
case WirelessSetupManager.NetworkStatusConnecting:
return qsTr("Connecting...");
case WirelessSetupManager.NetworkStatusLocal:
return qsTr("Connected local.");
case WirelessSetupManager.NetworkStatusConnectedSite:
return qsTr("Connected site.");
case WirelessSetupManager.NetworkStatusGlobal:
return qsTr("Online.");
default:
return "???"
}
}
@ -51,55 +115,11 @@ Page {
anchors.fill: parent
visible: networkManger.manager.initialized
MeaListItemDelegate {
Layout.fillWidth: true
iconName: "../images/info.svg"
text: qsTr("About this %1 box").arg(app.systemName)
onClicked: pageStack.push(infoPage)
}
SwitchDelegate {
Layout.fillWidth: true
text: qsTr("Wired network")
checked: networkManger.manager.networkingEnabled
onClicked: networkManger.manager.enableNetworking(checked)
}
SwitchDelegate {
Layout.fillWidth: true
enabled: networkManger.manager.networkingEnabled
text: qsTr("Wireless network")
checked: networkManger.manager.wirelessEnabled
onClicked: {
networkManger.manager.enableWireless(checked)
}
}
MeaListItemDelegate {
Layout.fillWidth: true
progressive: false
text: qsTr("Networking status")
subText: {
switch (networkManger.manager.networkStatus) {
case WirelessSetupManager.NetworkStatusUnknown:
return qsTr("Unknown status.");
case WirelessSetupManager.NetworkStatusAsleep:
return qsTr("Asleep.");
case WirelessSetupManager.NetworkStatusDisconnected:
return qsTr("Disconnected.");
case WirelessSetupManager.NetworkStatusDisconnecting:
return qsTr("Disconnecting...");
case WirelessSetupManager.NetworkStatusConnecting:
return qsTr("Connecting...");
case WirelessSetupManager.NetworkStatusLocal:
return qsTr("Connected local.");
case WirelessSetupManager.NetworkStatusConnectedSite:
return qsTr("Connected site.");
case WirelessSetupManager.NetworkStatusGlobal:
return qsTr("Online.");
}
return "???"
}
subText: getNetworkStatusString()
}
ThinDivider {
@ -109,9 +129,8 @@ Page {
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
visible: networkManger.manager.wirelessEnabled
model: networkManger.manager.accessPoints
model: networkManger.manager.accessPointsProxy
clip: true
BusyIndicator {
@ -122,38 +141,12 @@ Page {
delegate: MeaListItemDelegate {
width: parent.width
text: model.ssid
enabled: !networkManger.manager.working
subText: {
if (!model.selectedNetwork) {
return "";
}
switch (networkManger.manager.wirelessStatus) {
case WirelessSetupManager.WirelessStatusUnknown:
return qsTr("Unknown status.");
case WirelessSetupManager.WirelessStatusUnmanaged:
return qsTr("Network unmanaged.");
case WirelessSetupManager.WirelessStatusUnavailable:
return qsTr("Network unavailable.");
case WirelessSetupManager.WirelessStatusDisconnected:
return qsTr("Disconnected.");
case WirelessSetupManager.WirelessStatusPrepare:
return qsTr("Prepare connection...");
case WirelessSetupManager.WirelessStatusConfig:
return qsTr("Configure network...");
case WirelessSetupManager.WirelessStatusNeedAuth:
return qsTr("Authentication needed");
case WirelessSetupManager.WirelessStatusIpConfig:
return qsTr("Configuration IP...");
case WirelessSetupManager.WirelessStatusIpCheck:
return qsTr("Check IP...");
case WirelessSetupManager.WirelessStatusSecondaries:
return qsTr("Secondaries...");
case WirelessSetupManager.WirelessStatusActivated:
return qsTr("Network connected.");
case WirelessSetupManager.WirelessStatusDeactivating:
return qsTr("Network disconnecting...");
case WirelessSetupManager.WirelessStatusFailed:
return qsTr("Network connection failed.");
}
return getWirelessStatusString()
}
iconColor: model.selectedNetwork ? app.guhAccent : "#808080"
@ -190,7 +183,86 @@ Page {
onClicked: {
print("Connect to ", model.ssid, " --> ", model.macAddress)
pageStack.push(authenticationPage, { ssid: model.ssid, macAddress: model.macAddress })
if (model.selectedNetwork) {
pageStack.push(networkInformationPage, { ssid: model.ssid, macAddress: model.macAddress })
} else {
pageStack.push(authenticationPage, { ssid: model.ssid, macAddress: model.macAddress })
}
}
}
}
}
Component {
id: networkInformationPage
Page {
id: root
property string ssid
property string macAddress
property var accessPoint : networkManger.manager.accessPoints.getAccessPoint(ssid)
header: GuhHeader {
text: qsTr("Network information")
onBackPressed: pageStack.pop()
}
ColumnLayout {
anchors { left: parent.left; top: parent.top; right: parent.right }
MeaListItemDelegate {
Layout.fillWidth: true
progressive: false
text: qsTr("SSID:")
subText: root.ssid
}
MeaListItemDelegate {
Layout.fillWidth: true
progressive: false
text: qsTr("Mac Address:")
subText: root.macAddress
}
MeaListItemDelegate {
Layout.fillWidth: true
progressive: false
text: qsTr("Host Address:")
subText: accessPoint.hostAddress
}
MeaListItemDelegate {
Layout.fillWidth: true
progressive: false
text: qsTr("Signal strength:")
subText: accessPoint.signalStrength
}
MeaListItemDelegate {
Layout.fillWidth: true
progressive: false
text: qsTr("Protected:")
subText: accessPoint.isProtected ? "Protected" : "Open"
}
MeaListItemDelegate {
Layout.fillWidth: true
progressive: false
text: qsTr("Connection status:")
subText: getWirelessStatusString()
}
Button {
Layout.fillWidth: true
Layout.leftMargin: app.margins
Layout.rightMargin: app.margins
text: qsTr("Disconnect")
onPressed: {
networkManger.manager.disconnectWirelessNetwork()
pageStack.pop()
}
}
}
}
@ -266,7 +338,9 @@ Page {
text: qsTr("Connect")
onPressed: {
networkManger.manager.connectWirelessNetwork(ssid, passwordTextField.text)
networkManger.manager.accessPoints.setSelectedNetwork(ssid, macAddress)
var accessPoint = networkManger.manager.accessPoints.getAccessPoint(ssid)
networkManger.manager.accessPoints.clearSelectedNetwork()
accessPoint.selectedNetwork = true
pageStack.pop()
}
}
@ -274,6 +348,52 @@ Page {
}
}
Component {
id: settingsPage
Page {
id: root
header: GuhHeader {
text: qsTr("Network manager settings")
onBackPressed: pageStack.pop()
}
ColumnLayout {
anchors { left: parent.left; top: parent.top; right: parent.right }
MeaListItemDelegate {
Layout.fillWidth: true
iconName: "../images/info.svg"
text: qsTr("About this %1 box").arg(app.systemName)
onClicked: pageStack.push(infoPage)
}
SwitchDelegate {
Layout.fillWidth: true
text: qsTr("Networking")
checked: networkManger.manager.networkingEnabled
onClicked: networkManger.manager.enableNetworking(checked)
}
SwitchDelegate {
Layout.fillWidth: true
enabled: networkManger.manager.networkingEnabled
text: qsTr("Wireless network")
checked: networkManger.manager.wirelessEnabled
onClicked: {
networkManger.manager.enableWireless(checked)
}
}
Button {
Layout.fillWidth: true
text: qsTr("Trigger a wireless scan on the device.")
onClicked: networkManger.manager.performWifiScan()
}
}
}
}
Component {
id: infoPage