Good Morning,
I have a native C++ DLL managing BLE (Bluetooth Low Energy) connection who use the internal Bluetooth card of the computer. All works fine on Win10, I never had any problem connecting or reconnecting a device since 2019.
Then I pass under Win11 and none of the function used after discover services seems to work. I never received the callback of the function:
- GetCharacteristicsWithCacheModeAsync
- GetDescriptorsWithCacheModeAsync
- WriteClientCharacteristicConfigurationDescriptorAsync
So I change the two first function to the equivalent function without cache mode and it works fine:
- GetCharacteristicsWithCacheModeAsync -> GetCharacteristicsAsync
- GetDescriptorsWithCacheModeAsync -> GetDescriptorsAsync
I still don't know why the cache mode version doesn't work correctly.
In other hand, the last function to write on the descriptor to active the "Notify" or "Indicate" doesn't raise the callback whether I use "WriteClientCharacteristicConfigurationDescriptorAsync" or "WriteClientCharacteristicConfigurationDescriptorWithResultAsync".
Here is my code for writing on the descriptor:
//Try to write the correct "value" on the descripton
ComPtr<IAsyncOperation<enum GattCommunicationStatus>> writeOp;
HRESULT hr = charac->getChar()->WriteClientCharacteristicConfigurationDescriptorAsync(value, &writeOp);
if (ifFailedPrintErrorMessage(hr, "Can't write descriptor async")) {
return E_FAIL;
}
//Create event to simulate "await"
Event asyncCompletedWriteDescri(CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, WRITE_OWNER | EVENT_ALL_ACCESS));
HRESULT resultAsyncActionWriteDescri = S_OK;
//Callback
hr = writeOp->put_Completed(Callback<IAsyncOperationCompletedHandler<GattCommunicationStatus>>([this, charac, &resultAsyncActionWriteDescri, &asyncCompletedWriteDescri](IAsyncOperation<GattCommunicationStatus> *op, AsyncStatus status) {
//Get Result
GattCommunicationStatus result;
HRESULT hr = op->GetResults(&result);
if (ifFailedPrintErrorMessage(hr, "Can't get writeDescriptor result")) {
resultAsyncActionWriteDescri = E_FAIL;
SetEvent(asyncCompletedWriteDescri.Get());
return E_FAIL;
}
//Check if it's a success
if (result != GattCommunicationStatus_Success) {
std::cout << "Can't open pipe" << endl;
resultAsyncActionWriteDescri = E_FAIL;
SetEvent(asyncCompletedWriteDescri.Get());
return E_FAIL;
}
//Register characteristic to ValueChanged
if (registrerCharToValueChanged(charac) == E_FAIL) {
resultAsyncActionWriteDescri = E_FAIL;
SetEvent(asyncCompletedWriteDescri.Get());
return E_FAIL;
}
resultAsyncActionWriteDescri = S_OK;
SetEvent(asyncCompletedWriteDescri.Get());
return S_OK;
}).Get());
//If the put_Completed function failed
if (ifFailedPrintErrorMessage(hr, "Can't call put_Completed for write descriptor async")) {
return E_FAIL;
}
//Wait until the callback IAsyncOperationCompletedHandler is raised
WaitForSingleObject(asyncCompletedWriteDescri.Get(), INFINITE);
return resultAsyncActionWriteDescri;
I have see in MS example, that it uses the keyword "co_await" but I can't use it here because there is no ComPtr in MS example and the definition of the funtion isn't the same. The MS example works fine and I can write on descriptor. GattCommunicationStatus status = co_await selectedChar.WriteClientCharacteristicConfigurationDescriptorAsync(cccdValue);
Perhaps some security feature have changes?
I have try on Win11: Version 21H2 (build: 22000.856).
Thank you in advance for taking my problem into account :)
Best Regards
Julien