From bb570997e645413efec1a4426baf997cf36767bd Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Fri, 26 Jan 2018 17:34:25 +0300 Subject: 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 Reviewed-by: Lubomir I. Ivanov --- src/bluetooth/qlowenergycontroller_win.cpp | 112 +++++++++++++---------- 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 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(); + const DWORD error = WIN32_FROM_HRESULT(hr); + if (error == ERROR_MORE_DATA) { + foundServices.resize(servicesCount); + } else { + *systemErrorCode = error; + return QVector(); + } } } } @@ -292,14 +295,17 @@ static QVector 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(); + const DWORD error = WIN32_FROM_HRESULT(hr); + if (error == ERROR_MORE_DATA) { + foundCharacteristics.resize(characteristicsCount); + } else { + *systemErrorCode = error; + return QVector(); + } } } } @@ -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(&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(valueBuffer.data()), reliableWriteContext, - flags) != S_OK) { - *systemErrorCode = ::GetLastError(); - } else { + flags); + + if (SUCCEEDED(hr)) *systemErrorCode = NO_ERROR; - } + else + *systemErrorCode = WIN32_FROM_HRESULT(hr); } static QVector enumerateGattDescriptors( @@ -386,14 +395,17 @@ static QVector 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(); + const DWORD error = WIN32_FROM_HRESULT(hr); + if (error == ERROR_MORE_DATA) { + foundDescriptors.resize(descriptorsCount); + } else { + *systemErrorCode = error; + return QVector(); + } } } } @@ -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(&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 +#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 -- cgit v1.2.3