use of com.eveningoutpost.dexdrip.utils.bt.Subscription in project xDrip-plus by jamorham.
the class MiBandService method enableHeartRateNotification.
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");
}
}));
}
use of com.eveningoutpost.dexdrip.utils.bt.Subscription in project xDrip-plus by jamorham.
the class Ob1G5CollectionService method scan_for_device.
private synchronized void scan_for_device() {
if (state == SCAN) {
msg(gs(R.string.scanning));
stopScan();
// did we already find it?
tryLoadingSavedMAC();
if (always_scan || scan_next_run || (transmitterMAC == null) || (!transmitterID.equals(transmitterIDmatchingMAC)) || (static_last_timestamp < 1)) {
// reset if set
scan_next_run = false;
// reset if set
transmitterMAC = null;
last_scan_started = JoH.tsl();
scanWakeLock = JoH.getWakeLock("xdrip-jam-g5-scan", (int) Constants.MINUTE_IN_MS * 7);
// "" if unset
historicalTransmitterMAC = PersistentStore.getString(OB1G5_MACSTORE + transmitterID);
ScanFilter filter;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && historicalTransmitterMAC.length() > 5) {
filter = new ScanFilter.Builder().setDeviceAddress(historicalTransmitterMAC).build();
} else {
final String localTransmitterID = transmitterID;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && localTransmitterID != null && localTransmitterID.length() > 4) {
filter = new ScanFilter.Builder().setDeviceName(getTransmitterBluetoothName()).build();
} else {
filter = new ScanFilter.Builder().build();
}
}
scanSubscription = new Subscription(rxBleClient.scanBleDevices(new ScanSettings.Builder().setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).setScanMode(android_wear ? ScanSettings.SCAN_MODE_BALANCED : minimize_scanning ? ScanSettings.SCAN_MODE_BALANCED : ScanSettings.SCAN_MODE_LOW_LATENCY).build(), // scan filter doesn't work reliable on android sdk 23+
filter).subscribeOn(Schedulers.io()).subscribe(this::onScanResult, this::onScanFailure));
if (minimize_scanning) {
// Must be less than fail over timeout
Inevitable.task(STOP_SCAN_TASK_ID, 320 * Constants.SECOND_IN_MS, this::stopScanWithTimeoutAndReschedule);
}
UserError.Log.d(TAG, "Scanning for: " + getTransmitterBluetoothName());
} else {
UserError.Log.d(TAG, "Transmitter mac already known: " + transmitterMAC);
changeState(CONNECT);
}
} else {
UserError.Log.wtf(TAG, "Attempt to scan when not in SCAN state");
}
}
use of com.eveningoutpost.dexdrip.utils.bt.Subscription in project xDrip-plus by jamorham.
the class Ob1G5CollectionService method connect_to_device.
private synchronized void connect_to_device(boolean auto) {
if ((state == CONNECT) || (state == CONNECT_NOW)) {
// TODO check mac
if (transmitterMAC == null) {
tryLoadingSavedMAC();
}
final String localTransmitterMAC = transmitterMAC;
if (localTransmitterMAC != null) {
msg("Connect request");
if (state == CONNECT_NOW) {
if (connection_linger != null)
JoH.releaseWakeLock(connection_linger);
connection_linger = JoH.getWakeLock("jam-g5-pconnect", 60000);
}
if (d)
UserError.Log.d(TAG, "Local bonding state: " + (isDeviceLocallyBonded() ? "BONDED" : "NOT Bonded"));
stopConnect();
try {
bleDevice = rxBleClient.getBleDevice(localTransmitterMAC);
// / / Listen for connection state changes
stateSubscription = new Subscription(bleDevice.observeConnectionStateChanges().subscribeOn(Schedulers.io()).subscribe(this::onConnectionStateChange, throwable -> {
UserError.Log.wtf(TAG, "Got Error from state subscription: " + throwable);
}));
last_connect_started = JoH.tsl();
// Attempt to establish a connection // TODO does this need different connection timeout for auto vs normal?
connectionSubscription = new Subscription(bleDevice.establishConnection(auto).timeout(7, TimeUnit.MINUTES).subscribeOn(Schedulers.io()).subscribe(this::onConnectionReceived, this::onConnectionFailure));
} catch (IllegalArgumentException e) {
UserError.Log.e(TAG, "Caught IllegalArgument Exception: " + e + " retry on next run");
// TODO if this is due to concurrent access then changing state again may be a bad idea
state = SCAN;
// note backoff
backoff_automata();
}
} else {
UserError.Log.wtf(TAG, "No transmitter mac address!");
state = SCAN;
// note backoff
backoff_automata();
}
} else {
UserError.Log.wtf(TAG, "Attempt to connect when not in CONNECT state");
}
}
use of com.eveningoutpost.dexdrip.utils.bt.Subscription in project xDrip-plus by jamorham.
the class BlueJayService method enableNotifications.
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");
if (I.connection == null) {
UserError.Log.d(TAG, "Connection went away before we could enable notifications");
return;
}
notificationSubscription = new Subscription(I.connection.setupNotification(THINJAM_WRITE).observeOn(// needed?
Schedulers.newThread()).doOnNext(notificationObservable -> {
UserError.Log.d(TAG, "Notifications enabled");
I.connection.writeCharacteristic(THINJAM_BULK, new byte[] { 0x55 });
// Debug sleep to make sure notifications are actually enabled???
JoH.threadSleep(500);
I.isNotificationEnabled = true;
changeNextState();
}).flatMap(notificationObservable -> notificationObservable).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");
// removes first item from the queue which should be the one we just processed!
commandQueue.poll();
UserError.Log.d(TAG, "Scheduling immediate run of queue");
// remove timeout retry task
Inevitable.kill("tj-next-queue");
Inevitable.task("tj-next-queue", 0, this::processQueue);
} else {
revisedOffset = replyParam;
// race condition on display
UserError.Log.d(TAG, "Bulk up failure at: " + revisedOffset);
}
} 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);
}
}));
}
Aggregations