MainThread: Android Exception: GATT Write Characteristic Failed
See original GitHub issueIntermittent issue, after BT connection is complete, I attempt to write to a characteristic on the remote device, and in some instances (approx 50% of the time), an exception is thrown.
Steps to reproduce
- Scan for available BT devices
- Connect to device
- GetServiceAsync for a specific characteristic
- Assign event handler for ValueUpdated event for that characteristic
- If characteristic CanUpdate is true, StartUpdatesAsync
- Attempt to write data to that characteristic using WriteAsync
Expected behavior
Data is successfully written to the characteristic. In this case, this is the method of transparent data communication between the app and the BT device.
Actual behavior
An exception occurs in approximately 50% of connections
Crashlog
[mono] Unhandled Exception:
[mono] Plugin.BLE.Abstractions.Exceptions.CharacteristicReadException: Gatt write characteristic FAILED.
[mono] at Plugin.BLE.Android.Characteristic.InternalWrite (System.Byte[] data) [0x0004a] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:99
[mono] at Plugin.BLE.Android.Characteristic+<>c__DisplayClass19_0.<WriteNativeAsync>b__0 () [0x00000] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:75
[mono] at Plugin.BLE.Abstractions.Utils.TaskBuilder+<FromEvent>d__13[TReturn,TEventHandler,TRejectHandler].MoveNext () [0x000b3] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Abstractions\Utils\TaskBuilder.cs:50 [mono] --- End of stack trace from previous location where exception was thrown --- [mono] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 [mono] at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187 [mono] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156 [mono] at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128 [mono] at System.Runtime.CompilerServices.TaskAwaiter
1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357
[mono] at Plugin.BLE.Android.Characteristic+<WriteNativeAsync>d__19.MoveNext () [0x00097] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:74
[mono] — End of stack trace from previous location where exception was thrown —
[mono] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
[mono] at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
[mono] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
[mono] at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
[mono] at System.Runtime.CompilerServices.TaskAwaiter1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357 [mono] at Plugin.BLE.Abstractions.CharacteristicBase+<WriteAsync>d__31.MoveNext () [0x0006c] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Abstractions\CharacteristicBase.cs:91 [mono] --- End of stack trace from previous location where exception was thrown --- [mono] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionse [mono-rt] [ERROR] FATAL UNHANDLED EXCEPTION: Plugin.BLE.Abstractions.Exceptions.CharacteristicReadException: Gatt write characteristic FAILED. [mono-rt] at Plugin.BLE.Android.Characteristic.InternalWrite (System.Byte[] data) [0x0004a] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:99 [mono-rt] at Plugin.BLE.Android.Characteristic+<>c__DisplayClass19_0.<WriteNativeAsync>b__0 () [0x00000] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:75 [mono-rt] at Plugin.BLE.Abstractions.Utils.TaskBuilder+<FromEvent>d__1
3[TReturn,TEventHandler,TRejectHandler].MoveNext () [0x000b3] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Abstractions\Utils\TaskBuilder.cs:50
[mono-rt] — End of stack trace from previous location where exception was thrown —
[mono-rt] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
[mono-rt] at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
[mono-rt] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
[mono-rt] at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
[mono-rt] at System.Runtime.CompilerServices.TaskAwaiter1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357 [mono-rt] at Plugin.BLE.Android.Characteristic+<WriteNativeAsync>d__19.MoveNext () [0x00097] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Android\Characteristic.cs:74 [mono-rt] --- End of stack trace from previous location where exception was thrown --- [mono-rt] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 [mono-rt] at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187 [mono-rt] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156 [mono-rt] at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128 [mono-rt] at System.Runtime.CompilerServices.TaskAwaiter
1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357
[mono-rt] at Plugin.BLE.Abstractions.CharacteristicBase+<WriteAsync>d__31.MoveNext () [0x0006c] in C:\Users\Adrian\Documents\GitHub\xamarin-bluetooth-le\Source\Plugin.BLE.Abstractions\CharacteristicBase.cs:91
[mono-rt] — End of stack trace from previous location where exception was thrown —
[mono-rt] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionserv
Configuration
Version of the Plugin: 1.2.1
Platform: Android 7.1.1
Device: Google Pixel
Issue Analytics
- State:
- Created 6 years ago
- Comments:15
Top GitHub Comments
If any method which calls
Device.BeginInvokeOnMainThread(async() => { await SendData(data);});
gets called again (like on appear) you will get the threading issue and subsequently the error. You should make sure that your code always completes a ble task before invokeing the next.I was thinking of introducing a helper class, a serial queue which could be used to guarantee that async tasks called by using it are executed serially. I could also implement the main thread logic in there. This might help developers avoid this limitation.
I will add this as a hint in the readme
Hi
I’m still facing the same issue on the Android Platform.
https://github.com/xabre/xamarin-bluetooth-le/issues/621#issuecomment-1239658780
Please help me and provide the solution