mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-10-09 14:41:25 +02:00
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.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.bluetooth.BluetoothGattDescriptor;
|
||||||
import android.bluetooth.BluetoothGattService;
|
import android.bluetooth.BluetoothGattService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -173,6 +174,14 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
|
|||||||
BluetoothGattCharacteristic characteristic, int status) {
|
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
|
@Override
|
||||||
public void onCharacteristicChanged(BluetoothGatt gatt,
|
public void onCharacteristicChanged(BluetoothGatt gatt,
|
||||||
BluetoothGattCharacteristic characteristic) {
|
BluetoothGattCharacteristic characteristic) {
|
||||||
|
@ -5,6 +5,7 @@ import android.bluetooth.BluetoothDevice;
|
|||||||
import android.bluetooth.BluetoothGatt;
|
import android.bluetooth.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCallback;
|
import android.bluetooth.BluetoothGattCallback;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.bluetooth.BluetoothGattDescriptor;
|
||||||
import android.bluetooth.BluetoothGattService;
|
import android.bluetooth.BluetoothGattService;
|
||||||
import android.bluetooth.BluetoothProfile;
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -69,11 +70,10 @@ public final class BtLEQueue {
|
|||||||
// Run all actions of the transaction until one doesn't succeed
|
// Run all actions of the transaction until one doesn't succeed
|
||||||
for (BtLEAction action : transaction.getActions()) {
|
for (BtLEAction action : transaction.getActions()) {
|
||||||
mWaitCharacteristic = action.getCharacteristic();
|
mWaitCharacteristic = action.getCharacteristic();
|
||||||
boolean waitForResult = action.expectsResult();
|
|
||||||
if (waitForResult) {
|
|
||||||
mWaitForActionResultLatch = new CountDownLatch(1);
|
mWaitForActionResultLatch = new CountDownLatch(1);
|
||||||
}
|
|
||||||
if (action.run(mBluetoothGatt)) {
|
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) {
|
if (waitForResult) {
|
||||||
mWaitForActionResultLatch.await();
|
mWaitForActionResultLatch.await();
|
||||||
mWaitForActionResultLatch = null;
|
mWaitForActionResultLatch = null;
|
||||||
@ -278,6 +278,7 @@ public final class BtLEQueue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
||||||
|
LOG.debug("characteristic write: " + characteristic.getUuid());
|
||||||
if (!checkCorrectGattInstance(gatt, "characteristic write")) {
|
if (!checkCorrectGattInstance(gatt, "characteristic write")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -296,6 +297,7 @@ public final class BtLEQueue {
|
|||||||
public void onCharacteristicRead(BluetoothGatt gatt,
|
public void onCharacteristicRead(BluetoothGatt gatt,
|
||||||
BluetoothGattCharacteristic characteristic,
|
BluetoothGattCharacteristic characteristic,
|
||||||
int status) {
|
int status) {
|
||||||
|
LOG.debug("characteristic read: " + characteristic.getUuid());
|
||||||
if (!checkCorrectGattInstance(gatt, "characteristic read")) {
|
if (!checkCorrectGattInstance(gatt, "characteristic read")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -308,9 +310,40 @@ public final class BtLEQueue {
|
|||||||
checkWaitingCharacteristic(characteristic, status);
|
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
|
@Override
|
||||||
public void onCharacteristicChanged(BluetoothGatt gatt,
|
public void onCharacteristicChanged(BluetoothGatt gatt,
|
||||||
BluetoothGattCharacteristic characteristic) {
|
BluetoothGattCharacteristic characteristic) {
|
||||||
|
LOG.debug("characteristic changed: " + characteristic.getUuid());
|
||||||
if (!checkCorrectGattInstance(gatt, "characteristic changed")) {
|
if (!checkCorrectGattInstance(gatt, "characteristic changed")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -325,6 +358,7 @@ public final class BtLEQueue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
|
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
|
||||||
|
LOG.debug("remote rssi: " + rssi);
|
||||||
if (!checkCorrectGattInstance(gatt, "remote rssi")) {
|
if (!checkCorrectGattInstance(gatt, "remote rssi")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.btle;
|
|||||||
import android.bluetooth.BluetoothGatt;
|
import android.bluetooth.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCallback;
|
import android.bluetooth.BluetoothGattCallback;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.bluetooth.BluetoothGattDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback interface handling gatt events.
|
* Callback interface handling gatt events.
|
||||||
@ -66,23 +67,23 @@ public interface GattCallback {
|
|||||||
void onCharacteristicChanged(BluetoothGatt gatt,
|
void onCharacteristicChanged(BluetoothGatt gatt,
|
||||||
BluetoothGattCharacteristic characteristic);
|
BluetoothGattCharacteristic characteristic);
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * @see BluetoothGattCallback#onDescriptorRead(BluetoothGatt, BluetoothGattDescriptor, int)
|
* @see BluetoothGattCallback#onDescriptorRead(BluetoothGatt, BluetoothGattDescriptor, int)
|
||||||
// * @param gatt
|
* @param gatt
|
||||||
// * @param descriptor
|
* @param descriptor
|
||||||
// * @param status
|
* @param status
|
||||||
// */
|
*/
|
||||||
// public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
||||||
// int status);
|
int status);
|
||||||
//
|
|
||||||
// /**
|
/**
|
||||||
// * @see BluetoothGattCallback#onDescriptorWrite(BluetoothGatt, BluetoothGattDescriptor, int)
|
* @see BluetoothGattCallback#onDescriptorWrite(BluetoothGatt, BluetoothGattDescriptor, int)
|
||||||
// * @param gatt
|
* @param gatt
|
||||||
// * @param descriptor
|
* @param descriptor
|
||||||
// * @param status
|
* @param status
|
||||||
// */
|
*/
|
||||||
// public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
||||||
// int status);
|
int status);
|
||||||
//
|
//
|
||||||
// /**
|
// /**
|
||||||
// * @see BluetoothGattCallback#onReliableWriteCompleted(BluetoothGatt, int)
|
// * @see BluetoothGattCallback#onReliableWriteCompleted(BluetoothGatt, int)
|
||||||
|
@ -23,6 +23,7 @@ import nodomain.freeyourgadget.gadgetbridge.miband.MiBandService;
|
|||||||
public class MiBandNotifyAction extends NotifyAction {
|
public class MiBandNotifyAction extends NotifyAction {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(TransactionBuilder.class);
|
private static final Logger LOG = LoggerFactory.getLogger(TransactionBuilder.class);
|
||||||
|
private boolean hasWrittenDescriptor = true;
|
||||||
|
|
||||||
public MiBandNotifyAction(BluetoothGattCharacteristic characteristic, boolean enable) {
|
public MiBandNotifyAction(BluetoothGattCharacteristic characteristic, boolean enable) {
|
||||||
super(characteristic, enable);
|
super(characteristic, enable);
|
||||||
@ -32,24 +33,34 @@ public class MiBandNotifyAction extends NotifyAction {
|
|||||||
public boolean run(BluetoothGatt gatt) {
|
public boolean run(BluetoothGatt gatt) {
|
||||||
boolean result = super.run(gatt);
|
boolean result = super.run(gatt);
|
||||||
if (result) {
|
if (result) {
|
||||||
BluetoothGattDescriptor sleepDescriptor = getCharacteristic().getDescriptor(MiBandService.UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION);
|
BluetoothGattDescriptor notifyDescriptor = getCharacteristic().getDescriptor(MiBandService.UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION);
|
||||||
if (sleepDescriptor != null) {
|
if (notifyDescriptor != null) {
|
||||||
int properties = getCharacteristic().getProperties();
|
int properties = getCharacteristic().getProperties();
|
||||||
if ((properties & 0x10) > 0) {
|
if ((properties & 0x10) > 0) {
|
||||||
LOG.info("properties & 0x10 > 0");
|
LOG.debug("properties & 0x10 > 0");
|
||||||
sleepDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
|
notifyDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
|
||||||
result = gatt.writeDescriptor(sleepDescriptor);
|
result = gatt.writeDescriptor(notifyDescriptor);
|
||||||
} else if ((properties & 0x20) > 0){
|
} else if ((properties & 0x20) > 0){
|
||||||
LOG.info("properties & 0x20 > 0");
|
LOG.debug("properties & 0x20 > 0");
|
||||||
sleepDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
|
notifyDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
|
||||||
result = gatt.writeDescriptor(sleepDescriptor);
|
result = gatt.writeDescriptor(notifyDescriptor);
|
||||||
|
hasWrittenDescriptor = true;
|
||||||
|
} else {
|
||||||
|
hasWrittenDescriptor = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG.warn("sleep descriptor null");
|
LOG.warn("sleep descriptor null");
|
||||||
|
hasWrittenDescriptor = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
hasWrittenDescriptor = false;
|
||||||
LOG.error("Unable to enable notification for " + getCharacteristic().getUuid());
|
LOG.error("Unable to enable notification for " + getCharacteristic().getUuid());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean expectsResult() {
|
||||||
|
return hasWrittenDescriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.miband;
|
|||||||
|
|
||||||
import android.bluetooth.BluetoothGatt;
|
import android.bluetooth.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.bluetooth.BluetoothGattDescriptor;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
|
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;
|
return builder;
|
||||||
}
|
}
|
||||||
@ -362,7 +363,6 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
@Override
|
@Override
|
||||||
public void onCharacteristicChanged(BluetoothGatt gatt,
|
public void onCharacteristicChanged(BluetoothGatt gatt,
|
||||||
BluetoothGattCharacteristic characteristic) {
|
BluetoothGattCharacteristic characteristic) {
|
||||||
LOG.info("Notification characteristic changed: " + characteristic.getUuid());
|
|
||||||
super.onCharacteristicChanged(gatt, characteristic);
|
super.onCharacteristicChanged(gatt, characteristic);
|
||||||
|
|
||||||
UUID characteristicUUID = characteristic.getUuid();
|
UUID characteristicUUID = characteristic.getUuid();
|
||||||
@ -370,6 +370,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
handleActivityData(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
|
handleActivityData(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCharacteristicRead(BluetoothGatt gatt,
|
public void onCharacteristicRead(BluetoothGatt gatt,
|
||||||
BluetoothGattCharacteristic characteristic, int status) {
|
BluetoothGattCharacteristic characteristic, int status) {
|
||||||
|
Loading…
Reference in New Issue
Block a user