diff --git a/app/build.gradle b/app/build.gradle index a92fbf07b..7b342b05b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -74,6 +74,7 @@ dependencies { compile 'net.e175.klaus:solarpositioning:0.0.9' compile 'com.github.freeyourgadget:greendao:1998d7cd2d21f662c6044f6ccf3b3a251bbad341' compile 'com.github.woxthebox:draglistview:1.2.6' + compile 'org.apache.commons:commons-lang3:3.4' // compile project(":DaoCore") } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java index ddaab80e6..0c6f4f6fe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java @@ -22,6 +22,8 @@ public class MiBand2Service { public static final UUID UUID_UNKNOWN_CHARACTERISTIC6 = UUID.fromString("00000006-0000-3512-2118-0009af100700"); public static final UUID UUID_UNKNOWN_CHARACTERISTIC7 = UUID.fromString("00000007-0000-3512-2118-0009af100700"); public static final UUID UUID_UNKNOWN_CHARACTERISTIC8 = UUID.fromString("00000008-0000-3512-2118-0009af100700"); + // service uuid fee1 + public static final UUID UUID_UNKNOWN_CHARACTERISTIC9 = UUID.fromString("00000009-0000-3512-2118-0009af100700"); public static final UUID UUID_UNKNOWN_CHARACTERISTIC10 = UUID.fromString("00000010-0000-3512-2118-0009af100700"); // set metric distance diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java index 066b86f01..e7f4658c1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java @@ -8,12 +8,14 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; import android.widget.Toast; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -22,6 +24,10 @@ import java.util.GregorianCalendar; import java.util.List; import java.util.UUID; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; @@ -56,6 +62,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateA import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.battery.BatteryInfoProfile; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; +import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; @@ -165,13 +172,16 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } private MiBand2Support testInit(TransactionBuilder builder) { - builder.read(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC6)); // example read value: 0f6200e0070804072b2c20e00708040625372064 - builder.read(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC7)); // example read value: 0019000000 + //builder.read(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC6)); // example read value: 0f6200e0070804072b2c20e00708040625372064 + //builder.read(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC7)); // example read value: 0019000000 setCurrentTimeWithService(builder); - builder.write(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC4), new byte[] { 0x01, 0x01, (byte) 0xe0, 0x07, 0x07, 0x17, 0x15, 0x04, 0x00, 0x04 }); - builder.write(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC4), new byte[] { 0x02 }); + // write key to miband2 + builder.write(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9), new byte[] { 0x01, 0x01, (byte) 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45 }); + // get random auth number + builder.write(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9), new byte[] { 0x02 }); builder.read(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC6)); // probably superfluous builder.write(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC8), new byte[] { 0x20, 0x00, 0x00, 0x02 }); + Log.d("TESTINIT", "testinit"); return this; } @@ -236,6 +246,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { private MiBand2Support enableNotifications(TransactionBuilder builder, boolean enable) { builder.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_NOTIFICATION), enable); builder.notify(getCharacteristic(GattService.UUID_SERVICE_CURRENT_TIME), enable); + // Notify CHARACTERISTIC9 to receive random auth code + builder.notify(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9), enable); return this; } @@ -394,9 +406,13 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { */ private MiBand2Support pair(TransactionBuilder transaction) { LOG.info("Attempting to pair MI device..."); - BluetoothGattCharacteristic characteristic = getCharacteristic(MiBandService.UUID_CHARACTERISTIC_PAIR); + //BluetoothGattCharacteristic characteristic = getCharacteristic(MiBandService.UUID_CHARACTERISTIC_PAIR); + // write key to miband2 + BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9); if (characteristic != null) { - transaction.write(characteristic, new byte[]{2}); + transaction.write(characteristic, new byte[] { 0x01, 0x01, (byte) 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45 }); + transaction.write(characteristic, new byte[] { 0x02 }); + LOG.info("Pair write"); } else { LOG.info("Unable to pair MI device -- characteristic not available"); } @@ -882,6 +898,14 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { // } else if (MiBand2Service.UUID_UNKNOQN_CHARACTERISTIC0.equals(characteristicUUID)) { // handleUnknownCharacteristic(characteristic.getValue()); // return true; + } else if (MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9.equals(characteristicUUID)) { + if (characteristic.getValue()[0] == 0x10) { + byte[] eValue = handleAESAuth(characteristic.getValue()); + byte[] responseValue = org.apache.commons.lang3.ArrayUtils.addAll(new byte[] {0x03, 0x00}, eValue); + characteristic.setValue(responseValue); + gatt.writeCharacteristic(characteristic); + } + // } else { LOG.info("Unhandled characteristic changed: " + characteristicUUID); logMessageContent(characteristic.getValue()); @@ -997,6 +1021,22 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent); } + private byte[] handleAESAuth(byte[] value) { + byte[] mValue = Arrays.copyOfRange(value, 3, 188); + try { + Cipher ecipher = null; + byte[] sRandom = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45}; + ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKeySpec newKey = new SecretKeySpec(sRandom, "AES"); + ecipher.init(Cipher.ENCRYPT_MODE, newKey); + byte[] enc = ecipher.doFinal(mValue); + return enc; + } catch (Exception e) { + e.printStackTrace(); + } + return value; + } + /** * React to unsolicited messages sent by the Mi Band to the MiBandService.UUID_CHARACTERISTIC_NOTIFICATION * characteristic,