Skip to content

Commit

Permalink
BLE fixes
Browse files Browse the repository at this point in the history
Code Inspection fixes:
- Discovering new device means we could find New valid device/service (couple validity check with search) so changes to ServiceInterface, BleSensorSDK18, CscService, HeartRateService, BatteryService.

- When we buffer messages send to sensor, try to keep order: use FIFO  rather than LIFO so changes to Executer

Try to reconnect while riding with click or on disconnect (get far and comme back...) so changes to CockpitActivity, CockpitView, SensorService , AppBroadcaster, Connector

Improve new sensor discovery:
- Make selective scan to reduce sensor list to sort: so changes to BleScannerSDK21
- speed up new service association during scann: so changes to BleSensorsSDK18, SensorItemState

This improve significantly BLE discovery and keep connection, it would be worth in future to decouple "configuration" vs run time states
  • Loading branch information
arsab committed Oct 3, 2019
1 parent 1bbe1b8 commit b087bdd
Show file tree
Hide file tree
Showing 14 changed files with 134 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,8 @@ private View createCockpit() {

CockpitView c2 = new CockpitView(this);
c2.add(this, new MaximumSpeedDescription(this), InfoID.TRACKER);
c2.add(this, new HeartRateDescription(this), InfoID.HEART_RATE_SENSOR);
c2.add(this, new CadenceDescription(this), InfoID.CADENCE_SENSOR);

c2.addHeartRate(this); // With click to update sensors
c2.addCadence(this); // With click to update sensors

p.add(c1, 80);
p.add(c2, 20);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public void close() {
if (connected) {
connected = false;
SensorState.disconnect(iid);
AppBroadcaster.broadcast(context, AppBroadcaster.SENSOR_DISCONECTED + InfoID.SENSORS); // just disconected try reconnect
}
}

Expand Down
25 changes: 23 additions & 2 deletions app/src/main/java/ch/bailu/aat/services/sensor/SensorService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import android.support.annotation.NonNull;

import ch.bailu.aat.gpx.GpxInformation;
import ch.bailu.aat.gpx.InfoID;
import ch.bailu.aat.services.ServiceContext;
import ch.bailu.aat.services.VirtualService;
import ch.bailu.aat.services.sensor.list.SensorList;
Expand All @@ -28,9 +29,11 @@ public SensorService(ServiceContext sc) {
internal = Sensors.factoryInternal(sc.getContext(), sensorList);


AppBroadcaster.register(getContext(),
onBluetoothStateChanged, BluetoothAdapter.ACTION_STATE_CHANGED);
AppBroadcaster.register(getContext(), onBluetoothStateChanged, BluetoothAdapter.ACTION_STATE_CHANGED);

AppBroadcaster.register(getContext(), onSensorDisconected, AppBroadcaster.SENSOR_DISCONECTED + InfoID.SENSORS);

AppBroadcaster.register(getContext(), onSensorReconnect, AppBroadcaster.SENSOR_RECONECT + InfoID.SENSORS);

updateConnections();
}
Expand All @@ -55,6 +58,22 @@ public void onReceive(Context context, Intent intent) {
};


final BroadcastReceiver onSensorDisconected = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateConnections();
}
};


final BroadcastReceiver onSensorReconnect = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateConnections();
scann(); // rescan to get them in cache if they were not
}
};


@Override
public void appendStatusText(StringBuilder builder) {
Expand All @@ -68,6 +87,8 @@ public synchronized void close() {
internal.close();
sensorList.close();
getContext().unregisterReceiver(onBluetoothStateChanged);
getContext().unregisterReceiver(onSensorDisconected);
getContext().unregisterReceiver(onSensorReconnect);
}

public synchronized void updateConnections() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ public int getBatteryLevelPercentage() {
}


public void discovered(BluetoothGattCharacteristic c, Executer execute) {
public boolean discovered(BluetoothGattCharacteristic c, Executer execute) {
boolean disc = false;
if (BATTERY_SERVICE.equals(c.getService().getUuid()) && BATTERY_LEVEL.equals(c.getUuid())) {
disc = true;
execute.read(c);
}
return disc;
}

public void read(BluetoothGattCharacteristic c) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.os.ParcelUuid;
import android.support.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.Arrays;

@RequiresApi(api = 21)
public class BleScannerSDK21 extends BleScanner {
private final BluetoothAdapter adapter;
Expand All @@ -19,6 +25,21 @@ public void onScanResult(int callbackType, ScanResult result) {
};


private final ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // also possible SCAN_MODE_BALANCED, SCAN_MODE_LOW_LATENCY
.build();

private final ScanFilter HrFilter = new ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString("0000180d-0000-1000-8000-00805f9b34fb"))
.build();

private final ScanFilter CscFilter = new ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString("00001816-0000-1000-8000-00805f9b34fb"))
.build();

private final ArrayList<ScanFilter> filters = new ArrayList<ScanFilter>(Arrays.asList(HrFilter, CscFilter));


protected BleScannerSDK21(BleSensorsSDK18 sensors) {
super(sensors);
adapter = sensors.getAdapter();
Expand All @@ -29,7 +50,7 @@ public void start() {
if (adapter != null) {
BluetoothLeScanner scanner = adapter.getBluetoothLeScanner();
if (scanner != null) {
scanner.startScan(callback);
scanner.startScan(filters, settings, callback);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,18 @@ public BleSensorSDK18(ServiceContext c, BluetoothDevice d, SensorList l) {
connectingTimeout.kick();
item.setState(SensorItemState.CONNECTING);
item.setState(SensorItemState.SCANNING);

}
}
}


private BluetoothGatt connect() {
if (item.lock(this)) {

if (Build.VERSION.SDK_INT >= 23) {
return device.connectGatt(context, true, this,
BluetoothDevice.TRANSPORT_LE);
return device.connectGatt(context, true, this, BluetoothDevice.TRANSPORT_LE);
} else {
return device.connectGatt(context, true, this);

}

}
return null;
}
Expand Down Expand Up @@ -164,9 +159,8 @@ private void setNextState() {

@Override
public synchronized void onServicesDiscovered(BluetoothGatt gatt, int status) {
discover(gatt);

if (hasValidService()) {
if (discover(gatt)) {
executeNextAndSetState(gatt);

} else {
Expand All @@ -176,11 +170,23 @@ public synchronized void onServicesDiscovered(BluetoothGatt gatt, int status) {
}


private boolean hasValidService() {
for (ServiceInterface s : services) {
if (s.isValid()) return true;
private boolean discover(BluetoothGatt gatt) {
boolean discovered = false;

List<BluetoothGattService> lists = gatt.getServices();

for (BluetoothGattService service: lists) {

List<BluetoothGattCharacteristic> listc = service.getCharacteristics();

for (ServiceInterface s : services) { // scan each sensor to find valid caracteristics
for (BluetoothGattCharacteristic c : listc) { // characteristics belong to service
if ( s.discovered(c, execute) )
discovered = true; // found at least one valid new characteristics
}
}
}
return false;
return discovered;
}


Expand All @@ -189,6 +195,7 @@ public synchronized void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDesc
executeNextAndSetState(gatt);
}


@Override
public synchronized void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic c) {
Expand All @@ -199,26 +206,6 @@ public synchronized void onCharacteristicChanged(BluetoothGatt gatt,
}



private void discover(BluetoothGatt gatt) {
List<BluetoothGattService> list = gatt.getServices();

for (BluetoothGattService service: list) {
discover(service);
}
}


private void discover(BluetoothGattService service) {
List<BluetoothGattCharacteristic> list = service.getCharacteristics();

for (BluetoothGattCharacteristic c : list) {
for (ServiceInterface s : services)
s.discovered(c, execute);
}
}


@Override
public synchronized void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic c,
int status) {
Expand Down Expand Up @@ -261,8 +248,6 @@ public String getName() {





public synchronized GpxInformation getInformation(int iid) {
GpxInformation i = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,9 @@ private boolean isEnabled() {





public synchronized void foundDevice(BluetoothDevice device) {
if (sensorList.add(device.getAddress(), device.getName()).isUnscanned()) {
// if (sensorList.add(device.getAddress(), device.getName()).isUnscanned()) {
if (sensorList.add(device.getAddress(), device.getName()).isUnscanned_or_scanning()) {
new BleSensorSDK18(scontext, device, sensorList);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ public void changed(BluetoothGattCharacteristic c) {
}


public void discovered(BluetoothGattCharacteristic c, Executer execute) {
public boolean discovered(BluetoothGattCharacteristic c, Executer execute) {
boolean disc = false;
if (CSC_SERVICE.equals(c.getService().getUuid())) {
valid = true;
disc = true;

if (CSC_FEATURE.equals(c.getUuid())) {
execute.read(c);
Expand All @@ -84,6 +86,7 @@ public void discovered(BluetoothGattCharacteristic c, Executer execute) {

}
}
return disc;
}

public void read(BluetoothGattCharacteristic c) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,49 @@
import android.bluetooth.BluetoothGattDescriptor;
import android.support.annotation.RequiresApi;

import java.util.Stack;
import java.util.LinkedList;
import java.util.Queue;
import java.util.UUID;

@RequiresApi(api = 18)
public class Executer {
private final static UUID ENABLE_NOTIFICATION = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");


private final Stack<BluetoothGattCharacteristic> toRead = new Stack<>();
private final Stack<BluetoothGattCharacteristic> toNotify = new Stack<>();
private Queue<BluetoothGattCharacteristic> toReadQ = new LinkedList<BluetoothGattCharacteristic>();
private Queue<BluetoothGattCharacteristic> toNotifyQ = new LinkedList<BluetoothGattCharacteristic>();

private boolean discoverd = false;


public void notify(BluetoothGattCharacteristic c) {
toNotify.push(c);
public synchronized void notify(BluetoothGattCharacteristic c) {
toNotifyQ.add(c);
}
public void read(BluetoothGattCharacteristic c) {
toRead.push(c);
public synchronized void read(BluetoothGattCharacteristic c) {
toReadQ.add(c);
}

public boolean needToDiscover() { return !discoverd; }
public boolean haveToRead() {
return toRead.size() > 0;

public synchronized boolean haveToRead() {
return toReadQ.size() > 0;
}

public boolean haveToNotify() {
return toNotifyQ.size() > 0;
}
public boolean haveToNotify() { return toNotify.size() > 0;}



public void next(BluetoothGatt gatt) {
public synchronized void next(BluetoothGatt gatt) {
if (needToDiscover()) {
discoverd = gatt.discoverServices();

} else if (haveToRead()) {
gatt.readCharacteristic(toRead.pop());
gatt.readCharacteristic(toReadQ.poll());

} else if (haveToNotify()) {
enableNotification(gatt, toNotify.pop());
enableNotification(gatt, toNotifyQ.poll());

}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,22 @@ public boolean isValid() {
}


public void discovered(BluetoothGattCharacteristic c, Executer execute) {
public boolean discovered(BluetoothGattCharacteristic c, Executer execute) {
UUID sid = c.getService().getUuid();
UUID cid = c.getUuid();
boolean disc = false;

if (HEART_RATE_SERVICE.equals(sid)) {
valid = true;
disc = true;

if (HEART_RATE_MESUREMENT.equals(cid)) {
execute.notify(c);
} else if (BODY_SENSOR_LOCATION.equals(cid)) {
execute.read(c);
}
}
return disc;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public interface ServiceInterface {

boolean isValid();

void discovered(BluetoothGattCharacteristic c, Executer execute);
boolean discovered(BluetoothGattCharacteristic c, Executer execute);

void read(BluetoothGattCharacteristic c);

Expand Down
Loading

0 comments on commit b087bdd

Please sign in to comment.