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:
cpfeiffer 2015-05-24 14:39:36 +02:00
parent f004b7b11c
commit 637b43e892
5 changed files with 88 additions and 32 deletions

View File

@ -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) {

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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) {