From 4dc085de5721cdbd7eae77b1cc2e9383fc3a78cf Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Fri, 18 Nov 2016 23:36:27 +0100 Subject: [PATCH] Pebble 2: React to MTU notifications, fixes LE for older pebbles also It seems that setting the MTU on older pebbles does not work, so just use what we can use. Maybe old pebbles need setMTU() which only works on Android 5+, we could use that conditionally... --- .../devices/pebble/ble/PebbleGATTClient.java | 16 ++++++++++++---- .../devices/pebble/ble/PebbleLESupport.java | 10 +++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTClient.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTClient.java index fa29a6663..d8fa0a33a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTClient.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTClient.java @@ -15,6 +15,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import static android.bluetooth.BluetoothGattCharacteristic.FORMAT_UINT16; import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_WRITE; @@ -32,15 +33,17 @@ class PebbleGATTClient extends BluetoothGattCallback { private final String mBtDeviceAddress; private final BluetoothDevice mBtDevice; private final Context mContext; + private final PebbleLESupport mPebbleLESupport; private boolean oldPebble = false; private boolean doPairing = true; private boolean removeBond = false; private BluetoothGatt mBluetoothGatt; - PebbleGATTClient(Context context, BluetoothDevice btDevice) { + PebbleGATTClient(PebbleLESupport pebbleLESupport, Context context, BluetoothDevice btDevice) { mContext = context; mBtDevice = btDevice; + mPebbleLESupport = pebbleLESupport; mBtDeviceAddress = btDevice.getAddress(); } @@ -54,7 +57,13 @@ class PebbleGATTClient extends BluetoothGattCallback { LOG.info("onCharacteristicChanged() unexpected device: " + gatt.getDevice().getAddress() + " , expected: " + mBtDeviceAddress); return; } - LOG.info("onCharacteristicChanged()" + characteristic.getUuid().toString() + " " + GB.hexdump(characteristic.getValue(), 0, -1)); + if (characteristic.getUuid().equals(MTU_CHARACTERISTIC)) { + int newMTU = characteristic.getIntValue(FORMAT_UINT16, 0); + mPebbleLESupport.setMTU(newMTU); + LOG.info("Pebble requested MTU = " + newMTU); + } else { + LOG.info("onCharacteristicChanged()" + characteristic.getUuid().toString() + " " + GB.hexdump(characteristic.getValue(), 0, -1)); + } } public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { @@ -141,8 +150,7 @@ class PebbleGATTClient extends BluetoothGattCallback { if ((characteristic.getProperties() & PROPERTY_WRITE) != 0) { characteristic.setValue(new byte[]{1}); gatt.writeCharacteristic(characteristic); - } - else { + } else { LOG.info("This seems to be some <4.0 FW Pebble, reading pairing trigger"); gatt.readCharacteristic(characteristic); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java index c8faee1e9..55c0008b8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java @@ -19,6 +19,7 @@ public class PebbleLESupport { private PebbleGATTClient mPebbleGATTClient; private PipedInputStream mPipedInputStream; private PipedOutputStream mPipedOutputStream; + private int mMTU = 20; public PebbleLESupport(Context context, final String btDeviceAddress, PipedInputStream pipedInputStream, PipedOutputStream pipedOutputStream) { @@ -37,7 +38,7 @@ public class PebbleLESupport { mPebbleGATTServer = new PebbleGATTServer(this, context, btDevice); mPebbleGATTServer.initialize(); - mPebbleGATTClient = new PebbleGATTClient(context, btDevice); + mPebbleGATTClient = new PebbleGATTClient(this, context, btDevice); mPebbleGATTClient.initialize(); } @@ -83,13 +84,16 @@ public class PebbleLESupport { } } + void setMTU(int mtu) { + mMTU = mtu; + } + private class PipeReader extends Thread { int mmSequence = 0; private boolean mQuit = false; @Override public void run() { - int MTU = 339 - 3; byte[] buf = new byte[8192]; int bytesRead; while (!mQuit) { @@ -113,7 +117,7 @@ public class PebbleLESupport { int payloadToSend = bytesRead + 4; int srcPos = 0; while (payloadToSend > 0) { - int chunkSize = (payloadToSend < (MTU - 1)) ? payloadToSend : MTU - 1; + int chunkSize = (payloadToSend < (mMTU - 4)) ? payloadToSend : mMTU - 4; byte[] outBuf = new byte[chunkSize + 1]; outBuf[0] = (byte) ((mmSequence++ << 3) & 0xff); System.arraycopy(buf, srcPos, outBuf, 1, chunkSize);