Attila Bicskó
Attila Bicskó

Reputation: 80

Can't get GATT characteristics C# Unable to cast BluetoothLEDevice to IBluetoothLEDevice3

I'm a newbie in Bluetooth LE programming. I've already built the program I'm working on for Android, and now I'm trying to port it to C# / Windows IoT.

I'm trying to read Health Thermometer data sent in a BLE Advertisement package. Each time I try to access the device's GATT services, my code throws an exception:

private TypedEventHandler<BluetoothLEAdvertisementWatcher, BluetoothLEAdvertisementReceivedEventArgs> OnAdvertisementReceived = async (w, eventArgs) =>
    {
        BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress);
        try
        {
            var SERVICEUUID = eventArgs.Advertisement.ServiceUuids.FirstOrDefault();
            var CHARACUUID = new Guid("00001809-0000-1000-8000-00805f9b34fb");

            //FIXME: Getting invalid cast exception at this point
            var gatt = await device.GetGattServicesForUuidAsync(SERVICEUUID);
            Debug.WriteLine($"{device.Name} Services: {gatt.Services.Count}, {gatt.Status}, {gatt.ProtocolError}");

            var characs = await gatt.Services.Single(s => s.Uuid == SERVICEUUID).GetCharacteristicsAsync();
            var charac = characs.Characteristics.Single(c => c.Uuid == CHARACUUID);

            //TODO: Parse temperature value to float
            var val = await charac.ReadValueAsync();
        }
        catch (Exception e)
        {
            Debug.WriteLine("Error getting characteristics: " + e);
        }
    };

The exception I get is:

System.InvalidCastException: Unable to cast object of type 'Windows.Devices.Bluetooth.BluetoothLEDevice' to type 'Windows.Devices.Bluetooth.IBluetoothLEDevice3' 
at System.StubHelpers.StubHelpers.GetCOMIPFromRCW_WinRT(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget)    
at Windows.Devices.Bluetooth.BluetoothLEDevice.GetGattServicesForUuidAsync(Guid serviceUuid)

The BluetoothLEDevice apparently implements the IBluetoothLEDevice3 interface, so I don't understand how it can't be casted. Any help on why this happens is much appreciated. My device is a Raspberry PI3 if that matters. Thanks in advance!

Update:

When debugging the code, I see that the BluetoothLEDevice's DeviceAccessInformation property throws the exception and it gets propagated to the top level:

DeviceAccessInformation = 'device.DeviceAccessInformation' threw an exception of type 'System.InvalidCastException'

Update2

When I try accessing GATT services directly this way, I get a different exception:

BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress);
            var gattService = await GattDeviceService.FromIdAsync(device.DeviceId);

The exception in this case is

System.IO.FileNotFoundException: The system cannot find the file specified. (Exception from HRESULT: 0x80070002) at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at StempHub.StartupTask.<>c.<<-ctor>b__5_0>d.MoveNext()

Upvotes: 0

Views: 1409

Answers (1)

Rita Han
Rita Han

Reputation: 9710

GetGattServicesForUuidAsync() api is newly introduced in v10.0.14965 but not implemented in this version and it is implemented in 15003, you can check Windows 10 SDK Preview Build 14965 Released and Windows 10 SDK Preview Build 15003 Released.

So you may need windows iot core version 15003 or higher.

Upvotes: 0

Related Questions