Skip to content

Commit

Permalink
Character indications on connection as well.
Browse files Browse the repository at this point in the history
  • Loading branch information
mgranberryto committed Apr 18, 2016
1 parent e4b2430 commit dc60e8d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
Expand Up @@ -72,6 +72,21 @@ public String toString() {
*/
Observable<Observable<byte[]>> setupNotification(@NonNull UUID characteristicUuid);

/**
* Setup characteristic indication in order to receive callbacks when given characteristic has been changed. Returned observable will
* emit Observable<byte[]> once the indication setup has been completed. It is possible to setup more observables for the same
* characteristic and the lifecycle of the indication will be shared among them.
* <p>
* Indication is automatically unregistered once this observable is unsubscribed.
*
* @param characteristicUuid Characteristic UUID for indication setup.
* @return Observable emitting another observable when the indication setup is complete.
* @throws BleCharacteristicNotFoundException if characteristic with given UUID hasn't been found.
* @throws BleCannotSetCharacteristicNotificationException if setup process indication setup process fail. This may be an internal
* reason or lack of permissions.
*/
Observable<Observable<byte[]>> setupIndication(@NonNull UUID characteristicUuid);

/**
* Convenience method for characteristic retrieval. First step is service discovery which is followed by service/characteristic
* traversal. This is an alias to:
Expand Down
Expand Up @@ -27,6 +27,7 @@
import rx.Observable;

import static android.bluetooth.BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
import static android.bluetooth.BluetoothGattDescriptor.ENABLE_INDICATION_VALUE;
import static android.bluetooth.BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
import static rx.Observable.create;
import static rx.Observable.error;
Expand Down Expand Up @@ -94,12 +95,37 @@ public Observable<Observable<byte[]>> setupNotification(@NonNull UUID characteri
}
}

@Override
public Observable<Observable<byte[]>> setupIndication(@NonNull UUID characteristicUuid) {
synchronized (notificationObservableMap) {
final Observable<Observable<byte[]>> availableObservable = notificationObservableMap.get(characteristicUuid);

if (availableObservable != null) {
return availableObservable;
}

final Observable<Observable<byte[]>> newObservable = createCharacteristicIndicationObservable(characteristicUuid)
.doOnUnsubscribe(() -> dismissCharacteristicNotification(characteristicUuid))
.map(notificationDescriptorData -> observeOnCharacteristicChangeCallbacks(characteristicUuid))
.replay(1)
.refCount();
notificationObservableMap.put(characteristicUuid, newObservable);
return newObservable;
}
}

private Observable<byte[]> createCharacteristicNotificationObservable(UUID characteristicUuid) {
return getClientConfigurationDescriptor(characteristicUuid)
.flatMap(descriptor -> setupCharacteristicNotification(descriptor, true))
.flatMap(ObservableUtil::justOnNext);
}

private Observable<byte[]> createCharacteristicIndicationObservable(UUID characteristicUuid) {
return getClientConfigurationDescriptor(characteristicUuid)
.flatMap(descriptor -> setupCharacteristicIndication(descriptor, true))
.flatMap(ObservableUtil::justOnNext);
}

private void dismissCharacteristicNotification(UUID characteristicUuid) {

synchronized (notificationObservableMap) {
Expand Down Expand Up @@ -134,6 +160,18 @@ private Observable<byte[]> setupCharacteristicNotification(BluetoothGattDescript
}
}

@NonNull
private Observable<byte[]> setupCharacteristicIndication(BluetoothGattDescriptor bluetoothGattDescriptor, boolean enabled) {
final BluetoothGattCharacteristic characteristic = bluetoothGattDescriptor.getCharacteristic();

if (bluetoothGatt.setCharacteristicNotification(characteristic, enabled)) {
return writeDescriptor(bluetoothGattDescriptor, enabled ? ENABLE_INDICATION_VALUE : DISABLE_NOTIFICATION_VALUE)
.onErrorResumeNext(throwable -> error(new BleCannotSetCharacteristicNotificationException(characteristic)));
} else {
return error(new BleCannotSetCharacteristicNotificationException(characteristic));
}
}

@NonNull
private Observable<BluetoothGattDescriptor> getClientConfigurationDescriptor(UUID characteristicUuid) {
return getCharacteristic(characteristicUuid)
Expand Down

0 comments on commit dc60e8d

Please sign in to comment.