diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminCoordinator.java index f58e9cefd..6b6cc0bc9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminCoordinator.java @@ -2,7 +2,12 @@ package nodomain.freeyourgadget.gadgetbridge.devices.garmin; import androidx.annotation.NonNull; +import java.util.List; + import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsScreen; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; @@ -27,6 +32,16 @@ public abstract class GarminCoordinator extends AbstractBLEDeviceCoordinator { return GarminSupport.class; } + @Override + public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) { + final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings(); + + final List connection = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.CONNECTION); + connection.add(R.xml.devicesettings_high_mtu); + + return deviceSpecificSettings; + } + @Override public boolean supportsFindDevice() { return true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index 736366c7e..a37d8bc1c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -745,7 +745,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { LocalBroadcastManager.getInstance(context).sendBroadcast(messageIntent); } - protected Prefs getDevicePrefs() { + public Prefs getDevicePrefs() { return new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress())); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cmfwatchpro/CmfWatchProSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cmfwatchpro/CmfWatchProSupport.java index db6152697..36b034280 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cmfwatchpro/CmfWatchProSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cmfwatchpro/CmfWatchProSupport.java @@ -65,7 +65,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateA import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.MediaManager; -import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class CmfWatchProSupport extends AbstractBTLEDeviceSupport implements CmfCharacteristic.Handler { private static final Logger LOG = LoggerFactory.getLogger(CmfWatchProSupport.class); @@ -177,11 +176,6 @@ public class CmfWatchProSupport extends AbstractBTLEDeviceSupport implements Cmf mediaManager = new MediaManager(context); } - @Override - protected Prefs getDevicePrefs() { - return super.getDevicePrefs(); - } - @Override public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminSupport.java index 3ded65dbb..e37c02095 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminSupport.java @@ -1,5 +1,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_ALLOW_HIGH_MTU; + import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; @@ -53,7 +55,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.SetD import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.SupportedFileTypesMessage; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.SystemEventMessage; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; -import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; @@ -120,11 +121,29 @@ public class GarminSupport extends AbstractBTLEDeviceSupport implements ICommuni return builder; } + if (getDevicePrefs().getBoolean(PREF_ALLOW_HIGH_MTU, true)) { + builder.requestMtu(515); + } + communicator.initializeDevice(builder); return builder; } + @Override + public void onMtuChanged(final BluetoothGatt gatt, final int mtu, final int status) { + if (mtu < 23) { + LOG.warn("Ignoring mtu of {}, too low", mtu); + return; + } + if (!getDevicePrefs().getBoolean(PREF_ALLOW_HIGH_MTU, true)) { + LOG.warn("Ignoring mtu change to {} - high mtu is disabled", mtu); + return; + } + + communicator.onMtuChanged(mtu); + } + @Override public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) { final UUID characteristicUUID = characteristic.getUuid(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/ICommunicator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/ICommunicator.java index dd6e5f336..3c483b04b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/ICommunicator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/ICommunicator.java @@ -8,6 +8,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; public interface ICommunicator { void sendMessage(byte[] message); + void onMtuChanged(final int mtu); + void initializeDevice(TransactionBuilder builder); boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/v1/CommunicatorV1.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/v1/CommunicatorV1.java index f946de6fd..cfce06ad8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/v1/CommunicatorV1.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/v1/CommunicatorV1.java @@ -19,6 +19,11 @@ public class CommunicatorV1 implements ICommunicator { this.mSupport = garminSupport; } + @Override + public void onMtuChanged(final int mtu) { + + } + @Override public void initializeDevice(final TransactionBuilder builder) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/v2/CommunicatorV2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/v2/CommunicatorV2.java index 44a23f086..2c770bcd6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/v2/CommunicatorV2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/communicator/v2/CommunicatorV2.java @@ -23,7 +23,7 @@ public class CommunicatorV2 implements ICommunicator { public static final UUID UUID_CHARACTERISTIC_GARMIN_ML_GFDI_SEND = UUID.fromString("6a4e2822-667b-11e3-949a-0800200c9a66"); //VivomoveConstants.UUID_CHARACTERISTIC_GARMIN_ML_GFDI_SEND; public static final UUID UUID_CHARACTERISTIC_GARMIN_ML_GFDI_RECEIVE = UUID.fromString("6a4e2812-667b-11e3-949a-0800200c9a66"); //VivomoveConstants.UUID_CHARACTERISTIC_GARMIN_ML_GFDI_RECEIVE; - public static final int MAX_WRITE_SIZE = 20; //VivomoveConstants.MAX_WRITE_SIZE + public int maxWriteSize = 20; //VivomoveConstants.MAX_WRITE_SIZE private static final Logger LOG = LoggerFactory.getLogger(CommunicatorV2.class); public final CobsCoDec cobsCoDec; private final GarminSupport mSupport; @@ -35,8 +35,14 @@ public class CommunicatorV2 implements ICommunicator { this.cobsCoDec = new CobsCoDec(); } + @Override + public void onMtuChanged(final int mtu) { + maxWriteSize = mtu - 3; + } + @Override public void initializeDevice(final TransactionBuilder builder) { + builder.notify(this.mSupport.getCharacteristic(UUID_CHARACTERISTIC_GARMIN_ML_GFDI_RECEIVE), true); builder.write(this.mSupport.getCharacteristic(UUID_CHARACTERISTIC_GARMIN_ML_GFDI_SEND), closeAllServices()); } @@ -53,10 +59,10 @@ public class CommunicatorV2 implements ICommunicator { // LOG.debug("SENDING MESSAGE: {} - COBS ENCODED: {}", GB.hexdump(message), GB.hexdump(payload)); final TransactionBuilder builder = new TransactionBuilder("sendMessage()"); int remainingBytes = payload.length; - if (remainingBytes > MAX_WRITE_SIZE - 1) { + if (remainingBytes > maxWriteSize - 1) { int position = 0; while (remainingBytes > 0) { - final byte[] fragment = Arrays.copyOfRange(payload, position, position + Math.min(remainingBytes, MAX_WRITE_SIZE - 1)); + final byte[] fragment = Arrays.copyOfRange(payload, position, position + Math.min(remainingBytes, maxWriteSize - 1)); builder.write(this.mSupport.getCharacteristic(UUID_CHARACTERISTIC_GARMIN_ML_GFDI_SEND), ArrayUtils.addAll(new byte[]{(byte) gfdiHandle}, fragment)); position += fragment.length; remainingBytes -= fragment.length; @@ -168,6 +174,4 @@ public class CommunicatorV2 implements ICommunicator { return null; } } - - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index b33786ab4..e8242eea8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -4266,10 +4266,6 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements return (HuamiCoordinator) gbDevice.getDeviceCoordinator(); } - protected Prefs getDevicePrefs() { - return new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress())); - } - @Override public void handle2021Payload(short type, byte[] payload) { if (type == Huami2021Service.CHUNKED2021_ENDPOINT_COMPAT) {