summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2018-01-26 17:34:25 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2018-02-28 09:17:02 +0000
commitbb570997e645413efec1a4426baf997cf36767bd (patch)
treee53e260c0d61a95f31e7d06e930804cc840fcee7
parente78eb675e89fba8d6a518b7a9f02dd3086f6f52a (diff)
Use WIN32_FROM_HRESULT macro to decode BLE system errors
The GetLastError() function always returns the NO_ERROR code when any of the BluetoothGATTXXX() function fails. The reason is that the BluetoothGATTXXX() function uses the COM API, but the GetLastError() function uses the WIN32 API. We need to convert the HRESULT error code to the WIN32 error code directly, using a macro such as WIN32_FROM_HRESULT. Note: At least, it is reproduced with BluetoothGATTSetCharacteristicValue() function on Windows 10. Change-Id: I548e90bb16647c885b06c32397c277255fd362f4 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Lubomir I. Ivanov <neolit123@gmail.com>
-rw-r--r--src/bluetooth/qlowenergycontroller_win.cpp112
-rw-r--r--src/bluetooth/windows/qwinlowenergybluetooth_p.h4
2 files changed, 69 insertions, 47 deletions
diff --git a/src/bluetooth/qlowenergycontroller_win.cpp b/src/bluetooth/qlowenergycontroller_win.cpp
index fe4e56e9..b05d20e6 100644
--- a/src/bluetooth/qlowenergycontroller_win.cpp
+++ b/src/bluetooth/qlowenergycontroller_win.cpp
@@ -261,14 +261,17 @@ static QVector<BTH_LE_GATT_SERVICE> enumeratePrimaryGattServices(
&servicesCount,
BLUETOOTH_GATT_FLAG_NONE);
- if (hr == HRESULT_FROM_WIN32(ERROR_MORE_DATA)) {
- foundServices.resize(servicesCount);
- } else if (hr == S_OK) {
+ if (SUCCEEDED(hr)) {
*systemErrorCode = NO_ERROR;
return foundServices;
} else {
- *systemErrorCode = ::GetLastError();
- return QVector<BTH_LE_GATT_SERVICE>();
+ const DWORD error = WIN32_FROM_HRESULT(hr);
+ if (error == ERROR_MORE_DATA) {
+ foundServices.resize(servicesCount);
+ } else {
+ *systemErrorCode = error;
+ return QVector<BTH_LE_GATT_SERVICE>();
+ }
}
}
}
@@ -292,14 +295,17 @@ static QVector<BTH_LE_GATT_CHARACTERISTIC> enumerateGattCharacteristics(
&characteristicsCount,
BLUETOOTH_GATT_FLAG_NONE);
- if (hr == HRESULT_FROM_WIN32(ERROR_MORE_DATA)) {
- foundCharacteristics.resize(characteristicsCount);
- } else if (hr == S_OK) {
+ if (SUCCEEDED(hr)) {
*systemErrorCode = NO_ERROR;
return foundCharacteristics;
} else {
- *systemErrorCode = ::GetLastError();
- return QVector<BTH_LE_GATT_CHARACTERISTIC>();
+ const DWORD error = WIN32_FROM_HRESULT(hr);
+ if (error == ERROR_MORE_DATA) {
+ foundCharacteristics.resize(characteristicsCount);
+ } else {
+ *systemErrorCode = error;
+ return QVector<BTH_LE_GATT_CHARACTERISTIC>();
+ }
}
}
}
@@ -323,17 +329,19 @@ static QByteArray getGattCharacteristicValue(
&valueBufferSize,
BLUETOOTH_GATT_FLAG_NONE);
- if (hr == HRESULT_FROM_WIN32(ERROR_MORE_DATA)) {
- valueBuffer.resize(valueBufferSize);
- } else if (hr == S_OK) {
+ if (SUCCEEDED(hr)) {
*systemErrorCode = NO_ERROR;
const PBTH_LE_GATT_CHARACTERISTIC_VALUE value = reinterpret_cast<
PBTH_LE_GATT_CHARACTERISTIC_VALUE>(valueBuffer.data());
-
return QByteArray(reinterpret_cast<const char *>(&value->Data[0]), value->DataSize);
} else {
- *systemErrorCode = ::GetLastError();
- return QByteArray();
+ const DWORD error = WIN32_FROM_HRESULT(hr);
+ if (error == ERROR_MORE_DATA) {
+ valueBuffer.resize(valueBufferSize);
+ } else {
+ *systemErrorCode = error;
+ return QByteArray();
+ }
}
}
}
@@ -355,16 +363,17 @@ static void setGattCharacteristicValue(
BTH_LE_GATT_RELIABLE_WRITE_CONTEXT reliableWriteContext = 0;
- if (::BluetoothGATTSetCharacteristicValue(
+ const HRESULT hr = ::BluetoothGATTSetCharacteristicValue(
hService,
gattCharacteristic,
reinterpret_cast<PBTH_LE_GATT_CHARACTERISTIC_VALUE>(valueBuffer.data()),
reliableWriteContext,
- flags) != S_OK) {
- *systemErrorCode = ::GetLastError();
- } else {
+ flags);
+
+ if (SUCCEEDED(hr))
*systemErrorCode = NO_ERROR;
- }
+ else
+ *systemErrorCode = WIN32_FROM_HRESULT(hr);
}
static QVector<BTH_LE_GATT_DESCRIPTOR> enumerateGattDescriptors(
@@ -386,14 +395,17 @@ static QVector<BTH_LE_GATT_DESCRIPTOR> enumerateGattDescriptors(
&descriptorsCount,
BLUETOOTH_GATT_FLAG_NONE);
- if (hr == HRESULT_FROM_WIN32(ERROR_MORE_DATA)) {
- foundDescriptors.resize(descriptorsCount);
- } else if (hr == S_OK) {
+ if (SUCCEEDED(hr)) {
*systemErrorCode = NO_ERROR;
return foundDescriptors;
} else {
- *systemErrorCode = ::GetLastError();
- return QVector<BTH_LE_GATT_DESCRIPTOR>();
+ const DWORD error = WIN32_FROM_HRESULT(hr);
+ if (error == ERROR_MORE_DATA) {
+ foundDescriptors.resize(descriptorsCount);
+ } else {
+ *systemErrorCode = error;
+ return QVector<BTH_LE_GATT_DESCRIPTOR>();
+ }
}
}
}
@@ -417,17 +429,20 @@ static QByteArray getGattDescriptorValue(
&valueBufferSize,
BLUETOOTH_GATT_FLAG_NONE);
- if (hr == HRESULT_FROM_WIN32(ERROR_MORE_DATA)) {
- valueBuffer.resize(valueBufferSize);
- } else if (hr == S_OK) {
+ if (SUCCEEDED(hr)) {
*systemErrorCode = NO_ERROR;
const PBTH_LE_GATT_DESCRIPTOR_VALUE value = reinterpret_cast<
PBTH_LE_GATT_DESCRIPTOR_VALUE>(valueBuffer.data());
return QByteArray(reinterpret_cast<const char *>(&value->Data[0]), value->DataSize);
} else {
- *systemErrorCode = ::GetLastError();
- return QByteArray();
+ const DWORD error = WIN32_FROM_HRESULT(hr);
+ if (error == ERROR_MORE_DATA) {
+ valueBuffer.resize(valueBufferSize);
+ } else {
+ *systemErrorCode = error;
+ return QByteArray();
+ }
}
}
}
@@ -466,16 +481,16 @@ static void setGattDescriptorValue(
gattValue->DataSize = ULONG(value.size());
::memcpy(gattValue->Data, value.constData(), value.size());
- if (::BluetoothGATTSetDescriptorValue(
+ const HRESULT hr = ::BluetoothGATTSetDescriptorValue(
hService,
gattDescriptor,
gattValue,
- BLUETOOTH_GATT_FLAG_NONE) != S_OK) {
- *systemErrorCode = ::GetLastError();
- return;
- }
+ BLUETOOTH_GATT_FLAG_NONE);
- *systemErrorCode = NO_ERROR;
+ if (SUCCEEDED(hr))
+ *systemErrorCode = NO_ERROR;
+ else
+ *systemErrorCode = WIN32_FROM_HRESULT(hr);
}
static void WINAPI eventChangedCallbackEntry(
@@ -510,18 +525,20 @@ static HANDLE registerEvent(
::ZeroMemory(&registration, sizeof(registration));
registration.NumCharacteristics = 1;
registration.Characteristics[0] = gattCharacteristic;
- if (::BluetoothGATTRegisterEvent(
+
+ const HRESULT hr = ::BluetoothGATTRegisterEvent(
hService,
CharacteristicValueChangedEvent,
&registration,
eventChangedCallbackEntry,
context,
&hEvent,
- BLUETOOTH_GATT_FLAG_NONE) != S_OK) {
- *systemErrorCode = ::GetLastError();
- } else {
+ BLUETOOTH_GATT_FLAG_NONE);
+
+ if (SUCCEEDED(hr))
*systemErrorCode = NO_ERROR;
- }
+ else
+ *systemErrorCode = WIN32_FROM_HRESULT(hr);
return hEvent;
}
@@ -533,13 +550,14 @@ static void unregisterEvent(HANDLE hEvent, int *systemErrorCode)
return;
}
- if (::BluetoothGATTUnregisterEvent(
+ const HRESULT hr = ::BluetoothGATTUnregisterEvent(
hEvent,
- BLUETOOTH_GATT_FLAG_NONE) != S_OK) {
- *systemErrorCode = ::GetLastError();
- } else {
+ BLUETOOTH_GATT_FLAG_NONE);
+
+ if (SUCCEEDED(hr))
*systemErrorCode = NO_ERROR;
- }
+ else
+ *systemErrorCode = WIN32_FROM_HRESULT(hr);
}
static QBluetoothUuid qtBluetoothUuidFromNativeLeUuid(const BTH_LE_UUID &uuid)
diff --git a/src/bluetooth/windows/qwinlowenergybluetooth_p.h b/src/bluetooth/windows/qwinlowenergybluetooth_p.h
index ea7fc0c8..39b88a5f 100644
--- a/src/bluetooth/windows/qwinlowenergybluetooth_p.h
+++ b/src/bluetooth/windows/qwinlowenergybluetooth_p.h
@@ -56,6 +56,10 @@
#include <qt_windows.h>
+#define WIN32_FROM_HRESULT(hr) \
+ (SUCCEEDED(hr) ? ERROR_SUCCESS : \
+ (HRESULT_FACILITY(hr) == FACILITY_WIN32 ? HRESULT_CODE(hr) : (hr)))
+
#define BLUETOOTH_GATT_FLAG_NONE 0x00000000
#define BLUETOOTH_GATT_FLAG_CONNECTION_ENCRYPTED 0x00000001
#define BLUETOOTH_GATT_FLAG_CONNECTION_AUTHENTICATED 0x00000002