32feet icon indicating copy to clipboard operation
32feet copied to clipboard

Unable to cast object of type 'Linux.Bluetooth.IGattCharacteristic1Proxy' to type 'Linux.Bluetooth.GattCharacteristic'

Open SydneyOwl opened this issue 2 months ago • 2 comments

Hello, When trying to get all characteristics of service this will always occur on Ubuntu 22.04 but on windows won't: image Here's the code:

await device.Gatt.ConnectAsync();
        Console.WriteLine("Connected");
        var service = await device.Gatt.GetPrimaryServicesAsync();
        bool valid = false;
        if(service.Count!=0)
        {
            foreach (var gattService in service)
            {
               var characteristics =  await gattService.GetCharacteristicsAsync();        <----------------------Error cccurs here
               foreach (var gattCharacteristic in characteristics)
               {
                   Console.WriteLine(gattCharacteristic.Uuid.ToString());
                   if (gattCharacteristic.Uuid.ToString().ToLower().Contains(BLE.RW_CHARACTERISTIC_UUID))
                   {
                       characteristic = gattCharacteristic;
                       break;
                   }
               }
            }

and here's the sourcecode of PlatformGetCharacteristics: image

Wondering if any one knows how to solve this? Thanks in advance!

SydneyOwl avatar Apr 13 '24 07:04 SydneyOwl

solved this issue by using GetPrimaryServiceAsync and GetCharacteristicAsync directly in my code. Here's what it looks like:

var service = await device.Gatt.GetPrimaryServiceAsync(
    BluetoothUuid.FromShortId(Convert.ToUInt16(BLE.RW_SERVICE_UUID.ToUpper(), 16)));
var character = await service.GetCharacteristicAsync(
    BluetoothUuid.FromShortId(Convert.ToUInt16(BLE.RW_CHARACTERISTIC_UUID.ToUpper(), 16)));

But then I stumbled upon a problem when I tried calling StartNotificationsAsync on Linux. It kept throwing a NotSupportedException, saying 'properties not supported':

character.CharacteristicValueChanged += Characteristic_CharacteristicValueChanged;
await character.StartNotificationsAsync();

The thing is, when I looked into the GattCharacteristic.linux.cs file, I noticed that the GetProperties method always returns a zero value. This means, no matter what device we're dealing with, it'll inevitably fail to register a callback function because of this:

GattCharacteristicProperties GetProperties()
{
    return 0;
}

Maybe this BLE library hasn't fully implemented support for Linux yet?

SydneyOwl avatar Apr 14 '24 02:04 SydneyOwl

I think there are a couple of issues which need addressing. The casting issue can be worked around by using the IGattCharacteristic1 throughout rather than the GattCharacteristic helper as it has no public constructor. This will require implementing the logic around property change notification to hook up the events. The cross-platform code implemented a check that the characteristic supports either Notify or Indicate properties to allow you to start monitoring change events and this breaks the Linux implementation because it doesn't have a direct equivalent of the Properties property. However I believe the IGattCharacteristic1 now has a Flags property with these flags as strings so this can be converted to enum values. I don't have my Linux development environment setup but will look into this soon and hopefully get these issues resolved.

peterfoot avatar Apr 14 '24 09:04 peterfoot