mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-29 05:16:51 +01:00
Huami/Zepp OS: Improve reconnection
- Remove notification on unneeded characteristics for Zepp OS devices - Reset MTU before initializing device, since the support class is reused when reconnecting, and keeping the previous high MTU before renegotiating again can make the initialization fail sometimes (band will never reply) - If any of the chunked characteristics is null during initialization, mark the device as waiting for reconnect, which will make it retry the connection later with a backoff delay.
This commit is contained in:
parent
aa87c5abeb
commit
247a954920
@ -23,9 +23,9 @@ import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
import android.location.Location;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@ -38,8 +38,6 @@ import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Reminder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.WorldClock;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.CheckInitializedAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile;
|
||||
@ -56,6 +54,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBlePro
|
||||
* @see BtLEQueue
|
||||
*/
|
||||
public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport implements GattCallback, GattServerCallback {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractBTLEDeviceSupport.class);
|
||||
|
||||
private BtLEQueue mQueue;
|
||||
private Map<UUID, BluetoothGattCharacteristic> mAvailableCharacteristics;
|
||||
private final Set<UUID> mSupportedServices = new HashSet<>(4);
|
||||
@ -136,11 +136,13 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
|
||||
*/
|
||||
public TransactionBuilder performInitialized(String taskName) throws IOException {
|
||||
if (!isConnected()) {
|
||||
LOG.debug("Connecting to device for {}", taskName);
|
||||
if (!connect()) {
|
||||
throw new IOException("1: Unable to connect to device: " + getDevice());
|
||||
}
|
||||
}
|
||||
if (!isInitialized()) {
|
||||
LOG.debug("Initializing device for {}", taskName);
|
||||
// first, add a transaction that performs device initialization
|
||||
TransactionBuilder builder = createTransactionBuilder("Initialize device");
|
||||
builder.add(new CheckInitializedAction(gbDevice));
|
||||
|
@ -720,11 +720,16 @@ public abstract class Huami2021Support extends HuamiSupport implements ZeppOsFil
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HuamiSupport enableNotifications(final TransactionBuilder builder, final boolean enable) {
|
||||
builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_CHUNKEDTRANSFER_2021_READ), enable);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Huami2021Support enableFurtherNotifications(final TransactionBuilder builder,
|
||||
final boolean enable) {
|
||||
builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_CHUNKEDTRANSFER_2021_READ), enable);
|
||||
|
||||
// Nothing to do here, they are already enabled from enableNotifications
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -333,7 +333,10 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
||||
protected boolean isMusicAppStarted = false;
|
||||
protected MediaManager mediaManager;
|
||||
private boolean heartRateNotifyEnabled;
|
||||
private int mMTU = 23;
|
||||
private static final int MIN_MTU = 23;
|
||||
private int mMTU = MIN_MTU;
|
||||
// Keep track of the previous MTU before reconnection, so that we can request it after reconnection
|
||||
private int previousMtu = -1;
|
||||
protected int mActivitySampleSize = 4;
|
||||
|
||||
protected Huami2021ChunkedEncoder huami2021ChunkedEncoder;
|
||||
@ -371,6 +374,12 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
||||
|
||||
@Override
|
||||
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
|
||||
if (getMTU() != MIN_MTU) {
|
||||
// Reset the MTU before re-initializing the device, otherwise initialization will sometimes fail
|
||||
previousMtu = getMTU();
|
||||
setMtu(MIN_MTU);
|
||||
}
|
||||
|
||||
try {
|
||||
byte authFlags = getAuthFlags();
|
||||
byte cryptFlags = getCryptFlags();
|
||||
@ -385,8 +394,13 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
||||
if (characteristicChunked2021Write != null && huami2021ChunkedEncoder == null) {
|
||||
huami2021ChunkedEncoder = new Huami2021ChunkedEncoder(characteristicChunked2021Write, force2021Protocol(), mMTU);
|
||||
}
|
||||
if (characteristicChunked2021Write != null && force2021Protocol()) {
|
||||
new InitOperation2021(authenticate, authFlags, cryptFlags, this, builder, huami2021ChunkedEncoder, huami2021ChunkedDecoder).perform();
|
||||
if (force2021Protocol()) {
|
||||
if (characteristicChunked2021Write != null && characteristicChunked2021Read != null) {
|
||||
new InitOperation2021(authenticate, authFlags, cryptFlags, this, builder, huami2021ChunkedEncoder, huami2021ChunkedDecoder).perform();
|
||||
} else {
|
||||
LOG.warn("Chunked 2021 characteristics are null, will attempt to reconnect");
|
||||
builder.add(new SetDeviceStateAction(getDevice(), State.WAITING_FOR_RECONNECT, getContext()));
|
||||
}
|
||||
} else {
|
||||
new InitOperation(authenticate, authFlags, cryptFlags, this, builder).perform();
|
||||
}
|
||||
@ -510,7 +524,6 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
||||
// TODO: tear down the notifications on quit
|
||||
public HuamiSupport 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(HuamiService.UUID_CHARACTERISTIC_AUTH), enable);
|
||||
if (characteristicChunked2021Read != null) {
|
||||
@ -4116,6 +4129,13 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
||||
|
||||
public void phase2Initialize(TransactionBuilder builder) {
|
||||
LOG.info("phase2Initialize...");
|
||||
|
||||
if (previousMtu > MIN_MTU) {
|
||||
// We're reconnecting - request the previously set MTU
|
||||
builder.requestMtu(previousMtu);
|
||||
previousMtu = -1;
|
||||
}
|
||||
|
||||
requestBatteryInfo(builder);
|
||||
}
|
||||
|
||||
@ -4171,13 +4191,12 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
||||
}
|
||||
|
||||
protected void setMtu(final int mtu) {
|
||||
final Prefs prefs = getDevicePrefs();
|
||||
if (!prefs.getBoolean(PREF_ALLOW_HIGH_MTU, true)) {
|
||||
if (mtu > MIN_MTU && !allowHighMtu()) {
|
||||
LOG.warn("High MTU is not allowed, ignoring");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mtu < 23) {
|
||||
if (mtu < MIN_MTU) {
|
||||
LOG.error("Device announced unreasonable low MTU of {}, ignoring", mtu);
|
||||
return;
|
||||
}
|
||||
@ -4188,6 +4207,10 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean allowHighMtu() {
|
||||
return getDevicePrefs().getBoolean(PREF_ALLOW_HIGH_MTU, true);
|
||||
}
|
||||
|
||||
public int getActivitySampleSize() {
|
||||
return mActivitySampleSize;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user