diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2018-01-26 17:34:25 +0300 |
---|---|---|
committer | Denis Shienkov <denis.shienkov@gmail.com> | 2018-02-28 09:17:02 +0000 |
commit | bb570997e645413efec1a4426baf997cf36767bd (patch) | |
tree | e53e260c0d61a95f31e7d06e930804cc840fcee7 | |
parent | e78eb675e89fba8d6a518b7a9f02dd3086f6f52a (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.cpp | 112 | ||||
-rw-r--r-- | src/bluetooth/windows/qwinlowenergybluetooth_p.h | 4 |
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(®istration, sizeof(registration)); registration.NumCharacteristics = 1; registration.Characteristics[0] = gattCharacteristic; - if (::BluetoothGATTRegisterEvent( + + const HRESULT hr = ::BluetoothGATTRegisterEvent( hService, CharacteristicValueChangedEvent, ®istration, 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 |