diff --git a/app/src/main/java/com/platypii/baseline/lasers/rangefinder/RangefinderService.java b/app/src/main/java/com/platypii/baseline/lasers/rangefinder/RangefinderService.java index 12fb3563..e34ebef2 100644 --- a/app/src/main/java/com/platypii/baseline/lasers/rangefinder/RangefinderService.java +++ b/app/src/main/java/com/platypii/baseline/lasers/rangefinder/RangefinderService.java @@ -47,7 +47,6 @@ public void start(@NonNull Activity activity) { } else { // Turn on bluetooth Log.i(TAG, "Requesting to turn on bluetooth"); - final Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); Intents.requestEnableBluetooth(activity); } } else { diff --git a/app/src/main/java/com/platypii/baseline/location/LocationStatus.java b/app/src/main/java/com/platypii/baseline/location/LocationStatus.java index 9c20175b..a92abf8c 100644 --- a/app/src/main/java/com/platypii/baseline/location/LocationStatus.java +++ b/app/src/main/java/com/platypii/baseline/location/LocationStatus.java @@ -45,10 +45,11 @@ public static void updateStatus(@NonNull Context context) { return; } // GPS signal status - if (Services.bluetooth.preferences.preferenceEnabled && Services.bluetooth.getState() != BluetoothState.BT_CONNECTED) { + final int btState = Services.bluetooth.getState(); + if (Services.bluetooth.preferences.preferenceEnabled && btState != BluetoothState.BT_CONNECTED) { // Bluetooth enabled, but not connected icon = R.drawable.warning; - switch (Services.bluetooth.getState()) { + switch (btState) { case BluetoothState.BT_STARTING: message = "GPS bluetooth starting..."; break; @@ -60,7 +61,7 @@ public static void updateStatus(@NonNull Context context) { break; default: message = "GPS bluetooth not connected"; - Log.e(TAG, "Bluetooth inconsistent state: preference enabled, state " + BT_STATES[Services.bluetooth.getState()]); + Log.e(TAG, "Bluetooth inconsistent state: preference enabled, state " + BT_STATES[btState]); } } else { // Internal GPS, or bluetooth connected: diff --git a/app/src/main/java/com/platypii/baseline/views/bluetooth/BluetoothAdapter.java b/app/src/main/java/com/platypii/baseline/views/bluetooth/BluetoothAdapter.java index 64b424a1..8581bc58 100644 --- a/app/src/main/java/com/platypii/baseline/views/bluetooth/BluetoothAdapter.java +++ b/app/src/main/java/com/platypii/baseline/views/bluetooth/BluetoothAdapter.java @@ -56,7 +56,7 @@ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup final BluetoothItem device = devices.get(position - 1); nameView.setText(device.name); addressView.setText(device.address); - if (device.name.contains("GPS") || device.name.startsWith("Mohawk")) { + if (device.name.contains("GPS") || device.name.startsWith("FlySight") || device.name.startsWith("Mohawk")) { nameView.setTextColor(0xffeeeeee); } else { nameView.setTextColor(0xffbbbbbb); diff --git a/common/src/main/java/com/platypii/baseline/bluetooth/BleService.java b/common/src/main/java/com/platypii/baseline/bluetooth/BleService.java index ebd28154..e23d775a 100644 --- a/common/src/main/java/com/platypii/baseline/bluetooth/BleService.java +++ b/common/src/main/java/com/platypii/baseline/bluetooth/BleService.java @@ -106,7 +106,7 @@ private void scan() { setState(BT_SCANNING); // Scan for peripherals with a certain service UUIDs central.startPairingPopupHack(); - Log.i(TAG, "Scanning for laser rangefinders"); + Log.i(TAG, "Scanning for ble devices"); // TODO: Check for permissions central.scanForPeripherals(); // TODO: filter with services } diff --git a/common/src/main/java/com/platypii/baseline/bluetooth/BluetoothDeviceComparator.java b/common/src/main/java/com/platypii/baseline/bluetooth/BluetoothDeviceComparator.java index 819ce2c6..3f0b699e 100644 --- a/common/src/main/java/com/platypii/baseline/bluetooth/BluetoothDeviceComparator.java +++ b/common/src/main/java/com/platypii/baseline/bluetooth/BluetoothDeviceComparator.java @@ -12,11 +12,15 @@ public int compare(@NonNull BluetoothItem device1, @NonNull BluetoothItem device return score(device2) - score(device1); } + /** + * Devices with higher score will appear higher in the sorted list + */ private int score(@NonNull BluetoothItem device) { if (device.name.isEmpty()) return 0; - if (device.name.startsWith("Mohawk")) return 2; + if (device.name.startsWith("FlySight")) return 4; + if (device.name.startsWith("Mohawk")) return 3; + if (device.name.contains("GPS")) return 2; if (device.name.startsWith("RaceBox")) return 1; - if (device.name.contains("GPS")) return 1; return 0; } } diff --git a/common/src/main/java/com/platypii/baseline/bluetooth/BluetoothService.java b/common/src/main/java/com/platypii/baseline/bluetooth/BluetoothService.java index 4986dc80..13b34908 100644 --- a/common/src/main/java/com/platypii/baseline/bluetooth/BluetoothService.java +++ b/common/src/main/java/com/platypii/baseline/bluetooth/BluetoothService.java @@ -37,7 +37,10 @@ public class BluetoothService { public final PubSub locationUpdates = new PubSub<>(); // BLE subsystem - public final BleService ble = new BleService(new MohawkProtocol(locationUpdates)); + public final BleService ble = new BleService( + new MohawkProtocol(locationUpdates), + new Flysight2Protocol(locationUpdates) + ); // Android shared preferences for bluetooth public final BluetoothPreferences preferences = new BluetoothPreferences(); diff --git a/common/src/main/java/com/platypii/baseline/bluetooth/Flysight2Protocol.java b/common/src/main/java/com/platypii/baseline/bluetooth/Flysight2Protocol.java new file mode 100644 index 00000000..03a8e283 --- /dev/null +++ b/common/src/main/java/com/platypii/baseline/bluetooth/Flysight2Protocol.java @@ -0,0 +1,85 @@ +package com.platypii.baseline.bluetooth; + +import com.platypii.baseline.location.LocationCheck; +import com.platypii.baseline.location.NMEAException; +import com.platypii.baseline.measurements.MLocation; +import com.platypii.baseline.util.Exceptions; +import com.platypii.baseline.util.PubSub; + +import android.bluetooth.le.ScanRecord; +import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.welie.blessed.BluetoothPeripheral; +import com.welie.blessed.GattStatus; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.UUID; + +public class Flysight2Protocol extends BleProtocol { + private static final String TAG = "FlysightProtocol"; + private final PubSub locationUpdates; + + // Flysight services + private static final UUID flysightService0 = UUID.fromString("00000000-cc7a-482a-984a-7f2ed5b3e58f"); + private static final UUID flysightService1 = UUID.fromString("00000001-cc7a-482a-984a-7f2ed5b3e58f"); + private static final UUID flysightService2 = UUID.fromString("00000002-cc7a-482a-984a-7f2ed5b3e58f"); + // Flysight characteristics + private static final UUID flysightCharacteristicGNSS = UUID.fromString("00000000-8e22-4541-9d4c-21edae82ed19"); + private static final UUID flysightCharacteristicTX = UUID.fromString("00000001-8e22-4541-9d4c-21edae82ed19"); + private static final UUID flysightCharacteristicRX = UUID.fromString("00000002-8e22-4541-9d4c-21edae82ed19"); + + public Flysight2Protocol(@NonNull PubSub locationUpdates) { + this.locationUpdates = locationUpdates; + } + + @Override + public boolean canParse(@NonNull BluetoothPeripheral peripheral, @Nullable ScanRecord record) { + // TODO: Check address + return peripheral.getName().equals("FlySight"); + } + + @Override + public void onServicesDiscovered(@NonNull BluetoothPeripheral peripheral) { + Log.i(TAG, "flysight services discovered " + peripheral.getCurrentMtu()); + peripheral.requestMtu(256); + } + + @Override + public void onMtuChanged(@NonNull BluetoothPeripheral peripheral, int mtu, @NonNull GattStatus status) { + Log.i(TAG, "flysight mtu changed " + mtu); + // Subscribe to flysight service + peripheral.setNotify(flysightService1, flysightCharacteristicGNSS, true); + } + + @Override + public void processBytes(@NonNull BluetoothPeripheral peripheral, @NonNull byte[] value) { + try { + final ByteBuffer buf = ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN); + final int iTow = buf.getInt(0); // gps time of week + final double lng = buf.getInt(4) * 1e-7; + final double lat = buf.getInt(8) * 1e-7; + final double alt = buf.getInt(12) * 1e-3; + final double vN = buf.getInt(16) * 1e-3; + final double vE = buf.getInt(20) * 1e-3; + final double climb = buf.getInt(24) * -1e-3; + final long millis = System.currentTimeMillis(); // TODO + + final int locationError = LocationCheck.validate(lat, lng); + if (locationError == LocationCheck.VALID) { + final MLocation loc = new MLocation( + millis, lat, lng, alt, climb, vN, vE, + Float.NaN, Float.NaN, Float.NaN, Float.NaN, -1, -1 + ); + Log.i(TAG, "flysight -> app: gps " + loc); + // Update listeners + locationUpdates.post(loc); + } else { + Log.w(TAG, LocationCheck.message[locationError] + ": " + lat + "," + lng); + Exceptions.report(new NMEAException(LocationCheck.message[locationError] + ": " + lat + "," + lng)); + } + } catch (Exception e) { + Exceptions.report(e); + } + } +} diff --git a/common/src/main/java/com/platypii/baseline/location/LocationProviderBluetooth.java b/common/src/main/java/com/platypii/baseline/location/LocationProviderBluetooth.java index 5d62b8ec..be512007 100644 --- a/common/src/main/java/com/platypii/baseline/location/LocationProviderBluetooth.java +++ b/common/src/main/java/com/platypii/baseline/location/LocationProviderBluetooth.java @@ -67,7 +67,7 @@ public void start(@NonNull Context context) throws SecurityException { } private void onLocationUpdate(MLocation loc) { - locationUpdates.post(loc); + updateLocation(loc); } @Override