com.polidea.rxandroidble2.exceptions.BleCharacteristicNotFoundException Java Examples

The following examples show how to use com.polidea.rxandroidble2.exceptions.BleCharacteristicNotFoundException. 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: RxBleDeviceServices.java    From RxAndroidBle with Apache License 2.0 5 votes vote down vote up
/**
 * Creates an observable emitting {@link BluetoothGattCharacteristic} with matching characteristic UUID.
 * The observable completes after first emission.
 * <p>
 * The main assumption is that characteristics have unique UUID across all services as there is a traversal done
 * across all of them. For an alternative see RxBleDeviceServices#getCharacteristic(UUID)
 *
 * @param characteristicUuid Characteristic UUID to be found
 * @return Observable emitting matching characteristic or error if hasn't been found.
 * @throws BleCharacteristicNotFoundException if characteristic with given UUID hasn't been found.
 */
public Single<BluetoothGattCharacteristic> getCharacteristic(@NonNull final UUID characteristicUuid) {
    return Single.fromCallable(new Callable<BluetoothGattCharacteristic>() {
        @Override
        public BluetoothGattCharacteristic call() {
            for (BluetoothGattService service : bluetoothGattServices) {
                BluetoothGattCharacteristic characteristic = service.getCharacteristic(characteristicUuid);
                if (characteristic != null) {
                    return characteristic;
                }
            }
            throw new BleCharacteristicNotFoundException(characteristicUuid);
        }
    });
}
 
Example #2
Source File: RxBleDeviceServices.java    From RxAndroidBle with Apache License 2.0 5 votes vote down vote up
/**
 * Creates an observable emitting {@link BluetoothGattCharacteristic}s with matching service UUID and characteristic UUID.
 * The observable completes after first emission.
 *
 * @param characteristicUuid Characteristic UUID to be found
 * @param serviceUuid        Service UUID to search in
 * @return Observable emitting matching characteristic or error if hasn't been found.
 * @throws BleCharacteristicNotFoundException if characteristic with given UUID hasn't been found.
 * @see RxBleDeviceServices#getCharacteristic(UUID)
 */
public Single<BluetoothGattCharacteristic> getCharacteristic(@NonNull UUID serviceUuid, @NonNull final UUID characteristicUuid) {
    return getService(serviceUuid)
            .map(new Function<BluetoothGattService, BluetoothGattCharacteristic>() {
                @Override
                public BluetoothGattCharacteristic apply(BluetoothGattService bluetoothGattService) {
                    final BluetoothGattCharacteristic characteristic = bluetoothGattService.getCharacteristic(characteristicUuid);

                    if (characteristic == null) {
                        throw new BleCharacteristicNotFoundException(characteristicUuid);
                    }
                    return characteristic;
                }
            });
}
 
Example #3
Source File: MiBandService.java    From xDrip with GNU General Public License v3.0 5 votes vote down vote up
private void enableHeartRateNotification() {
    if (MiBandEntry.isNeedToCollectHR()) {
        if (notifSubscriptionHeartRateMeasurement != null) return;
    } else {
        if (notifSubscriptionHeartRateMeasurement != null) {
            notifSubscriptionHeartRateMeasurement.unsubscribe();
            notifSubscriptionHeartRateMeasurement = null;
            return;
        }
    }

    if (d)
        UserError.Log.d(TAG, "Requesting to enable HR notifications");

    notifSubscriptionHeartRateMeasurement = new Subscription(I.connection.setupNotification(Const.UUID_CHAR_HEART_RATE_MEASUREMENT)
            .flatMap(notificationObservable -> notificationObservable)
            .observeOn(Schedulers.newThread())
            .subscribe(bytes -> {
                        // incoming notifications
                        if (d)
                            UserError.Log.d(TAG, "Received HR notification bytes: " + bytesToHex(bytes));
                        handleHeartrate(bytes);
                    }, throwable -> {
                        notifSubscriptionHeartRateMeasurement.unsubscribe();
                        notifSubscriptionHeartRateMeasurement = null;
                        UserError.Log.d(TAG, "HR Throwable in Record Notification: " + throwable);
                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            UserError.Log.d(TAG, "HR Characteristic not found for notification");
                        } else {
                            UserError.Log.d(TAG, "HR Disconnected exception");
                        }
                    }
            ));

}
 
Example #4
Source File: BlueJayService.java    From xDrip with GNU General Public License v3.0 5 votes vote down vote up
private void sendTime() {
    final String func = "SetTime";
    final SetTimeTx outbound = new SetTimeTx();
    UserError.Log.d(TAG, "Outbound: " + bytesToHex(outbound.getBytes()));
    I.connection.writeCharacteristic(THINJAM_WRITE, outbound.getBytes()).subscribe(
            response -> {
                SetTimeTx reply = new SetTimeTx(response);
                if (D)
                    UserError.Log.d(TAG, func + " response: " + bytesToHex(response) + " " + reply.toS());

                UserError.Log.e(TAG, "Time difference with watch: " + ((outbound.getTimestamp() - reply.getTimestamp()) / 1000d));
                changeNextState();

            }, throwable -> {
                UserError.Log.e(TAG, "Failed to write " + func + " request: " + throwable);
                if (throwable instanceof BleGattCharacteristicException) {
                    final int status = ((BleGattCharacteristicException) throwable).getStatus();
                    UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
                } else {
                    UserError.Log.d(TAG, "Throwable in " + func + " " + throwable);
                    if (throwable instanceof BleCharacteristicNotFoundException) {
                        UserError.Log.d(TAG, "Assuming wrong firmware version");
                        changeNextState();
                    } else {
                        changeState(CLOSE);
                    }
                }
            });
}
 
Example #5
Source File: MiBandService.java    From xDrip-plus with GNU General Public License v3.0 5 votes vote down vote up
private void enableHeartRateNotification() {
    if (MiBandEntry.isNeedToCollectHR()) {
        if (notifSubscriptionHeartRateMeasurement != null) return;
    } else {
        if (notifSubscriptionHeartRateMeasurement != null) {
            notifSubscriptionHeartRateMeasurement.unsubscribe();
            notifSubscriptionHeartRateMeasurement = null;
            return;
        }
    }

    if (d)
        UserError.Log.d(TAG, "Requesting to enable HR notifications");

    notifSubscriptionHeartRateMeasurement = new Subscription(I.connection.setupNotification(Const.UUID_CHAR_HEART_RATE_MEASUREMENT)
            .flatMap(notificationObservable -> notificationObservable)
            .observeOn(Schedulers.newThread())
            .subscribe(bytes -> {
                        // incoming notifications
                        if (d)
                            UserError.Log.d(TAG, "Received HR notification bytes: " + bytesToHex(bytes));
                        handleHeartrate(bytes);
                    }, throwable -> {
                        notifSubscriptionHeartRateMeasurement.unsubscribe();
                        notifSubscriptionHeartRateMeasurement = null;
                        UserError.Log.d(TAG, "HR Throwable in Record Notification: " + throwable);
                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            UserError.Log.d(TAG, "HR Characteristic not found for notification");
                        } else {
                            UserError.Log.d(TAG, "HR Disconnected exception");
                        }
                    }
            ));

}
 
Example #6
Source File: BlueJayService.java    From xDrip-plus with GNU General Public License v3.0 5 votes vote down vote up
private void sendTime() {
    final String func = "SetTime";
    final SetTimeTx outbound = new SetTimeTx();
    UserError.Log.d(TAG, "Outbound: " + bytesToHex(outbound.getBytes()));
    I.connection.writeCharacteristic(THINJAM_WRITE, outbound.getBytes()).subscribe(
            response -> {
                SetTimeTx reply = new SetTimeTx(response);
                if (D)
                    UserError.Log.d(TAG, func + " response: " + bytesToHex(response) + " " + reply.toS());

                UserError.Log.e(TAG, "Time difference with watch: " + ((outbound.getTimestamp() - reply.getTimestamp()) / 1000d));
                changeNextState();

            }, throwable -> {
                UserError.Log.e(TAG, "Failed to write " + func + " request: " + throwable);
                if (throwable instanceof BleGattCharacteristicException) {
                    final int status = ((BleGattCharacteristicException) throwable).getStatus();
                    UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
                } else {
                    UserError.Log.d(TAG, "Throwable in " + func + " " + throwable);
                    if (throwable instanceof BleCharacteristicNotFoundException) {
                        UserError.Log.d(TAG, "Assuming wrong firmware version");
                        changeNextState();
                    } else {
                        changeState(CLOSE);
                    }
                }
            });
}
 
Example #7
Source File: MiBandService.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
@SuppressLint("CheckResult")
private void authPhase() {
    extendWakeLock(30000);
    RxBleConnection connection = I.connection;
    if (d)
        UserError.Log.d(TAG, "Authorizing");
    if (I.connection == null) {
        if (d)
            UserError.Log.d(TAG, "Cannot enable as connection is null!");
        return;
    }

    String authKey = MiBand.getPersistentAuthKey();
    if (MiBand.getMibandType() == MI_BAND4) {
        if (authKey.isEmpty()) {
            authKey = MiBand.getAuthKey();
            if (authKey.isEmpty()) {
                authKey = AuthMessages.getAuthCodeFromFilesSystem(MiBand.getMac());
            }
            if (!AuthMessages.isValidAuthKey(authKey)) {
                JoH.static_toast_long("Wrong miband authorization key, please recheck a key and try to reconnect again");
                changeState(AUTHORIZE_FAILED);
                return;
            } else {
                MiBand.setAuthKey(authKey);
            }
        }
    }
    if (!AuthMessages.isValidAuthKey(authKey)) {
        authKey = "";
    }
    if (d)
        UserError.Log.d(TAG, "authKey: " + authKey);

    authorisation = new AuthMessages(MiBand.getMibandType(), authKey);
    if (d)
        UserError.Log.d(TAG, "localKey: " + JoH.bytesToHex(authorisation.getLocalKey()));
    authSubscription = new Subscription(
            connection.setupNotification(authorisation.getCharacteristicUUID())
                    .timeout(20, TimeUnit.SECONDS) // WARN
                    // .observeOn(Schedulers.newThread()) // needed?
                    .doOnNext(notificationObservable -> {
                                if (d)
                                    UserError.Log.d(TAG, "Notification for auth enabled");
                                if (MiBand.isAuthenticated()) {
                                    connection.writeCharacteristic(authorisation.getCharacteristicUUID(), authorisation.getAuthKeyRequest()) //get random key from band
                                            .subscribe(val -> {
                                                if (d)
                                                    UserError.Log.d(TAG, "Wrote getAuthKeyRequest: " + JoH.bytesToHex(val));
                                            }, throwable -> {
                                                UserError.Log.e(TAG, "Could not getAuthKeyRequest: " + throwable);
                                            });
                                } else {
                                    connection.writeCharacteristic(authorisation.getCharacteristicUUID(), authorisation.getAuthCommand())
                                            .subscribe(characteristicValue -> {
                                                        UserError.Log.d(TAG, "Wrote getAuthCommand, got: " + JoH.bytesToHex(characteristicValue));
                                                    },
                                                    throwable -> {
                                                        UserError.Log.e(TAG, "Could not write getAuthCommand: " + throwable);
                                                    }
                                            );
                                }

                            }
                    )
                    .flatMap(notificationObservable -> notificationObservable)
                    .subscribe(bytes -> {
                        // incoming notifications
                        if (d)
                            UserError.Log.d(TAG, "Received auth notification bytes: " + bytesToHex(bytes));
                        ProcessAuthCommands(connection, bytes);
                        // changeNextState();
                    }, throwable -> {
                        UserError.Log.d(TAG, "Throwable in Record Notification: " + throwable);
                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            // maybe legacy - ignore for now but needs better handling
                            UserError.Log.d(TAG, "Characteristic not found for notification");
                        } else if (throwable instanceof BleCannotSetCharacteristicNotificationException) {
                            UserError.Log.e(TAG, "Problems setting notifications - disconnecting");
                        } else if (throwable instanceof BleDisconnectedException) {
                            UserError.Log.d(TAG, "Disconnected while enabling notifications");
                        } else if (throwable instanceof TimeoutException) {
                            //check if it is normal timeout
                            if (!MiBand.isAuthenticated()) {
                                String errorText = "MiBand authentication failed due to authentication timeout. When your Mi Band vibrates and blinks, tap it a few times in a row.";
                                UserError.Log.d(TAG, errorText);
                                JoH.static_toast_long(errorText);
                            }
                        }
                        if (authSubscription != null) {
                            authSubscription.unsubscribe();
                        }
                        changeState(CLOSE);
                    }));
}
 
Example #8
Source File: MiBandService.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
@SuppressLint("CheckResult")
private void installWatchface() {
    //TODO decrease display brightness before uploading watchface to minimize battery consumption
    RxBleConnection connection = I.connection;
    if (d)
        UserError.Log.d(TAG, "Install WatchFace");
    if (I.connection == null) {
        if (d)
            UserError.Log.d(TAG, "Cannot enable as connection is null!");
        return;
    }
    try {
        WatchFaceGenerator wfGen = new WatchFaceGenerator(getBaseContext().getAssets());
        byte[] fwArray = wfGen.genWatchFace();
        if (fwArray == null || fwArray.length == 0) {
            resetFirmwareState(false, "Empty image");
            return;
        }
        firmware = new FirmwareOperations(fwArray);
    } catch (Exception e) {
        resetFirmwareState(false, "FirmwareOperations error " + e.getMessage());
        return;
    }
    if (d)
        UserError.Log.d(TAG, "Begin uploading Watchface, lenght: " + firmware.getSize());
    if (d)
        UserError.Log.d(TAG, "Requesting to enable notifications for installWatchface");
    watchfaceSubscription = new Subscription(
            connection.setupNotification(firmware.getFirmwareCharacteristicUUID())
                    .timeout(400, TimeUnit.SECONDS) // WARN
                    .doOnNext(notificationObservable -> {
                                if (d)
                                    UserError.Log.d(TAG, "Notification for firmware enabled");
                                firmware.nextSequence();
                                processFirmwareCommands(null, true);
                            }
                    )
                    .flatMap(notificationObservable -> notificationObservable)
                    .subscribe(bytes -> {
                        // incoming notifications
                        if (d)
                            UserError.Log.d(TAG, "Received firmware notification bytes: " + bytesToHex(bytes));
                        processFirmwareCommands(bytes, false);
                    }, throwable -> {
                        UserError.Log.d(TAG, "Throwable in firmware Notification: " + throwable);
                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            // maybe legacy - ignore for now but needs better handling
                            UserError.Log.d(TAG, "Characteristic not found for notification");
                        } else if (throwable instanceof BleCannotSetCharacteristicNotificationException) {
                            UserError.Log.e(TAG, "Problems setting notifications - disconnecting");
                        } else if (throwable instanceof BleDisconnectedException) {
                            UserError.Log.d(TAG, "Disconnected while enabling notifications");
                        } else if (throwable instanceof TimeoutException) {
                            UserError.Log.d(TAG, "Timeout");
                        }
                        resetFirmwareState(false);
                    }));
}
 
Example #9
Source File: MiBandService.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
@SuppressLint("CheckResult")
private void enableNotification() {
    if (d)
        UserError.Log.d(TAG, "enableNotifications called");
    if (I.connection == null) {
        if (d)
            UserError.Log.d(TAG, "Cannot enable as connection is null!");
        return;
    }
    enableHeartRateNotification();
    if (I.isNotificationEnabled) {
        if (d)
            UserError.Log.d(TAG, "Notifications already enabled");
        changeNextState();
        return;
    }
    if (notifSubscriptionDeviceEvent != null) {
        notifSubscriptionDeviceEvent.unsubscribe();
    }
    if (notifSubscriptionHeartRateMeasurement != null) {
        notifSubscriptionHeartRateMeasurement.unsubscribe();
    }
    if (d)
        UserError.Log.d(TAG, "Requesting to enable device event notifications");

    I.connection.requestMtu(PREFERRED_MTU_SIZE).subscribe();

    notifSubscriptionDeviceEvent = new Subscription(I.connection.setupNotification(Const.UUID_CHARACTERISTIC_DEVICEEVENT)
            .doOnNext(notificationObservable -> {
                I.isNotificationEnabled = true;
                changeNextState();
            }).flatMap(notificationObservable -> notificationObservable)
            //.timeout(5, TimeUnit.SECONDS)
            .observeOn(Schedulers.newThread())
            .subscribe(bytes -> {
                        // incoming notifications
                        if (d)
                            UserError.Log.d(TAG, "Received device notification bytes: " + bytesToHex(bytes));
                        handleDeviceEvent(bytes);
                    }, throwable -> {
                        UserError.Log.d(TAG, "Throwable in Record Notification: " + throwable);
                        I.isNotificationEnabled = false;
                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            // maybe legacy - ignore for now but needs better handling
                            UserError.Log.d(TAG, "Characteristic not found for notification");
                            changeNextState();
                        } else {
                            UserError.Log.d(TAG, "Disconnected exception");
                            isNeedToAuthenticate = true;
                            messageQueue.clear();
                            changeState(CLOSE);
                        }
                    }
            ));

}
 
Example #10
Source File: BlueJayService.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
private void enableNotifications() {
    UserError.Log.d(TAG, "enableNotifications called()");
    if (I.isNotificationEnabled) {
        UserError.Log.d(TAG, "Notifications already enabled");
        changeNextState();
        return;
    }
    if (notificationSubscription != null) {
        notificationSubscription.unsubscribe();
    }
    JoH.threadSleep(500);
    UserError.Log.d(TAG, "Requesting to enable notifications");
    notificationSubscription = new Subscription(
            I.connection.setupNotification(THINJAM_WRITE)
                    // .timeout(15, TimeUnit.SECONDS) // WARN
                    // .observeOn(Schedulers.newThread()) // needed?
                    .doOnNext(notificationObservable -> {

                                UserError.Log.d(TAG, "Notifications enabled");
                                I.connection.writeCharacteristic(THINJAM_BULK, new byte[]{0x55});

                                JoH.threadSleep(500); // Debug sleep to make sure notifications are actually enabled???
                                I.isNotificationEnabled = true;
                                changeNextState();
                            }

                    ).flatMap(notificationObservable -> notificationObservable)
                    //.timeout(5, TimeUnit.SECONDS)
                    .observeOn(Schedulers.newThread())
                    .subscribe(bytes -> {
                        // incoming notifications
                        UserError.Log.d(TAG, "Received notification bytes: " + JoH.bytesToHex(bytes));
                        val pushRx = PushRx.parse(bytes);
                        if (pushRx != null) {
                            UserError.Log.d(TAG, "Received PushRX: " + pushRx.toS());
                            getInfo().processPushRx(pushRx);
                            processPushRxActions(pushRx);
                        } else if (bytes[0] == 0x06) {
                            // TODO move this to parsed response
                            final int replyParam = ((int) bytes[1]) & 0xff;
                            if (replyParam == 0) {
                                UserError.Log.d(TAG, "Bulk up success reply marker received! - removing queue head item");
                                commandQueue.poll(); // removes first item from the queue which should be the one we just processed!
                                UserError.Log.d(TAG, "Scheduling immediate run of queue");
                                Inevitable.kill("tj-next-queue"); // remove timeout retry task
                                Inevitable.task("tj-next-queue", 0, this::processQueue);
                            } else {
                                revisedOffset = replyParam;
                                UserError.Log.d(TAG, "Bulk up failure at: " + revisedOffset); // race condition on display
                            }
                        } else if (bytes[0] == (byte) 0xFE) {
                            audioStreamCallBack(bytes);
                        } else {
                            if (ThinJamActivity.isD()) {
                                notificationString.append(new String(bytes));
                                Inevitable.task("tj update notifi", 250, new Runnable() {
                                    @Override
                                    public void run() {
                                        stringObservableField.set(notificationString.toString());
                                    }
                                });
                            }
                        }
                    }, throwable -> {
                        UserError.Log.d(TAG, "Throwable in Record Notification: " + throwable);
                        I.isNotificationEnabled = false;

                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            // maybe legacy - ignore for now but needs better handling
                            UserError.Log.d(TAG, "Characteristic not found for notification");
                            debug.processTestSuite("logcharerror");
                            tryGattRefresh(getI().connection);
                        }
                        if (throwable instanceof BleCannotSetCharacteristicNotificationException) {
                            UserError.Log.e(TAG, "Problems setting notifications - disconnecting");
                            changeState(CLOSE);
                        }
                        if (throwable instanceof BleDisconnectedException) {
                            UserError.Log.d(TAG, "Disconnected while enabling notifications");
                            changeState(CLOSE);
                        }

                    }));
}
 
Example #11
Source File: MiBandService.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
@SuppressLint("CheckResult")
private void authPhase() {
    extendWakeLock(30000);
    RxBleConnection connection = I.connection;
    if (d)
        UserError.Log.d(TAG, "Authorizing");
    if (I.connection == null) {
        if (d)
            UserError.Log.d(TAG, "Cannot enable as connection is null!");
        return;
    }

    String authKey = MiBand.getPersistentAuthKey();
    if (MiBand.getMibandType() == MI_BAND4) {
        if (authKey.isEmpty()) {
            authKey = MiBand.getAuthKey();
            if (authKey.isEmpty()) {
                authKey = AuthMessages.getAuthCodeFromFilesSystem(MiBand.getMac());
            }
            if (!AuthMessages.isValidAuthKey(authKey)) {
                JoH.static_toast_long("Wrong miband authorization key, please recheck a key and try to reconnect again");
                changeState(AUTHORIZE_FAILED);
                return;
            } else {
                MiBand.setAuthKey(authKey);
            }
        }
    }
    if (!AuthMessages.isValidAuthKey(authKey)) {
        authKey = "";
    }
    if (d)
        UserError.Log.d(TAG, "authKey: " + authKey);

    authorisation = new AuthMessages(MiBand.getMibandType(), authKey);
    if (d)
        UserError.Log.d(TAG, "localKey: " + JoH.bytesToHex(authorisation.getLocalKey()));
    authSubscription = new Subscription(
            connection.setupNotification(authorisation.getCharacteristicUUID())
                    .timeout(20, TimeUnit.SECONDS) // WARN
                    // .observeOn(Schedulers.newThread()) // needed?
                    .doOnNext(notificationObservable -> {
                                if (d)
                                    UserError.Log.d(TAG, "Notification for auth enabled");
                                if (MiBand.isAuthenticated()) {
                                    connection.writeCharacteristic(authorisation.getCharacteristicUUID(), authorisation.getAuthKeyRequest()) //get random key from band
                                            .subscribe(val -> {
                                                if (d)
                                                    UserError.Log.d(TAG, "Wrote getAuthKeyRequest: " + JoH.bytesToHex(val));
                                            }, throwable -> {
                                                UserError.Log.e(TAG, "Could not getAuthKeyRequest: " + throwable);
                                            });
                                } else {
                                    connection.writeCharacteristic(authorisation.getCharacteristicUUID(), authorisation.getAuthCommand())
                                            .subscribe(characteristicValue -> {
                                                        UserError.Log.d(TAG, "Wrote getAuthCommand, got: " + JoH.bytesToHex(characteristicValue));
                                                    },
                                                    throwable -> {
                                                        UserError.Log.e(TAG, "Could not write getAuthCommand: " + throwable);
                                                    }
                                            );
                                }

                            }
                    )
                    .flatMap(notificationObservable -> notificationObservable)
                    .subscribe(bytes -> {
                        // incoming notifications
                        if (d)
                            UserError.Log.d(TAG, "Received auth notification bytes: " + bytesToHex(bytes));
                        ProcessAuthCommands(connection, bytes);
                        // changeNextState();
                    }, throwable -> {
                        UserError.Log.d(TAG, "Throwable in Record Notification: " + throwable);
                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            // maybe legacy - ignore for now but needs better handling
                            UserError.Log.d(TAG, "Characteristic not found for notification");
                        } else if (throwable instanceof BleCannotSetCharacteristicNotificationException) {
                            UserError.Log.e(TAG, "Problems setting notifications - disconnecting");
                        } else if (throwable instanceof BleDisconnectedException) {
                            UserError.Log.d(TAG, "Disconnected while enabling notifications");
                        } else if (throwable instanceof TimeoutException) {
                            //check if it is normal timeout
                            if (!MiBand.isAuthenticated()) {
                                String errorText = "MiBand authentication failed due to authentication timeout. When your Mi Band vibrates and blinks, tap it a few times in a row.";
                                UserError.Log.d(TAG, errorText);
                                JoH.static_toast_long(errorText);
                            }
                        }
                        if (authSubscription != null) {
                            authSubscription.unsubscribe();
                        }
                        changeState(CLOSE);
                    }));
}
 
Example #12
Source File: MiBandService.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
@SuppressLint("CheckResult")
private void installWatchface() {
    //TODO decrease display brightness before uploading watchface to minimize battery consumption
    RxBleConnection connection = I.connection;
    if (d)
        UserError.Log.d(TAG, "Install WatchFace");
    if (I.connection == null) {
        if (d)
            UserError.Log.d(TAG, "Cannot enable as connection is null!");
        return;
    }
    try {
        WatchFaceGenerator wfGen = new WatchFaceGenerator(getBaseContext().getAssets());
        byte[] fwArray = wfGen.genWatchFace();
        if (fwArray == null || fwArray.length == 0) {
            resetFirmwareState(false, "Empty image");
            return;
        }
        firmware = new FirmwareOperations(fwArray);
    } catch (Exception e) {
        resetFirmwareState(false, "FirmwareOperations error " + e.getMessage());
        return;
    }
    if (d)
        UserError.Log.d(TAG, "Begin uploading Watchface, lenght: " + firmware.getSize());
    if (d)
        UserError.Log.d(TAG, "Requesting to enable notifications for installWatchface");
    watchfaceSubscription = new Subscription(
            connection.setupNotification(firmware.getFirmwareCharacteristicUUID())
                    .timeout(400, TimeUnit.SECONDS) // WARN
                    .doOnNext(notificationObservable -> {
                                if (d)
                                    UserError.Log.d(TAG, "Notification for firmware enabled");
                                firmware.nextSequence();
                                processFirmwareCommands(null, true);
                            }
                    )
                    .flatMap(notificationObservable -> notificationObservable)
                    .subscribe(bytes -> {
                        // incoming notifications
                        if (d)
                            UserError.Log.d(TAG, "Received firmware notification bytes: " + bytesToHex(bytes));
                        processFirmwareCommands(bytes, false);
                    }, throwable -> {
                        UserError.Log.d(TAG, "Throwable in firmware Notification: " + throwable);
                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            // maybe legacy - ignore for now but needs better handling
                            UserError.Log.d(TAG, "Characteristic not found for notification");
                        } else if (throwable instanceof BleCannotSetCharacteristicNotificationException) {
                            UserError.Log.e(TAG, "Problems setting notifications - disconnecting");
                        } else if (throwable instanceof BleDisconnectedException) {
                            UserError.Log.d(TAG, "Disconnected while enabling notifications");
                        } else if (throwable instanceof TimeoutException) {
                            UserError.Log.d(TAG, "Timeout");
                        }
                        resetFirmwareState(false);
                    }));
}
 
Example #13
Source File: MiBandService.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
@SuppressLint("CheckResult")
private void enableNotification() {
    if (d)
        UserError.Log.d(TAG, "enableNotifications called");
    if (I.connection == null) {
        if (d)
            UserError.Log.d(TAG, "Cannot enable as connection is null!");
        return;
    }
    enableHeartRateNotification();
    if (I.isNotificationEnabled) {
        if (d)
            UserError.Log.d(TAG, "Notifications already enabled");
        changeNextState();
        return;
    }
    if (notifSubscriptionDeviceEvent != null) {
        notifSubscriptionDeviceEvent.unsubscribe();
    }
    if (notifSubscriptionHeartRateMeasurement != null) {
        notifSubscriptionHeartRateMeasurement.unsubscribe();
    }
    if (d)
        UserError.Log.d(TAG, "Requesting to enable device event notifications");

    I.connection.requestMtu(PREFERRED_MTU_SIZE).subscribe();

    notifSubscriptionDeviceEvent = new Subscription(I.connection.setupNotification(Const.UUID_CHARACTERISTIC_DEVICEEVENT)
            .doOnNext(notificationObservable -> {
                I.isNotificationEnabled = true;
                changeNextState();
            }).flatMap(notificationObservable -> notificationObservable)
            //.timeout(5, TimeUnit.SECONDS)
            .observeOn(Schedulers.newThread())
            .subscribe(bytes -> {
                        // incoming notifications
                        if (d)
                            UserError.Log.d(TAG, "Received device notification bytes: " + bytesToHex(bytes));
                        handleDeviceEvent(bytes);
                    }, throwable -> {
                        UserError.Log.d(TAG, "Throwable in Record Notification: " + throwable);
                        I.isNotificationEnabled = false;
                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            // maybe legacy - ignore for now but needs better handling
                            UserError.Log.d(TAG, "Characteristic not found for notification");
                            changeNextState();
                        } else {
                            UserError.Log.d(TAG, "Disconnected exception");
                            isNeedToAuthenticate = true;
                            messageQueue.clear();
                            changeState(CLOSE);
                        }
                    }
            ));

}
 
Example #14
Source File: BlueJayService.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
private void enableNotifications() {
    UserError.Log.d(TAG, "enableNotifications called()");
    if (I.isNotificationEnabled) {
        UserError.Log.d(TAG, "Notifications already enabled");
        changeNextState();
        return;
    }
    if (notificationSubscription != null) {
        notificationSubscription.unsubscribe();
    }
    JoH.threadSleep(500);
    UserError.Log.d(TAG, "Requesting to enable notifications");
    notificationSubscription = new Subscription(
            I.connection.setupNotification(THINJAM_WRITE)
                    // .timeout(15, TimeUnit.SECONDS) // WARN
                    // .observeOn(Schedulers.newThread()) // needed?
                    .doOnNext(notificationObservable -> {

                                UserError.Log.d(TAG, "Notifications enabled");
                                I.connection.writeCharacteristic(THINJAM_BULK, new byte[]{0x55});

                                JoH.threadSleep(500); // Debug sleep to make sure notifications are actually enabled???
                                I.isNotificationEnabled = true;
                                changeNextState();
                            }

                    ).flatMap(notificationObservable -> notificationObservable)
                    //.timeout(5, TimeUnit.SECONDS)
                    .observeOn(Schedulers.newThread())
                    .subscribe(bytes -> {
                        // incoming notifications
                        UserError.Log.d(TAG, "Received notification bytes: " + JoH.bytesToHex(bytes));
                        val pushRx = PushRx.parse(bytes);
                        if (pushRx != null) {
                            UserError.Log.d(TAG, "Received PushRX: " + pushRx.toS());
                            getInfo().processPushRx(pushRx);
                            processPushRxActions(pushRx);
                        } else if (bytes[0] == 0x06) {
                            // TODO move this to parsed response
                            final int replyParam = ((int) bytes[1]) & 0xff;
                            if (replyParam == 0) {
                                UserError.Log.d(TAG, "Bulk up success reply marker received! - removing queue head item");
                                commandQueue.poll(); // removes first item from the queue which should be the one we just processed!
                                UserError.Log.d(TAG, "Scheduling immediate run of queue");
                                Inevitable.kill("tj-next-queue"); // remove timeout retry task
                                Inevitable.task("tj-next-queue", 0, this::processQueue);
                            } else {
                                revisedOffset = replyParam;
                                UserError.Log.d(TAG, "Bulk up failure at: " + revisedOffset); // race condition on display
                            }
                        } else if (bytes[0] == (byte) 0xFE) {
                            audioStreamCallBack(bytes);
                        } else {
                            if (ThinJamActivity.isD()) {
                                notificationString.append(new String(bytes));
                                Inevitable.task("tj update notifi", 250, new Runnable() {
                                    @Override
                                    public void run() {
                                        stringObservableField.set(notificationString.toString());
                                    }
                                });
                            }
                        }
                    }, throwable -> {
                        UserError.Log.d(TAG, "Throwable in Record Notification: " + throwable);
                        I.isNotificationEnabled = false;

                        if (throwable instanceof BleCharacteristicNotFoundException) {
                            // maybe legacy - ignore for now but needs better handling
                            UserError.Log.d(TAG, "Characteristic not found for notification");
                            debug.processTestSuite("logcharerror");
                            tryGattRefresh(getI().connection);
                        }
                        if (throwable instanceof BleCannotSetCharacteristicNotificationException) {
                            UserError.Log.e(TAG, "Problems setting notifications - disconnecting");
                            changeState(CLOSE);
                        }
                        if (throwable instanceof BleDisconnectedException) {
                            UserError.Log.d(TAG, "Disconnected while enabling notifications");
                            changeState(CLOSE);
                        }

                    }));
}