From 08f2b0eb7cc24bddcf5c113a139e2942f956929f Mon Sep 17 00:00:00 2001 From: JohnnySun Date: Tue, 13 Sep 2016 18:15:03 +0800 Subject: [PATCH] fix somebug and rewirte the auth process --- .../gadgetbridge/model/DeviceService.java | 2 + .../devices/miband/MiBand2Support.java | 58 ++++++++++++++----- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index 7c459f42..6db9f4a8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -12,6 +12,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; public interface DeviceService extends EventHandler { String PREFIX = "nodomain.freeyourgadget.gadgetbridge.devices"; + String ACTION_MIBAND2_AUTH = PREFIX + ".action.miban2_auth"; String ACTION_START = PREFIX + ".action.start"; String ACTION_CONNECT = PREFIX + ".action.connect"; String ACTION_NOTIFICATION = PREFIX + ".action.notification"; @@ -83,6 +84,7 @@ public interface DeviceService extends EventHandler { String EXTRA_CALENDAREVENT_DURATION = "calendarevent_duration"; String EXTRA_CALENDAREVENT_TITLE = "calendarevent_title"; String EXTRA_CALENDAREVENT_DESCRIPTION = "calendarevent_description"; + String EXTRA_MIBAND2_AUTH_BYTE = "miband2_auth_byte"; void start(); 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 e7f4658c..2a95a94c 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 @@ -7,6 +7,9 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.widget.Toast; @@ -55,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; +import nodomain.freeyourgadget.gadgetbridge.service.btle.Transaction; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ConditionalWriteAction; @@ -104,12 +108,25 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } else if (s.equals(BatteryInfoProfile.ACTION_BATTERY_INFO)) { handleBatteryInfo((nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.battery.BatteryInfo) intent.getParcelableExtra(BatteryInfoProfile.EXTRA_BATTERY_INFO)); + } else if (s.equals(DeviceService.ACTION_MIBAND2_AUTH)) { + byte[] response = intent.getExtras().getByteArray(DeviceService.EXTRA_MIBAND2_AUTH_BYTE); + BluetoothGattCharacteristic temp = getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9); + temp.setValue(response); + if ((temp.getProperties() & (BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) != 0) { + Log.d("HELLO", "its looks ok"); + } + if (!mBluetoothGatt.writeCharacteristic(temp)) { + Log.d("ERROR", "ERROR"); + } + Log.d("HELLO", "HELLO"); + } } }; private volatile boolean telephoneRinging; private volatile boolean isLocatingDevice; + private BluetoothGatt mBluetoothGatt; private DeviceInfo mDeviceInfo; @@ -136,6 +153,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(DeviceInfoProfile.ACTION_DEVICE_INFO); intentFilter.addAction(BatteryInfoProfile.ACTION_BATTERY_INFO); + intentFilter.addAction(DeviceService.ACTION_MIBAND2_AUTH); broadcastManager.registerReceiver(mReceiver, intentFilter); } @@ -155,9 +173,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { // this is apparently not needed anymore, and actually causes problems when bonding is not used/does not work // so we simply not use the UUID_PAIR characteristic. // .pair(builder) - .testInit(builder) - .requestDeviceInfo(builder) - .requestBatteryInfo(builder); + .testInit(builder); + //.requestDeviceInfo(builder) + //.requestBatteryInfo(builder); // .sendUserInfo(builder) // .checkAuthenticationNeeded(builder, getDevice()) // .setWearLocation(builder) @@ -176,12 +194,11 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { //builder.read(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC7)); // example read value: 0019000000 setCurrentTimeWithService(builder); // 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 }); + //builder.write(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9), new byte[] { 0x01, 0x08, (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"); + builder.write(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9), new byte[] { 0x02 , 0x08}); + //builder.read(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC6)); // probably superfluous + //builder.write(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC8), new byte[] { 0x20, 0x00, 0x00, 0x02 }); return this; } @@ -410,8 +427,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { // write key to miband2 BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9); if (characteristic != null) { - 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 }); + transaction.write(characteristic, new byte[] { 0x01, 0x08, (byte) 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45 }); + //transaction.write(characteristic, new byte[] { 0x02, 0x08 }); LOG.info("Pair write"); } else { LOG.info("Unable to pair MI device -- characteristic not available"); @@ -878,6 +895,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { super.onCharacteristicChanged(gatt, characteristic); + mBluetoothGatt = gatt; UUID characteristicUUID = characteristic.getUuid(); if (MiBandService.UUID_CHARACTERISTIC_BATTERY.equals(characteristicUUID)) { @@ -899,11 +917,15 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { // handleUnknownCharacteristic(characteristic.getValue()); // return true; } else if (MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9.equals(characteristicUUID)) { - if (characteristic.getValue()[0] == 0x10) { + logMessageContent(characteristic.getValue()); + if (characteristic.getValue()[0] == 0x10 && + characteristic.getValue()[1] == 0x02 && + characteristic.getValue()[2] == 0x01) { byte[] eValue = handleAESAuth(characteristic.getValue()); - byte[] responseValue = org.apache.commons.lang3.ArrayUtils.addAll(new byte[] {0x03, 0x00}, eValue); - characteristic.setValue(responseValue); - gatt.writeCharacteristic(characteristic); + byte[] responseValue = org.apache.commons.lang3.ArrayUtils.addAll(new byte[] {0x03, 0x08}, eValue); + Intent intent = new Intent(DeviceService.ACTION_MIBAND2_AUTH) + .putExtra(DeviceService.EXTRA_MIBAND2_AUTH_BYTE, responseValue); + LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent); } // } else { @@ -958,6 +980,10 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } else if (MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT.equals(characteristicUUID)) { handleControlPointResult(characteristic.getValue(), status); return true; + } else if (MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC9.equals(characteristicUUID)) { + LOG.info("KEY AES SEND"); + logMessageContent(characteristic.getValue()); + return true; } return false; } @@ -1022,11 +1048,11 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } private byte[] handleAESAuth(byte[] value) { - byte[] mValue = Arrays.copyOfRange(value, 3, 188); + byte[] mValue = Arrays.copyOfRange(value, 3, 19); 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"); + ecipher = Cipher.getInstance("AES/ECB/NoPadding"); SecretKeySpec newKey = new SecretKeySpec(sRandom, "AES"); ecipher.init(Cipher.ENCRYPT_MODE, newKey); byte[] enc = ecipher.doFinal(mValue);