From 1b6bb20890dee0a68bd1fdfa2c63badbc4ec05ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Tue, 17 Oct 2023 22:39:49 +0100 Subject: [PATCH] Xiaomi: Move initialization logic to base class --- .../xiaomi/XiaomiEncryptedSupport.java | 54 ++++++-------- .../xiaomi/XiaomiPlaintextSupport.java | 70 +++++++------------ .../service/devices/xiaomi/XiaomiSupport.java | 46 ++++++++++++ 3 files changed, 93 insertions(+), 77 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiEncryptedSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiEncryptedSupport.java index 8e51887e1..1da4fab33 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiEncryptedSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiEncryptedSupport.java @@ -62,44 +62,32 @@ public class XiaomiEncryptedSupport extends XiaomiSupport { } @Override - protected TransactionBuilder initializeDevice(final TransactionBuilder builder) { - final BluetoothGattCharacteristic btCharacteristicCommandRead = getCharacteristic(UUID_CHARACTERISTIC_XIAOMI_COMMAND_READ); - final BluetoothGattCharacteristic btCharacteristicCommandWrite = getCharacteristic(UUID_CHARACTERISTIC_XIAOMI_COMMAND_WRITE); - final BluetoothGattCharacteristic btCharacteristicActivityData = getCharacteristic(UUID_CHARACTERISTIC_XIAOMI_ACTIVITY_DATA); - final BluetoothGattCharacteristic btCharacteristicDataUpload = getCharacteristic(UUID_CHARACTERISTIC_XIAOMI_DATA_UPLOAD); + protected boolean isEncrypted() { + return true; + } - if (btCharacteristicCommandRead == null || btCharacteristicCommandWrite == null) { - LOG.warn("Characteristics are null, will attempt to reconnect"); - builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.WAITING_FOR_RECONNECT, getContext())); - return builder; - } + @Override + protected UUID getCharacteristicCommandRead() { + return UUID_CHARACTERISTIC_XIAOMI_COMMAND_READ; + } - // TODO move this initialization to upstream class - this.characteristicCommandRead = new XiaomiCharacteristic(this, btCharacteristicCommandRead, authService); - this.characteristicCommandRead.setEncrypted(true); - this.characteristicCommandRead.setHandler(this::handleCommandBytes); - this.characteristicCommandWrite = new XiaomiCharacteristic(this, btCharacteristicCommandWrite, authService); - this.characteristicCommandRead.setEncrypted(true); - this.characteristicActivityData = new XiaomiCharacteristic(this, btCharacteristicActivityData, authService); - this.characteristicActivityData.setHandler(healthService.getActivityFetcher()::addChunk); - this.characteristicCommandRead.setEncrypted(true); - this.characteristicDataUpload = new XiaomiCharacteristic(this, btCharacteristicDataUpload, authService); - this.characteristicCommandRead.setEncrypted(true); + @Override + protected UUID getCharacteristicCommandWrite() { + return UUID_CHARACTERISTIC_XIAOMI_COMMAND_WRITE; + } - // FIXME why is this needed? - getDevice().setFirmwareVersion("..."); - //getDevice().setFirmwareVersion2("..."); + @Override + protected UUID getCharacteristicActivityData() { + return UUID_CHARACTERISTIC_XIAOMI_ACTIVITY_DATA; + } - builder.requestMtu(247); - - builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); - builder.notify(getCharacteristic(UUID_CHARACTERISTIC_XIAOMI_COMMAND_READ), true); - builder.notify(getCharacteristic(UUID_CHARACTERISTIC_XIAOMI_COMMAND_WRITE), true); - builder.notify(getCharacteristic(UUID_CHARACTERISTIC_XIAOMI_ACTIVITY_DATA), true); - builder.notify(getCharacteristic(UUID_CHARACTERISTIC_XIAOMI_DATA_UPLOAD), true); + @Override + protected UUID getCharacteristicDataUpload() { + return UUID_CHARACTERISTIC_XIAOMI_DATA_UPLOAD; + } + @Override + protected void startAuthentication(TransactionBuilder builder) { authService.startEncryptedHandshake(builder); - - return builder; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiPlaintextSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiPlaintextSupport.java index 8b5ff3788..8a2ea5e53 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiPlaintextSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiPlaintextSupport.java @@ -16,23 +16,17 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi; -import android.bluetooth.BluetoothGattCharacteristic; import android.content.SharedPreferences; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; -import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; -import nodomain.freeyourgadget.gadgetbridge.util.GB; public class XiaomiPlaintextSupport extends XiaomiSupport { @@ -50,46 +44,34 @@ public class XiaomiPlaintextSupport extends XiaomiSupport { } @Override - protected TransactionBuilder initializeDevice(final TransactionBuilder builder) { - final BluetoothGattCharacteristic btCharacteristicCommandRead = getCharacteristic(UUID_CHARACTERISTIC_MAIN_READ); - final BluetoothGattCharacteristic btCharacteristicCommandWrite = getCharacteristic(UUID_CHARACTERISTIC_MAIN_WRITE); - final BluetoothGattCharacteristic btCharacteristicActivityData = getCharacteristic(UUID_CHARACTERISTIC_ACTIVITY_DATA); - final BluetoothGattCharacteristic btCharacteristicDataUpload = getCharacteristic(UUID_CHARACTERISTIC_DATA_UPLOAD); - - if (btCharacteristicCommandRead == null || btCharacteristicCommandWrite == null) { - LOG.warn("Characteristics are null, will attempt to reconnect"); - builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.WAITING_FOR_RECONNECT, getContext())); - return builder; - } - - // TODO move this initialization to upstream class - this.characteristicCommandRead = new XiaomiCharacteristic(this, btCharacteristicCommandRead, authService); - this.characteristicCommandRead.setEncrypted(false); - this.characteristicCommandRead.setHandler(this::handleCommandBytes); - this.characteristicCommandWrite = new XiaomiCharacteristic(this, btCharacteristicCommandWrite, authService); - this.characteristicCommandWrite.setEncrypted(false); - this.characteristicActivityData = new XiaomiCharacteristic(this, btCharacteristicActivityData, authService); - this.characteristicActivityData.setHandler(healthService.getActivityFetcher()::addChunk); - this.characteristicActivityData.setEncrypted(false); - this.characteristicDataUpload = new XiaomiCharacteristic(this, btCharacteristicDataUpload, authService); - this.characteristicDataUpload.setEncrypted(false); - - builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); - enableNotifications(builder, true); - builder.requestMtu(247); - - String userId = getUserId(gbDevice); - authService.startClearTextHandshake(builder, userId); - - return builder; + protected boolean isEncrypted() { + return false; } - private void enableNotifications(TransactionBuilder builder, boolean enable) { - builder.notify(getCharacteristic(UUID_CHARACTERISTIC_MAIN_WRITE), enable); - builder.notify(getCharacteristic(UUID_CHARACTERISTIC_MAIN_READ), enable); - builder.notify(getCharacteristic(UUID_CHARACTERISTIC_ACTIVITY_DATA), enable); - builder.notify(getCharacteristic(UUID_CHARACTERISTIC_DATA_UPLOAD), enable); - builder.notify(getCharacteristic(UUID_CHARACTERISTIC_UNK5), enable); + @Override + protected UUID getCharacteristicCommandRead() { + return UUID_CHARACTERISTIC_MAIN_READ; + } + + @Override + protected UUID getCharacteristicCommandWrite() { + return UUID_CHARACTERISTIC_MAIN_WRITE; + } + + @Override + protected UUID getCharacteristicActivityData() { + return UUID_CHARACTERISTIC_ACTIVITY_DATA; + } + + @Override + protected UUID getCharacteristicDataUpload() { + return UUID_CHARACTERISTIC_DATA_UPLOAD; + } + + @Override + protected void startAuthentication(final TransactionBuilder builder) { + final String userId = getUserId(gbDevice); + authService.startClearTextHandshake(builder, userId); } protected static String getUserId(final GBDevice device) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiSupport.java index 1441ea584..485bc0df2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiSupport.java @@ -49,6 +49,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services.AbstractXiaomiService; import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services.XiaomiCalendarService; import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services.XiaomiHealthService; @@ -92,6 +93,51 @@ public abstract class XiaomiSupport extends AbstractBTLEDeviceSupport { super(LOG); } + protected abstract boolean isEncrypted(); + protected abstract UUID getCharacteristicCommandRead(); + protected abstract UUID getCharacteristicCommandWrite(); + protected abstract UUID getCharacteristicActivityData(); + protected abstract UUID getCharacteristicDataUpload(); + protected abstract void startAuthentication(TransactionBuilder builder); + + @Override + protected final TransactionBuilder initializeDevice(final TransactionBuilder builder) { + final BluetoothGattCharacteristic btCharacteristicCommandRead = getCharacteristic(getCharacteristicCommandRead()); + final BluetoothGattCharacteristic btCharacteristicCommandWrite = getCharacteristic(getCharacteristicCommandWrite()); + final BluetoothGattCharacteristic btCharacteristicActivityData = getCharacteristic(getCharacteristicActivityData()); + final BluetoothGattCharacteristic btCharacteristicDataUpload = getCharacteristic(getCharacteristicDataUpload()); + + if (btCharacteristicCommandRead == null || btCharacteristicCommandWrite == null) { + LOG.warn("Characteristics are null, will attempt to reconnect"); + builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.WAITING_FOR_RECONNECT, getContext())); + return builder; + } + + this.characteristicCommandRead = new XiaomiCharacteristic(this, btCharacteristicCommandRead, authService); + this.characteristicCommandRead.setEncrypted(isEncrypted()); + this.characteristicCommandRead.setHandler(this::handleCommandBytes); + this.characteristicCommandWrite = new XiaomiCharacteristic(this, btCharacteristicCommandWrite, authService); + this.characteristicCommandRead.setEncrypted(isEncrypted()); + this.characteristicActivityData = new XiaomiCharacteristic(this, btCharacteristicActivityData, authService); + this.characteristicActivityData.setHandler(healthService.getActivityFetcher()::addChunk); + this.characteristicCommandRead.setEncrypted(isEncrypted()); + this.characteristicDataUpload = new XiaomiCharacteristic(this, btCharacteristicDataUpload, authService); + this.characteristicCommandRead.setEncrypted(isEncrypted()); + + builder.requestMtu(247); + + builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); + + builder.notify(btCharacteristicCommandRead, true); + builder.notify(btCharacteristicCommandWrite, true); + builder.notify(btCharacteristicActivityData, true); + builder.notify(btCharacteristicDataUpload, true); + + startAuthentication(builder); + + return builder; + } + @Override public boolean useAutoConnect() { return true;