in rx-central-ble/src/main/java/com/uber/rxcentralble/core/CorePeripheral.java [506:689]
private BluetoothGattCallback getGattCallback() {
return new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(
final BluetoothGatt gatt, final int status, final int newState) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onConnectionStateChange - Status: " + status
+ " | State: " + newState);
}
synchronized (syncRoot) {
if (connectionStateSubject != null) {
if (newState == BluetoothGatt.STATE_CONNECTED) {
if (status == 0) {
if (!gatt.discoverServices()) {
connectionStateSubject.onError(
new ConnectionError(
ConnectionError.Code.CONNECT_FAILED,
new PeripheralError(
PeripheralError.Code.SERVICE_DISCOVERY_FAILED, ERROR_STATUS_CALL_FAILED)));
}
} else {
connectionStateSubject.onError(
new ConnectionError(
ConnectionError.Code.CONNECT_FAILED,
new PeripheralError(CONNECTION_FAILED, status)));
}
} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
if (status == 0 || status == 8) {
connectionStateSubject.onError(
new ConnectionError(
DISCONNECTION, new PeripheralError(PeripheralError.Code.CONNECTION_LOST, status)));
} else {
connectionStateSubject.onError(
new ConnectionError(DISCONNECTION, new PeripheralError(CONNECTION_FAILED, status)));
}
gatt.close();
}
}
}
}
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, final int status) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onServicesDiscovered - Status: " + status);
}
synchronized (syncRoot) {
if (connectionStateSubject != null) {
if (status == 0) {
connectionStateSubject.onNext(CONNECTED);
} else {
connectionStateSubject.onError(
new ConnectionError(
ConnectionError.Code.CONNECT_FAILED,
new PeripheralError(PeripheralError.Code.SERVICE_DISCOVERY_FAILED, status)));
}
}
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic chr) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onCharacteristicChanged - UUID: " + chr.getUuid() + " | Data: "
+ Utils.bytesToHex(chr.getValue()));
}
synchronized (syncRoot) {
Preprocessor preprocessor = preprocessorMap.get(chr.getUuid());
if (preprocessor != null) {
byte[] processedBytes = preprocessor.process(chr.getValue());
if (processedBytes != null) {
notificationRelay.accept(new Pair<>(chr.getUuid(), processedBytes));
}
} else {
notificationRelay.accept(new Pair<>(chr.getUuid(), chr.getValue()));
}
}
}
@Override
public void onCharacteristicRead(
BluetoothGatt gatt, BluetoothGattCharacteristic chr, int status) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onCharacteristicRead - UUID: " + chr.getUuid() + " | Status: "
+ status + " | Data: " + Utils.bytesToHex(chr.getValue()));
}
operationResult(
readSubject,
new Pair<>(chr.getUuid(), chr.getValue()),
status,
READ_CHARACTERISTIC_FAILED);
}
@Override
public void onCharacteristicWrite(
BluetoothGatt gatt, BluetoothGattCharacteristic chr, int status) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onCharacteristicWrite - UUID: " + chr.getUuid() + " | Status: "
+ status + " | Data: " + Utils.bytesToHex(chr.getValue()));
}
operationResult(writeSubject, chr.getUuid(), status, WRITE_CHARACTERISTIC_FAILED);
}
@Override
public void onDescriptorWrite(
BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onDescriptorWrite - UUID: "
+ descriptor.getCharacteristic().getUuid() + " | Status: " + status);
}
if (descriptor.getUuid().equals(CCCD_UUID)) {
operationResult(
registerNotificationSubject,
descriptor.getCharacteristic().getUuid(),
status,
PeripheralError.Code.WRITE_DESCRIPTOR_FAILED);
}
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onMtuChanged - Status: " + status + " | MTU: " + mtu);
}
if (status == 0) {
CorePeripheral.this.mtu = mtu;
}
operationResult(requestMtuSubject, mtu, status, REQUEST_MTU_FAILED);
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onReadRemoteRssi - Status: " + status + " | RSSI: " + rssi);
}
operationResult(readRssiSubject, rssi, status, READ_RSSI_FAILED);
}
@Override
public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onPhyUpdate - Status: " + status + " | txPHY: "
+ txPhy + " | rxPHY: " + rxPhy);
}
}
@Override
public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
if (RxCentralLogger.isDebug()) {
RxCentralLogger.debug("onPhyRead - Status: " + status + " | txPHY: "
+ txPhy + " | rxPHY: " + rxPhy);
}
}
private <T> void operationResult(
@Nullable SingleSubject<T> operationSubject,
T result,
int status,
PeripheralError.Code errorType) {
synchronized (syncRoot) {
if (currentOperation == operationSubject && operationSubject != null) {
if (status == 0) {
operationSubject.onSuccess(result);
} else {
operationSubject.onError(new PeripheralError(errorType, status));
}
} else if (currentOperation != null) {
PeripheralError cause = new PeripheralError(PeripheralError.Code.OPERATION_RESULT_MISMATCH);
currentOperation.onError(new PeripheralError(errorType, status, cause));
}
}
}
};
}