1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-07-07 22:22:00 +02:00

Some BTLE cleanup:

- the BASE_UUID is shared between all BTLE devices, not miband specific. So are the UUID DESCRIPTORS. Hence these have been moved to AbstractBTLEDeviceSupport
- the gatt-characteristic-property-constants used previously in MiBandNotifyAction are also general, and exposed by the gatt subsystem, hence the specific action has been dropped moving the logic to the NotifyAction class
 - the logic for checking the gatt-characteristic-property-constants has been extended also to the ReadAction and WriteAction class, this way we won't try to read (or write)  a characteristic that isn't readable (or writeable)
This commit is contained in:
Daniele Gobbetti 2015-08-07 16:59:52 +02:00
parent 6125594703
commit fe11e6d306
7 changed files with 50 additions and 77 deletions

View File

@ -1,64 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.NotifyAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
/**
* Enables or disables notifications for a given GATT characteristic.
* The result will be made available asynchronously through the
* {@link BluetoothGattCallback}.
* <p/>
* This class is Mi Band specific.
*/
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);
}
@Override
public boolean run(BluetoothGatt gatt) {
boolean result = super.run(gatt);
if (result) {
BluetoothGattDescriptor notifyDescriptor = getCharacteristic().getDescriptor(MiBandService.UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION);
if (notifyDescriptor != null) {
int properties = getCharacteristic().getProperties();
if ((properties & 0x10) > 0) {
LOG.debug("use NOTIFICATION");
notifyDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
result = gatt.writeDescriptor(notifyDescriptor);
} else if ((properties & 0x20) > 0) {
LOG.debug("use INDICATION");
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

@ -4,13 +4,13 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import static nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport.BASE_UUID;
public class MiBandService {
public static final String MAC_ADDRESS_FILTER = "88:0F:10";
public static final String BASE_UUID = "0000%s-0000-1000-8000-00805f9b34fb";
public static final UUID UUID_SERVICE_MIBAND_SERVICE = UUID.fromString(String.format(BASE_UUID, "FEE0"));
public static final UUID UUID_CHARACTERISTIC_DEVICE_INFO = UUID.fromString(String.format(BASE_UUID, "FF01"));
@ -53,10 +53,6 @@ public class MiBandService {
public static final String UUID_SERVICE_WEIGHT_SERVICE = "00001530-0000-3512-2118-0009af100700";
public static final UUID UUID_DESCRIPTOR_CHARACTERISTIC_USER_CONFIGURATION = UUID.fromString(String.format(BASE_UUID, "2901"));
public static final UUID UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION = UUID.fromString(String.format(BASE_UUID, "2902"));
public static final byte ALIAS_LEN = 0xa;
/*NOTIFICATIONS: usually received on the UUID_CHARACTERISTIC_NOTIFICATION characteristic */

View File

@ -17,6 +17,6 @@ public class MiBandTransactionBuilder extends TransactionBuilder {
@Override
protected NotifyAction createNotifyAction(BluetoothGattCharacteristic characteristic, boolean enable) {
return new MiBandNotifyAction(characteristic, enable);
return new NotifyAction(characteristic, enable);
}
}

View File

@ -20,7 +20,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport;
/**
* Abstract base class for all devices connected through Bluetooth Low Energy (LE) aka
* Bluetooth Smart.
*
* <p/>
* The connection to the device and all communication is made with a generic {@link BtLEQueue}.
* Messages to the device are encoded as {@link BtLEAction actions} that are grouped with a
* {@link Transaction} and sent via {@link BtLEQueue}.
@ -35,6 +35,11 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
private HashMap<UUID, BluetoothGattCharacteristic> mAvailableCharacteristics;
private Set<UUID> mSupportedServices = new HashSet<>(4);
public static final String BASE_UUID = "0000%s-0000-1000-8000-00805f9b34fb"; //this is common for all BTLE devices. see http://stackoverflow.com/questions/18699251/finding-out-android-bluetooth-le-gatt-profiles
public static final UUID UUID_DESCRIPTOR_CHARACTERISTIC_USER_CONFIGURATION = UUID.fromString(String.format(BASE_UUID, "2901"));
public static final UUID UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION = UUID.fromString(String.format(BASE_UUID, "2902"));
@Override
public boolean connect() {
if (mQueue == null) {

View File

@ -3,6 +3,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle.actions;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -10,6 +11,8 @@ import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import static nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport.UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION;
/**
* Enables or disables notifications for a given GATT characteristic.
* The result will be made available asynchronously through the
@ -19,6 +22,7 @@ public class NotifyAction extends BtLEAction {
private static final Logger LOG = LoggerFactory.getLogger(TransactionBuilder.class);
protected final boolean enableFlag;
private boolean hasWrittenDescriptor = true;
public NotifyAction(BluetoothGattCharacteristic characteristic, boolean enable) {
super(characteristic);
@ -27,11 +31,36 @@ public class NotifyAction extends BtLEAction {
@Override
public boolean run(BluetoothGatt gatt) {
return gatt.setCharacteristicNotification(getCharacteristic(), enableFlag);
boolean result = gatt.setCharacteristicNotification(getCharacteristic(), enableFlag);
if (result) {
BluetoothGattDescriptor notifyDescriptor = getCharacteristic().getDescriptor(UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION);
if (notifyDescriptor != null) {
int properties = getCharacteristic().getProperties();
if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
LOG.debug("use NOTIFICATION");
notifyDescriptor.setValue(enableFlag ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
result = gatt.writeDescriptor(notifyDescriptor);
} else if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0) {
LOG.debug("use INDICATION");
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 false;
return hasWrittenDescriptor;
}
}

View File

@ -19,7 +19,11 @@ public class ReadAction extends BtLEAction {
@Override
public boolean run(BluetoothGatt gatt) {
return gatt.readCharacteristic(getCharacteristic());
int properties = getCharacteristic().getProperties();
if ((properties & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
return gatt.readCharacteristic(getCharacteristic());
}
return false;
}
@Override

View File

@ -22,8 +22,11 @@ public class WriteAction extends BtLEAction {
@Override
public boolean run(BluetoothGatt gatt) {
if (getCharacteristic().setValue(value)) {
return gatt.writeCharacteristic(getCharacteristic());
int properties = getCharacteristic().getProperties();
if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
if (getCharacteristic().setValue(value)) {
return gatt.writeCharacteristic(getCharacteristic());
}
}
return false;
}