question

jalza avatar image
0 Votes"
jalza asked RobCaplan edited

OnCharacteristicChanged is not fired in BLE notications

I'm developing Xamarin.Forms app that uses BLE communication with a specific BLE device that is in development in my company. The device needs bonding and can notify characteristics value changes.

I have BLE native implementations for iOS and Android smartphones. The BLE on iOS everything works: device scanning, service and characteristic discovery, reading/writing of characteristic and their notifications. The BLE on Android almost everything works: device scanning, service and characteristic discovery, reading/writing of characteristic. But I have problems with notifications.

This is a part of my BLE service, I think that all I need is implemented. Code of how I enable notifications:

 [assembly: Dependency(typeof(MyApp.Droid.Services.BleManager))]
 namespace MyApp.Droid.Services
 {
     public class BleManager : BluetoothGattCallback, IBleManager
     {
         private const string CCC_DESCRIPTOR_UUID = "00002902-0000-1000-8000-00805f9b34fb";
         //...

         public override void OnServicesDiscovered(BluetoothGatt gatt, [GeneratedEnum] GattStatus status)
         {
             this.discoverdServices = gatt.Services.ToList();
             foreach (BluetoothGattService service in this.discoverdServices)
             {
                 ...
                 foreach (BluetoothGattCharacteristic characteristic in service.Characteristics)
                 {
                     ...
                     // Enable BLE notifications
                     this.enableNotifications(gatt, characteristic);
                 }
             }
         }

         private void enableNotifications(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
         {
             GattProperty properties = characteristic.Properties;
             if ((properties & GattProperty.Notify) > 0)
             {
                 gatt.SetCharacteristicNotification(characteristic, true);

                 BluetoothGattDescriptor descriptor = characteristic.GetDescriptor(UUID.FromString(CCC_DESCRIPTOR_UUID));
                 descriptor.SetValue(BluetoothGattDescriptor.EnableNotificationValue.ToArray());

                 // Create a task to write operation
                 Runnable runnable = new Runnable(() =>
                 {
                     try
                     {
                         bool writeResult = gatt.WriteDescriptor(descriptor);
                         if (writeResult)
                             Log.Debug(TAG, $"{characteristic.Uuid}: Writting descriptor.");
                         else
                             Log.Warn(TAG, $"{characteristic.Uuid}: Writting descriptor FAILED.");
                     }
                     catch (System.Exception exception)
                     {
                         Log.Error(TAG, $"ERROR: enableNotifications({characteristic.Uuid}): {exception.Message}");
                     }
                 });
                 // BLE commands queue to run tasks one by one
                 bool result;
                 lock (this.commandQueueSync)
                 {
                     result = this.commandQueue.Add(runnable);
                 }
                 if (result)
                 {
                     this.nextCommand();
                 }
                 else
                 {
                     Log.Error(TAG, $"{characteristic.Uuid}: ERROR. Could not enqueue write descriptor command.");
                 }
             }
             else
             {
                 Log.Warn(TAG, $"{characteristic.Uuid}: Does not support notifications.");
             }
         }
            
         public override void OnCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
         {
             Log.Debug(TAG, $"{characteristic.Uuid}: Notification received.");
             this.processCharacteristicValue(characteristic, true);
         }
     }
 }

In BLE device logs I can see how notification is sent and value read by the smartphone, but OnCharacteristicChanged is never fired. I tried in 2 Android smartphones one with Android 6.0 and another with Android 9.0 with the same result. I tried uninstalling the app and running again using Visual Studio and removing obj and debug folders, without success.

I'm using Microsoft Visual Studio Professional 2019 Version 16.10.4 and Xamarin.Forms 5.0.0.2083.

dotnet-xamarin
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Please change your CCC_DESCRIPTOR_UUID type from string to UUID , I find a similar thread about it. https://stackoverflow.com/questions/30088818/ble-gatt-oncharacteristicchanged-not-called-after-subscribing-to-notification


private  UUID CCC_DESCRIPTOR_UUID = UUID.FromString("00002902-0000-1000-8000-00805f9b34fb");
0 Votes 0 ·

Thank you for answer, but I use UUID in enableNotifications() method:

BluetoothGattDescriptor descriptor = characteristic.GetDescriptor(UUID.FromString(CCC_DESCRIPTOR_UUID));
0 Votes 0 ·

1 Answer

jalza avatar image
0 Votes"
jalza answered

It seems that the problem is due to Android having a limit of 15 subscriptions for each BluetoothGatt object:
https://stackoverflow.com/questions/42771904/android-bluetooth-low-energy-characteristic-notification-count-limit-does-this

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.