Update bluetooth functionality

This commit is contained in:
Simon Stürz 2018-07-05 11:21:33 +02:00
parent 5e407ff13f
commit 045edd52aa
7 changed files with 77 additions and 36 deletions

View File

@ -24,6 +24,7 @@
#include <QUrl> #include <QUrl>
#include <QDebug> #include <QDebug>
#include <QUrlQuery>
BluetoothInterface::BluetoothInterface(QObject *parent) : BluetoothInterface::BluetoothInterface(QObject *parent) :
NymeaInterface(parent) NymeaInterface(parent)
@ -47,9 +48,12 @@ void BluetoothInterface::connect(const QUrl &url)
return; return;
} }
QString macAddress = url.host(); QUrlQuery query(url);
qDebug() << "Connecting to bluetooth server" << macAddress; QString macAddressString = query.queryItemValue("mac");
m_socket->connectToService(QBluetoothAddress(macAddress), QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b"))); QBluetoothAddress macAddress = QBluetoothAddress(macAddressString);
qDebug() << "Connecting to bluetooth server" << macAddressString << macAddress.toString();
m_socket->connectToService(macAddress, QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b")));
} }
void BluetoothInterface::disconnect() void BluetoothInterface::disconnect()
@ -99,13 +103,6 @@ void BluetoothInterface::onDisconnected()
void BluetoothInterface::onDataReady() void BluetoothInterface::onDataReady()
{ {
QByteArray message; QByteArray data = m_socket->readAll();
while (m_socket->canReadLine()) { emit dataReady(data);
QByteArray dataLine = m_socket->readLine();
message.append(dataLine);
if (dataLine.endsWith('\n')) {
emit dataReady(message);
message.clear();
}
}
} }

View File

@ -6,6 +6,9 @@ BluetoothServiceDiscovery::BluetoothServiceDiscovery(DiscoveryModel *discoveryMo
QObject(parent), QObject(parent),
m_discoveryModel(discoveryModel) m_discoveryModel(discoveryModel)
{ {
m_nymeaServiceUuid = QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b"));
m_localDevice = new QBluetoothLocalDevice(this); m_localDevice = new QBluetoothLocalDevice(this);
connect(m_localDevice, &QBluetoothLocalDevice::hostModeStateChanged, this, &BluetoothServiceDiscovery::onHostModeChanged); connect(m_localDevice, &QBluetoothLocalDevice::hostModeStateChanged, this, &BluetoothServiceDiscovery::onHostModeChanged);
@ -21,18 +24,25 @@ bool BluetoothServiceDiscovery::discovering() const
bool BluetoothServiceDiscovery::available() const bool BluetoothServiceDiscovery::available() const
{ {
return m_available; return m_localDevice->isValid() && !m_localDevice->hostMode() != QBluetoothLocalDevice::HostPoweredOff;
} }
void BluetoothServiceDiscovery::discover(const QBluetoothUuid &uuid) void BluetoothServiceDiscovery::discover()
{ {
m_enabed = true; m_enabed = true;
if (!m_localDevice->isValid() || m_localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) {
qWarning() << "BluetoothServiceDiscovery: Not restart discovery, the bluetooth device is not available";
return;
}
m_serviceDiscovery->setUuidFilter(m_nymeaServiceUuid);
if (m_discovering) if (m_discovering)
return; return;
qDebug() << "BluetoothServiceDiscovery: Start scanning services"; qDebug() << "BluetoothServiceDiscovery: Start scanning for service" << m_nymeaServiceUuid.toString();
setDiscovering(true); setDiscovering(true);
m_serviceDiscovery->setUuidFilter(uuid); m_serviceDiscovery->setUuidFilter(m_nymeaServiceUuid);
m_serviceDiscovery->start(QBluetoothServiceDiscoveryAgent::FullDiscovery); m_serviceDiscovery->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
} }
@ -40,7 +50,7 @@ void BluetoothServiceDiscovery::stopDiscovery()
{ {
m_enabed = false; m_enabed = false;
setDiscovering(false); setDiscovering(false);
m_deviceDiscovery->stop(); m_serviceDiscovery->stop();
} }
void BluetoothServiceDiscovery::setDiscovering(const bool &discovering) void BluetoothServiceDiscovery::setDiscovering(const bool &discovering)
@ -55,6 +65,11 @@ void BluetoothServiceDiscovery::setDiscovering(const bool &discovering)
void BluetoothServiceDiscovery::onHostModeChanged(const QBluetoothLocalDevice::HostMode &mode) void BluetoothServiceDiscovery::onHostModeChanged(const QBluetoothLocalDevice::HostMode &mode)
{ {
qDebug() << "BluetoothServiceDiscovery: Host mode changed" << mode; qDebug() << "BluetoothServiceDiscovery: Host mode changed" << mode;
if (mode != QBluetoothLocalDevice::HostPoweredOff && m_enabed) {
qDebug() << "Bluetooth available again, continue discovery";
m_serviceDiscovery->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
}
} }
void BluetoothServiceDiscovery::onServiceDiscovered(const QBluetoothServiceInfo &serviceInfo) void BluetoothServiceDiscovery::onServiceDiscovered(const QBluetoothServiceInfo &serviceInfo)
@ -76,7 +91,7 @@ void BluetoothServiceDiscovery::onServiceDiscovered(const QBluetoothServiceInfo
return; return;
if (serviceInfo.serviceClassUuids().first() == QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b"))) { if (serviceInfo.serviceClassUuids().first() == QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b"))) {
qDebug() << "Found nymea rfcom service!"; qDebug() << "BluetoothServiceDiscovery: Found nymea rfcom service!";
DiscoveryDevice* device = m_discoveryModel->find(serviceInfo.device().address()); DiscoveryDevice* device = m_discoveryModel->find(serviceInfo.device().address());
if (!device) { if (!device) {
@ -100,8 +115,12 @@ void BluetoothServiceDiscovery::onServiceDiscoveryFinished()
// If discover was called, but never stopDiscover, continue discovery // If discover was called, but never stopDiscover, continue discovery
if (m_enabed) { if (m_enabed) {
qDebug() << "BluetoothServiceDiscovery: Restart bluetooth discovery"; if (!m_localDevice->isValid() || m_localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) {
m_serviceDiscovery->start(QBluetoothServiceDiscoveryAgent::FullDiscovery); qWarning() << "BluetoothServiceDiscovery: Not restart discovery, the bluetooth adapter is not available.";
return;
}
qDebug() << "BluetoothServiceDiscovery: Restart service discovery";
discover();
} }
} }

View File

@ -2,6 +2,7 @@
#define BLUETOOTHSERVICEDISCOVERY_H #define BLUETOOTHSERVICEDISCOVERY_H
#include <QObject> #include <QObject>
#include <QBluetoothUuid>
#include <QBluetoothLocalDevice> #include <QBluetoothLocalDevice>
#include <QBluetoothServiceDiscoveryAgent> #include <QBluetoothServiceDiscoveryAgent>
@ -16,14 +17,14 @@ public:
bool discovering() const; bool discovering() const;
bool available() const; bool available() const;
Q_INVOKABLE void discover(const QBluetoothUuid &uuid); Q_INVOKABLE void discover();
Q_INVOKABLE void stopDiscovery(); Q_INVOKABLE void stopDiscovery();
private: private:
DiscoveryModel *m_discoveryModel = nullptr; DiscoveryModel *m_discoveryModel = nullptr;
QBluetoothLocalDevice *m_localDevice = nullptr; QBluetoothLocalDevice *m_localDevice = nullptr;
QBluetoothDeviceDiscoveryAgent *m_deviceDiscovery = nullptr;
QBluetoothServiceDiscoveryAgent *m_serviceDiscovery = nullptr; QBluetoothServiceDiscoveryAgent *m_serviceDiscovery = nullptr;
QBluetoothUuid m_nymeaServiceUuid;
bool m_enabed = false; bool m_enabed = false;
bool m_discovering = false; bool m_discovering = false;

View File

@ -48,9 +48,9 @@ public:
void addDevice(DiscoveryDevice *device); void addDevice(DiscoveryDevice *device);
Q_INVOKABLE DiscoveryDevice* get(int index) const; Q_INVOKABLE DiscoveryDevice *get(int index) const;
Q_INVOKABLE DiscoveryDevice* find(const QUuid &uuid); Q_INVOKABLE DiscoveryDevice *find(const QUuid &uuid);
Q_INVOKABLE DiscoveryDevice* find(const QBluetoothAddress &bluetoothAddress); Q_INVOKABLE DiscoveryDevice *find(const QBluetoothAddress &bluetoothAddress);
void clearModel(); void clearModel();
@ -61,7 +61,7 @@ protected:
QHash<int, QByteArray> roleNames() const; QHash<int, QByteArray> roleNames() const;
private: private:
QList<DiscoveryDevice*> m_devices; QList<DiscoveryDevice *> m_devices;
}; };
#endif // DISCOVERYMODEL_H #endif // DISCOVERYMODEL_H

View File

@ -4,6 +4,9 @@
#include "zeroconfdiscovery.h" #include "zeroconfdiscovery.h"
#include "bluetoothservicediscovery.h" #include "bluetoothservicediscovery.h"
#include <QUuid>
#include <QBluetoothUuid>
NymeaDiscovery::NymeaDiscovery(QObject *parent) : QObject(parent) NymeaDiscovery::NymeaDiscovery(QObject *parent) : QObject(parent)
{ {
m_discoveryModel = new DiscoveryModel(this); m_discoveryModel = new DiscoveryModel(this);
@ -26,9 +29,9 @@ void NymeaDiscovery::setDiscovering(bool discovering)
m_discovering = discovering; m_discovering = discovering;
// For zeroconf we'll ignore it as zeroconf doesn't do active discovery but just listens for changes in the net all the time // For zeroconf we'll ignore it as zeroconf doesn't do active discovery but just listens for changes in the net all the time
if (discovering) { if (discovering) {
//m_upnp->discover(); m_upnp->discover();
// Note: this is the nymea uuid // Note: this is the nymea uuid
m_bluetooth->discover(QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b"))); m_bluetooth->discover();
} else { } else {
m_upnp->stopDiscovery(); m_upnp->stopDiscovery();
m_bluetooth->stopDiscovery(); m_bluetooth->stopDiscovery();

View File

@ -3,12 +3,14 @@
#include <QUrl> #include <QUrl>
#include <QDebug> #include <QDebug>
#include <QSslKey> #include <QSslKey>
#include <QUrlQuery>
#include <QSettings> #include <QSettings>
#include <QMetaEnum> #include <QMetaEnum>
#include "nymeainterface.h" #include "nymeainterface.h"
#include "tcpsocketinterface.h" #include "tcpsocketinterface.h"
#include "websocketinterface.h" #include "websocketinterface.h"
#include "bluetoothinterface.h"
NymeaConnection::NymeaConnection(QObject *parent) : QObject(parent) NymeaConnection::NymeaConnection(QObject *parent) : QObject(parent)
{ {
@ -17,6 +19,9 @@ NymeaConnection::NymeaConnection(QObject *parent) : QObject(parent)
iface = new WebsocketInterface(this); iface = new WebsocketInterface(this);
registerInterface(iface); registerInterface(iface);
iface = new BluetoothInterface(this);
registerInterface(iface);
} }
void NymeaConnection::connect(const QString &url) void NymeaConnection::connect(const QString &url)
@ -25,6 +30,7 @@ void NymeaConnection::connect(const QString &url)
qWarning() << "Already connected. Cannot connect multiple times"; qWarning() << "Already connected. Cannot connect multiple times";
return; return;
} }
m_currentUrl = QUrl(url); m_currentUrl = QUrl(url);
m_currentInterface = m_interfaces.value(m_currentUrl.scheme()); m_currentInterface = m_interfaces.value(m_currentUrl.scheme());
if (!m_currentInterface) { if (!m_currentInterface) {

View File

@ -197,8 +197,21 @@ Page {
ColorIcon { ColorIcon {
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: height Layout.preferredWidth: height
property bool hasSecurePort: discoveryDeviceDelegate.discoveryDevice.portConfigs.get(discoveryDeviceDelegate.defaultPortConfigIndex).sslEnabled property bool hasSecurePort: {
property bool isTrusted: Engine.connection.isTrusted(discoveryDeviceDelegate.discoveryDevice.toUrl(discoveryDeviceDelegate.defaultPortConfigIndex)) if (model.type === DiscoveryDevice.DeviceTypeNetwork) {
return discoveryDeviceDelegate.discoveryDevice.portConfigs.get(discoveryDeviceDelegate.defaultPortConfigIndex).sslEnabled
} else {
return false
}
}
property bool isTrusted: {
if (model.type === DiscoveryDevice.DeviceTypeNetwork) {
Engine.connection.isTrusted(discoveryDeviceDelegate.discoveryDevice.toUrl(discoveryDeviceDelegate.defaultPortConfigIndex))
} else {
return false
}
}
visible: hasSecurePort visible: hasSecurePort
name: "../images/network-secure.svg" name: "../images/network-secure.svg"
color: isTrusted ? app.guhAccent : keyColor color: isTrusted ? app.guhAccent : keyColor
@ -208,8 +221,8 @@ Page {
onClicked: { onClicked: {
if (model.type === DiscoveryDevice.DeviceTypeNetwork) { if (model.type === DiscoveryDevice.DeviceTypeNetwork) {
Engine.connection.connect(discoveryDevice.toUrl(defaultPortConfigIndex)) Engine.connection.connect(discoveryDevice.toUrl(defaultPortConfigIndex))
} else if (model.type === DiscoveryDevice.DeviceTypeNetwork) { } else if (model.type === DiscoveryDevice.DeviceTypeBluetooth) {
Engine.connection.connect(discoveryDevice.toUrl(model.bluetoothAddress)) Engine.connection.connect("rfcom://bluetooth.local?mac=" + model.bluetoothAddress)
} }
pageStack.push(connectingPage) pageStack.push(connectingPage)
@ -225,9 +238,11 @@ Page {
name: "../images/info.svg" name: "../images/info.svg"
} }
onClicked: { onClicked: {
swipe.close() if (model.type === DiscoveryDevice.DeviceTypeNetwork) {
var popup = infoDialog.createObject(app,{discoveryDevice: discovery.discoveryModel.get(index)}) swipe.close()
popup.open() var popup = infoDialog.createObject(app,{discoveryDevice: discovery.discoveryModel.get(index)})
popup.open()
}
} }
} }
} }
@ -351,7 +366,7 @@ Page {
ColumnLayout { ColumnLayout {
id: certLayout id: certLayout
anchors.fill: parent anchors.fill: parent
// spacing: app.margins // spacing: app.margins
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true