summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndre de la Rocha <andre.rocha@qt.io>2018-11-23 18:04:40 +0100
committerAndre de la Rocha <andre.rocha@qt.io>2019-08-05 09:16:09 +0200
commit8b7b52d66f2616040ca4aaae3f2732be96e19ab8 (patch)
treebfc38942bd95718030a142540821f28911a611ef /src
parent5a2c8a39d76d634161e87b1c55d36cbbcc778289 (diff)
Enable the use of the Win32 Bluetooth backend
This change enables the optional use of the Win32-based Bluetooth backend on Windows. By default, the WinRT backend is used, if supported by the platform. The use of the Win32 backend must be selected by the -native-win32-bluetooth configuration option. Task-number: QTBUG-40698 Change-Id: I6904bf077467d826e3ff5ad026ebae5f955f2e37 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/bluetooth/bluetooth.pro3
-rw-r--r--src/bluetooth/configure.json16
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp43
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_win.cpp32
-rw-r--r--src/bluetooth/qbluetoothserver.cpp3
-rw-r--r--src/bluetooth/qbluetoothserver_android.cpp5
-rw-r--r--src/bluetooth/qbluetoothserver_bluez.cpp5
-rw-r--r--src/bluetooth/qbluetoothserver_p.cpp6
-rw-r--r--src/bluetooth/qbluetoothserver_p.h10
-rw-r--r--src/bluetooth/qbluetoothserver_win.cpp162
-rw-r--r--src/bluetooth/qbluetoothserver_winrt.cpp6
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent.h4
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_p.h1
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_win.cpp157
-rw-r--r--src/bluetooth/qbluetoothserviceinfo_p.h13
-rw-r--r--src/bluetooth/qbluetoothserviceinfo_win.cpp59
-rw-r--r--src/bluetooth/qbluetoothsocket_win.cpp168
-rw-r--r--src/bluetooth/qbluetoothsocket_win_p.h5
-rw-r--r--src/bluetooth/qbluetoothtransfermanager.cpp4
-rw-r--r--src/bluetooth/qlowenergycontroller.cpp1
-rw-r--r--src/bluetooth/qlowenergycontroller_p.h1
-rw-r--r--src/bluetooth/qlowenergycontroller_win.cpp90
22 files changed, 497 insertions, 297 deletions
diff --git a/src/bluetooth/bluetooth.pro b/src/bluetooth/bluetooth.pro
index eedd4864..a2fd617d 100644
--- a/src/bluetooth/bluetooth.pro
+++ b/src/bluetooth/bluetooth.pro
@@ -252,9 +252,6 @@ qtConfig(bluez) {
include(windows/windows.pri)
- # remove dummy warning once platform port is complete
- include(dummy/dummy.pri)
-
SOURCES += \
qbluetoothdevicediscoveryagent_win.cpp \
qbluetoothlocaldevice_win.cpp \
diff --git a/src/bluetooth/configure.json b/src/bluetooth/configure.json
index 53923e12..3bd95903 100644
--- a/src/bluetooth/configure.json
+++ b/src/bluetooth/configure.json
@@ -2,6 +2,12 @@
"module": "bluetooth",
"testDir": "../../config.tests",
+ "commandline": {
+ "options": {
+ "native-win32-bluetooth": "boolean"
+ }
+ },
+
"libraries": {
"bluez": {
"label": "BlueZ",
@@ -52,9 +58,16 @@
"condition": "features.bluez_le && tests.linux_crypto_api",
"output": [ "privateFeature" ]
},
+ "native-win32-bluetooth": {
+ "label": "Native Win32 Bluetooth",
+ "purpose": "Uses the native Win32 Bluetooth backend.",
+ "section": "Qt Bluetooth",
+ "autoDetect": false,
+ "output": [ "publicFeature", "feature" ]
+ },
"winrt_bt": {
"label": "WinRT Bluetooth API (desktop & UWP)",
- "condition": "config.win32 && tests.winrt_bt",
+ "condition": "config.win32 && !features.native-win32-bluetooth && tests.winrt_bt",
"output": [ "privateFeature" ]
},
"winrt_btle_no_pairing": {
@@ -85,6 +98,7 @@ Only classic Bluetooth will be available."
"bluez",
"bluez_le",
"linux_crypto_api",
+ "native-win32-bluetooth",
"winrt_bt",
"winrt_btle_no_pairing"
]
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp
index 3645bd21..159428d4 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp
@@ -154,7 +154,7 @@ static QBluetoothDeviceInfo findFirstClassicDevice(
*systemErrorCode = NO_ERROR;
foundDevice = createClassicDeviceInfo(deviceInfo);
} else {
- *systemErrorCode = ::GetLastError();
+ *systemErrorCode = int(::GetLastError());
}
return foundDevice;
@@ -168,7 +168,7 @@ static QBluetoothDeviceInfo findNextClassicDevice(
QBluetoothDeviceInfo foundDevice;
if (!::BluetoothFindNextDevice(hSearch, &deviceInfo)) {
- *systemErrorCode = ::GetLastError();
+ *systemErrorCode = int(::GetLastError());
} else {
*systemErrorCode = NO_ERROR;
foundDevice = createClassicDeviceInfo(deviceInfo);
@@ -186,6 +186,7 @@ static void closeClassicSearch(HBLUETOOTH_DEVICE_FIND hSearch)
static QVector<QBluetoothDeviceInfo> enumerateLeDevices(
DWORD *systemErrorCode)
{
+ // GUID_BLUETOOTHLE_DEVICE_INTERFACE
const QUuid deviceInterfaceGuid("781aee18-7733-4ce4-add0-91f41c67b592");
const HDEVINFO hDeviceInfo = ::SetupDiGetClassDevs(
reinterpret_cast<const GUID *>(&deviceInterfaceGuid),
@@ -194,7 +195,7 @@ static QVector<QBluetoothDeviceInfo> enumerateLeDevices(
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDeviceInfo == INVALID_HANDLE_VALUE) {
- *systemErrorCode = ::GetLastError();
+ *systemErrorCode = int(::GetLastError());
return QVector<QBluetoothDeviceInfo>();
}
@@ -213,7 +214,7 @@ static QVector<QBluetoothDeviceInfo> enumerateLeDevices(
reinterpret_cast<const GUID *>(&deviceInterfaceGuid),
index++,
&deviceInterfaceData)) {
- *systemErrorCode = ::GetLastError();
+ *systemErrorCode = int(::GetLastError());
break;
}
@@ -226,7 +227,7 @@ static QVector<QBluetoothDeviceInfo> enumerateLeDevices(
&deviceInterfaceDetailDataSize,
nullptr)) {
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
- *systemErrorCode = ::GetLastError();
+ *systemErrorCode = int(::GetLastError());
break;
}
}
@@ -251,7 +252,7 @@ static QVector<QBluetoothDeviceInfo> enumerateLeDevices(
deviceInterfaceDetailDataBuffer.size(),
&deviceInterfaceDetailDataSize,
&deviceInfoData)) {
- *systemErrorCode = ::GetLastError();
+ *systemErrorCode = int(::GetLastError());
break;
}
@@ -534,28 +535,20 @@ void QBluetoothDeviceDiscoveryAgentPrivate::processDiscoveredDevice(
auto end = discoveredDevices.end();
auto deviceIt = std::find_if(discoveredDevices.begin(), end, equalAddress);
if (deviceIt == end) {
- qCDebug(QT_BT_WINDOWS) << "Emit: " << foundDevice.address();
+ qCDebug(QT_BT_WINDOWS) << "Found device: " << foundDevice.name() << foundDevice.address();
discoveredDevices.append(foundDevice);
emit q->deviceDiscovered(foundDevice);
- } else if (*deviceIt == foundDevice
- || deviceIt->coreConfigurations() == foundDevice.coreConfigurations()) {
- qCDebug(QT_BT_WINDOWS) << "Duplicate: " << foundDevice.address();
} else {
- // We assume that if the existing device it is low energy, it means that
- // the found device should be as classic, because it is impossible to get
- // same low energy device.
- if (deviceIt->coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration)
- *deviceIt = foundDevice;
-
- // We assume that it is impossible to have multiple devices with same core
- // configurations, which have one address. This possible only in case a device
- // provided both low energy and classic features at the same time.
- deviceIt->setCoreConfigurations(QBluetoothDeviceInfo::BaseRateAndLowEnergyCoreConfiguration);
- deviceIt->setCached(foundDevice.isCached());
-
- Q_Q(QBluetoothDeviceDiscoveryAgent);
- qCDebug(QT_BT_WINDOWS) << "Updated: " << deviceIt->address();
- emit q->deviceDiscovered(*deviceIt);
+ qCDebug(QT_BT_WINDOWS) << "Updating device:" << deviceIt->name() << deviceIt->address();
+ // merge service uuids
+ QList<QBluetoothUuid> uuids = deviceIt->serviceUuids();
+ uuids.append(foundDevice.serviceUuids());
+ const QSet<QBluetoothUuid> uuidSet = uuids.toSet();
+ if (deviceIt->serviceUuids().count() != uuidSet.count())
+ deviceIt->setServiceUuids(uuidSet.toList().toVector());
+ if (deviceIt->coreConfigurations() != foundDevice.coreConfigurations())
+ deviceIt->setCoreConfigurations(
+ QBluetoothDeviceInfo::BaseRateAndLowEnergyCoreConfiguration);
}
}
diff --git a/src/bluetooth/qbluetoothlocaldevice_win.cpp b/src/bluetooth/qbluetoothlocaldevice_win.cpp
index a3f3c339..cf17cad1 100644
--- a/src/bluetooth/qbluetoothlocaldevice_win.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_win.cpp
@@ -100,39 +100,34 @@ void QBluetoothLocalDevice::setHostMode(
return;
if (requestedMode == QBluetoothLocalDevice::HostPoweredOff) {
- if (::BluetoothIsDiscoverable(NULL)
- && !::BluetoothEnableDiscovery(NULL, FALSE)) {
+ if (::BluetoothIsDiscoverable(nullptr)
+ && !::BluetoothEnableDiscovery(nullptr, FALSE)) {
qCWarning(QT_BT_WINDOWS) << "Unable to disable the discoverable mode";
emit error(QBluetoothLocalDevice::UnknownError);
return;
}
- if (::BluetoothIsConnectable(NULL)
- && !::BluetoothEnableIncomingConnections(NULL, FALSE)) {
+ if (::BluetoothIsConnectable(nullptr)
+ && !::BluetoothEnableIncomingConnections(nullptr, FALSE)) {
qCWarning(QT_BT_WINDOWS) << "Unable to disable the connectable mode";
emit error(QBluetoothLocalDevice::UnknownError);
return;
}
} else if (requestedMode == QBluetoothLocalDevice::HostConnectable) {
- if (::BluetoothIsDiscoverable(NULL)) {
- if (!::BluetoothEnableDiscovery(NULL, FALSE)) {
- qCWarning(QT_BT_WINDOWS) << "Unable to disable the discoverable mode";
- emit error(QBluetoothLocalDevice::UnknownError);
- return;
- }
- } else if (!::BluetoothEnableIncomingConnections(NULL, TRUE)) {
+ if (!::BluetoothIsConnectable(nullptr)
+ && !::BluetoothEnableIncomingConnections(nullptr, TRUE)) {
qCWarning(QT_BT_WINDOWS) << "Unable to enable the connectable mode";
emit error(QBluetoothLocalDevice::UnknownError);
return;
}
} else if (requestedMode == QBluetoothLocalDevice::HostDiscoverable
|| requestedMode == QBluetoothLocalDevice::HostDiscoverableLimitedInquiry) {
- if (!::BluetoothIsConnectable(NULL)
- && !::BluetoothEnableIncomingConnections(NULL, TRUE)) {
+ if (!::BluetoothIsConnectable(nullptr)
+ && !::BluetoothEnableIncomingConnections(nullptr, TRUE)) {
qCWarning(QT_BT_WINDOWS) << "Unable to enable the connectable mode";
emit error(QBluetoothLocalDevice::UnknownError);
return;
}
- if (!::BluetoothEnableDiscovery(NULL, TRUE)) {
+ if (!::BluetoothEnableDiscovery(nullptr, TRUE)) {
qCWarning(QT_BT_WINDOWS) << "Unable to enable the discoverable mode";
emit error(QBluetoothLocalDevice::UnknownError);
return;
@@ -149,9 +144,9 @@ QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const
return HostPoweredOff;
}
- if (::BluetoothIsDiscoverable(NULL))
+ if (::BluetoothIsDiscoverable(nullptr))
return HostDiscoverable;
- if (::BluetoothIsConnectable(NULL))
+ if (::BluetoothIsConnectable(nullptr))
return HostConnectable;
return HostPoweredOff;
}
@@ -170,18 +165,21 @@ void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pai
{
Q_UNUSED(address);
Q_UNUSED(pairing);
+ Q_UNIMPLEMENTED();
}
QBluetoothLocalDevice::Pairing QBluetoothLocalDevice::pairingStatus(
const QBluetoothAddress &address) const
{
Q_UNUSED(address);
+ Q_UNIMPLEMENTED();
return Unpaired;
}
void QBluetoothLocalDevice::pairingConfirmation(bool confirmation)
{
Q_UNUSED(confirmation);
+ Q_UNIMPLEMENTED();
}
QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate(
@@ -230,7 +228,7 @@ QList<QBluetoothHostInfo> QBluetoothLocalDevicePrivate::localAdapters()
QList<QBluetoothHostInfo> foundAdapters;
- HANDLE hRadio = 0;
+ HANDLE hRadio = nullptr;
if (const HBLUETOOTH_RADIO_FIND hSearch = ::BluetoothFindFirstRadio(&params, &hRadio)) {
for (;;) {
BLUETOOTH_RADIO_INFO radio;
diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp
index 6991518f..75ac9979 100644
--- a/src/bluetooth/qbluetoothserver.cpp
+++ b/src/bluetooth/qbluetoothserver.cpp
@@ -167,9 +167,8 @@ QT_BEGIN_NAMESPACE
Constructs a bluetooth server with \a parent and \a serverType.
*/
QBluetoothServer::QBluetoothServer(QBluetoothServiceInfo::Protocol serverType, QObject *parent)
- : QObject(parent), d_ptr(new QBluetoothServerPrivate(serverType))
+ : QObject(parent), d_ptr(new QBluetoothServerPrivate(serverType, this))
{
- d_ptr->q_ptr = this;
}
/*!
diff --git a/src/bluetooth/qbluetoothserver_android.cpp b/src/bluetooth/qbluetoothserver_android.cpp
index 4c469c76..eed3a1ea 100644
--- a/src/bluetooth/qbluetoothserver_android.cpp
+++ b/src/bluetooth/qbluetoothserver_android.cpp
@@ -53,9 +53,10 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
QHash<QBluetoothServerPrivate*, int> __fakeServerPorts;
-QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
+QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType,
+ QBluetoothServer *parent)
: socket(0),maxPendingConnections(1), securityFlags(QBluetooth::NoSecurity), serverType(sType),
- m_lastError(QBluetoothServer::NoError)
+ m_lastError(QBluetoothServer::NoError), q_ptr(parent)
{
thread = new ServerAcceptanceThread();
thread->setMaxPendingConnections(maxPendingConnections);
diff --git a/src/bluetooth/qbluetoothserver_bluez.cpp b/src/bluetooth/qbluetoothserver_bluez.cpp
index 54bc85a0..a98f5398 100644
--- a/src/bluetooth/qbluetoothserver_bluez.cpp
+++ b/src/bluetooth/qbluetoothserver_bluez.cpp
@@ -66,9 +66,10 @@ QBluetoothSocket *QBluetoothServerPrivate::createSocketForServer(
return socket;
}
-QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
+QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType,
+ QBluetoothServer *parent)
: maxPendingConnections(1), securityFlags(QBluetooth::Authorization), serverType(sType),
- m_lastError(QBluetoothServer::NoError)
+ m_lastError(QBluetoothServer::NoError), q_ptr(parent)
{
if (sType == QBluetoothServiceInfo::RfcommProtocol)
socket = createSocketForServer(QBluetoothServiceInfo::RfcommProtocol);
diff --git a/src/bluetooth/qbluetoothserver_p.cpp b/src/bluetooth/qbluetoothserver_p.cpp
index 4f28c9b1..6657e151 100644
--- a/src/bluetooth/qbluetoothserver_p.cpp
+++ b/src/bluetooth/qbluetoothserver_p.cpp
@@ -46,8 +46,10 @@
QT_BEGIN_NAMESPACE
-QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
- : maxPendingConnections(1), serverType(sType), m_lastError(QBluetoothServer::NoError)
+QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType,
+ QBluetoothServer *parent)
+ : maxPendingConnections(1), serverType(sType), m_lastError(QBluetoothServer::NoError),
+ q_ptr(parent)
{
#ifndef QT_IOS_BLUETOOTH
printDummyWarning();
diff --git a/src/bluetooth/qbluetoothserver_p.h b/src/bluetooth/qbluetoothserver_p.h
index d78eee5f..5ace7f75 100644
--- a/src/bluetooth/qbluetoothserver_p.h
+++ b/src/bluetooth/qbluetoothserver_p.h
@@ -57,7 +57,7 @@
#include "qbluetoothserver.h"
#include "qbluetooth.h"
-#if QT_CONFIG(bluez)
+#if QT_CONFIG(bluez) || defined(QT_WIN_BLUETOOTH)
QT_FORWARD_DECLARE_CLASS(QSocketNotifier)
#endif
@@ -81,7 +81,6 @@ QT_BEGIN_NAMESPACE
class QBluetoothAddress;
class QBluetoothSocket;
-
class QBluetoothServer;
#ifndef QT_OSX_BLUETOOTH
@@ -91,7 +90,7 @@ class QBluetoothServerPrivate
Q_DECLARE_PUBLIC(QBluetoothServer)
public:
- QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol serverType);
+ QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol serverType, QBluetoothServer *parent);
~QBluetoothServerPrivate();
#if QT_CONFIG(bluez)
@@ -101,6 +100,9 @@ public:
static QBluetoothSocket *createSocketForServer(
QBluetoothServiceInfo::Protocol socketType = QBluetoothServiceInfo::RfcommProtocol);
#endif
+#if defined(QT_WIN_BLUETOOTH)
+ void _q_newConnection();
+#endif
public:
QBluetoothSocket *socket;
@@ -114,7 +116,7 @@ protected:
private:
QBluetoothServer::Error m_lastError;
-#if QT_CONFIG(bluez)
+#if QT_CONFIG(bluez) || defined(QT_WIN_BLUETOOTH)
QSocketNotifier *socketNotifier = nullptr;
#elif defined(QT_ANDROID_BLUETOOTH)
ServerAcceptanceThread *thread;
diff --git a/src/bluetooth/qbluetoothserver_win.cpp b/src/bluetooth/qbluetoothserver_win.cpp
index a9f8659e..a57d39a5 100644
--- a/src/bluetooth/qbluetoothserver_win.cpp
+++ b/src/bluetooth/qbluetoothserver_win.cpp
@@ -40,35 +40,134 @@
#include "qbluetoothserver.h"
#include "qbluetoothserver_p.h"
#include "qbluetoothsocket.h"
+#include "qbluetoothlocaldevice.h"
+
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QSocketNotifier>
+
+#include <winsock2.h>
+#include <ws2bth.h>
+#include <bluetoothapis.h>
QT_BEGIN_NAMESPACE
-QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
- : maxPendingConnections(1), serverType(sType), m_lastError(QBluetoothServer::NoError)
+Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINDOWS)
+
+QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType,
+ QBluetoothServer *parent)
+ : maxPendingConnections(1), serverType(sType), q_ptr(parent),
+ m_lastError(QBluetoothServer::NoError)
{
- if (sType == QBluetoothServiceInfo::RfcommProtocol)
- socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
- else
- socket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol);
+ Q_Q(QBluetoothServer);
+ Q_ASSERT(sType == QBluetoothServiceInfo::RfcommProtocol);
+ socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, q);
}
QBluetoothServerPrivate::~QBluetoothServerPrivate()
{
- delete socket;
+}
+
+void QBluetoothServerPrivate::_q_newConnection()
+{
+ // disable socket notifier until application calls nextPendingConnection().
+ socketNotifier->setEnabled(false);
+
+ emit q_ptr->newConnection();
}
void QBluetoothServer::close()
{
+ Q_D(QBluetoothServer);
+
+ delete d->socketNotifier;
+ d->socketNotifier = nullptr;
+
+ d->socket->close();
}
bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
{
- Q_UNUSED(address);
- Q_UNUSED(port);
Q_D(QBluetoothServer);
- d->m_lastError = UnsupportedProtocolError;
- emit error(d->m_lastError);
- return false;
+
+ if (d->serverType != QBluetoothServiceInfo::RfcommProtocol) {
+ qCWarning(QT_BT_WINDOWS) << "Protocol is not supported.";
+ d->m_lastError = QBluetoothServer::UnsupportedProtocolError;
+ emit error(d->m_lastError);
+ return false;
+ }
+
+ if (d->socket->state() == QBluetoothSocket::ListeningState) {
+ qCWarning(QT_BT_WINDOWS) << "Socket already in listen mode, close server first";
+ return false;
+ }
+
+ const QBluetoothLocalDevice device(address);
+ if (!device.isValid()) {
+ qCWarning(QT_BT_WINDOWS) << "Device does not support Bluetooth or"
+ << address.toString() << "is not a valid local adapter";
+ d->m_lastError = QBluetoothServer::UnknownError;
+ emit error(d->m_lastError);
+ return false;
+ }
+
+ const QBluetoothLocalDevice::HostMode hostMode = device.hostMode();
+ if (hostMode == QBluetoothLocalDevice::HostPoweredOff) {
+ d->m_lastError = QBluetoothServer::PoweredOffError;
+ emit error(d->m_lastError);
+ qCWarning(QT_BT_WINDOWS) << "Bluetooth device is powered off";
+ return false;
+ }
+
+ int sock = d->socket->socketDescriptor();
+ if (sock < 0) {
+ /* Negative socket descriptor is not always an error case.
+ * Another cause could be a call to close()/abort().
+ * Check whether we can recover by re-creating the socket.
+ */
+ delete d->socket;
+ d->socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, this);
+ sock = d->socket->socketDescriptor();
+ if (sock < 0) {
+ d->m_lastError = InputOutputError;
+ emit error(d->m_lastError);
+ return false;
+ }
+ }
+
+ if (sock < 0)
+ return false;
+
+ SOCKADDR_BTH addr = {};
+ addr.addressFamily = AF_BTH;
+ addr.port = (port == 0) ? BT_PORT_ANY : port;
+ addr.btAddr = address.toUInt64();
+
+ if (::bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(SOCKADDR_BTH)) < 0) {
+ if (errno == EADDRINUSE)
+ d->m_lastError = ServiceAlreadyRegisteredError;
+ else
+ d->m_lastError = InputOutputError;
+ emit error(d->m_lastError);
+ return false;
+ }
+
+ if (::listen(sock, d->maxPendingConnections) < 0) {
+ d->m_lastError = InputOutputError;
+ emit error(d->m_lastError);
+ return false;
+ }
+
+ d->socket->setSocketState(QBluetoothSocket::ListeningState);
+
+ if (!d->socketNotifier) {
+ d->socketNotifier = new QSocketNotifier(d->socket->socketDescriptor(),
+ QSocketNotifier::Read, this);
+ connect(d->socketNotifier, &QSocketNotifier::activated, this, [d](){
+ d->_q_newConnection();
+ });
+ }
+
+ return true;
}
void QBluetoothServer::setMaxPendingConnections(int numConnections)
@@ -78,22 +177,53 @@ void QBluetoothServer::setMaxPendingConnections(int numConnections)
bool QBluetoothServer::hasPendingConnections() const
{
- return false;
+ Q_D(const QBluetoothServer);
+
+ if (!d || !d->socketNotifier)
+ return false;
+
+ // if the socket notifier is disabled there is a pending connection waiting for us to accept.
+ return !d->socketNotifier->isEnabled();
}
QBluetoothSocket *QBluetoothServer::nextPendingConnection()
{
- return 0;
+ Q_D(QBluetoothServer);
+
+ if (!hasPendingConnections())
+ return nullptr;
+
+ if (d->serverType != QBluetoothServiceInfo::RfcommProtocol)
+ return nullptr;
+
+ SOCKADDR_BTH addr = {};
+ int length = sizeof(SOCKADDR_BTH);
+ int pending = ::accept(d->socket->socketDescriptor(),
+ reinterpret_cast<sockaddr *>(&addr), &length);
+
+ QBluetoothSocket *newSocket = nullptr;
+
+ if (pending >= 0) {
+ newSocket = new QBluetoothSocket();
+ newSocket->setSocketDescriptor(pending, QBluetoothServiceInfo::RfcommProtocol);
+ }
+
+ d->socketNotifier->setEnabled(true);
+ return newSocket;
}
QBluetoothAddress QBluetoothServer::serverAddress() const
{
- return QBluetoothAddress();
+ Q_D(const QBluetoothServer);
+
+ return d->socket->localAddress();
}
quint16 QBluetoothServer::serverPort() const
{
- return 0;
+ Q_D(const QBluetoothServer);
+
+ return d->socket->localPort();
}
void QBluetoothServer::setSecurityFlags(QBluetooth::SecurityFlags security)
diff --git a/src/bluetooth/qbluetoothserver_winrt.cpp b/src/bluetooth/qbluetoothserver_winrt.cpp
index 3bcd6b33..b9d98eb7 100644
--- a/src/bluetooth/qbluetoothserver_winrt.cpp
+++ b/src/bluetooth/qbluetoothserver_winrt.cpp
@@ -70,8 +70,10 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINRT)
QHash<QBluetoothServerPrivate *, int> __fakeServerPorts;
-QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
- : maxPendingConnections(1), serverType(sType), m_lastError(QBluetoothServer::NoError), socket(0)
+QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType,
+ QBluetoothServer *parent)
+ : maxPendingConnections(1), serverType(sType), m_lastError(QBluetoothServer::NoError),
+ socket(0), q_ptr(parent)
{
#ifdef CLASSIC_APP_BUILD
CoInitialize(NULL);
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.h b/src/bluetooth/qbluetoothservicediscoveryagent.h
index 8533ab72..f1fa4640 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent.h
+++ b/src/bluetooth/qbluetoothservicediscoveryagent.h
@@ -111,10 +111,6 @@ Q_SIGNALS:
private:
QBluetoothServiceDiscoveryAgentPrivate *d_ptr;
-
-#ifdef QT_WIN_BLUETOOTH
- Q_PRIVATE_SLOT(d_func(), void _q_nextSdpScan(QVariant input))
-#endif
};
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_p.h b/src/bluetooth/qbluetoothservicediscoveryagent_p.h
index 4a522826..cb588f70 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_p.h
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_p.h
@@ -165,6 +165,7 @@ public:
#endif
#ifdef QT_WIN_BLUETOOTH
void _q_nextSdpScan(const QVariant &input);
+ bool serviceMatches(const QBluetoothServiceInfo &info);
#endif
private:
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_win.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_win.cpp
index 98ec1952..c34443aa 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_win.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_win.cpp
@@ -49,55 +49,30 @@
#include <initguid.h>
#include <winsock2.h>
#include <qt_windows.h>
-#include <bluetoothapis.h>
-#include <ws2bth.h>
-
-Q_GLOBAL_STATIC(QLibrary, bluetoothapis)
-
-#define DEFINEFUNC(ret, func, ...) \
- typedef ret (WINAPI *fp_##func)(__VA_ARGS__); \
- static fp_##func p##func;
-#define RESOLVEFUNC(func) \
- p##func = (fp_##func)resolveFunction(library, #func); \
- if (!p##func) \
- return false;
+#if defined(Q_CC_MINGW)
+// Workaround for MinGW headers declaring BluetoothSdpGetElementData incorrectly.
+# define BluetoothSdpGetElementData _BluetoothSdpGetElementData_notok
+# include <bluetoothapis.h>
+# undef BluetoothSdpGetElementData
+ extern "C" DWORD WINAPI BluetoothSdpGetElementData(LPBYTE, ULONG, PSDP_ELEMENT_DATA);
+#else
+# include <bluetoothapis.h>
+#endif
-DEFINEFUNC(DWORD, BluetoothSdpGetElementData, LPBYTE, ULONG, PSDP_ELEMENT_DATA)
+#include <ws2bth.h>
+#include <iostream>
QT_BEGIN_NAMESPACE
struct FindServiceResult {
QBluetoothServiceInfo info;
- Qt::HANDLE hSearch;
- int systemError;
+ Qt::HANDLE hSearch = INVALID_HANDLE_VALUE;
+ int systemError = NO_ERROR;
};
Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINDOWS)
-static inline QFunctionPointer resolveFunction(QLibrary *library, const char *func)
-{
- const QFunctionPointer symbolFunctionPointer = library->resolve(func);
- if (!symbolFunctionPointer)
- qWarning("Cannot resolve '%s' in '%s'.", func, qPrintable(library->fileName()));
- return symbolFunctionPointer;
-}
-
-static inline bool resolveFunctions(QLibrary *library)
-{
- if (!library->isLoaded()) {
- library->setFileName(QStringLiteral("bluetoothapis"));
- if (!library->load()) {
- qWarning("Unable to load '%s' library.", qPrintable(library->fileName()));
- return false;
- }
- }
-
- RESOLVEFUNC(BluetoothSdpGetElementData)
-
- return true;
-}
-
static QList<QVariant> spdContainerToVariantList(LPBYTE containerStream, ULONG containerLength);
static QVariant spdElementToVariant(const SDP_ELEMENT_DATA &element)
@@ -152,19 +127,15 @@ static QVariant spdElementToVariant(const SDP_ELEMENT_DATA &element)
}
case SDP_TYPE_UUID: {
switch (element.specificType) {
- case SDP_ST_UUID128: {
- //Not sure if this will work, might be evil
- Q_ASSERT(sizeof(element.data.uuid128) == sizeof(quint128));
-
- quint128 uuid128;
- memcpy(&uuid128, &(element.data.uuid128), sizeof(quint128));
-
- variant = QVariant::fromValue(QBluetoothUuid(uuid128));
- }
+ case SDP_ST_UUID128:
+ variant = QVariant::fromValue(QBluetoothUuid(element.data.uuid128));
+ break;
case SDP_ST_UUID32:
variant = QVariant::fromValue(QBluetoothUuid(quint32(element.data.uuid32)));
+ break;
case SDP_ST_UUID16:
variant = QVariant::fromValue(QBluetoothUuid(quint16(element.data.uuid16)));
+ break;
default:
break;
}
@@ -177,7 +148,7 @@ static QVariant spdElementToVariant(const SDP_ELEMENT_DATA &element)
}
case SDP_TYPE_URL: {
const QString urlString = QString::fromLocal8Bit(reinterpret_cast<const char*>(element.data.url.value),
- (int)element.data.url.length);
+ int(element.data.url.length));
const QUrl url(urlString);
if (url.isValid())
variant = QVariant::fromValue<QUrl>(url);
@@ -198,7 +169,7 @@ static QVariant spdElementToVariant(const SDP_ELEMENT_DATA &element)
break;
}
case SDP_TYPE_BOOLEAN:
- variant = QVariant::fromValue<bool>((bool)element.data.booleanVal);
+ variant = QVariant::fromValue<bool>(bool(element.data.booleanVal));
break;
case SDP_TYPE_NIL:
break;
@@ -211,13 +182,13 @@ static QVariant spdElementToVariant(const SDP_ELEMENT_DATA &element)
static QList<QVariant> spdContainerToVariantList(LPBYTE containerStream, ULONG containerLength)
{
- HBLUETOOTH_CONTAINER_ELEMENT iter = NULL;
- SDP_ELEMENT_DATA element;
+ HBLUETOOTH_CONTAINER_ELEMENT iter = nullptr;
+ SDP_ELEMENT_DATA element = {};
QList<QVariant> sequence;
for (;;) {
- const DWORD result = BluetoothSdpGetContainerElementData(containerStream,
+ const DWORD result = ::BluetoothSdpGetContainerElementData(containerStream,
containerLength,
&iter,
&element);
@@ -244,9 +215,9 @@ static BOOL SDP_CALLBACK bluetoothSdpCallback(ULONG attributeId, LPBYTE valueStr
{
QBluetoothServiceInfo *result = static_cast<QBluetoothServiceInfo*>(param);
- SDP_ELEMENT_DATA element;
+ SDP_ELEMENT_DATA element = {};
- if (pBluetoothSdpGetElementData(valueStream, streamSize, &element) == ERROR_SUCCESS)
+ if (::BluetoothSdpGetElementData(valueStream, streamSize, &element) == ERROR_SUCCESS) {
switch (element.type) {
case SDP_TYPE_UINT:
case SDP_TYPE_INT:
@@ -257,6 +228,7 @@ static BOOL SDP_CALLBACK bluetoothSdpCallback(ULONG attributeId, LPBYTE valueStr
case SDP_TYPE_SEQUENCE:
case SDP_TYPE_ALTERNATIVE: {
const QVariant variant = spdElementToVariant(element);
+
result->setAttribute(attributeId, variant);
break;
}
@@ -265,7 +237,7 @@ static BOOL SDP_CALLBACK bluetoothSdpCallback(ULONG attributeId, LPBYTE valueStr
default:
break;
}
-
+ }
return true;
}
@@ -281,13 +253,12 @@ enum {
static FindServiceResult findNextService(HANDLE hSearch)
{
FindServiceResult result;
- result.systemError = NO_ERROR;
result.hSearch = hSearch;
QByteArray resultBuffer(2048, 0);
WSAQUERYSET *resultQuery = reinterpret_cast<WSAQUERYSET*>(resultBuffer.data());
DWORD resultBufferSize = DWORD(resultBuffer.size());
- const int resultCode = WSALookupServiceNext(hSearch,
+ const int resultCode = ::WSALookupServiceNext(hSearch,
WSAControlFlags,
&resultBufferSize,
resultQuery);
@@ -295,12 +266,12 @@ static FindServiceResult findNextService(HANDLE hSearch)
if (resultCode == SOCKET_ERROR) {
result.systemError = ::WSAGetLastError();
if (result.systemError == WSA_E_NO_MORE)
- WSALookupServiceEnd(hSearch);
+ ::WSALookupServiceEnd(hSearch);
return result;
}
if (resultQuery->lpBlob
- && BluetoothSdpEnumAttributes(resultQuery->lpBlob->pBlobData,
+ && ::BluetoothSdpEnumAttributes(resultQuery->lpBlob->pBlobData,
resultQuery->lpBlob->cbSize,
bluetoothSdpCallback,
&result.info)) {
@@ -313,38 +284,35 @@ static FindServiceResult findNextService(HANDLE hSearch)
static FindServiceResult findFirstService(const QBluetoothAddress &address)
{
- //### should we try for 2.2 on all platforms ??
- WSAData wsadata;
+ WSAData wsadata = {};
FindServiceResult result;
- result.hSearch = INVALID_HANDLE_VALUE;
// IPv6 requires Winsock v2.0 or better.
- if (WSAStartup(MAKEWORD(2, 0), &wsadata) != 0) {
+ if (::WSAStartup(MAKEWORD(2, 0), &wsadata) != 0) {
result.systemError = ::WSAGetLastError();
return result;
}
const QString addressAsString = QStringLiteral("(%1)").arg(address.toString());
-
- QVector<WCHAR> addressAsWChar(addressAsString.size());
+ QVector<WCHAR> addressAsWChar(addressAsString.size() + 1);
addressAsString.toWCharArray(addressAsWChar.data());
GUID protocol = L2CAP_PROTOCOL_UUID; //Search for L2CAP and RFCOMM services
WSAQUERYSET serviceQuery = {};
- serviceQuery.dwSize = sizeof(WSAQUERYSET); //As specified by the windows documentation
- serviceQuery.lpServiceClassId = &protocol; //The protocal of the service what is being queried
- serviceQuery.dwNameSpace = NS_BTH; //As specified by the windows documentation
- serviceQuery.dwNumberOfCsAddrs = 0; //As specified by the windows documentation
- serviceQuery.lpszContext = addressAsWChar.data(); //The remote address that query will run on
-
- HANDLE hSearch;
- const int resultCode = WSALookupServiceBegin(&serviceQuery,
+ serviceQuery.dwSize = sizeof(WSAQUERYSET);
+ serviceQuery.lpServiceClassId = &protocol;
+ serviceQuery.dwNameSpace = NS_BTH;
+ serviceQuery.dwNumberOfCsAddrs = 0;
+ serviceQuery.lpszContext = addressAsWChar.data();
+
+ HANDLE hSearch = nullptr;
+ const int resultCode = ::WSALookupServiceBegin(&serviceQuery,
WSAControlFlags,
&hSearch);
if (resultCode == SOCKET_ERROR) {
result.systemError = ::WSAGetLastError();
- WSALookupServiceEnd(hSearch);
+ ::WSALookupServiceEnd(hSearch);
return result;
}
return findNextService(hSearch);
@@ -363,8 +331,6 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
{
Q_UNUSED(deviceAdapter);
- resolveFunctions(bluetoothapis());
-
threadFind = new QThread;
threadWorkerFind = new ThreadWorkerFind;
threadWorkerFind->moveToThread(threadFind);
@@ -376,9 +342,8 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
QBluetoothServiceDiscoveryAgentPrivate::~QBluetoothServiceDiscoveryAgentPrivate()
{
- if (pendingFinish) {
+ if (pendingFinish)
stop();
- }
if (threadFind)
threadFind->quit();
}
@@ -392,7 +357,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr
const auto threadWorker = threadWorkerFind;
QMetaObject::invokeMethod(threadWorkerFind, [threadWorker, address]()
{
- FindServiceResult result = findFirstService(address);
+ const FindServiceResult result = findFirstService(address);
emit threadWorker->findFinished(QVariant::fromValue(result));
}, Qt::QueuedConnection);
}
@@ -403,13 +368,29 @@ void QBluetoothServiceDiscoveryAgentPrivate::stop()
pendingStop = true;
}
+bool QBluetoothServiceDiscoveryAgentPrivate::serviceMatches(const QBluetoothServiceInfo &info)
+{
+ if (uuidFilter.isEmpty())
+ return true;
+
+ if (uuidFilter.contains(info.serviceUuid()))
+ return true;
+
+ const QList<QBluetoothUuid> serviceClassUuids = info.serviceClassUuids();
+ for (const QBluetoothUuid &uuid : serviceClassUuids)
+ if (uuidFilter.contains(uuid))
+ return true;
+
+ return false;
+}
+
void QBluetoothServiceDiscoveryAgentPrivate::_q_nextSdpScan(const QVariant &input)
{
Q_Q(QBluetoothServiceDiscoveryAgent);
auto result = input.value<FindServiceResult>();
if (pendingStop) {
- WSALookupServiceEnd(result.hSearch);
+ ::WSALookupServiceEnd(result.hSearch);
pendingStop = false;
pendingFinish = false;
emit q->canceled();
@@ -418,7 +399,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_nextSdpScan(const QVariant &inpu
result.systemError = NO_ERROR;
} else if (result.systemError != NO_ERROR) {
if (result.hSearch != INVALID_HANDLE_VALUE)
- WSALookupServiceEnd(result.hSearch);
+ ::WSALookupServiceEnd(result.hSearch);
error = (result.systemError == ERROR_INVALID_HANDLE) ?
QBluetoothServiceDiscoveryAgent::InvalidBluetoothAdapterError
: QBluetoothServiceDiscoveryAgent::InputOutputError;
@@ -426,13 +407,17 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_nextSdpScan(const QVariant &inpu
qCWarning(QT_BT_WINDOWS) << errorString;
emit q->error(this->error);
} else {
- result.info.setDevice(discoveredDevices.at(0));
- if (result.info.isValid()) {
- if (!isDuplicatedService(result.info)) {
- discoveredServices.append(result.info);
- emit q->serviceDiscovered(result.info);
+
+ if (serviceMatches(result.info)) {
+ result.info.setDevice(discoveredDevices.at(0));
+ if (result.info.isValid()) {
+ if (!isDuplicatedService(result.info)) {
+ discoveredServices.append(result.info);
+ emit q->serviceDiscovered(result.info);
+ }
}
}
+
const auto threadWorker = threadWorkerFind;
const auto hSearch = result.hSearch;
QMetaObject::invokeMethod(threadWorkerFind, [threadWorker, hSearch]()
diff --git a/src/bluetooth/qbluetoothserviceinfo_p.h b/src/bluetooth/qbluetoothserviceinfo_p.h
index e4e835e4..0638867d 100644
--- a/src/bluetooth/qbluetoothserviceinfo_p.h
+++ b/src/bluetooth/qbluetoothserviceinfo_p.h
@@ -78,6 +78,11 @@ namespace ABI {
}
#endif
+#ifdef QT_WIN_BLUETOOTH
+#include <winsock2.h>
+#include <ws2bth.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QBluetoothServiceInfo;
@@ -120,6 +125,14 @@ private:
bool writeSdpAttributes();
#endif
+#ifdef QT_WIN_BLUETOOTH
+ SOCKADDR_BTH sockaddr = {};
+ CSADDR_INFO addrinfo = {};
+ WSAQUERYSET regInfo = {};
+ QVector<WCHAR> serviceName;
+ QVector<WCHAR> serviceDescription;
+#endif
+
mutable bool registered;
};
diff --git a/src/bluetooth/qbluetoothserviceinfo_win.cpp b/src/bluetooth/qbluetoothserviceinfo_win.cpp
index 6629e610..1f1293ad 100644
--- a/src/bluetooth/qbluetoothserviceinfo_win.cpp
+++ b/src/bluetooth/qbluetoothserviceinfo_win.cpp
@@ -39,10 +39,15 @@
#include "qbluetoothserviceinfo.h"
#include "qbluetoothserviceinfo_p.h"
+#include "qbluetoothserver_p.h"
+#include "qbluetoothserver.h"
+
+#include <bluetoothapis.h>
QT_BEGIN_NAMESPACE
QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate()
+ : registered(false)
{
}
@@ -52,18 +57,64 @@ QBluetoothServiceInfoPrivate::~QBluetoothServiceInfoPrivate()
bool QBluetoothServiceInfoPrivate::isRegistered() const
{
- return false;
+ return registered;
}
bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &localAdapter)
{
- Q_UNUSED(localAdapter);
- return false;
+ if (registered)
+ return false;
+
+ GUID serviceUuid = attributes.value(QBluetoothServiceInfo::ServiceId).value<QBluetoothUuid>();
+ const QString name = attributes.value(QBluetoothServiceInfo::ServiceName).toString();
+ const QString description = attributes.value(QBluetoothServiceInfo::ServiceDescription).toString();
+
+ ::memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.addressFamily = AF_BTH;
+ sockaddr.port = serverChannel();
+ sockaddr.btAddr = localAdapter.toUInt64();
+
+ ::memset(&addrinfo, 0, sizeof(addrinfo));
+ addrinfo.LocalAddr.iSockaddrLength = sizeof(SOCKADDR_BTH);
+ addrinfo.LocalAddr.lpSockaddr = (LPSOCKADDR)&sockaddr;
+ addrinfo.RemoteAddr.iSockaddrLength = sizeof(SOCKADDR_BTH);
+ addrinfo.RemoteAddr.lpSockaddr = (LPSOCKADDR)&sockaddr;
+ addrinfo.iSocketType = SOCK_STREAM;
+ addrinfo.iProtocol = BTHPROTO_RFCOMM;
+
+ serviceName.resize(name.size() + 1);
+ name.toWCharArray(serviceName.data());
+ serviceName[name.size()] = WCHAR(0);
+ serviceDescription.resize(description.size() + 1);
+ description.toWCharArray(serviceDescription.data());
+ serviceDescription[description.size()] = WCHAR(0);
+
+ ::memset(&regInfo, 0, sizeof(regInfo));
+ regInfo.dwSize = sizeof(WSAQUERYSET);
+ regInfo.dwNameSpace = NS_BTH;
+ regInfo.dwNumberOfCsAddrs = 1;
+ regInfo.lpcsaBuffer = &addrinfo;
+ regInfo.lpszServiceInstanceName = serviceName.data();
+ regInfo.lpszComment = serviceDescription.data();
+ regInfo.lpServiceClassId = &serviceUuid;
+
+ if (::WSASetService(&regInfo, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
+ return false;
+
+ registered = true;
+ return true;
}
bool QBluetoothServiceInfoPrivate::unregisterService()
{
- return false;
+ if (!registered)
+ return false;
+
+ if (::WSASetService(&regInfo, RNRSERVICE_DELETE, 0) == SOCKET_ERROR)
+ return false;
+
+ registered = false;
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothsocket_win.cpp b/src/bluetooth/qbluetoothsocket_win.cpp
index 781decad..83855323 100644
--- a/src/bluetooth/qbluetoothsocket_win.cpp
+++ b/src/bluetooth/qbluetoothsocket_win.cpp
@@ -57,6 +57,8 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINDOWS)
QBluetoothSocketPrivateWin::QBluetoothSocketPrivateWin()
: QBluetoothSocketBasePrivate()
{
+ WSAData wsadata = {};
+ ::WSAStartup(MAKEWORD(2, 0), &wsadata);
}
QBluetoothSocketPrivateWin::~QBluetoothSocketPrivateWin()
@@ -73,20 +75,17 @@ bool QBluetoothSocketPrivateWin::ensureNativeSocket(QBluetoothServiceInfo::Proto
return true;
abort();
}
-
socketType = type;
- switch (type) {
- case QBluetoothServiceInfo::RfcommProtocol:
- socket = ::socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
- break;
- default:
- socket = INVALID_SOCKET;
+ if (type != QBluetoothServiceInfo::RfcommProtocol) {
+ socket = int(INVALID_SOCKET);
errorString = QBluetoothSocket::tr("Unsupported protocol. Win32 only supports RFCOMM sockets");
q->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
return false;
}
+ socket = ::socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
+
if (static_cast<SOCKET>(socket) == INVALID_SOCKET) {
const int error = ::WSAGetLastError();
qCWarning(QT_BT_WINDOWS) << "Failed to create socket:" << error << qt_error_string(error);
@@ -157,27 +156,14 @@ void QBluetoothSocketPrivateWin::connectToService(
// we are checking the service protocol and not socketType()
// socketType will change in ensureNativeSocket()
- if (service.socketProtocol() == QBluetoothServiceInfo::UnknownProtocol) {
- qCWarning(QT_BT_WINDOWS) << "QBluetoothSocket::connectToService cannot "
- "connect with 'UnknownProtocol' (type provided by given service)";
+ if (service.socketProtocol() != QBluetoothServiceInfo::RfcommProtocol) {
+ qCWarning(QT_BT_WINDOWS) << "QBluetoothSocket::connectToService called with unsupported protocol";
errorString = QBluetoothSocket::tr("Socket type not supported");
q->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
return;
}
- if (service.protocolServiceMultiplexer() > 0) {
- Q_ASSERT(service.socketProtocol() == QBluetoothServiceInfo::L2capProtocol);
-
- if (!ensureNativeSocket(QBluetoothServiceInfo::L2capProtocol)) {
- errorString = QBluetoothSocket::tr("Unknown socket error");
- q->setSocketError(QBluetoothSocket::UnknownSocketError);
- return;
- }
- connectToServiceHelper(service.device().address(), service.protocolServiceMultiplexer(),
- openMode);
- } else if (service.serverChannel() > 0) {
- Q_ASSERT(service.socketProtocol() == QBluetoothServiceInfo::RfcommProtocol);
-
+ if (service.serverChannel() > 0) {
if (!ensureNativeSocket(QBluetoothServiceInfo::RfcommProtocol)) {
errorString = QBluetoothSocket::tr("Unknown socket error");
q->setSocketError(QBluetoothSocket::UnknownSocketError);
@@ -195,14 +181,13 @@ void QBluetoothSocketPrivateWin::connectToService(
q->doDeviceDiscovery(service, openMode);
}
}
+
void QBluetoothSocketPrivateWin::_q_writeNotify()
{
Q_Q(QBluetoothSocket);
if (state == QBluetoothSocket::ConnectingState) {
- updateAddressesAndPorts();
q->setSocketState(QBluetoothSocket::ConnectedState);
- emit q->connected();
connectWriteNotifier->setEnabled(false);
} else {
if (txBuffer.isEmpty()) {
@@ -220,7 +205,7 @@ void QBluetoothSocketPrivateWin::_q_writeNotify()
q->setSocketError(QBluetoothSocket::NetworkError);
} else if (writtenBytes <= size) {
// add remainder back to buffer
- char *remainder = &buf[writtenBytes];
+ const char *remainder = &buf[writtenBytes];
txBuffer.ungetBlock(remainder, size - writtenBytes);
if (writtenBytes > 0)
emit q->bytesWritten(writtenBytes);
@@ -264,6 +249,9 @@ void QBluetoothSocketPrivateWin::_q_readNotify()
}
q->disconnectFromService();
+ } else if (bytesRead == 0) {
+ q->setSocketError(QBluetoothSocket::RemoteHostClosedError);
+ q->setSocketState(QBluetoothSocket::UnconnectedState);
} else {
const int unusedBytes = QPRIVATELINEARBUFFER_BUFFERSIZE - bytesRead;
buffer.chop(unusedBytes);
@@ -280,11 +268,8 @@ void QBluetoothSocketPrivateWin::_q_exceptNotify()
errorString = qt_error_string(error);
q->setSocketError(QBluetoothSocket::UnknownSocketError);
- if (state == QBluetoothSocket::ConnectingState) {
+ if (state == QBluetoothSocket::ConnectingState)
abort();
- q->setSocketState(QBluetoothSocket::UnconnectedState);
- emit q->disconnected();
- }
}
void QBluetoothSocketPrivateWin::connectToService(
@@ -348,55 +333,104 @@ void QBluetoothSocketPrivateWin::abort()
delete exceptNotifier;
exceptNotifier = nullptr;
- m_localAddress.clear();
- m_localPort = 0;
- m_peerAddress.clear();
- m_peerPort = 0;
-
// We don't transition through Closing for abort, so
// we don't call disconnectFromService or QBluetoothSocket::close
::closesocket(socket);
- socket = INVALID_SOCKET;
+ socket = int(INVALID_SOCKET);
+
+ Q_Q(QBluetoothSocket);
+
+ const bool wasConnected = q->state() == QBluetoothSocket::ConnectedState;
+ q->setSocketState(QBluetoothSocket::UnconnectedState);
+ if (wasConnected) {
+ q->setOpenMode(QIODevice::NotOpen);
+ emit q->readChannelFinished();
+ }
}
QString QBluetoothSocketPrivateWin::localName() const
{
- const QBluetoothLocalDevice device(m_localAddress);
+ const QBluetoothAddress localAddr = localAddress();
+ if (localAddr == QBluetoothAddress())
+ return {};
+ const QBluetoothLocalDevice device(localAddr);
return device.name();
}
QBluetoothAddress QBluetoothSocketPrivateWin::localAddress() const
{
- return m_localAddress;
+ if (static_cast<SOCKET>(socket) == INVALID_SOCKET)
+ return {};
+ SOCKADDR_BTH localAddr = {};
+ int localAddrLength = sizeof(localAddr);
+ const int localResult = ::getsockname(socket, reinterpret_cast<sockaddr *>(&localAddr), &localAddrLength);
+ if (localResult == SOCKET_ERROR) {
+ const int error = ::WSAGetLastError();
+ qCWarning(QT_BT_WINDOWS) << "Error getting local address" << error << qt_error_string(error);
+ return {};
+ }
+ return QBluetoothAddress(localAddr.btAddr);
}
quint16 QBluetoothSocketPrivateWin::localPort() const
{
- return m_localPort;
+ if (static_cast<SOCKET>(socket) == INVALID_SOCKET)
+ return {};
+ SOCKADDR_BTH localAddr = {};
+ int localAddrLength = sizeof(localAddr);
+ const int localResult = ::getsockname(socket, reinterpret_cast<sockaddr *>(&localAddr), &localAddrLength);
+ if (localResult == SOCKET_ERROR) {
+ const int error = ::WSAGetLastError();
+ qCWarning(QT_BT_WINDOWS) << "Error getting local port" << error << qt_error_string(error);
+ return {};
+ }
+ return localAddr.port;
}
QString QBluetoothSocketPrivateWin::peerName() const
{
- if (static_cast<SOCKET>(socket) == INVALID_SOCKET)
+ const QBluetoothAddress peerAddr = peerAddress();
+ if (peerAddr == QBluetoothAddress())
return {};
BLUETOOTH_DEVICE_INFO bdi = {};
bdi.dwSize = sizeof(bdi);
- bdi.Address.ullLong = m_peerAddress.toUInt64();
+ bdi.Address.ullLong = peerAddr.toUInt64();
const DWORD res = ::BluetoothGetDeviceInfo(nullptr, &bdi);
- if (res == ERROR_SUCCESS)
- return QString::fromWCharArray(&bdi.szName[0]);
- qCWarning(QT_BT_WINDOWS) << "Error calling BluetoothGetDeviceInfo" << res << qt_error_string(res);
- return {};
+ if (res != ERROR_SUCCESS) {
+ qCWarning(QT_BT_WINDOWS) << "Error calling BluetoothGetDeviceInfo" << res << qt_error_string(res);
+ return {};
+ }
+ return QString::fromWCharArray(&bdi.szName[0]);
}
QBluetoothAddress QBluetoothSocketPrivateWin::peerAddress() const
{
- return m_peerAddress;
+ if (static_cast<SOCKET>(socket) == INVALID_SOCKET)
+ return {};
+ SOCKADDR_BTH peerAddr = {};
+ int peerAddrLength = sizeof(peerAddr);
+ const int peerResult = ::getpeername(socket, reinterpret_cast<sockaddr *>(&peerAddr), &peerAddrLength);
+ if (peerResult == SOCKET_ERROR) {
+ const int error = ::WSAGetLastError();
+ qCWarning(QT_BT_WINDOWS) << "Error getting peer address and port" << error << qt_error_string(error);
+ return {};
+ }
+ return QBluetoothAddress(peerAddr.btAddr);
}
quint16 QBluetoothSocketPrivateWin::peerPort() const
{
- return m_peerPort;
+ if (static_cast<SOCKET>(socket) == INVALID_SOCKET)
+ return {};
+ SOCKADDR_BTH peerAddr = {};
+ int peerAddrLength = sizeof(peerAddr);
+ const int peerResult = ::getpeername(socket, reinterpret_cast<sockaddr *>(&peerAddr), &peerAddrLength);
+ if (peerResult == SOCKET_ERROR) {
+ const int error = ::WSAGetLastError();
+ qCWarning(QT_BT_WINDOWS) << "Error getting peer address and port" << error << qt_error_string(error);
+ return {};
+ }
+ return peerAddr.port;
}
qint64 QBluetoothSocketPrivateWin::writeData(const char *data, qint64 maxSize)
@@ -427,8 +461,10 @@ qint64 QBluetoothSocketPrivateWin::writeData(const char *data, qint64 maxSize)
if (!connectWriteNotifier)
return -1;
- if (txBuffer.isEmpty())
+ if (txBuffer.isEmpty()) {
connectWriteNotifier->setEnabled(true);
+ QMetaObject::invokeMethod(this, "_q_writeNotify", Qt::QueuedConnection);
+ }
char *txbuf = txBuffer.reserve(maxSize);
::memcpy(txbuf, data, maxSize);
@@ -459,19 +495,20 @@ void QBluetoothSocketPrivateWin::close()
connectWriteNotifier->setEnabled(true);
}
-bool QBluetoothSocketPrivateWin::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType_,
- QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode)
+bool QBluetoothSocketPrivateWin::setSocketDescriptor(int socketDescriptor,
+ QBluetoothServiceInfo::Protocol protocol,
+ QBluetoothSocket::SocketState socketState,
+ QBluetoothSocket::OpenMode openMode)
{
Q_Q(QBluetoothSocket);
abort();
- socketType = socketType_;
+ socketType = protocol;
socket = socketDescriptor;
if (!createNotifiers())
return false;
- updateAddressesAndPorts();
q->setSocketState(socketState);
q->setOpenMode(openMode);
if (socketState == QBluetoothSocket::ConnectedState) {
@@ -526,33 +563,6 @@ bool QBluetoothSocketPrivateWin::createNotifiers()
return true;
}
-void QBluetoothSocketPrivateWin::updateAddressesAndPorts()
-{
- SOCKADDR_BTH localAddr = {};
- int localAddrLength = sizeof(localAddr);
- const int localResult = ::getsockname(socket, reinterpret_cast<sockaddr *>(&localAddr), &localAddrLength);
- if (localResult != SOCKET_ERROR) {
- m_localAddress = QBluetoothAddress(localAddr.btAddr);
- m_localPort = localAddr.port;
- } else {
- const int error = ::WSAGetLastError();
- qCWarning(QT_BT_WINDOWS) << "Error getting local address and port" << error << qt_error_string(error);
- errorString = QBluetoothSocket::tr("Cannot get socket's local address and port");
- }
-
- SOCKADDR_BTH peerAddr = {};
- int peerAddrLength = sizeof(peerAddr);
- const int peerResult = ::getpeername(socket, reinterpret_cast<sockaddr *>(&peerAddr), &peerAddrLength);
- if (peerResult != SOCKET_ERROR) {
- m_peerAddress = QBluetoothAddress(peerAddr.btAddr);
- m_peerPort = peerAddr.port;
- } else {
- const int error = ::WSAGetLastError();
- qCWarning(QT_BT_WINDOWS) << "Error getting peer address and port" << error << qt_error_string(error);
- errorString = QBluetoothSocket::tr("Cannot get socket's peer address and port");
- }
-}
-
bool QBluetoothSocketPrivateWin::configureSecurity()
{
Q_Q(QBluetoothSocket);
diff --git a/src/bluetooth/qbluetoothsocket_win_p.h b/src/bluetooth/qbluetoothsocket_win_p.h
index fe0fc99f..77f4842e 100644
--- a/src/bluetooth/qbluetoothsocket_win_p.h
+++ b/src/bluetooth/qbluetoothsocket_win_p.h
@@ -108,14 +108,9 @@ private slots:
private:
bool createNotifiers();
- void updateAddressesAndPorts();
bool configureSecurity();
QSocketNotifier *exceptNotifier = nullptr;
- QBluetoothAddress m_localAddress;
- quint16 m_localPort = 0;
- QBluetoothAddress m_peerAddress;
- quint16 m_peerPort = 0;
};
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothtransfermanager.cpp b/src/bluetooth/qbluetoothtransfermanager.cpp
index 37a3191a..d84f726c 100644
--- a/src/bluetooth/qbluetoothtransfermanager.cpp
+++ b/src/bluetooth/qbluetoothtransfermanager.cpp
@@ -121,8 +121,8 @@ QBluetoothTransferReply *QBluetoothTransferManager::put(const QBluetoothTransfer
connect(reply, SIGNAL(finished(QBluetoothTransferReply*)), this, SIGNAL(finished(QBluetoothTransferReply*)));
return reply;
#else
- // Android, iOS, and WinRT have no implementation
-#if !defined(QT_ANDROID_BLUETOOTH) && !defined(QT_IOS_BLUETOOTH) && !defined(QT_WINRT_BLUETOOTH)
+ // Android, iOS, and Win/WinRT have no implementation
+#if !defined(QT_ANDROID_BLUETOOTH) && !defined(QT_IOS_BLUETOOTH) && !defined(QT_WINRT_BLUETOOTH) && !defined(QT_WIN_BLUETOOTH)
printDummyWarning();
#endif
Q_UNUSED(request);
diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp
index c3742b76..444bfb38 100644
--- a/src/bluetooth/qlowenergycontroller.cpp
+++ b/src/bluetooth/qlowenergycontroller.cpp
@@ -324,6 +324,7 @@ static QLowEnergyControllerPrivate *privateController(QLowEnergyController::Role
return new QLowEnergyControllerPrivateWinRT();
#endif
#elif defined(QT_WIN_BLUETOOTH)
+ Q_UNUSED(role);
return new QLowEnergyControllerPrivateWin32();
#else
Q_UNUSED(role);
diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h
index fe1da852..54a49b53 100644
--- a/src/bluetooth/qlowenergycontroller_p.h
+++ b/src/bluetooth/qlowenergycontroller_p.h
@@ -104,7 +104,6 @@ public:
const QByteArray &newValue) override;
void addToGenericAttributeList(const QLowEnergyServiceData &service,
-
QLowEnergyHandle startHandle) override;
};
diff --git a/src/bluetooth/qlowenergycontroller_win.cpp b/src/bluetooth/qlowenergycontroller_win.cpp
index cc848d1e..ced69685 100644
--- a/src/bluetooth/qlowenergycontroller_win.cpp
+++ b/src/bluetooth/qlowenergycontroller_win.cpp
@@ -51,7 +51,7 @@
#include <algorithm> // for std::max
-#include <setupapi.h>
+#include <SetupAPI.h>
QT_BEGIN_NAMESPACE
@@ -81,7 +81,7 @@ public:
return;
m_value = QByteArray(reinterpret_cast<const char *>(&gattValue->Data[0]),
- gattValue->DataSize);
+ int(gattValue->DataSize));
}
QByteArray m_value;
@@ -109,12 +109,12 @@ static QString getServiceSystemPath(const QBluetoothAddress &deviceAddress,
{
const HDEVINFO deviceInfoSet = ::SetupDiGetClassDevs(
reinterpret_cast<const GUID *>(&serviceUuid),
- NULL,
- 0,
+ nullptr,
+ nullptr,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (deviceInfoSet == INVALID_HANDLE_VALUE) {
- *systemErrorCode = ::GetLastError();
+ *systemErrorCode = int(::GetLastError());
return QString();
}
@@ -128,11 +128,11 @@ static QString getServiceSystemPath(const QBluetoothAddress &deviceAddress,
if (!::SetupDiEnumDeviceInterfaces(
deviceInfoSet,
- NULL,
+ nullptr,
reinterpret_cast<const GUID *>(&serviceUuid),
index++,
&deviceInterfaceData)) {
- *systemErrorCode = ::GetLastError();
+ *systemErrorCode = int(::GetLastError());
break;
}
@@ -140,11 +140,11 @@ static QString getServiceSystemPath(const QBluetoothAddress &deviceAddress,
if (!::SetupDiGetDeviceInterfaceDetail(
deviceInfoSet,
&deviceInterfaceData,
- NULL,
+ nullptr,
deviceInterfaceDetailDataSize,
&deviceInterfaceDetailDataSize,
- NULL)) {
- const DWORD error = ::GetLastError();
+ nullptr)) {
+ const int error = int(::GetLastError());
if (error != ERROR_INSUFFICIENT_BUFFER) {
*systemErrorCode = error;
break;
@@ -156,7 +156,7 @@ static QString getServiceSystemPath(const QBluetoothAddress &deviceAddress,
deviceInfoData.cbSize = sizeof(deviceInfoData);
QByteArray deviceInterfaceDetailDataBuffer(
- deviceInterfaceDetailDataSize, 0);
+ int(deviceInterfaceDetailDataSize), 0);
PSP_INTERFACE_DEVICE_DETAIL_DATA deviceInterfaceDetailData =
reinterpret_cast<PSP_INTERFACE_DEVICE_DETAIL_DATA>
@@ -169,10 +169,10 @@ static QString getServiceSystemPath(const QBluetoothAddress &deviceAddress,
deviceInfoSet,
&deviceInterfaceData,
deviceInterfaceDetailData,
- deviceInterfaceDetailDataBuffer.size(),
+ DWORD(deviceInterfaceDetailDataBuffer.size()),
&deviceInterfaceDetailDataSize,
&deviceInfoData)) {
- *systemErrorCode = ::GetLastError();
+ *systemErrorCode = int(::GetLastError());
break;
}
@@ -195,29 +195,28 @@ static HANDLE openSystemDevice(
const QString &systemPath, QIODevice::OpenMode openMode, int *systemErrorCode)
{
DWORD desiredAccess = 0;
- DWORD shareMode = 0;
+ DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
if (openMode & QIODevice::ReadOnly) {
desiredAccess |= GENERIC_READ;
- shareMode |= FILE_SHARE_READ;
}
if (openMode & QIODevice::WriteOnly) {
desiredAccess |= GENERIC_WRITE;
- shareMode |= FILE_SHARE_WRITE;
+ shareMode &= ~DWORD(FILE_SHARE_WRITE);
}
const HANDLE hDevice = ::CreateFile(
reinterpret_cast<const wchar_t *>(systemPath.utf16()),
desiredAccess,
shareMode,
- NULL,
+ nullptr,
OPEN_EXISTING,
0,
- NULL);
+ nullptr);
*systemErrorCode = (INVALID_HANDLE_VALUE == hDevice)
- ? ::GetLastError() : NO_ERROR;
+ ? int(::GetLastError()) : NO_ERROR;
return hDevice;
}
@@ -259,7 +258,7 @@ static QVector<BTH_LE_GATT_SERVICE> enumeratePrimaryGattServices(
const HRESULT hr = ::BluetoothGATTGetServices(
hDevice,
servicesCount,
- foundServices.isEmpty() ? NULL : &foundServices[0],
+ foundServices.isEmpty() ? nullptr : &foundServices[0],
&servicesCount,
BLUETOOTH_GATT_FLAG_NONE);
@@ -267,7 +266,7 @@ static QVector<BTH_LE_GATT_SERVICE> enumeratePrimaryGattServices(
*systemErrorCode = NO_ERROR;
return foundServices;
} else {
- const DWORD error = WIN32_FROM_HRESULT(hr);
+ const int error = WIN32_FROM_HRESULT(hr);
if (error == ERROR_MORE_DATA) {
foundServices.resize(servicesCount);
} else {
@@ -293,7 +292,7 @@ static QVector<BTH_LE_GATT_CHARACTERISTIC> enumerateGattCharacteristics(
hService,
gattService,
characteristicsCount,
- foundCharacteristics.isEmpty() ? NULL : &foundCharacteristics[0],
+ foundCharacteristics.isEmpty() ? nullptr : &foundCharacteristics[0],
&characteristicsCount,
BLUETOOTH_GATT_FLAG_NONE);
@@ -301,7 +300,7 @@ static QVector<BTH_LE_GATT_CHARACTERISTIC> enumerateGattCharacteristics(
*systemErrorCode = NO_ERROR;
return foundCharacteristics;
} else {
- const DWORD error = WIN32_FROM_HRESULT(hr);
+ const int error = WIN32_FROM_HRESULT(hr);
if (error == ERROR_MORE_DATA) {
foundCharacteristics.resize(characteristicsCount);
} else {
@@ -324,7 +323,7 @@ static QByteArray getGattCharacteristicValue(
USHORT valueBufferSize = 0;
for (;;) {
const auto valuePtr = valueBuffer.isEmpty()
- ? NULL
+ ? nullptr
: reinterpret_cast<PBTH_LE_GATT_CHARACTERISTIC_VALUE>(valueBuffer.data());
const HRESULT hr = ::BluetoothGATTGetCharacteristicValue(
@@ -338,11 +337,12 @@ static QByteArray getGattCharacteristicValue(
if (SUCCEEDED(hr)) {
*systemErrorCode = NO_ERROR;
return QByteArray(reinterpret_cast<const char *>(&valuePtr->Data[0]),
- valuePtr->DataSize);
+ int(valuePtr->DataSize));
} else {
- const DWORD error = WIN32_FROM_HRESULT(hr);
+ const int error = WIN32_FROM_HRESULT(hr);
if (error == ERROR_MORE_DATA) {
valueBuffer.resize(valueBufferSize);
+ valueBuffer.fill(0);
} else {
*systemErrorCode = error;
return QByteArray();
@@ -362,7 +362,7 @@ static void setGattCharacteristicValue(
QByteArray valueBuffer;
QDataStream out(&valueBuffer, QIODevice::WriteOnly);
- ULONG dataSize = value.size();
+ ULONG dataSize = ULONG(value.size());
out.writeRawData(reinterpret_cast<const char *>(&dataSize), sizeof(dataSize));
out.writeRawData(value.constData(), value.size());
@@ -396,7 +396,7 @@ static QVector<BTH_LE_GATT_DESCRIPTOR> enumerateGattDescriptors(
hService,
gattCharacteristic,
descriptorsCount,
- foundDescriptors.isEmpty() ? NULL : &foundDescriptors[0],
+ foundDescriptors.isEmpty() ? nullptr : &foundDescriptors[0],
&descriptorsCount,
BLUETOOTH_GATT_FLAG_NONE);
@@ -404,7 +404,7 @@ static QVector<BTH_LE_GATT_DESCRIPTOR> enumerateGattDescriptors(
*systemErrorCode = NO_ERROR;
return foundDescriptors;
} else {
- const DWORD error = WIN32_FROM_HRESULT(hr);
+ const int error = WIN32_FROM_HRESULT(hr);
if (error == ERROR_MORE_DATA) {
foundDescriptors.resize(descriptorsCount);
} else {
@@ -427,7 +427,7 @@ static QByteArray getGattDescriptorValue(
USHORT valueBufferSize = 0;
for (;;) {
const auto valuePtr = valueBuffer.isEmpty()
- ? NULL
+ ? nullptr
: reinterpret_cast<PBTH_LE_GATT_DESCRIPTOR_VALUE>(valueBuffer.data());
const HRESULT hr = ::BluetoothGATTGetDescriptorValue(
@@ -440,12 +440,18 @@ static QByteArray getGattDescriptorValue(
if (SUCCEEDED(hr)) {
*systemErrorCode = NO_ERROR;
+ if (gattDescriptor->DescriptorType == CharacteristicUserDescription) {
+ QString valueString = QString::fromUtf16(reinterpret_cast<const ushort *>(&valuePtr->Data[0]),
+ valuePtr->DataSize/2);
+ return valueString.toUtf8();
+ }
return QByteArray(reinterpret_cast<const char *>(&valuePtr->Data[0]),
- valuePtr->DataSize);
+ int(valuePtr->DataSize));
} else {
- const DWORD error = WIN32_FROM_HRESULT(hr);
+ const int error = WIN32_FROM_HRESULT(hr);
if (error == ERROR_MORE_DATA) {
valueBuffer.resize(valueBufferSize);
+ valueBuffer.fill(0);
} else {
*systemErrorCode = error;
return QByteArray();
@@ -463,7 +469,7 @@ static void setGattDescriptorValue(
return;
}
- const int requiredValueBufferSize = sizeof(BTH_LE_GATT_DESCRIPTOR_VALUE)
+ const int requiredValueBufferSize = int(sizeof(BTH_LE_GATT_DESCRIPTOR_VALUE))
+ value.size();
QByteArray valueBuffer(requiredValueBufferSize, 0);
@@ -486,7 +492,7 @@ static void setGattDescriptorValue(
}
gattValue->DataSize = ULONG(value.size());
- ::memcpy(gattValue->Data, value.constData(), value.size());
+ ::memcpy(gattValue->Data, value.constData(), size_t(value.size()));
const HRESULT hr = ::BluetoothGATTSetDescriptorValue(
hService,
@@ -579,7 +585,7 @@ static BTH_LE_UUID nativeLeUuidFromQtBluetoothUuid(const QBluetoothUuid &uuid)
::ZeroMemory(&gattUuid, sizeof(gattUuid));
if (uuid.minimumSize() == 2) {
gattUuid.IsShortUuid = TRUE;
- gattUuid.Value.ShortUuid = uuid.data1; // other fields should be empty!
+ gattUuid.Value.ShortUuid = USHORT(uuid.data1); // other fields should be empty!
} else {
gattUuid.Value.LongUuid = uuid;
}
@@ -701,7 +707,6 @@ QLowEnergyControllerPrivateWin32::~QLowEnergyControllerPrivateWin32()
void QLowEnergyControllerPrivateWin32::init()
{
- Q_UNIMPLEMENTED();
}
void QLowEnergyControllerPrivateWin32::connectToDevice()
@@ -762,7 +767,7 @@ void QLowEnergyControllerPrivateWin32::disconnectFromDevice()
thread = nullptr;
}
- for (const QSharedPointer<QLowEnergyServicePrivate> servicePrivate: serviceList)
+ for (const auto &servicePrivate: serviceList)
closeSystemDevice(servicePrivate->hService);
Q_Q(QLowEnergyController);
@@ -839,6 +844,11 @@ void QLowEnergyControllerPrivateWin32::discoverServiceDetails(
servicePrivate->hService = openSystemService(remoteDevice, service,
QIODevice::ReadOnly | QIODevice::WriteOnly,
&systemErrorCode);
+ if (systemErrorCode != NO_ERROR) {
+ servicePrivate->hService = openSystemService(remoteDevice, service,
+ QIODevice::ReadOnly,
+ &systemErrorCode);
+ }
}
if (systemErrorCode != NO_ERROR) {
@@ -853,7 +863,7 @@ void QLowEnergyControllerPrivateWin32::discoverServiceDetails(
servicePrivate->endHandle = servicePrivate->startHandle;
const QVector<BTH_LE_GATT_CHARACTERISTIC> foundCharacteristics =
- enumerateGattCharacteristics(servicePrivate->hService, NULL, &systemErrorCode);
+ enumerateGattCharacteristics(servicePrivate->hService, nullptr, &systemErrorCode);
if (systemErrorCode != NO_ERROR) {
qCWarning(QT_BT_WINDOWS) << "Unable to get characteristics for service" << service.toString()
@@ -868,7 +878,7 @@ void QLowEnergyControllerPrivateWin32::discoverServiceDetails(
QLowEnergyServicePrivate::CharData detailsData;
- detailsData.hValueChangeEvent = NULL;
+ detailsData.hValueChangeEvent = nullptr;
detailsData.uuid = qtBluetoothUuidFromNativeLeUuid(
gattCharacteristic.CharacteristicUuid);
@@ -1150,7 +1160,7 @@ void QLowEnergyControllerPrivateWin32::jobFinished(const ThreadWorkerJob &job)
} else {
if (charDetails.hValueChangeEvent) {
unregisterEvent(charDetails.hValueChangeEvent, &data.systemErrorCode);
- charDetails.hValueChangeEvent = NULL;
+ charDetails.hValueChangeEvent = nullptr;
}
}