mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-18 06:21:25 +02:00
discover Bluetooth services only for debug Bluetooth driver
This commit is contained in:
@@ -17,7 +17,6 @@
|
|||||||
package com.health.openscale.core.bluetooth;
|
package com.health.openscale.core.bluetooth;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.bluetooth.BluetoothGattService;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
@@ -35,8 +34,6 @@ import com.polidea.rxandroidble2.scan.ScanSettings;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@@ -85,7 +82,6 @@ public abstract class BluetoothCommunication {
|
|||||||
private PublishSubject<Boolean> disconnectTriggerSubject = PublishSubject.create();
|
private PublishSubject<Boolean> disconnectTriggerSubject = PublishSubject.create();
|
||||||
|
|
||||||
private Handler callbackBtHandler;
|
private Handler callbackBtHandler;
|
||||||
private RxBleDeviceServices rxBleDeviceServices;
|
|
||||||
|
|
||||||
private int cmdStepNr;
|
private int cmdStepNr;
|
||||||
private int initStepNr;
|
private int initStepNr;
|
||||||
@@ -99,7 +95,6 @@ public abstract class BluetoothCommunication {
|
|||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.bleClient = OpenScale.getInstance().getBleClient();
|
this.bleClient = OpenScale.getInstance().getBleClient();
|
||||||
this.rxBleDeviceServices = null;
|
|
||||||
this.scanSubscription = null;
|
this.scanSubscription = null;
|
||||||
this.disconnectHandler = new Handler();
|
this.disconnectHandler = new Handler();
|
||||||
|
|
||||||
@@ -275,6 +270,13 @@ public abstract class BluetoothCommunication {
|
|||||||
*/
|
*/
|
||||||
protected void onBluetoothNotify(UUID characteristic, byte[] value) {}
|
protected void onBluetoothNotify(UUID characteristic, byte[] value) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method is triggered if a Bluetooth services from a device is discovered.
|
||||||
|
*
|
||||||
|
* @param rxBleDeviceServices
|
||||||
|
*/
|
||||||
|
protected void onBluetoothDiscovery(RxBleDeviceServices rxBleDeviceServices) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the Bluetooth machine state to a specific state.
|
* Set the Bluetooth machine state to a specific state.
|
||||||
*
|
*
|
||||||
@@ -294,24 +296,22 @@ public abstract class BluetoothCommunication {
|
|||||||
* @param bytes the bytes that should be write
|
* @param bytes the bytes that should be write
|
||||||
*/
|
*/
|
||||||
protected void writeBytes(UUID characteristic, byte[] bytes) {
|
protected void writeBytes(UUID characteristic, byte[] bytes) {
|
||||||
if (isConnected()) {
|
final Disposable disposable = connectionObservable
|
||||||
final Disposable disposable = connectionObservable
|
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
||||||
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
.flatMapSingle(rxBleConnection -> rxBleConnection.writeCharacteristic(characteristic, bytes))
|
||||||
.flatMapSingle(rxBleConnection -> rxBleConnection.writeCharacteristic(characteristic, bytes))
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.retry(BT_RETRY_TIMES_ON_ERROR)
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
.subscribe(
|
||||||
.subscribe(
|
value -> {
|
||||||
value -> {
|
Timber.d("Write characteristic %s: %s",
|
||||||
Timber.d("Write characteristic %s: %s",
|
BluetoothGattUuid.prettyPrint(characteristic),
|
||||||
BluetoothGattUuid.prettyPrint(characteristic),
|
byteInHex(value));
|
||||||
byteInHex(value));
|
nextMachineStateStep();
|
||||||
nextMachineStateStep();
|
},
|
||||||
},
|
throwable -> onError(throwable)
|
||||||
throwable -> onError(throwable)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
compositeDisposable.add(disposable);
|
compositeDisposable.add(disposable);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -321,22 +321,20 @@ public abstract class BluetoothCommunication {
|
|||||||
*@param characteristic the Bluetooth UUID characteristic
|
*@param characteristic the Bluetooth UUID characteristic
|
||||||
*/
|
*/
|
||||||
protected void readBytes(UUID characteristic) {
|
protected void readBytes(UUID characteristic) {
|
||||||
if (isConnected()) {
|
final Disposable disposable = connectionObservable
|
||||||
final Disposable disposable = connectionObservable
|
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
||||||
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
.firstOrError()
|
||||||
.firstOrError()
|
.flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(characteristic))
|
||||||
.flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(characteristic))
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.retry(BT_RETRY_TIMES_ON_ERROR)
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
.subscribe(bytes -> {
|
||||||
.subscribe(bytes -> {
|
Timber.d("Read characteristic %s", BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
Timber.d("Read characteristic %s", BluetoothGattUuid.prettyPrint(characteristic));
|
onBluetoothRead(characteristic, bytes);
|
||||||
onBluetoothRead(characteristic, bytes);
|
},
|
||||||
},
|
throwable -> onError(throwable)
|
||||||
throwable -> onError(throwable)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
compositeDisposable.add(disposable);
|
compositeDisposable.add(disposable);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -345,31 +343,29 @@ public abstract class BluetoothCommunication {
|
|||||||
* @param characteristic the Bluetooth UUID characteristic
|
* @param characteristic the Bluetooth UUID characteristic
|
||||||
*/
|
*/
|
||||||
protected void setIndicationOn(UUID characteristic) {
|
protected void setIndicationOn(UUID characteristic) {
|
||||||
if (isConnected()) {
|
final Disposable disposable = connectionObservable
|
||||||
final Disposable disposable = connectionObservable
|
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
||||||
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
.flatMap(rxBleConnection -> rxBleConnection.setupIndication(characteristic))
|
||||||
.flatMap(rxBleConnection -> rxBleConnection.setupIndication(characteristic))
|
.doOnNext(notificationObservable -> {
|
||||||
.doOnNext(notificationObservable -> {
|
Timber.d("Successful set indication on for %s", BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
Timber.d("Successful set indication on for %s", BluetoothGattUuid.prettyPrint(characteristic));
|
nextMachineStateStep();
|
||||||
nextMachineStateStep();
|
}
|
||||||
}
|
)
|
||||||
)
|
.flatMap(indicationObservable -> indicationObservable)
|
||||||
.flatMap(indicationObservable -> indicationObservable)
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.retry(BT_RETRY_TIMES_ON_ERROR)
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
.subscribe(
|
||||||
.subscribe(
|
bytes -> {
|
||||||
bytes -> {
|
onBluetoothNotify(characteristic, bytes);
|
||||||
onBluetoothNotify(characteristic, bytes);
|
Timber.d("onCharacteristicChanged %s: %s",
|
||||||
Timber.d("onCharacteristicChanged %s: %s",
|
BluetoothGattUuid.prettyPrint(characteristic),
|
||||||
BluetoothGattUuid.prettyPrint(characteristic),
|
byteInHex(bytes));
|
||||||
byteInHex(bytes));
|
resetDisconnectTimer();
|
||||||
resetDisconnectTimer();
|
},
|
||||||
},
|
throwable -> onError(throwable)
|
||||||
throwable -> onError(throwable)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
compositeDisposable.add(disposable);
|
compositeDisposable.add(disposable);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -378,31 +374,47 @@ public abstract class BluetoothCommunication {
|
|||||||
* @param characteristic the Bluetooth UUID characteristic
|
* @param characteristic the Bluetooth UUID characteristic
|
||||||
*/
|
*/
|
||||||
protected void setNotificationOn(UUID characteristic) {
|
protected void setNotificationOn(UUID characteristic) {
|
||||||
if (isConnected()) {
|
final Disposable disposable = connectionObservable
|
||||||
final Disposable disposable = connectionObservable
|
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
||||||
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
.flatMap(rxBleConnection -> rxBleConnection.setupNotification(characteristic))
|
||||||
.flatMap(rxBleConnection -> rxBleConnection.setupNotification(characteristic))
|
.doOnNext(notificationObservable -> {
|
||||||
.doOnNext(notificationObservable -> {
|
Timber.d("Successful set notification on for %s", BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
Timber.d("Successful set notification on for %s", BluetoothGattUuid.prettyPrint(characteristic));
|
nextMachineStateStep();
|
||||||
nextMachineStateStep();
|
}
|
||||||
}
|
)
|
||||||
)
|
.flatMap(notificationObservable -> notificationObservable)
|
||||||
.flatMap(notificationObservable -> notificationObservable)
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.retry(BT_RETRY_TIMES_ON_ERROR)
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
.subscribe(
|
||||||
.subscribe(
|
bytes -> {
|
||||||
bytes -> {
|
onBluetoothNotify(characteristic, bytes);
|
||||||
onBluetoothNotify(characteristic, bytes);
|
Timber.d("onCharacteristicChanged %s: %s",
|
||||||
Timber.d("onCharacteristicChanged %s: %s",
|
BluetoothGattUuid.prettyPrint(characteristic),
|
||||||
BluetoothGattUuid.prettyPrint(characteristic),
|
byteInHex(bytes));
|
||||||
byteInHex(bytes));
|
resetDisconnectTimer();
|
||||||
resetDisconnectTimer();
|
},
|
||||||
},
|
throwable -> onError(throwable)
|
||||||
throwable -> onError(throwable)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
compositeDisposable.add(disposable);
|
compositeDisposable.add(disposable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void doBluetoothDiscoverServices() {
|
||||||
|
final Disposable connectionDisposable = connectionObservable
|
||||||
|
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
||||||
|
.flatMapSingle(RxBleConnection::discoverServices)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.retry(BT_RETRY_TIMES_ON_ERROR)
|
||||||
|
.subscribe(
|
||||||
|
deviceServices -> {
|
||||||
|
Timber.d("Successful Bluetooth services discovered");
|
||||||
|
onBluetoothDiscovery(deviceServices);
|
||||||
|
nextMachineStateStep();
|
||||||
|
},
|
||||||
|
throwable -> onError(throwable)
|
||||||
|
);
|
||||||
|
|
||||||
|
compositeDisposable.add(connectionDisposable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -447,14 +459,6 @@ public abstract class BluetoothCommunication {
|
|||||||
return checksum;
|
return checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<BluetoothGattService> getBluetoothGattServices() {
|
|
||||||
if (rxBleDeviceServices == null) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return rxBleDeviceServices.getBluetoothGattServices();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test in a byte if a bit is set (1) or not (0)
|
* Test in a byte if a bit is set (1) or not (0)
|
||||||
*
|
*
|
||||||
@@ -507,13 +511,16 @@ public abstract class BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void connectToDevice(String macAddress) {
|
private void connectToDevice(String macAddress) {
|
||||||
Timber.d("Try to connect to BLE device " + macAddress);
|
|
||||||
|
|
||||||
// stop LE scan before connecting to device
|
// stop LE scan before connecting to device
|
||||||
if (scanSubscription != null) {
|
if (scanSubscription != null) {
|
||||||
|
Timber.d("Stop Le san");
|
||||||
scanSubscription.dispose();
|
scanSubscription.dispose();
|
||||||
|
scanSubscription = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timber.d("Try to connect to BLE device " + macAddress);
|
||||||
|
|
||||||
connectionObservable = bleDevice
|
connectionObservable = bleDevice
|
||||||
.establishConnection(false)
|
.establishConnection(false)
|
||||||
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
||||||
@@ -525,30 +532,12 @@ public abstract class BluetoothCommunication {
|
|||||||
if (isConnected()) {
|
if (isConnected()) {
|
||||||
disconnect();
|
disconnect();
|
||||||
} else {
|
} else {
|
||||||
final Disposable connectionDisposable = connectionObservable
|
initStepNr = -1;
|
||||||
.delay(BT_DELAY, TimeUnit.MILLISECONDS)
|
cmdStepNr = -1;
|
||||||
.flatMapSingle(RxBleConnection::discoverServices)
|
cleanupStepNr = -1;
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
|
||||||
.subscribe(
|
|
||||||
deviceServices -> {
|
|
||||||
rxBleDeviceServices = deviceServices;
|
|
||||||
//setBtMonitoringOn();
|
|
||||||
|
|
||||||
initStepNr = -1;
|
setBtMonitoringOn();
|
||||||
cmdStepNr = -1;
|
setBtMachineState(BT_MACHINE_STATE.BT_INIT_STATE);
|
||||||
cleanupStepNr = -1;
|
|
||||||
|
|
||||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_ESTABLISHED);
|
|
||||||
setBtMachineState(BT_MACHINE_STATE.BT_INIT_STATE);
|
|
||||||
},
|
|
||||||
throwable -> {
|
|
||||||
setBtStatus(BT_STATUS_CODE.BT_NO_DEVICE_FOUND);
|
|
||||||
disconnect();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
compositeDisposable.add(connectionDisposable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,7 +556,7 @@ public abstract class BluetoothCommunication {
|
|||||||
// empty
|
// empty
|
||||||
break;
|
break;
|
||||||
case DISCONNECTED:
|
case DISCONNECTED:
|
||||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_LOST);
|
// setBtStatus(BT_STATUS_CODE.BT_CONNECTION_LOST);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -604,14 +593,15 @@ public abstract class BluetoothCommunication {
|
|||||||
* Disconnect from a Bluetooth device
|
* Disconnect from a Bluetooth device
|
||||||
*/
|
*/
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
|
Timber.d("Bluetooth disconnect");
|
||||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_DISCONNECT);
|
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_DISCONNECT);
|
||||||
|
if (scanSubscription != null) {
|
||||||
|
scanSubscription.dispose();
|
||||||
|
}
|
||||||
callbackBtHandler = null;
|
callbackBtHandler = null;
|
||||||
disconnectHandler.removeCallbacksAndMessages(null);
|
disconnectHandler.removeCallbacksAndMessages(null);
|
||||||
disconnectTriggerSubject.onNext(true);
|
disconnectTriggerSubject.onNext(true);
|
||||||
compositeDisposable.clear();
|
compositeDisposable.clear();
|
||||||
if (scanSubscription != null) {
|
|
||||||
scanSubscription.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -21,14 +21,15 @@ import android.bluetooth.BluetoothGattDescriptor;
|
|||||||
import android.bluetooth.BluetoothGattService;
|
import android.bluetooth.BluetoothGattService;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.polidea.rxandroidble2.RxBleClient;
|
import com.polidea.rxandroidble2.RxBleDeviceServices;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class BluetoothDebug extends BluetoothCommunication {
|
public class BluetoothDebug extends BluetoothCommunication {
|
||||||
HashMap<Integer, String> propertyString;
|
private HashMap<Integer, String> propertyString;
|
||||||
|
private RxBleDeviceServices rxBleDeviceServices;
|
||||||
|
|
||||||
BluetoothDebug(Context context) {
|
BluetoothDebug(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@@ -157,22 +158,39 @@ public class BluetoothDebug extends BluetoothCommunication {
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBluetoothDiscovery(RxBleDeviceServices rxBleDeviceServices) {
|
||||||
|
this.rxBleDeviceServices = rxBleDeviceServices;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean nextInitCmd(int stateNr) {
|
||||||
int offset = stateNr;
|
switch (stateNr)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
doBluetoothDiscoverServices();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
int offset = stateNr;
|
||||||
|
|
||||||
for (BluetoothGattService service : getBluetoothGattServices()) {
|
for (BluetoothGattService service : rxBleDeviceServices.getBluetoothGattServices()) {
|
||||||
offset = readServiceCharacteristics(service, offset);
|
offset = readServiceCharacteristics(service, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BluetoothGattService service : rxBleDeviceServices.getBluetoothGattServices()) {
|
||||||
|
logService(service, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_LOST);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
disconnect();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (BluetoothGattService service : getBluetoothGattServices()) {
|
return true;
|
||||||
logService(service, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_LOST);
|
|
||||||
disconnect();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Reference in New Issue
Block a user