use of com.polidea.rxandroidble2.RxBleConnection in project xDrip-plus by jamorham.
the class MiBandService method authPhase.
@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, // WARN
TimeUnit.SECONDS).doOnNext(notificationObservable -> {
if (d)
UserError.Log.d(TAG, "Notification for auth enabled");
if (MiBand.isAuthenticated()) {
// get random key from band
connection.writeCharacteristic(authorisation.getCharacteristicUUID(), authorisation.getAuthKeyRequest()).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);
}));
}
use of com.polidea.rxandroidble2.RxBleConnection in project xDrip by NightscoutFoundation.
the class Ob1G5StateMachine method doReset.
@SuppressLint("CheckResult")
public static boolean doReset(Ob1G5CollectionService parent, RxBleConnection connection) {
if (connection == null)
return false;
parent.msg("Hard Resetting Transmitter");
connection.writeCharacteristic(Control, nn(new ResetTxMessage().byteSequence)).subscribe(characteristicValue -> {
if (d)
UserError.Log.d(TAG, "Wrote ResetTxMessage request!!");
parent.msg("Hard Reset Sent");
}, throwable -> {
parent.msg("Hard Reset maybe Failed");
UserError.Log.e(TAG, "Failed to write ResetTxMessage: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + getStatusName(status));
}
});
return true;
}
use of com.polidea.rxandroidble2.RxBleConnection in project xDrip by NightscoutFoundation.
the class MiBandService method processFirmwareCommands.
@SuppressLint("CheckResult")
private void processFirmwareCommands(byte[] value, boolean isSeqCommand) {
RxBleConnection connection = I.connection;
FirmwareOperations.SequenceType seq = firmware.getSequence();
if (d)
UserError.Log.d(TAG, "processFirmwareCommands: " + bytesToHex(value) + ": seq:" + seq.toString());
if (isSeqCommand) {
switch(seq) {
case SET_NIGHTMODE:
{
if (true) {
isNeedToRestoreNightMode = true;
DisplayControllMessageMiband3_4 dispControl = new DisplayControllMessageMiband3_4();
Calendar sheduledCalendar = Calendar.getInstance();
sheduledCalendar.set(Calendar.HOUR_OF_DAY, 0);
sheduledCalendar.set(Calendar.MINUTE, 0);
Date sheduledDate = sheduledCalendar.getTime();
connection.writeCharacteristic(dispControl.getCharacteristicUUID(), dispControl.setNightModeCmd(Sheduled, sheduledDate, sheduledDate)).subscribe(valB -> {
UserError.Log.d(TAG, "Wrote nigntmode, got: " + JoH.bytesToHex(valB));
firmware.nextSequence();
processFirmwareCommands(null, true);
}, throwable -> {
UserError.Log.e(TAG, "Could not write nigntmode: " + throwable);
firmware.nextSequence();
processFirmwareCommands(null, true);
});
} else {
firmware.nextSequence();
processFirmwareCommands(null, true);
}
break;
}
case PREPARE_UPLOAD:
{
connection.writeCharacteristic(firmware.getFirmwareCharacteristicUUID(), firmware.prepareFWUploadInitCommand()).subscribe(valB -> {
UserError.Log.d(TAG, "Wrote prepareFWUploadInitCommand, got: " + JoH.bytesToHex(valB));
}, throwable -> {
UserError.Log.e(TAG, "Could not write prepareFWUploadInitCommand: " + throwable);
resetFirmwareState(false);
});
firmware.nextSequence();
break;
}
}
return;
} else {
if (value.length != 3 && value.length != 11) {
UserError.Log.e(TAG, "Notifications should be 3 or 11 bytes long.");
return;
}
boolean success = value[2] == OperationCodes.SUCCESS;
if (value[0] == OperationCodes.RESPONSE && success) {
try {
switch(value[1]) {
case OperationCodes.COMMAND_FIRMWARE_INIT:
{
if (seq == FirmwareOperations.SequenceType.TRANSFER_FW_START) {
connection.writeCharacteristic(firmware.getFirmwareCharacteristicUUID(), firmware.getFirmwareStartCommand()).subscribe(valB -> {
UserError.Log.d(TAG, "Wrote Start command, got: " + JoH.bytesToHex(valB));
}, throwable -> {
UserError.Log.e(TAG, "Could not write Start command: " + throwable);
resetFirmwareState(false);
});
firmware.nextSequence();
} else if (seq == FirmwareOperations.SequenceType.TRANSFER_SEND_WF_INFO) {
connection.writeCharacteristic(firmware.getFirmwareCharacteristicUUID(), firmware.sendFwInfo()).subscribe(valB -> {
UserError.Log.d(TAG, "Wrote sendFwInfo, got: " + JoH.bytesToHex(valB));
}, throwable -> {
UserError.Log.e(TAG, "Could not write firmware info: " + throwable);
resetFirmwareState(false);
});
firmware.nextSequence();
break;
}
break;
}
case OperationCodes.COMMAND_FIRMWARE_START_DATA:
{
sendFirmwareData();
break;
}
case OperationCodes.COMMAND_FIRMWARE_CHECKSUM:
{
firmware.nextSequence();
if (firmware.getFirmwareType() == FirmwareOperations.FirmwareType.FIRMWARE) {
// send reboot
} else {
UserError.Log.e(TAG, "Watch Face has been installed successfully");
resetFirmwareState(true);
}
break;
}
case OperationCodes.COMMAND_FIRMWARE_REBOOT:
{
UserError.Log.e(TAG, "Reboot command successfully sent.");
resetFirmwareState(true);
break;
}
default:
{
resetFirmwareState(false, "Unexpected response during firmware update");
}
}
} catch (Exception ex) {
resetFirmwareState(false);
}
} else {
String errorMessage = null;
Boolean sendBGNotification = false;
if (value[2] == OperationCodes.LOW_BATTERY_ERROR) {
errorMessage = "Cannot upload watchface, low battery, please charge device";
sendBGNotification = true;
} else if (value[2] == OperationCodes.TIMER_RUNNING) {
errorMessage = "Cannot upload watchface, timer running on band";
} else if (value[2] == OperationCodes.ON_CALL) {
errorMessage = "Cannot upload watchface, call in progress";
} else {
errorMessage = "Unexpected notification during firmware update:" + JoH.bytesToHex(value);
}
resetFirmwareState(false, errorMessage);
if (sendBGNotification) {
emptyQueue();
JoH.startService(MiBandService.class, "function", "update_bg_as_notification");
changeState(SLEEP);
}
}
}
}
use of com.polidea.rxandroidble2.RxBleConnection in project xDrip by NightscoutFoundation.
the class MiBandService method authPhase.
@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, // WARN
TimeUnit.SECONDS).doOnNext(notificationObservable -> {
if (d)
UserError.Log.d(TAG, "Notification for auth enabled");
if (MiBand.isAuthenticated()) {
// get random key from band
connection.writeCharacteristic(authorisation.getCharacteristicUUID(), authorisation.getAuthKeyRequest()).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);
}));
}
use of com.polidea.rxandroidble2.RxBleConnection in project xDrip by NightscoutFoundation.
the class MiBandService method setNightMode.
private void setNightMode() {
if (d)
UserError.Log.d(TAG, "Restore night mode");
Date start = null, end = null;
DisplayControllMessageMiband3_4.NightMode nightMode = DisplayControllMessageMiband3_4.NightMode.Off;
if (MiBandEntry.isNightModeEnabled()) {
nightMode = DisplayControllMessageMiband3_4.NightMode.Sheduled;
start = MiBandEntry.getNightModeStart();
end = MiBandEntry.getNightModeEnd();
}
RxBleConnection connection = I.connection;
DisplayControllMessageMiband3_4 dispControl = new DisplayControllMessageMiband3_4();
connection.writeCharacteristic(dispControl.getCharacteristicUUID(), dispControl.setNightModeCmd(nightMode, start, end)).subscribe(valB -> {
if (d)
UserError.Log.d(TAG, "Wrote nightmode");
isNeedToRestoreNightMode = false;
}, throwable -> {
if (d)
UserError.Log.e(TAG, "Could not write nightmode: " + throwable);
});
}
Aggregations