1
0
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:
oliexdev
2019-02-10 21:04:07 +01:00
parent c20577c5a8
commit 60d6818520
2 changed files with 142 additions and 134 deletions

View File

@@ -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();
}
} }
/** /**

View File

@@ -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