Rewrite the matching code for BT devices

This should be much more robust in getting us the correct Bluetooth address
and the correct vendor / product for our selection.

When we pick a paired device, we extract the address right from its name.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2017-07-03 17:28:27 -07:00
parent bc864c3bce
commit 345e063eb5
3 changed files with 39 additions and 72 deletions

View file

@ -175,11 +175,6 @@ QList<BTDiscovery::btVendorProduct> BTDiscovery::getBtDcs()
return btDCs;
}
QList <BTDiscovery::btVendorProduct> BTDiscovery::getBtAllDevices()
{
return btAllDevices;
}
// Android: As Qt is not able to pull the pairing data from a device, i
// a lengthy discovery process is needed to see what devices are paired. On
// https://forum.qt.io/topic/46075/solved-bluetooth-list-paired-devices

View file

@ -44,7 +44,6 @@ public:
void getBluetoothDevices();
#endif
QList<btVendorProduct> getBtDcs();
QList<btVendorProduct> getBtAllDevices();
#endif
private:
static BTDiscovery *m_instance;

View file

@ -1,6 +1,7 @@
#include "downloadfromdcthread.h"
#include "core/libdivecomputer.h"
#include <QDebug>
#include <QRegularExpression>
QStringList vendorList;
QHash<QString, QStringList> productList;
@ -289,7 +290,6 @@ int DCDeviceData::getDetectedVendorIndex(const QString &currentText)
{
#if defined(BT_SUPPORT)
QList<BTDiscovery::btVendorProduct> btDCs = BTDiscovery::instance()->getBtDcs();
QList<BTDiscovery::btVendorProduct> btAllDevices = BTDiscovery::instance()->getBtAllDevices();
// Pick the vendor of the first confirmed find of a DC (if any), but
// only return a true vendor, and not our virtual one
@ -297,12 +297,6 @@ int DCDeviceData::getDetectedVendorIndex(const QString &currentText)
qDebug() << "getDetectedVendorIndex" << currentText << btDCs.first().vendorIdx;
return btDCs.first().vendorIdx;
}
// When the above fails, just pick the (one and only) virtual vendor
if (!btAllDevices.isEmpty() && currentText == QObject::tr("Paired Bluetooth Devices")) {
qDebug() << "getDetectedVendorIndex" << currentText << btAllDevices.first().vendorIdx;
return btAllDevices.first().vendorIdx;
}
#endif
return -1;
}
@ -334,86 +328,65 @@ QString DCDeviceData::getDetectedDeviceAddress(const QString &currentVendorText,
const QString &currentProductText)
{
#if defined(BT_SUPPORT)
QList<BTDiscovery::btVendorProduct> btDCs = BTDiscovery::instance()->getBtDcs();
QList<BTDiscovery::btVendorProduct> btAllDevices = BTDiscovery::instance()->getBtAllDevices();
// Pull the BT address from the first found dive computer that is been
// detected as a possible real dive computer (and not some other paired
// BT device
if (currentVendorText != QObject::tr("Paired Bluetooth Devices") && !btDCs.isEmpty()) {
QString btAddr = btDCs.first().btpdi.address;
qDebug() << "getDetectedDeviceAddress" << btAddr;
return btAddr;
}
// if the above fails, pull the BT address from the selected paired device
// unsure being a dive computer
if (currentVendorText == QObject::tr("Paired Bluetooth Devices")) {
int i = productList[currentVendorText].indexOf(currentProductText);
QString btAddr = btAllDevices[i].btpdi.address;
qDebug() << "getDetectedDeviceAddress" << btAddr;
return btAddr;
// simply get the address from the product text
QRegularExpression extractAddr(".*\\(([0-9A-FL:]*)\\)");
QRegularExpressionMatch m = extractAddr.match(currentProductText);
if (m.hasMatch()) {
qDebug() << "matched" << m.captured(1);
return m.captured(1);
}
}
// Otherwise, pull the vendor from the found devices that are possible real dive computers
// HACK: this assumes that dive computer names are unique across vendors
// and will only give you the first of multiple identically named dive computers - use
// the Paired Bluetooth Devices vendor in cases like that
QList<BTDiscovery::btVendorProduct> btDCs = BTDiscovery::instance()->getBtDcs();
BTDiscovery::btVendorProduct btDC;
Q_FOREACH(btDC, btDCs) {
if (currentProductText.startsWith(dc_descriptor_get_product(btDC.dcDescriptor)))
return btDC.btpdi.address;
}
#endif
return QString();
return QStringLiteral("cannot determine address of dive computer");
}
QString DCDeviceData::getDeviceDescriptorVendor(const QString &currentVendorText,
const QString &currentProductText)
{
#if defined(BT_SUPPORT)
if (currentVendorText != QObject::tr("Paired Bluetooth Devices"))
return currentVendorText;
QList<BTDiscovery::btVendorProduct> btDCs = BTDiscovery::instance()->getBtDcs();
QList<BTDiscovery::btVendorProduct> btAllDevices = BTDiscovery::instance()->getBtAllDevices();
// Pull the vendor from the first found dive computer that is been
// detected as a possible real dive computer (and not some other paired
// BT device
if (currentVendorText != QObject::tr("Paired Bluetooth Devices") && !btDCs.isEmpty()) {
QString dcVendor = dc_descriptor_get_vendor(btDCs.first().dcDescriptor);
qDebug() << "getDeviceDescriptorVendor" << dcVendor;
return dcVendor;
}
// if the above fails, pull vendor from the selected paired device
// unsure being a dive computer
if (currentVendorText == QObject::tr("Paired Bluetooth Devices")) {
int i = productList[currentVendorText].indexOf(currentProductText);
if (i < 0 || btAllDevices.length() <= i)
return QString();
QString dcVendor = dc_descriptor_get_vendor(btAllDevices[i].dcDescriptor);
qDebug() << "getDeviceDescriptorVendor" << dcVendor;
return dcVendor;
// Pull the vendor from the found devices that are possible real dive computers
// HACK: this assumes that dive computer names are unique across vendors
BTDiscovery::btVendorProduct btDC;
Q_FOREACH(btDC, btDCs) {
if (currentProductText.startsWith(dc_descriptor_get_product(btDC.dcDescriptor)))
return dc_descriptor_get_vendor(btDC.dcDescriptor);
}
#endif
return NULL;
return QStringLiteral("failed to detect vendor");
}
QString DCDeviceData::getDeviceDescriptorProduct(const QString &currentVendorText,
const QString &currentProductText)
{
#if defined(BT_SUPPORT)
if (currentVendorText != QObject::tr("Paired Bluetooth Devices"))
return currentProductText;
QList<BTDiscovery::btVendorProduct> btDCs = BTDiscovery::instance()->getBtDcs();
QList<BTDiscovery::btVendorProduct> btAllDevices = BTDiscovery::instance()->getBtAllDevices();
// Pull the product from the first found dive computer that is been
// detected as a possible real dive computer (and not some other paired
// BT device
if (currentVendorText != QObject::tr("Paired Bluetooth Devices") && !btDCs.isEmpty()) {
QString dcProduct = dc_descriptor_get_product(btDCs.first().dcDescriptor);
qDebug() << "getDeviceDescriptorProduct" << dcProduct;
return dcProduct;
}
// if the above fails, pull product from the selected paired device
// unsure being a dive computer
if (currentVendorText == QObject::tr("Paired Bluetooth Devices")) {
int i = productList[currentVendorText].indexOf(currentProductText);
if (i >= btAllDevices.length() || i < 0)
return QString();
QString dcProduct = dc_descriptor_get_product(btAllDevices[i].dcDescriptor);
qDebug() << "getDeviceDescriptorProduct" << dcProduct;
return dcProduct;
// Pull the canonical product from the found devices that are possible real dive computers
// HACK: this assumes that dive computer names are unique across vendors
BTDiscovery::btVendorProduct btDC;
Q_FOREACH(btDC, btDCs) {
if (currentProductText.startsWith(dc_descriptor_get_product(btDC.dcDescriptor)))
return dc_descriptor_get_product(btDC.dcDescriptor);
}
#endif
return NULL;
return QStringLiteral("failed to detect product");
}