com.polidea.rxandroidble2.exceptions.BleGattCallbackTimeoutException Java Examples

The following examples show how to use com.polidea.rxandroidble2.exceptions.BleGattCallbackTimeoutException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SingleResponseOperation.java    From RxAndroidBle with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unused")
protected Single<T> timeoutFallbackProcedure(
        BluetoothGatt bluetoothGatt,
        RxBleGattCallback rxBleGattCallback,
        Scheduler timeoutScheduler
) {
    return Single.error(new BleGattCallbackTimeoutException(this.bluetoothGatt, operationType));
}
 
Example #2
Source File: ServiceDiscoveryOperation.java    From RxAndroidBle with Apache License 2.0 5 votes vote down vote up
/**
 * Sometimes it happens that the {@link BluetoothGatt} will receive all {@link BluetoothGattService}'s,
 * {@link android.bluetooth.BluetoothGattCharacteristic}'s and {@link android.bluetooth.BluetoothGattDescriptor}
 * but it won't receive the final callback that the service discovery was completed. This is a potential workaround.
 * <p>
 * There is a change in Android 7.0.0_r1 where all data is received at once - in this situation returned services size will be always 0
 * https://android.googlesource.com/platform/frameworks/base/+/android-7.0.0_r1/core/java/android/bluetooth/BluetoothGatt.java#206
 * https://android.googlesource.com/platform/frameworks/base/+/android-6.0.1_r72/core/java/android/bluetooth/BluetoothGatt.java#205
 *
 * @param bluetoothGatt     the BluetoothGatt to use
 * @param rxBleGattCallback the RxBleGattCallback to use
 * @param timeoutScheduler  the Scheduler for timeout to use
 * @return Observable that may emit {@link RxBleDeviceServices} or {@link TimeoutException}
 */
@NonNull
@Override
protected Single<RxBleDeviceServices> timeoutFallbackProcedure(
        final BluetoothGatt bluetoothGatt,
        final RxBleGattCallback rxBleGattCallback,
        final Scheduler timeoutScheduler
) {
    return Single.defer(new Callable<SingleSource<? extends RxBleDeviceServices>>() {
        @Override
        public SingleSource<? extends RxBleDeviceServices> call() {
            final List<BluetoothGattService> services = bluetoothGatt.getServices();
            if (services.size() == 0) {
                // if after the timeout services are empty we have no other option to declare a failed discovery
                return Single.error(new BleGattCallbackTimeoutException(bluetoothGatt, BleGattOperationType.SERVICE_DISCOVERY));
            } else {
            /*
            it is observed that usually the Android OS is returning services, characteristics and descriptors in a short period of time
            if there are some services available we will wait for 5 more seconds just to be sure that
            the timeout was not triggered right in the moment of filling the services and then emit a value.
             */
                return Single
                        .timer(5, TimeUnit.SECONDS, timeoutScheduler)
                        .flatMap(new Function<Long, Single<RxBleDeviceServices>>() {
                            @Override
                            public Single<RxBleDeviceServices> apply(Long delayedSeconds) {
                                return Single.fromCallable(new Callable<RxBleDeviceServices>() {
                                    @Override
                                    public RxBleDeviceServices call() {
                                        return new RxBleDeviceServices(bluetoothGatt.getServices());
                                    }
                                });
                            }
                        });
            }
        }
    });
}
 
Example #3
Source File: ConnectOperation.java    From RxAndroidBle with Apache License 2.0 5 votes vote down vote up
@NonNull
Single<BluetoothGatt> prepareConnectionTimeoutError() {
    return Single.fromCallable(new Callable<BluetoothGatt>() {
        @Override
        public BluetoothGatt call() {
            throw new BleGattCallbackTimeoutException(bluetoothGattProvider.getBluetoothGatt(), BleGattOperationType.CONNECTION_STATE);
        }
    });
}
 
Example #4
Source File: CharacteristicLongWriteOperation.java    From RxAndroidBle with Apache License 2.0 4 votes vote down vote up
@Override
protected void protectedRun(final ObservableEmitter<byte[]> emitter, final QueueReleaseInterface queueReleaseInterface) {
    final int batchSize = batchSizeProvider.getPayloadSizeLimit();
    if (batchSize <= 0) {
        throw new IllegalArgumentException("batchSizeProvider value must be greater than zero (now: " + batchSize + ")");
    }
    final Observable<ByteAssociation<UUID>> timeoutObservable = Observable.error(
            new BleGattCallbackTimeoutException(bluetoothGatt, BleGattOperationType.CHARACTERISTIC_LONG_WRITE)
    );
    final ByteBuffer byteBuffer = ByteBuffer.wrap(bytesToWrite);
    final QueueReleasingEmitterWrapper<byte[]> emitterWrapper = new QueueReleasingEmitterWrapper<>(emitter, queueReleaseInterface);
    final IntSupplier previousBatchIndexSupplier = new IntSupplier() {
        @Override
        public int get() {
            return (int) Math.ceil(byteBuffer.position() / (float) batchSize) - 1;
        }
    };
    writeBatchAndObserve(batchSize, byteBuffer, previousBatchIndexSupplier)
            .subscribeOn(bluetoothInteractionScheduler)
            .filter(writeResponseForMatchingCharacteristic(bluetoothGattCharacteristic))
            .take(1)
            .timeout(
                    timeoutConfiguration.timeout,
                    timeoutConfiguration.timeoutTimeUnit,
                    timeoutConfiguration.timeoutScheduler,
                    timeoutObservable
            )
            .repeatWhen(bufferIsNotEmptyAndOperationHasBeenAcknowledgedAndNotUnsubscribed(
                    writeOperationAckStrategy, byteBuffer, emitterWrapper
            ))
            .retryWhen(errorIsRetryableAndAccordingTo(writeOperationRetryStrategy, byteBuffer, batchSize, previousBatchIndexSupplier))
            .subscribe(new Observer<ByteAssociation<UUID>>() {
                @Override
                public void onSubscribe(Disposable d) {
                    // not used
                }

                @Override
                public void onNext(ByteAssociation<UUID> uuidByteAssociation) {
                    // not used
                }

                @Override
                public void onError(Throwable e) {
                    emitterWrapper.onError(e);
                }

                @Override
                public void onComplete() {
                    emitterWrapper.onNext(bytesToWrite);
                    emitterWrapper.onComplete();
                }
            });
}
 
Example #5
Source File: Ob1G5CollectionService.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
private void onConnectionFailure(final Throwable throwable) {
    // msg("Connection failure");
    // TODO under what circumstances should we change state or do something here?
    UserError.Log.d(TAG, "Connection Disconnected/Failed: " + throwable);

    if (state == DISCOVER) {
        // possible encryption failure
        if (!resetBondIfAllowed(false) && android_wear) {
            UserError.Log.d(TAG, "Trying alternate reconnection strategy");
            changeState(CONNECT_NOW);
        }
        return;
    }

    if (state == CONNECT_NOW) {
        connectNowFailures++;
        lastConnectFailed = true;
        if (throwable instanceof BleGattCallbackTimeoutException) {
            if (throwable.getMessage().contains("BleGattOperation{description='CONNECTION_STATE'")) {
                UserError.Log.d(TAG, "Setting pre-scan failure marker enabled due to exception type");
                preScanFailureMarker = true;
            }
        } else if (JoH.msSince(last_connect_started) < Constants.SECOND_IN_MS) {
            UserError.Log.d(TAG, "Setting pre-scan failure marker enabled due to exception timing");
            preScanFailureMarker = true;
        }

        UserError.Log.d(TAG, "Connect Now failures incremented to: " + connectNowFailures);
        if (minimize_scanning && DexSyncKeeper.anticipate(transmitterID) > 0) {
            // TODO under what circumstances does this CLOSE state not get executed? and anticipate not scheduled?
            changeState(CLOSE);
        } else {
            changeState(CONNECT);
        }
        return;
    }

    if (state == CONNECT) {
        connectFailures++;
        lastConnectFailed = true;
        // TODO check bluetooth on or in connect section
        if (JoH.ratelimit("ob1-restart-scan-on-connect-failure", 10)) {
            UserError.Log.d(TAG, "Restarting scan due to connect failure");
            tryGattRefresh();
            changeState(SCAN);
        }
    }

}
 
Example #6
Source File: Ob1G5CollectionService.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
private void onConnectionFailure(final Throwable throwable) {
    // msg("Connection failure");
    // TODO under what circumstances should we change state or do something here?
    UserError.Log.d(TAG, "Connection Disconnected/Failed: " + throwable);

    if (state == DISCOVER) {
        // possible encryption failure
        if (!resetBondIfAllowed(false) && android_wear) {
            UserError.Log.d(TAG, "Trying alternate reconnection strategy");
            changeState(CONNECT_NOW);
        }
        return;
    }

    if (state == CONNECT_NOW) {
        connectNowFailures++;
        lastConnectFailed = true;

        if ((connectNowFailures % 12 == 7) && genericBluetoothWatchdog()) {
            UserError.Log.e(TAG, "Initiating bluetooth watchdog reset");
            JoH.niceRestartBluetooth(xdrip.getAppContext());
        }

        if (throwable instanceof BleGattCallbackTimeoutException) {
            if (throwable.getMessage().contains("BleGattOperation{description='CONNECTION_STATE'")) {
                UserError.Log.d(TAG, "Setting pre-scan failure marker enabled due to exception type");
                preScanFailureMarker = true;
            }
        } else if (JoH.msSince(last_connect_started) < Constants.SECOND_IN_MS) {
            UserError.Log.d(TAG, "Setting pre-scan failure marker enabled due to exception timing");
            preScanFailureMarker = true;
        }

        UserError.Log.d(TAG, "Connect Now failures incremented to: " + connectNowFailures);
        if (minimize_scanning && DexSyncKeeper.anticipate(transmitterID) > 0) {
            // TODO under what circumstances does this CLOSE state not get executed? and anticipate not scheduled?
            changeState(CLOSE);
        } else {
            changeState(CONNECT);
        }
        return;
    }

    if (state == CONNECT) {
        connectFailures++;
        lastConnectFailed = true;
        // TODO check bluetooth on or in connect section
        if (JoH.ratelimit("ob1-restart-scan-on-connect-failure", 10)) {
            UserError.Log.d(TAG, "Restarting scan due to connect failure");
            tryGattRefresh();
            changeState(SCAN);
        }
    }

}
 
Example #7
Source File: Ob1G5CollectionService.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
private void onConnectionFailure(final Throwable throwable) {
    // msg("Connection failure");
    // TODO under what circumstances should we change state or do something here?
    UserError.Log.d(TAG, "Connection Disconnected/Failed: " + throwable);

    if (state == DISCOVER) {
        // possible encryption failure
        if (!resetBondIfAllowed(false) && android_wear) {
            UserError.Log.d(TAG, "Trying alternate reconnection strategy");
            changeState(CONNECT_NOW);
        }
        return;
    }

    if (state == CONNECT_NOW) {
        connectNowFailures++;
        lastConnectFailed = true;
        if (throwable instanceof BleGattCallbackTimeoutException) {
            if (throwable.getMessage().contains("BleGattOperation{description='CONNECTION_STATE'")) {
                UserError.Log.d(TAG, "Setting pre-scan failure marker enabled due to exception type");
                preScanFailureMarker = true;
            }
        } else if (JoH.msSince(last_connect_started) < Constants.SECOND_IN_MS) {
            UserError.Log.d(TAG, "Setting pre-scan failure marker enabled due to exception timing");
            preScanFailureMarker = true;
        }

        UserError.Log.d(TAG, "Connect Now failures incremented to: " + connectNowFailures);
        if (minimize_scanning && DexSyncKeeper.anticipate(transmitterID) > 0) {
            // TODO under what circumstances does this CLOSE state not get executed? and anticipate not scheduled?
            changeState(CLOSE);
        } else {
            changeState(CONNECT);
        }
        return;
    }

    if (state == CONNECT) {
        connectFailures++;
        lastConnectFailed = true;
        // TODO check bluetooth on or in connect section
        if (JoH.ratelimit("ob1-restart-scan-on-connect-failure", 10)) {
            UserError.Log.d(TAG, "Restarting scan due to connect failure");
            tryGattRefresh();
            changeState(SCAN);
        }
    }

}
 
Example #8
Source File: Ob1G5CollectionService.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
private void onConnectionFailure(final Throwable throwable) {
    // msg("Connection failure");
    // TODO under what circumstances should we change state or do something here?
    UserError.Log.d(TAG, "Connection Disconnected/Failed: " + throwable);

    if (state == DISCOVER) {
        // possible encryption failure
        if (!resetBondIfAllowed(false) && android_wear) {
            UserError.Log.d(TAG, "Trying alternate reconnection strategy");
            changeState(CONNECT_NOW);
        }
        return;
    }

    if (state == CONNECT_NOW) {
        connectNowFailures++;
        lastConnectFailed = true;

        if ((connectNowFailures % 12 == 7) && genericBluetoothWatchdog()) {
            UserError.Log.e(TAG, "Initiating bluetooth watchdog reset");
            JoH.niceRestartBluetooth(xdrip.getAppContext());
        }

        if (throwable instanceof BleGattCallbackTimeoutException) {
            if (throwable.getMessage().contains("BleGattOperation{description='CONNECTION_STATE'")) {
                UserError.Log.d(TAG, "Setting pre-scan failure marker enabled due to exception type");
                preScanFailureMarker = true;
            }
        } else if (JoH.msSince(last_connect_started) < Constants.SECOND_IN_MS) {
            UserError.Log.d(TAG, "Setting pre-scan failure marker enabled due to exception timing");
            preScanFailureMarker = true;
        }

        UserError.Log.d(TAG, "Connect Now failures incremented to: " + connectNowFailures);
        if (minimize_scanning && DexSyncKeeper.anticipate(transmitterID) > 0) {
            // TODO under what circumstances does this CLOSE state not get executed? and anticipate not scheduled?
            changeState(CLOSE);
        } else {
            changeState(CONNECT);
        }
        return;
    }

    if (state == CONNECT) {
        connectFailures++;
        lastConnectFailed = true;
        // TODO check bluetooth on or in connect section
        if (JoH.ratelimit("ob1-restart-scan-on-connect-failure", 10)) {
            UserError.Log.d(TAG, "Restarting scan due to connect failure");
            tryGattRefresh();
            changeState(SCAN);
        }
    }

}