The BLE device that I'm connecting to emits bytes on one of its GATT characteristics in response to writes to the characteristic. Clients are supposed to enable notifications on that characteristic, and to interpret change bytes on the characteristic. (The behavior I'm controlling is turning on a scanning service for nearby wireless networks, then listening to the service output.)
I'm using RxAndroidBle and following the examples. I have an active connection Observable. The characteristic I want to observe has a UUID called AP_SCAN_DATA
. It's supposed to emit 0xFE
in response to receiving a written 0xFF
.
How do I call setupNotification
and set up an Observer on it to catch emitted byte[]
s, then write a value to the characteristic, so that I can catch the response?
My best effort so far:
connectionObservable.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<RxBleConnection>() {
@Override
public void onCompleted() { // ignore...
}
@Override
public void onError(Throwable e) { // ignore...
}
@Override
public void onNext(final RxBleConnection connection) {
Observable.just(connection)
.flatMap(new Func1<RxBleConnection, Observable<Observable<byte[]>>>() {
@Override
public Observable<Observable<byte[]>> call(RxBleConnection connection) {
return connection.setupNotification(AP_SCAN_DATA);
}
})
.doOnNext(new Action1<Observable<byte[]>>() {
@Override
public void call(Observable<byte[]> observable) {
Log.i(TAG, "notification has been set up");
// This code logs on DEBUG that a write was made, but no response ever arrives
connection.writeCharacteristic(AP_SCAN_DATA, CharacteristicValue.RESET.asBytes())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
}
})
.flatMap(new Func1<Observable<byte[]>, Observable<byte[]>>() {
@Override
public Observable<byte[]> call(Observable<byte[]> observable) {
return observable;
}
})
.doOnNext(new Action1<byte[]>() {
@Override
public void call(byte[] bytes) {
Log.i(TAG, "want to read response bytes here, but I don't... " + HexString.bytesToHex(bytes));
}
})
.subscribe();
}
});
For those readers not using a Java version that supports lambdas, here's my implementation of @s_noopy's answer.
There is already a topic in which you may find some insight -> RxAndroidBle keeping a persistant connection + Write/Notification handling
This is how you could achieve the same result while using only a single
.subscribe()
.FYI - you should handle errors in every
.subscribe()
unless you're 100% sure that theObservable
does not emit errors.