Update to latest bt discovery code

pull/624/head
Michael Zanetti 2021-08-04 12:05:13 +02:00
parent 5d8da13924
commit 57c7850735
6 changed files with 198 additions and 19 deletions

View File

@ -279,6 +279,7 @@ void registerQmlTypes() {
qmlRegisterType<BluetoothDiscovery>(uri, 1, 0, "BluetoothDiscovery");
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.");
qmlRegisterType<BluetoothDeviceInfosProxy>(uri, 1, 0, "BluetoothDeviceInfosProxy");
qmlRegisterUncreatableType<WirelessAccessPoint>(uri, 1, 0, "WirelessAccessPoint", "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.");
qmlRegisterType<WirelessAccessPointsProxy>(uri, 1, 0, "WirelessAccessPointsProxy");

View File

@ -31,6 +31,7 @@
#include "bluetoothdeviceinfos.h"
#include <QDebug>
#include <QBluetoothUuid>
BluetoothDeviceInfos::BluetoothDeviceInfos(QObject *parent) : QAbstractListModel(parent)
{
@ -108,3 +109,126 @@ QHash<int, QByteArray> BluetoothDeviceInfos::roleNames() const
roles[BluetoothDeviceInfoRoleSignalStrength] = "signalStrength";
return roles;
}
BluetoothDeviceInfosProxy::BluetoothDeviceInfosProxy(QObject *parent): QSortFilterProxyModel(parent)
{
}
BluetoothDeviceInfos *BluetoothDeviceInfosProxy::model() const
{
return m_model;
}
void BluetoothDeviceInfosProxy::setModel(BluetoothDeviceInfos *model)
{
if (m_model == model) {
return;
}
if (m_model) {
disconnect(m_model, &BluetoothDeviceInfos::countChanged, this, &BluetoothDeviceInfosProxy::countChanged);
}
m_model = model;
setSourceModel(model);
emit modelChanged();
emit countChanged();
if (m_model) {
connect(m_model, &BluetoothDeviceInfos::countChanged, this, &BluetoothDeviceInfosProxy::countChanged);
}
}
QStringList BluetoothDeviceInfosProxy::nameWhitelist() const
{
return m_nameWhitelist;
}
void BluetoothDeviceInfosProxy::setNameWhitelist(const QStringList &nameWhitelist)
{
if (m_nameWhitelist != nameWhitelist) {
m_nameWhitelist = nameWhitelist;
emit nameWhitelistChanged();
invalidateFilter();
emit countChanged();
}
}
bool BluetoothDeviceInfosProxy::filterForLowEnergy() const
{
return m_filterForLowEnergy;
}
void BluetoothDeviceInfosProxy::setFilterForLowEnergy(bool filterForLowEnergy)
{
if (m_filterForLowEnergy != filterForLowEnergy) {
m_filterForLowEnergy = filterForLowEnergy;
emit filterForLowEnergyChanged();
invalidateFilter();
emit countChanged();
}
}
QString BluetoothDeviceInfosProxy::filterForServiceUUID() const
{
return m_filterForServiceUUID.toString();
}
void BluetoothDeviceInfosProxy::setFilterForServiceUUID(const QString &filterForServiceUUID)
{
if (m_filterForServiceUUID != filterForServiceUUID) {
m_filterForServiceUUID = filterForServiceUUID;
emit filterForServiceUUIDChanged();
invalidateFilter();
emit countChanged();
}
}
QString BluetoothDeviceInfosProxy::filterForName() const
{
return m_filterForName;
}
void BluetoothDeviceInfosProxy::setFilterForName(const QString &name)
{
if (m_filterForName != name) {
m_filterForName = name;
emit filterForNameChanged();
invalidateFilter();
emit countChanged();
}
}
BluetoothDeviceInfo *BluetoothDeviceInfosProxy::get(int index) const
{
return m_model->get(mapToSource(this->index(index, 0)).row());
}
bool BluetoothDeviceInfosProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
Q_UNUSED(source_parent)
BluetoothDeviceInfo *info = m_model->get(source_row);
if (!m_nameWhitelist.isEmpty()) {
if (m_nameWhitelist.contains(info->name())) {
return true;
}
}
if (m_filterForLowEnergy && !info->bluetoothDeviceInfo().coreConfigurations().testFlag(QBluetoothDeviceInfo::LowEnergyCoreConfiguration)) {
return false;
}
if (!m_filterForServiceUUID.isNull() && !info->bluetoothDeviceInfo().serviceUuids().contains(QBluetoothUuid(m_filterForServiceUUID))) {
return false;
}
if (!m_filterForName.isEmpty() && info->name() != m_filterForName) {
return false;
}
return true;
}

View File

@ -33,6 +33,8 @@
#include <QObject>
#include <QAbstractListModel>
#include <QSortFilterProxyModel>
#include <QUuid>
#include "bluetoothdeviceinfo.h"
@ -72,4 +74,55 @@ private:
QList<BluetoothDeviceInfo *> m_deviceInfos;
};
class BluetoothDeviceInfosProxy: public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(BluetoothDeviceInfos* model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
// Workaround for allowing particular names, even if they'd fail the filters below (used for legacy compatibility)
Q_PROPERTY(QStringList nameWhitelist READ nameWhitelist WRITE setNameWhitelist NOTIFY nameWhitelistChanged)
Q_PROPERTY(bool filterForLowEnergy READ filterForLowEnergy WRITE setFilterForLowEnergy NOTIFY filterForLowEnergyChanged)
Q_PROPERTY(QString filterForServiceUUID READ filterForServiceUUID WRITE setFilterForServiceUUID NOTIFY filterForServiceUUIDChanged)
Q_PROPERTY(QString filterForName READ filterForName WRITE setFilterForName NOTIFY filterForNameChanged)
public:
BluetoothDeviceInfosProxy(QObject *parent = nullptr);
BluetoothDeviceInfos* model() const;
void setModel(BluetoothDeviceInfos *model);
QStringList nameWhitelist() const;
void setNameWhitelist(const QStringList &nameWhitelist);
bool filterForLowEnergy() const;
void setFilterForLowEnergy(bool filterForLowEnergy);
QString filterForServiceUUID() const;
void setFilterForServiceUUID(const QString &filterForServiceUUID);
QString filterForName() const;
void setFilterForName(const QString &name);
Q_INVOKABLE BluetoothDeviceInfo* get(int index) const;
signals:
void modelChanged();
void countChanged();
void nameWhitelistChanged();
void filterForLowEnergyChanged();
void filterForServiceUUIDChanged();
void filterForNameChanged();
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
private:
BluetoothDeviceInfos *m_model = nullptr;
QStringList m_nameWhitelist;
bool m_filterForLowEnergy = false;
QUuid m_filterForServiceUUID;
QString m_filterForName;
};
#endif // BLUETOOTHDEVICEINFOS_H

View File

@ -175,19 +175,6 @@ void BluetoothDiscovery::onBluetoothHostModeChanged(const QBluetoothLocalDevice:
void BluetoothDiscovery::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo)
{
if (!deviceInfo.isValid()
|| !deviceInfo.coreConfigurations().testFlag(QBluetoothDeviceInfo::LowEnergyCoreConfiguration)
|| deviceInfo.name().isEmpty()) {
return;
}
// Only show devices that either list the wifi service uuid or are called BT WLAN setup (for legacy reasons)
static QBluetoothUuid wifiServiceUuid = QBluetoothUuid(QUuid("e081fec0-f757-4449-b9c9-bfa83133f7fc"));
if (!deviceInfo.serviceUuids().contains(wifiServiceUuid) && deviceInfo.name() != "BT WLAN setup") {
qDebug() << "Skipping device" << deviceInfo.name() << deviceInfo.serviceUuids();
return;
}
foreach (BluetoothDeviceInfo *di, m_deviceInfos->deviceInfos()) {
if (di->address() == deviceInfo.address().toString()) {
di->setBluetoothDeviceInfo(deviceInfo);
@ -197,7 +184,7 @@ void BluetoothDiscovery::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo
BluetoothDeviceInfo *deviceInformation = new BluetoothDeviceInfo(deviceInfo);
// qDebug() << "BluetoothDiscovery: [+]" << deviceInformation->name() << "(" << deviceInformation->address() << ")" << (isLowEnergy ? "LE" : "") << deviceInfo.majorDeviceClass() << deviceInfo.minorDeviceClass() << deviceInfo.serviceClasses();
qDebug() << "BluetoothDiscovery: [+]" << deviceInformation->name() << "(" << deviceInformation->address() << ")" << (deviceInformation->isLowEnergy() ? "LE" : "") << deviceInfo.serviceUuids();
m_deviceInfos->addBluetoothDeviceInfo(deviceInformation);
}

View File

@ -447,11 +447,17 @@ WizardPageBase {
content: ListView {
anchors.fill: parent
model: bluetoothDiscovery.deviceInfos
model: BluetoothDeviceInfosProxy {
id: deviceInfosProxy
model: bluetoothDiscovery.deviceInfos
filterForLowEnergy: true
filterForServiceUUID: "e081fec0-f757-4449-b9c9-bfa83133f7fc"
nameWhitelist: ["BT WLAN setup"]
}
BusyIndicator {
anchors.centerIn: parent
visible: bluetoothDiscovery.discovering && bluetoothDiscovery.deviceInfos.count == 0
visible: bluetoothDiscovery.discovering && deviceInfosProxy.count == 0
}
delegate: NymeaSwipeDelegate {
@ -461,7 +467,7 @@ WizardPageBase {
subText: model.address
onClicked: {
wifiSetup.connectToDevice(bluetoothDiscovery.deviceInfos.get(index))
wifiSetup.connectToDevice(deviceInfosProxy.get(index))
pageStack.push(wirelessBluetoothConnectingComponent)
}
}

View File

@ -46,6 +46,14 @@ Page {
discoveryEnabled: pageStack.currentItem === root
}
BluetoothDeviceInfosProxy {
id: deviceInfosProxy
model: bluetoothDiscovery.deviceInfos
filterForLowEnergy: true
filterForServiceUUID: "e081fec0-f757-4449-b9c9-bfa83133f7fc"
nameWhitelist: ["BT WLAN setup"]
}
BtWiFiSetup {
id: wifiSetup
@ -129,7 +137,7 @@ Page {
Layout.fillWidth: true
Layout.fillHeight: true
model: bluetoothDiscovery.deviceInfos
model: deviceInfosProxy
clip: true
delegate: NymeaSwipeDelegate {
@ -139,7 +147,7 @@ Page {
subText: model.address
onClicked: {
root.connectDevice(bluetoothDiscovery.deviceInfos.get(index))
root.connectDevice(deviceInfosProxy.get(index))
}
}
}