dotnet-bluetooth-le
                                
                                 dotnet-bluetooth-le copied to clipboard
                                
                                    dotnet-bluetooth-le copied to clipboard
                            
                            
                            
                        Gatt write characteristic FAILED
Steps to reproduce
- 
I load a observable list with services list ObservableCollection<servicesBT100> AuxservicosBT100 = new ObservableCollection<servicesBT100>(); foreach (IService servico in _servicos) { switch (servico.Id.ToString()) { case Constants.F1: // Função F1 var aux1 = new servicesBT100(); aux1.Servico = servico.Id.ToString(); aux1.Fn = "F1"; aux1.Funcao = App.Resx.GetTraducao("F1"); aux1.DescFunc = App.Resx.GetTraducao("DescF1"); aux1.DescFuncCompleta = App.Resx.GetTraducao("DescF1Completa"); aux1.Farquivo = Application.Current.Resources["F1arquivo"].ToString(); aux1.IServico = servico; AuxservicosBT100.Add(aux1); break; 
- 
After Tapped Action var paginaFuncao3 = new TabbedPageF3(_characteristic, _numIntervalos, _charactIntervalos); await Navigation.PushAsync(paginaFuncao3); break; 
- 
The error happens when I send / submit the push feature to the next page. then the error Plugin.BLE.Abstractions.Exceptions.CharacteristicReadException: 'Gatt write characteristic FAILED.' happens. 
- 
Everything was working 60 days ago, something was updated / modified and the functionality started to give a problem only on Android. On iOS it's working fine. 
Crashlog
Plugin.BLE.Abstractions.Exceptions.CharacteristicReadException
Message=Gatt write characteristic FAILED.
Source=mscorlib
StackTrace:
at Plugin.BLE.Android.Characteristic.InternalWrite (System.Byte[] data) [0x0004a] in D:\a\xamarin-bluetooth-le\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:110
at Plugin.BLE.Android.Characteristic+<>c__DisplayClass19_0.<WriteNativeAsync>b__0 () [0x00000] in D:\a\xamarin-bluetooth-le\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:81
at Plugin.BLE.Abstractions.Utils.TaskBuilder.FromEvent[TReturn,TEventHandler,TRejectHandler] (System.Action execute, System.Func3[T1,T2,TResult] getCompleteHandler, System.Action1[T] subscribeComplete, System.Action1[T] unsubscribeComplete, System.Func2[T,TResult] getRejectHandler, System.Action1[T] subscribeReject, System.Action1[T] unsubscribeReject, System.Threading.CancellationToken token) [0x000b3] in D:\a\xamarin-bluetooth-le\xamarin-bluetooth-le\Source\Plugin.BLE.Abstractions\Utils\TaskBuilder.cs:48
at Plugin.BLE.Android.Characteristic.WriteNativeAsync (System.Byte[] data, Plugin.BLE.Abstractions.CharacteristicWriteType writeType) [0x000b2] in D:\a\xamarin-bluetooth-le\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:80
at Plugin.BLE.Abstractions.CharacteristicBase.WriteAsync (System.Byte[] data, System.Threading.CancellationToken cancellationToken) [0x00061] in D:\a\xamarin-bluetooth-le\xamarin-bluetooth-le\Source\Plugin.BLE.Abstractions\CharacteristicBase.cs:92
at BT110MC.TabbedPageF3.picIntervalo_SelectedIndexChanged (System.Object sender, System.EventArgs e) [0x000b5] in E:\app\BT110MC\BT110\BT110\TabbedPageF3.xaml.cs:312
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in /Users/builder/azdo/_work/278/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36
at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in /Users/builder/azdo/_work/278/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36
at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/builder/azdo/_work/278/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-29/mcw/Java.Lang.IRunnable.cs:84
at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.1(intptr,intptr)
Configuration
**Version of the Plugin: Nuget 2.1.2
**Platform: Android 11 / Android 7
**Device: Xiaomi A3 / Moto G4 Plus
Hi @diegoperfeito,
I'm the friendly issue checker. It seems like (62.50 %) you haven't used our issue template :cry: I think it is very frustrating for the repository owners, if you ignore them.
If you think it's fine to make an exception, just ignore this message. But if you think it was a mistake to delete the template, please close the issue and create a new one.
Thanks!
Looks like you're writing from a different thread than the main thread.
Be aware of what's stated in the documentation:
Characteristic/Descriptor Write: make sure you call characteristic.WriteAsync(...) from the main thread, failing to do so will most probably result in a GattWriteError.
If you are using Xamarin.Essentials, wrap the write up like this:
var success = false;
if (MainThread.IsMainThread)
{
   success  = await writer.WriteAsync(buffer);
}
else 
{
   success  = await MainThread.InvokeOnMainThreadAsync(async () =>  await writer.WriteAsync(buffer));
}
Something like that. But Android is not very good at writing a lot of data to characteristics. I implemented Reliable Writes in my fork of this library because of this. The Reliable Writes lets you write all the data in a transaction and then commit it, so that the controller can send all of the data reliably in one or more transmission windows.
Hi, I return in this project, and continue in this error, but worked to more details. When share/passtrought characteristics over functions or navigation pages, but, same after instanced that characteristics, this device and service execute this command : await _characteristic.StopUpdatesAsync(); Return error 'GATT: SetCharacteristicNotification to false, FAILED.' In Android 9 and 11 _characteristic.CanWrite is false. Only Android 9 and 11 tested, but allrigh in Android 7. I had testing any implements, but not suceeded. 1 - Implemented variables/characteristics how to property 2 - Passtrought variable/characteristics how to a reference
Any Idea?
Regards.
bool d0 = _characteristic.CanRead; //true bool d1 = _characteristic.CanUpdate; //true bool d2 = _characteristic.CanWrite; //false var a1 = _characteristic.Id; //{f0cba101-c838-c592-f00b-000a000a000a} var a2 = _characteristic.Name; //"Unknown characteristic" var a3 = _characteristic.Properties; //Plugin.BLE.Abstractions.CharacteristicPropertyType.Notify | Plugin.BLE.Abstractions.CharacteristicPropertyType.Read var a4 = _characteristic.Service; //{Plugin.BLE.Android.Service} var a5 = _characteristic.StringValue; //"" var a6 = _characteristic.Uuid; //f0cba101-c838-c592-f00b-000a000a000a" var a7 = _characteristic.Value; //{byte[0]} var a8 = _characteristic.WriteType; //Plugin.BLE.Abstractions.CharacteristicWriteType.Default
It didn't work either way
await Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync(async () => await _characteristic.StopUpdatesAsync()); or Device.BeginInvokeOnMainThread(async () => { await _characteristic.StopUpdatesAsync(); });
Same error in two ways. I had testing, when not used await the error occour instantanely
Plugin.BLE.Abstractions.Exceptions.CharacteristicReadException Message=GATT: SetCharacteristicNotification to false, FAILED. Source=mscorlib StackTrace: at Plugin.BLE.Android.Characteristic.StopUpdatesNativeAsync () [0x00061] in D:\a\xamarin-bluetooth-le\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:164 at BT110MC.TabbedPageF1.<Button_Clicked>b__21_0 () [0x00025] in E:\app\BT110MC\BT110\BT110\TabbedPageF1.xaml.cs:206 at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021 at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36 at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36 at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-29/mcw/Java.Lang.IRunnable.cs:84 at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.1(intptr,intptr)
I tryed use the xamarin-bluetooth-le project with my device and the connection loose right after connect. Prox 12 secs. I must be fast, but, Connect in device, list services, select caractheristic, details...and CONNECTION LOST DEVICE I can read services, and select characteristics, but only. After select Display a message "Connection Lost" and SetCharacteristicNotification to false, FAILED. Or when in same screen, click in START UPDATES
I just ran into this issue on my app and have a solution.
- Use Xamarin.Essentials MainThreadto ensure everyWriteAsynchappens on the main thread.
_mainThread.InvokeOnMainThreadAsync(async () => characteristic.WriteAsync(data))
- Use Gentlee's SerialQueue to ensure all of my writes happen synchronously.
It seems that ensuring the Android implementation uses the main thread and performs writes in a serial queue would be a good addition to this library. Is there any interest in adding this to the library?
Edit:
It seems ensuring I was on the main thread wasn't necessary in my scenario. (Needs more experimentation)