Closed jdschin closed 1 year ago
While I'm personally unfamiliar with the bluetooth APIs, I can help suggest some debugging steps. First, you say that:
When Im trying to disconnect the BLE Device Im getting an exception with no context and the connection is still established.
I see that logging the exception object gave you [TypeError: Object expected]
and trying to convert to JSON string gave you {}
. The first error is interesting, however I'm unsure if it's expected or not. The second output seems possibly reasonable to me given how we've had issues in the past with JSI not giving us the proper facilities to ensure things like properties being enumerable. If you change to something like the following, do you have better success?
console.log(`ERROR: ${e.message} (${e.number})`);
Does that give you better output? If not, the next thing I'd try doing is running the application under a debugger like Visual Studio (either launch under the debugger or attach after launch) and then enable the "break on exception" feature. This will allow you to see where the exception is actually originating from. The callstack should hopefully give you enough context as to what's going on.
From what I've read in the C# UWP documentation for the native implementation, this.gattService?.close() (I assume that this is the equivalent to gattService.Dispose() in C#) should do the trick and disconnect the device.
This is kind of interesting because the documentaton, even when scoped down to only C++/WinRT, shows both Close
and Dispose
being functions available on the GattDeviceService
class. By default I'd assume that this is a docs bug, however the description text for the two is different and I don't see mention of Dispose
being .NET specific. I'll try and dig into that a bit more
Okay, so looking at the WinMD I don't see any indication that the type has a Dispose
function and it implements IClosable
, which is where the Close
method comes from and is projected in .NET as IDisposable
. So I agree, close
is the correct function to call and the inconsistency seems to be an unfortunate docs bug.
Hey @dunhor thanks for the fast reply! When trying
console.log(`ERROR: ${e.message} (${e.number})`);
I get:
ERROR: Object expected (-2146823281)
I also tried to use VisualStudio for debugging (InstanceSettings.UseDirectDebugger = true) but the exception never reaches VisualStudio it always appears in the React Native window.
When debugging in Chrome with Pause On Caught Exceptions enabled, the debugger also never pauses.
Do you have any ideas how to access the "real" stack trace?
Hmm, okay, so this one is a little interesting. -2146823281
corresponds to 0x800A138F
, which, from what I can see in source, corresponds to ERROR_RESOURCE_NOT_FOUND
(although if you're familiar with the way HRESULT
s work, you'll notice that this is NOT a Win32 error encoded as an HRESULT
, which would start with 0x8007XXXX
). So I don't think that this error is originating from the call. Instead, this error seems to be coming from Chakra as all the info I've been able to find suggests that this is a JS specific error. Two things I'd suggest trying next:
console.log(typeof this.gattService)
console.log(typeof this.gattService.close)
Do you have any ideas how to access the "real" stack trace?
Sorry, I should have been more specific. When I suggested attaching the Visual Studio debugger, I was implying that you'll need a native debugger. The Chrome debugger is not a native debugger. That said, if this error is coming from Chakra, I'm unsure why the JS debugger never breaks in. A native debugger might break in, but I'm not personally familiar enough with Chakra to really know.
Ok, logging this brought a bit more clarity:
console.log('Close: ', this.connectedBleDevice?.close); // => Close: undefined
the function is somehow not there. With that ERROR_RESOURCE_NOT_FOUND makes sense. BluetoothLEDevice.close seems to be missing.
Same goes for GattDeviceService.close
Okay, I think I have an idea. What does your RnWinRTParameters
entry look like in your ExperimentalFeatures.props
file? E.g. it should look something like this
<RnWinRTParameters>
-include Windows.Devices.Bluetooth.GenericAttributeProfile
...
</RnWinRTParameters>
If it doesn't already, please try adding -include Windows.Foundation
to the list of included namespaces as that's the namespace where IClosable
is defined.
I just had those Parameters set. I thought having -include Windows.Devices.Bluetooth
would be enough.
But having the config like this fixes the undefined problem.
<RnWinRTParameters>
-include Windows.Devices.Bluetooth
-include Windows.Devices.Bluetooth.Advertisement
-include Windows.Storage.Streams
-include Windows.Devices.Radios
-include Windows.Devices.Bluetooth.GenericAttributeProfile
-include Windows.Foundation
</RnWinRTParameters>
Calling .close()
still doesn't disconnect my Bluetooth LE device. I'm also setting all of the references I have in TypeScript to null or undefined. Any idea what else I could try?
FYI: The react native base project is a C# project. Not sure if this changes anything since react-native-winrt generates JSI wrappers for the C++ library.
But having the config like this fixes the undefined problem
Awesome, great to hear!
I thought having -include Windows.Devices.Bluetooth would be enough.
It's a balancing act. If we recursively include namespaces that are referenced by the included namespaces, we'd end up including a lot of types that aren't needed which would produce a binary that's both large and time consuming to build.
Calling .close() still doesn't disconnect my Bluetooth LE device. I'm also setting all of the references I have in TypeScript to null or undefined. Any idea what else I could try?
Unfortunately, I'm not familiar with the Bluetooth APIs and have never tried to use them. I'd suggest following an existing sample (which it sounds like you might be doing?). You might find something useful in the Windows-universal-samples repo
FYI: The react native base project is a C# project. Not sure if this changes anything since react-native-winrt generates JSI wrappers for the C++ library.
No, that shouldn't pose an issue. WinRT describes and ABI, so it doesn't matter which language is being used, so long as the ABI is being respected.
I have a react-native application that runs on windows.
Im connecting a BLE Device like this (after a search with the BluetoothLEAdvertisementWatcher)
this.connectedBleDevice = await BluetoothLEDevice.fromBluetoothAddressAsync(bluetoothAddress);
Im having a function that loads a specific Gatt Service
With the service Im connecting on characteristics that send notifications. All that works perfectly fine.
When Im trying to disconnect the BLE Device Im getting an exception with no context and the connection is still established.
After calling
disconnect()
the BLE device is still connected.From what I've read in the C# UWP documentation for the native implementation, this.gattService?.close() (I assume that this is the equivalent to gattService.Dispose() in C#) should do the trick and disconnect the device.
I've also tried
Version combination I've tried:
react-native-windows: 0.72.8 react-native-winrt: 0.72.0 react-native: 0.72.4
And
react-native-windows: 0.72.0 react-native-winrt: 0.72.0 react-native: 0.72.0