Also wait for descriptor reads and writes
(not just characteristic reads/writes) This fixes initialization of notification characteristics (activity, sensor data, battery, ...)
This commit is contained in:
parent
f004b7b11c
commit
637b43e892
|
@ -2,6 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.btle;
|
|||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -173,6 +174,14 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
|
|||
BluetoothGattCharacteristic characteristic, int status) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCharacteristicChanged(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.bluetooth.BluetoothDevice;
|
|||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCallback;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
|
@ -69,11 +70,10 @@ public final class BtLEQueue {
|
|||
// Run all actions of the transaction until one doesn't succeed
|
||||
for (BtLEAction action : transaction.getActions()) {
|
||||
mWaitCharacteristic = action.getCharacteristic();
|
||||
boolean waitForResult = action.expectsResult();
|
||||
if (waitForResult) {
|
||||
mWaitForActionResultLatch = new CountDownLatch(1);
|
||||
}
|
||||
if (action.run(mBluetoothGatt)) {
|
||||
// check again, maybe due to some condition, action did not need to write, so we can't wait
|
||||
boolean waitForResult = action.expectsResult();
|
||||
if (waitForResult) {
|
||||
mWaitForActionResultLatch.await();
|
||||
mWaitForActionResultLatch = null;
|
||||
|
@ -278,6 +278,7 @@ public final class BtLEQueue {
|
|||
|
||||
@Override
|
||||
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
||||
LOG.debug("characteristic write: " + characteristic.getUuid());
|
||||
if (!checkCorrectGattInstance(gatt, "characteristic write")) {
|
||||
return;
|
||||
}
|
||||
|
@ -296,6 +297,7 @@ public final class BtLEQueue {
|
|||
public void onCharacteristicRead(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic,
|
||||
int status) {
|
||||
LOG.debug("characteristic read: " + characteristic.getUuid());
|
||||
if (!checkCorrectGattInstance(gatt, "characteristic read")) {
|
||||
return;
|
||||
}
|
||||
|
@ -308,9 +310,40 @@ public final class BtLEQueue {
|
|||
checkWaitingCharacteristic(characteristic, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
|
||||
LOG.debug("descriptor read: " + descriptor.getUuid());
|
||||
if (!checkCorrectGattInstance(gatt, "descriptor read")) {
|
||||
return;
|
||||
}
|
||||
if (status != BluetoothGatt.GATT_SUCCESS) {
|
||||
LOG.error("Reading descriptor " + descriptor.getUuid() + " failed: " + status);
|
||||
}
|
||||
if (mExternalGattCallback != null) {
|
||||
mExternalGattCallback.onDescriptorRead(gatt, descriptor, status);
|
||||
}
|
||||
checkWaitingCharacteristic(descriptor.getCharacteristic(), status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
|
||||
LOG.debug("descriptor write: " + descriptor.getUuid());
|
||||
if (!checkCorrectGattInstance(gatt, "descriptor write")) {
|
||||
return;
|
||||
}
|
||||
if (status != BluetoothGatt.GATT_SUCCESS) {
|
||||
LOG.error("Writing descriptor " + descriptor.getUuid() + " failed: " + status);
|
||||
}
|
||||
if (mExternalGattCallback != null) {
|
||||
mExternalGattCallback.onDescriptorWrite(gatt, descriptor, status);
|
||||
}
|
||||
checkWaitingCharacteristic(descriptor.getCharacteristic(), status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCharacteristicChanged(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic) {
|
||||
LOG.debug("characteristic changed: " + characteristic.getUuid());
|
||||
if (!checkCorrectGattInstance(gatt, "characteristic changed")) {
|
||||
return;
|
||||
}
|
||||
|
@ -325,6 +358,7 @@ public final class BtLEQueue {
|
|||
|
||||
@Override
|
||||
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
|
||||
LOG.debug("remote rssi: " + rssi);
|
||||
if (!checkCorrectGattInstance(gatt, "remote rssi")) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.btle;
|
|||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCallback;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
|
||||
/**
|
||||
* Callback interface handling gatt events.
|
||||
|
@ -66,23 +67,23 @@ public interface GattCallback {
|
|||
void onCharacteristicChanged(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic);
|
||||
|
||||
// /**
|
||||
// * @see BluetoothGattCallback#onDescriptorRead(BluetoothGatt, BluetoothGattDescriptor, int)
|
||||
// * @param gatt
|
||||
// * @param descriptor
|
||||
// * @param status
|
||||
// */
|
||||
// public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
||||
// int status);
|
||||
//
|
||||
// /**
|
||||
// * @see BluetoothGattCallback#onDescriptorWrite(BluetoothGatt, BluetoothGattDescriptor, int)
|
||||
// * @param gatt
|
||||
// * @param descriptor
|
||||
// * @param status
|
||||
// */
|
||||
// public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
||||
// int status);
|
||||
/**
|
||||
* @see BluetoothGattCallback#onDescriptorRead(BluetoothGatt, BluetoothGattDescriptor, int)
|
||||
* @param gatt
|
||||
* @param descriptor
|
||||
* @param status
|
||||
*/
|
||||
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
||||
int status);
|
||||
|
||||
/**
|
||||
* @see BluetoothGattCallback#onDescriptorWrite(BluetoothGatt, BluetoothGattDescriptor, int)
|
||||
* @param gatt
|
||||
* @param descriptor
|
||||
* @param status
|
||||
*/
|
||||
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
||||
int status);
|
||||
//
|
||||
// /**
|
||||
// * @see BluetoothGattCallback#onReliableWriteCompleted(BluetoothGatt, int)
|
||||
|
|
|
@ -23,6 +23,7 @@ import nodomain.freeyourgadget.gadgetbridge.miband.MiBandService;
|
|||
public class MiBandNotifyAction extends NotifyAction {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TransactionBuilder.class);
|
||||
private boolean hasWrittenDescriptor = true;
|
||||
|
||||
public MiBandNotifyAction(BluetoothGattCharacteristic characteristic, boolean enable) {
|
||||
super(characteristic, enable);
|
||||
|
@ -32,24 +33,34 @@ public class MiBandNotifyAction extends NotifyAction {
|
|||
public boolean run(BluetoothGatt gatt) {
|
||||
boolean result = super.run(gatt);
|
||||
if (result) {
|
||||
BluetoothGattDescriptor sleepDescriptor = getCharacteristic().getDescriptor(MiBandService.UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION);
|
||||
if (sleepDescriptor != null) {
|
||||
BluetoothGattDescriptor notifyDescriptor = getCharacteristic().getDescriptor(MiBandService.UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION);
|
||||
if (notifyDescriptor != null) {
|
||||
int properties = getCharacteristic().getProperties();
|
||||
if ((properties & 0x10) > 0) {
|
||||
LOG.info("properties & 0x10 > 0");
|
||||
sleepDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
|
||||
result = gatt.writeDescriptor(sleepDescriptor);
|
||||
LOG.debug("properties & 0x10 > 0");
|
||||
notifyDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
|
||||
result = gatt.writeDescriptor(notifyDescriptor);
|
||||
} else if ((properties & 0x20) > 0){
|
||||
LOG.info("properties & 0x20 > 0");
|
||||
sleepDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
|
||||
result = gatt.writeDescriptor(sleepDescriptor);
|
||||
LOG.debug("properties & 0x20 > 0");
|
||||
notifyDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
|
||||
result = gatt.writeDescriptor(notifyDescriptor);
|
||||
hasWrittenDescriptor = true;
|
||||
} else {
|
||||
hasWrittenDescriptor = false;
|
||||
}
|
||||
} else {
|
||||
LOG.warn("sleep descriptor null");
|
||||
hasWrittenDescriptor = false;
|
||||
}
|
||||
} else {
|
||||
hasWrittenDescriptor = false;
|
||||
LOG.error("Unable to enable notification for " + getCharacteristic().getUuid());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean expectsResult() {
|
||||
return hasWrittenDescriptor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.miband;
|
|||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
|
@ -50,7 +51,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||
|
||||
@Override
|
||||
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
|
||||
pair(builder).sendUserInfo(builder).setCurrentTime(builder).requestBatteryInfo(builder).enableNotifications(builder, true);
|
||||
pair(builder).sendUserInfo(builder).enableNotifications(builder, true).setCurrentTime(builder).requestBatteryInfo(builder);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
@ -59,7 +60,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||
private MiBandSupport enableNotifications(TransactionBuilder builder, boolean enable) {
|
||||
builder.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_NOTIFICATION), enable)
|
||||
.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_REALTIME_STEPS), enable)
|
||||
.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_ACTIVITY_DATA),enable)
|
||||
.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_ACTIVITY_DATA), enable)
|
||||
.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_BATTERY), enable)
|
||||
.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_SENSOR_DATA), enable);
|
||||
|
||||
|
@ -362,7 +363,6 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||
@Override
|
||||
public void onCharacteristicChanged(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic) {
|
||||
LOG.info("Notification characteristic changed: " + characteristic.getUuid());
|
||||
super.onCharacteristicChanged(gatt, characteristic);
|
||||
|
||||
UUID characteristicUUID = characteristic.getUuid();
|
||||
|
@ -370,6 +370,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||
handleActivityData(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCharacteristicRead(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic, int status) {
|
||||
|
|
Loading…
Reference in New Issue