Bluetooth: use standard Qt code on Windows

We shouldn't need our hand crafted code anymore.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2018-09-29 22:39:07 -07:00
parent d3d06bc580
commit 1f59629a76
3 changed files with 6 additions and 264 deletions

View file

@ -31,8 +31,8 @@ static dc_descriptor_t *getDeviceType(QString btName)
}
if (btName.startsWith("Predator") ||
btName.startsWith("Petrel") ||
btName.startsWith("Perdix") ||
btName.startsWith("Petrel") ||
btName.startsWith("Perdix") ||
btName.startsWith("Teric")) {
vendor = "Shearwater";
if (btName.startsWith("Petrel")) product = "Petrel"; // or petrel 2?
@ -98,7 +98,7 @@ void BTDiscovery::BTDiscoveryReDiscover()
if (1) {
#endif
m_btValid = true;
#if defined(Q_OS_IOS) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
#if defined(Q_OS_WIN) || defined(Q_OS_IOS) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BTDiscovery::btDeviceDiscovered);
qDebug() << "starting BLE discovery";
@ -178,7 +178,7 @@ void BTDiscovery::btDeviceDiscovered(const QBluetoothDeviceInfo &device)
qDebug() << id.toByteArray();
}
#if defined(Q_OS_IOS)
#if defined(Q_OS_IOS) || defined(Q_OS_WIN)
// On Desktop this is called when "Save" button is clicked. All
// DeviceInfo are stored as data on the ui list items.
// On mobile (iOS) the current ConnectionListModel does not support

View file

@ -10,13 +10,6 @@
#include "ui_btdeviceselectiondialog.h"
#include "btdeviceselectiondialog.h"
#if defined(Q_OS_WIN)
Q_DECLARE_METATYPE(QBluetoothDeviceDiscoveryAgent::Error)
#endif
#if QT_VERSION < 0x050500
Q_DECLARE_METATYPE(QBluetoothDeviceInfo)
#endif
BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::BtDeviceSelectionDialog),
@ -50,24 +43,6 @@ BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) :
connect(ui->discoveredDevicesList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
this, SLOT(currentItemChanged(QListWidgetItem*,QListWidgetItem*)));
#if defined(Q_OS_WIN)
ULONG ulRetCode = SUCCESS;
WSADATA WSAData = { 0 };
// Initialize WinSock and ask for version 2.2.
ulRetCode = WSAStartup(MAKEWORD(2, 2), &WSAData);
if (ulRetCode != SUCCESS) {
QMessageBox::critical(this, "Bluetooth",
tr("Could not initialize Winsock version 2.2"), QMessageBox::Ok);
return;
}
// Initialize the device discovery agent
initializeDeviceDiscoveryAgent();
// On Windows we cannot select a device or show information about the local device
ui->localDeviceDetails->hide();
#else
// Initialize the local Bluetooth device
localDevice = new QBluetoothLocalDevice();
@ -103,38 +78,25 @@ BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) :
// Initialize the device discovery agent
if (localDevice->isValid())
initializeDeviceDiscoveryAgent();
#endif
}
BtDeviceSelectionDialog::~BtDeviceSelectionDialog()
{
delete ui;
#if defined(Q_OS_WIN)
// Terminate the use of Winsock 2 DLL
WSACleanup();
#else
// Clean the local device
delete localDevice;
#endif
if (remoteDeviceDiscoveryAgent) {
// Clean the device discovery agent
if (remoteDeviceDiscoveryAgent->isActive()) {
if (remoteDeviceDiscoveryAgent->isActive())
remoteDeviceDiscoveryAgent->stop();
#if defined(Q_OS_WIN)
remoteDeviceDiscoveryAgent->wait();
#endif
}
delete remoteDeviceDiscoveryAgent;
}
}
void BtDeviceSelectionDialog::on_changeDeviceState_clicked()
{
#if defined(Q_OS_WIN)
// TODO add implementation
#else
if (localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) {
ui->dialogStatus->setText(tr("Trying to turn on the local Bluetooth device..."));
localDevice->powerOn();
@ -142,7 +104,6 @@ void BtDeviceSelectionDialog::on_changeDeviceState_clicked()
ui->dialogStatus->setText(tr("Trying to turn off the local Bluetooth device..."));
localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff);
}
#endif
}
void BtDeviceSelectionDialog::on_save_clicked()
@ -159,9 +120,6 @@ void BtDeviceSelectionDialog::on_save_clicked()
if (remoteDeviceDiscoveryAgent->isActive()) {
// Stop the SDP agent if the clear button is pressed and enable the Scan button
remoteDeviceDiscoveryAgent->stop();
#if defined(Q_OS_WIN)
remoteDeviceDiscoveryAgent->wait();
#endif
ui->scan->setEnabled(true);
}
@ -177,9 +135,6 @@ void BtDeviceSelectionDialog::on_clear_clicked()
if (remoteDeviceDiscoveryAgent->isActive()) {
// Stop the SDP agent if the clear button is pressed and enable the Scan button
remoteDeviceDiscoveryAgent->stop();
#if defined(Q_OS_WIN)
remoteDeviceDiscoveryAgent->wait();
#endif
ui->scan->setEnabled(true);
}
}
@ -206,9 +161,6 @@ void BtDeviceSelectionDialog::remoteDeviceScanFinished()
void BtDeviceSelectionDialog::hostModeStateChanged(QBluetoothLocalDevice::HostMode mode)
{
#if defined(Q_OS_WIN)
// TODO add implementation
#else
bool on = !(mode == QBluetoothLocalDevice::HostPoweredOff);
//: %1 will be replaced with "turned on" or "turned off"
@ -216,7 +168,6 @@ void BtDeviceSelectionDialog::hostModeStateChanged(QBluetoothLocalDevice::HostMo
.arg(on? tr("turned on") : tr("turned off")));
ui->deviceState->setChecked(on);
ui->scan->setEnabled(on);
#endif
}
void BtDeviceSelectionDialog::addRemoteDevice(const QBluetoothDeviceInfo &remoteDeviceInfo)
@ -304,9 +255,6 @@ void BtDeviceSelectionDialog::currentItemChanged(QListWidgetItem *item, QListWid
void BtDeviceSelectionDialog::localDeviceChanged(int index)
{
#if defined(Q_OS_WIN)
// TODO add implementation
#else
QBluetoothAddress localDeviceSelectedAddress = ui->localSelectedDevice->itemData(index, Qt::UserRole).value<QBluetoothAddress>();
// Delete the old localDevice
@ -327,14 +275,10 @@ void BtDeviceSelectionDialog::localDeviceChanged(int index)
// Initialize the device discovery agent
if (localDevice->isValid())
initializeDeviceDiscoveryAgent();
#endif
}
void BtDeviceSelectionDialog::displayPairingMenu(const QPoint &pos)
{
#if defined(Q_OS_WIN)
// TODO add implementation
#else
QMenu menu(this);
QAction *pairAction = menu.addAction(tr("Pair"));
QAction *removePairAction = menu.addAction(tr("Remove pairing"));
@ -361,7 +305,6 @@ void BtDeviceSelectionDialog::displayPairingMenu(const QPoint &pos)
.arg(currentRemoteDeviceInfo.address().toString()));
localDevice->requestPairing(currentRemoteDeviceInfo.address(), QBluetoothLocalDevice::Unpaired);
}
#endif
}
void BtDeviceSelectionDialog::pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing)
@ -438,11 +381,7 @@ void BtDeviceSelectionDialog::deviceDiscoveryError(QBluetoothDeviceDiscoveryAgen
errorDescription = tr("Writing to or reading from the device resulted in an error.");
break;
default:
#if defined(Q_OS_WIN)
errorDescription = remoteDeviceDiscoveryAgent->errorToString();
#else
errorDescription = tr("An unknown error has occurred.");
#endif
break;
}
@ -495,9 +434,6 @@ QString BtDeviceSelectionDialog::formatDeviceText(const QString &address, const
void BtDeviceSelectionDialog::updateLocalDeviceInformation()
{
#if defined(Q_OS_WIN)
// TODO add implementation
#else
// Check if the selected Bluetooth device can be accessed
if (!localDevice->isValid()) {
QString na = tr("Not available");
@ -537,21 +473,10 @@ void BtDeviceSelectionDialog::updateLocalDeviceInformation()
connect(localDevice, SIGNAL(error(QBluetoothLocalDevice::Error)),
this, SLOT(error(QBluetoothLocalDevice::Error)));
#endif
}
void BtDeviceSelectionDialog::initializeDeviceDiscoveryAgent()
{
#if defined(Q_OS_WIN)
// Register QBluetoothDeviceInfo metatype
qRegisterMetaType<QBluetoothDeviceInfo>();
// Register QBluetoothDeviceDiscoveryAgent metatype (Needed for QBluetoothDeviceDiscoveryAgent::Error)
qRegisterMetaType<QBluetoothDeviceDiscoveryAgent::Error>();
// Intialize the discovery agent
remoteDeviceDiscoveryAgent = new WinBluetoothDeviceDiscoveryAgent(this);
#else
// Intialize the discovery agent
remoteDeviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(localDevice->address());
@ -564,7 +489,6 @@ void BtDeviceSelectionDialog::initializeDeviceDiscoveryAgent()
ui->clear->setEnabled(false);
return;
}
#endif
connect(remoteDeviceDiscoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
this, SLOT(addRemoteDevice(QBluetoothDeviceInfo)));
connect(remoteDeviceDiscoveryAgent, SIGNAL(finished()),
@ -572,143 +496,3 @@ void BtDeviceSelectionDialog::initializeDeviceDiscoveryAgent()
connect(remoteDeviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
this, SLOT(deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error)));
}
#if defined(Q_OS_WIN)
WinBluetoothDeviceDiscoveryAgent::WinBluetoothDeviceDiscoveryAgent(QObject *parent) : QThread(parent)
{
// Initialize the internal flags by their default values
running = false;
stopped = false;
lastError = QBluetoothDeviceDiscoveryAgent::NoError;
lastErrorToString = tr("No error");
}
WinBluetoothDeviceDiscoveryAgent::~WinBluetoothDeviceDiscoveryAgent()
{
}
bool WinBluetoothDeviceDiscoveryAgent::isActive() const
{
return running;
}
QString WinBluetoothDeviceDiscoveryAgent::errorToString() const
{
return lastErrorToString;
}
QBluetoothDeviceDiscoveryAgent::Error WinBluetoothDeviceDiscoveryAgent::error() const
{
return lastError;
}
void WinBluetoothDeviceDiscoveryAgent::run()
{
// Initialize query for device and start the lookup service
WSAQUERYSET queryset;
HANDLE hLookup;
int result = SUCCESS;
running = true;
lastError = QBluetoothDeviceDiscoveryAgent::NoError;
lastErrorToString = tr("No error");
memset(&queryset, 0, sizeof(WSAQUERYSET));
queryset.dwSize = sizeof(WSAQUERYSET);
queryset.dwNameSpace = NS_BTH;
// The LUP_CONTAINERS flag is used to signal that we are doing a device inquiry
// while LUP_FLUSHCACHE flag is used to flush the device cache for all inquiries
// and to do a fresh lookup instead.
result = WSALookupServiceBegin(&queryset, LUP_CONTAINERS | LUP_FLUSHCACHE, &hLookup);
if (result != SUCCESS) {
// Get the last error and emit a signal
lastErrorToString = qt_error_string();
lastError = QBluetoothDeviceDiscoveryAgent::PoweredOffError;
emit error(lastError);
// Announce that the inquiry finished and restore the stopped flag
running = false;
stopped = false;
return;
}
// Declare the necessary variables to collect the information
BYTE buffer[4096];
DWORD bufferLength = sizeof(buffer);
WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
memset(buffer, 0, sizeof(buffer));
pResults->dwSize = sizeof(WSAQUERYSET);
pResults->dwNameSpace = NS_BTH;
pResults->lpBlob = NULL;
//Start looking for devices
while (result == SUCCESS && !stopped){
// LUP_RETURN_NAME and LUP_RETURN_ADDR flags are used to return the name and the address of the discovered device
result = WSALookupServiceNext(hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &bufferLength, pResults);
if (result == SUCCESS) {
// Found a device
QString deviceAddress(BTH_ADDR_BUF_LEN, Qt::Uninitialized);
DWORD addressSize = BTH_ADDR_BUF_LEN;
// Collect the address of the device from the WSAQUERYSET
SOCKADDR_BTH *socketBthAddress = (SOCKADDR_BTH *) pResults->lpcsaBuffer->RemoteAddr.lpSockaddr;
// Convert the BTH_ADDR to string
if (WSAAddressToStringW((LPSOCKADDR) socketBthAddress,
sizeof (*socketBthAddress),
NULL,
reinterpret_cast<wchar_t*>(deviceAddress.data()),
&addressSize
) != 0) {
// Get the last error and emit a signal
lastErrorToString = qt_error_string();
lastError = QBluetoothDeviceDiscoveryAgent::UnknownError;
emit error(lastError);
break;
}
// Remove the round parentheses
deviceAddress.remove(')');
deviceAddress.remove('(');
// Save the name of the discovered device and truncate the address
QString deviceName = QString(pResults->lpszServiceInstanceName);
deviceAddress.truncate(BTH_ADDR_PRETTY_STRING_LEN);
// Create an object with information about the discovered device
QBluetoothDeviceInfo deviceInfo(QBluetoothAddress(deviceAddress), deviceName, 0);
// Raise a signal with information about the found remote device
emit deviceDiscovered(deviceInfo);
} else {
// Get the last error and emit a signal
lastErrorToString = qt_error_string();
lastError = QBluetoothDeviceDiscoveryAgent::UnknownError;
emit error(lastError);
}
}
// Announce that the inquiry finished and restore the stopped flag
running = false;
stopped = false;
// Restore the error status
lastError = QBluetoothDeviceDiscoveryAgent::NoError;
// End the lookup service
WSALookupServiceEnd(hLookup);
}
void WinBluetoothDeviceDiscoveryAgent::stop()
{
// Stop the inqury
stopped = true;
}
#endif

View file

@ -8,48 +8,10 @@
#include <QtBluetooth/QBluetoothLocalDevice>
#include <QtBluetooth/QBluetoothDeviceDiscoveryAgent>
#if defined(Q_OS_WIN)
#include <QThread>
#include <winsock2.h>
#include <ws2bth.h>
#define SUCCESS 0
#define BTH_ADDR_BUF_LEN 40
#define BTH_ADDR_PRETTY_STRING_LEN 17 // there are 6 two-digit hex values and 5 colons
#undef ERROR // this is already declared in our headers
#undef IGNORE // this is already declared in our headers
#undef DC_VERSION // this is already declared in libdivecomputer header
#endif
namespace Ui {
class BtDeviceSelectionDialog;
}
#if defined(Q_OS_WIN)
class WinBluetoothDeviceDiscoveryAgent : public QThread {
Q_OBJECT
signals:
void deviceDiscovered(const QBluetoothDeviceInfo &info);
void error(QBluetoothDeviceDiscoveryAgent::Error error);
public:
WinBluetoothDeviceDiscoveryAgent(QObject *parent);
~WinBluetoothDeviceDiscoveryAgent();
bool isActive() const;
QString errorToString() const;
QBluetoothDeviceDiscoveryAgent::Error error() const;
void run() override;
void stop();
private:
bool running;
bool stopped;
QString lastErrorToString;
QBluetoothDeviceDiscoveryAgent::Error lastError;
};
#endif
class BtDeviceSelectionDialog : public QDialog {
Q_OBJECT
@ -78,12 +40,8 @@ private slots:
private:
Ui::BtDeviceSelectionDialog *ui;
#if defined(Q_OS_WIN)
WinBluetoothDeviceDiscoveryAgent *remoteDeviceDiscoveryAgent;
#else
QBluetoothLocalDevice *localDevice;
QBluetoothDeviceDiscoveryAgent *remoteDeviceDiscoveryAgent;
#endif
QScopedPointer<QBluetoothDeviceInfo> selectedRemoteDeviceInfo;
void updateLocalDeviceInformation();