Description
Version: react-native-ble-plx 3.5.0
I would like to control my old Tacx Vortex smart indoor cycling trainer via Bluetooth connection.
It can be done sending ANT+ FE-C command via BLE
Service UUID: 6e40fec1-b5a3-f393-e0a9-e50e24dcca9e (Tacx FE-C tunnel)
Characteristic UUID: 6e40fec2-b5a3-f393-e0a9-e50e24dcca9e (Write characteristic)
Operation: writeCharacteristicWithResponseForService
related code for monitorCharacteristicForService call
connectedDevice.monitorCharacteristicForService(svc, ch, (error, characteristic) => { if (error) { logDebug(Tacx monitor error: ${error.message}); return; } if (characteristic?.value) { try { parseTacxData(Buffer.from(characteristic.value, 'base64')); } catch (e: any) { logDebug(Tacx parse error: ${e?.message ?? e}); } } });
Error is NPE, because error code is null
com.polidea.rxandroidble2.exceptions.BleGattCannotStartException: GATT exception from MAC address ..., with type BleGattOperation{description='CHARACTERISTIC_WRITE'} Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method com.facebook.react.bridge.PromiseImpl.reject, parameter code
The TACX documentation about FE-C over BLE communication is available at https://github.com/qcsesz/MyFTMSApp/blob/develop/docs/How-to%20FE-C%20over%20BLE%20v1_0_0%20(1).pdf
Steps to reproduce
You need an app connected to a BLE device what provides
Service UUID: 6e40fec1-b5a3-f393-e0a9-e50e24dcca9e (Tacx FE-C tunnel)
and
Characteristic UUID: 6e40fec2-b5a3-f393-e0a9-e50e24dcca9e (Write characteristic)
NPE happens during subscription of service UUID
React Native Version
0.82.1
Affected Platforms
Runtime - Android
Output of npx @react-native-community/cli info
npx @react-native-community/cli info
info Fetching system and libraries information...
System:
OS: Windows 10 10.0.19045
CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
Memory: 14.63 GB / 31.92 GB
Binaries:
Node:
version: 22.14.0
path: C:\Program Files\nodejs\node.EXE
Yarn: Not Found
npm:
version: 10.8.3
path: C:\Program Files\nodejs\npm.CMD
Watchman: Not Found
SDKs:
Android SDK: Not Found
Windows SDK:
AllowDevelopmentWithoutDevLicense: Enabled
IDEs:
Android Studio: AI-221.6008.13.2211.9619390
Visual Studio:
- 17.14.36705.20 (Visual Studio Community 2022)
Languages:
Java:
version: 17.0.1
path: C:\jdk\coretto\jdk17.0.1_12\bin\javac.EXE
Ruby: Not Found
npmPackages:
"@react-native-community/cli":
installed: 20.0.0
wanted: 20.0.0
react:
installed: 19.1.1
wanted: 19.1.1
react-native:
installed: 0.82.1
wanted: 0.82.1
react-native-windows: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
Stacktrace or Logs
FATAL EXCEPTION: RxComputationThreadPool-8
io.reactivex.exceptions.CompositeException: 2 exceptions occurred.
at io.reactivex.internal.subscribers.LambdaSubscriber.onError(LambdaSubscriber.java:82)
at io.reactivex.internal.operators.flowable.FlowableDoOnEach$DoOnEachSubscriber.onError(FlowableDoOnEach.java:111)
at io.reactivex.internal.operators.flowable.FlowableDoOnLifecycle$SubscriptionLambdaSubscriber.onError(FlowableDoOnLifecycle.java:85)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.checkTerminated(FlowableObserveOn.java:209)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$ObserveOnSubscriber.runAsync(FlowableObserveOn.java:399)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.run(FlowableObserveOn.java:176)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:348)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651)
at java.lang.Thread.run(Thread.java:1119)
ComposedException 1 :
com.bleplx.adapter.exceptions.CannotMonitorCharacteristicException
at com.bleplx.adapter.BleModule.lambda$safeMonitorCharacteristicForDevice$40(BleModule.java:1470)
at com.bleplx.adapter.BleModule$$ExternalSyntheticLambda45.call(D8$$SyntheticClass:0)
at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:33)
at io.reactivex.Observable.subscribe(Observable.java:12284)
at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)
at io.reactivex.Observable.subscribe(Observable.java:12284)
at io.reactivex.internal.operators.flowable.FlowableFromObservable.subscribeActual(FlowableFromObservable.java:29)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.internal.operators.flowable.FlowableOnBackpressureBuffer.subscribeActual(FlowableOnBackpressureBuffer.java:46)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.internal.operators.flowable.FlowableObserveOn.subscribeActual(FlowableObserveOn.java:56)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.internal.operators.flowable.FlowableDoOnLifecycle.subscribeActual(FlowableDoOnLifecycle.java:38)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.internal.operators.flowable.FlowableDoOnEach.subscribeActual(FlowableDoOnEach.java:50)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.Flowable.subscribe(Flowable.java:14872)
at io.reactivex.Flowable.subscribe(Flowable.java:14791)
at com.bleplx.adapter.BleModule.safeMonitorCharacteristicForDevice(BleModule.java:1480)
at com.bleplx.adapter.BleModule.monitorCharacteristicForDevice(BleModule.java:701)
at com.bleplx.BlePlxModule.monitorCharacteristicForDevice(BlePlxModule.java:777)
at com.facebook.jni.NativeRunnable.run(Native Method)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.kt:21)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$Companion.startNewBackgroundThread$lambda$0(MessageQueueThreadImpl.kt:152)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$Companion.$r8$lambda$YYXYCFexeoKtAeDpeNYkxZZlpbA(Unknown Source:0)
2025-11-28 12:25:31.560 12232-13109 AndroidRuntime com.myftmsapp3 E at com.facebook.react.bridge.queue.MessageQueueThreadImpl$Companion$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at java.lang.Thread.run(Thread.java:1119)
Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method com.facebook.react.bridge.PromiseImpl.reject, parameter code
at com.facebook.react.bridge.PromiseImpl.reject(Unknown Source:2)
at com.bleplx.utils.SafePromise.reject(SafePromise.java:25)
at com.bleplx.BlePlxModule$41.onError(BlePlxModule.java:791)
at com.bleplx.adapter.utils.SafeExecutor.error(SafeExecutor.java:30)
at com.bleplx.adapter.BleModule.lambda$safeMonitorCharacteristicForDevice$45(BleModule.java:1485)
at com.bleplx.adapter.BleModule.$r8$lambda$JVuqIGnSfaxzZFLoyHm91xQUhdI(Unknown Source:0)
at com.bleplx.adapter.BleModule$$ExternalSyntheticLambda3.accept(D8$$SyntheticClass:0)
at io.reactivex.internal.subscribers.LambdaSubscriber.onError(LambdaSubscriber.java:79)
at io.reactivex.internal.operators.flowable.FlowableDoOnEach$DoOnEachSubscriber.onError(FlowableDoOnEach.java:111)
at io.reactivex.internal.operators.flowable.FlowableDoOnLifecycle$SubscriptionLambdaSubscriber.onError(FlowableDoOnLifecycle.java:85)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.checkTerminated(FlowableObserveOn.java:209)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$ObserveOnSubscriber.runAsync(FlowableObserveOn.java:399)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.run(FlowableObserveOn.java:176)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:348)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651)
at java.lang.Thread.run(Thread.java:1119)
ComposedException 2 :
java.lang.NullPointerException: Parameter specified as non-null is null: method com.facebook.react.bridge.PromiseImpl.reject, parameter code
at com.facebook.react.bridge.PromiseImpl.reject(Unknown Source:2)
at com.bleplx.utils.SafePromise.reject(SafePromise.java:25)
at com.bleplx.BlePlxModule$41.onError(BlePlxModule.java:791)
at com.bleplx.adapter.utils.SafeExecutor.error(SafeExecutor.java:30)
at com.bleplx.adapter.BleModule.lambda$safeMonitorCharacteristicForDevice$45(BleModule.java:1485)
at com.bleplx.adapter.BleModule.$r8$lambda$JVuqIGnSfaxzZFLoyHm91xQUhdI(Unknown Source:0)
at com.bleplx.adapter.BleModule$$ExternalSyntheticLambda3.accept(D8$$SyntheticClass:0)
at io.reactivex.internal.subscribers.LambdaSubscriber.onError(LambdaSubscriber.java:79)
at io.reactivex.internal.operators.flowable.FlowableDoOnEach$DoOnEachSubscriber.onError(FlowableDoOnEach.java:111)
at io.reactivex.internal.operators.flowable.FlowableDoOnLifecycle$SubscriptionLambdaSubscriber.onError(FlowableDoOnLifecycle.java:85)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.checkTerminated(FlowableObserveOn.java:209)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$ObserveOnSubscriber.runAsync(FlowableObserveOn.java:399)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.run(FlowableObserveOn.java:176)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:348)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156)
2025-11-28 12:25:31.560 12232-13109 AndroidRuntime com.myftmsapp3 E at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651)
at java.lang.Thread.run(Thread.java:1119)
MANDATORY Reproducer
https://github.com/qcsesz/MyFTMSApp/blob/develop/RNTesterPlayground.js
Screenshots and Videos
No response
Description
Version: react-native-ble-plx 3.5.0
I would like to control my old Tacx Vortex smart indoor cycling trainer via Bluetooth connection.
It can be done sending ANT+ FE-C command via BLE
Service UUID: 6e40fec1-b5a3-f393-e0a9-e50e24dcca9e (Tacx FE-C tunnel)
Characteristic UUID: 6e40fec2-b5a3-f393-e0a9-e50e24dcca9e (Write characteristic)
Operation: writeCharacteristicWithResponseForService
related code for monitorCharacteristicForService call
connectedDevice.monitorCharacteristicForService(svc, ch, (error, characteristic) => { if (error) { logDebug(Tacx monitor error: ${error.message}); return; } if (characteristic?.value) { try { parseTacxData(Buffer.from(characteristic.value, 'base64')); } catch (e: any) { logDebug(Tacx parse error: ${e?.message ?? e}); } } });Error is NPE, because error code is null
com.polidea.rxandroidble2.exceptions.BleGattCannotStartException: GATT exception from MAC address ..., with type BleGattOperation{description='CHARACTERISTIC_WRITE'} Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method com.facebook.react.bridge.PromiseImpl.reject, parameter codeThe TACX documentation about FE-C over BLE communication is available at https://github.com/qcsesz/MyFTMSApp/blob/develop/docs/How-to%20FE-C%20over%20BLE%20v1_0_0%20(1).pdf
Steps to reproduce
You need an app connected to a BLE device what provides
Service UUID: 6e40fec1-b5a3-f393-e0a9-e50e24dcca9e (Tacx FE-C tunnel)
and
Characteristic UUID: 6e40fec2-b5a3-f393-e0a9-e50e24dcca9e (Write characteristic)
NPE happens during subscription of service UUID
React Native Version
0.82.1
Affected Platforms
Runtime - Android
Output of
npx @react-native-community/cli infoStacktrace or Logs
MANDATORY Reproducer
https://github.com/qcsesz/MyFTMSApp/blob/develop/RNTesterPlayground.js
Screenshots and Videos
No response