enhance existing BtLE log messages

- add bonding information - `Connected to GATT server. (BOND_BONDED)`
- add read/write/etc property decoding - `characteristic: (Propr: Ultrahuman State): 86f61001-f706-58a0-95b2-1fb9261e4dc7 (read,notify)`
- decode common GATT errors encountered by InternalGattCallback and InternalGattServerCallback
This commit is contained in:
Thomas Kuehne
2025-05-01 13:35:53 +00:00
committed by José Rebelo
parent 742d5d96ab
commit 7acca2dd47
4 changed files with 91 additions and 24 deletions
@@ -325,7 +325,7 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
HashMap<UUID, BluetoothGattCharacteristic> intmAvailableCharacteristics = new HashMap<>(characteristics.size());
for (BluetoothGattCharacteristic characteristic : characteristics) {
intmAvailableCharacteristics.put(characteristic.getUuid(), characteristic);
logger.info(" characteristic: {}: {}", BleNamesResolver.resolveCharacteristicName(characteristic.getUuid().toString()), characteristic.getUuid());
logger.info(" characteristic: {}: {} ({})", BleNamesResolver.resolveCharacteristicName(characteristic.getUuid().toString()), characteristic.getUuid(), BleNamesResolver.getCharacteristicPropertyString(characteristic.getProperties()));
}
newCharacteristics.putAll(intmAvailableCharacteristics);
@@ -397,10 +397,12 @@ public abstract class AbstractBTLEMultiDeviceSupport extends AbstractDeviceSuppo
new HashMap<>(characteristics.size());
for (BluetoothGattCharacteristic characteristic : characteristics) {
intmAvailableCharacteristics.put(characteristic.getUuid(), characteristic);
logger.info(" characteristic: {}: {}",
logger.info(" characteristic: {}: {} ({})",
BleNamesResolver.resolveCharacteristicName(
characteristic.getUuid().toString()),
characteristic.getUuid());
characteristic.getUuid(),
BleNamesResolver.getCharacteristicPropertyString(
characteristic.getProperties()));
}
newCharacteristics.putAll(intmAvailableCharacteristics);
@@ -16,6 +16,9 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.btle;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.util.SparseArray;
import java.util.HashMap;
@@ -71,6 +74,76 @@ public class BleNamesResolver {
return mCharacteristics.containsKey(uuid);
}
static public String getBondStateString(int state) {
switch (state) {
case BluetoothDevice.BOND_NONE:
return "BOND_NONE";
case BluetoothDevice.BOND_BONDED:
return "BOND_BONDED";
case BluetoothDevice.BOND_BONDING:
return "BOND_BONDING";
default:
return "bond_" + state;
}
}
static public String getStatusString(int status) {
switch (status) {
case BluetoothGatt.GATT_SUCCESS:
return "SUCCESS";
case BluetoothGatt.GATT_READ_NOT_PERMITTED:
return "READ_NOT_PERMITTED";
case BluetoothGatt.GATT_WRITE_NOT_PERMITTED:
return "WRITE_NOT_PERMITTED";
case BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION:
return "INSUFFICIENT_AUTHENTICATION";
case BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED:
return "REQUEST_NOT_SUPPORTED";
case BluetoothGatt.GATT_INVALID_OFFSET:
return "INVALID_OFFSET";
case BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION:
return "INSUFFICIENT_AUTHORIZATION";
case BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH:
return "GATT_INVALID_ATTRIBUTE_LENGTH";
case BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION:
return "INSUFFICIENT_ENCRYPTION";
case BluetoothGatt.GATT_CONNECTION_CONGESTED:
return "CONNECTION_CONGESTED";
case BluetoothGatt.GATT_CONNECTION_TIMEOUT:
return "CONNECTION_TIMEOUT";
case BluetoothGatt.GATT_FAILURE:
return "FAILURE";
default:
return "failed_" + status;
}
}
static public String getCharacteristicPropertyString(int property) {
StringBuilder builder = new StringBuilder();
if (BluetoothGattCharacteristic.PROPERTY_BROADCAST == (BluetoothGattCharacteristic.PROPERTY_BROADCAST & property)) {
builder.append("broadcast,");
}
if (BluetoothGattCharacteristic.PROPERTY_READ == (BluetoothGattCharacteristic.PROPERTY_READ & property)) {
builder.append("read,");
}
if (BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE == (BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE & property)) {
builder.append("writeNoResponse,");
}
if (BluetoothGattCharacteristic.PROPERTY_WRITE == (BluetoothGattCharacteristic.PROPERTY_WRITE & property)) {
builder.append("write,");
}
if (BluetoothGattCharacteristic.PROPERTY_NOTIFY == (BluetoothGattCharacteristic.PROPERTY_NOTIFY & property)) {
builder.append("notify,");
}
if (BluetoothGattCharacteristic.PROPERTY_INDICATE == (BluetoothGattCharacteristic.PROPERTY_INDICATE & property)) {
builder.append("indicate,");
}
if (builder.length() > 0) {
builder.setLength(builder.length() - 1);
}
return builder.toString();
}
static {
// source: https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/uuids/service_uuids.yaml
mServices.put("00001801-0000-1000-8000-00805f9b34fb", "GATT");
@@ -252,7 +252,7 @@ public final class BtLEQueue {
public boolean connect() {
mPauseTransaction = false;
if (isConnected()) {
LOG.warn("Ingoring connect() because already connected.");
LOG.warn("Ignoring connect() because already connected.");
return false;
}
synchronized (mGattMonitor) {
@@ -512,7 +512,7 @@ public final class BtLEQueue {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
LOG.debug("connection state change, newState: {}{}", newState, getStatusString(status));
LOG.debug("connection state change, newState: {} {}", newState, BleNamesResolver.getStatusString(status));
synchronized (mGattMonitor) {
if (mBluetoothGatt == null) {
@@ -530,7 +530,7 @@ public final class BtLEQueue {
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
LOG.info("Connected to GATT server.");
LOG.info("Connected to GATT server. ({})", BleNamesResolver.getBondStateString(gatt.getDevice().getBondState()));
setDeviceConnectionState(State.CONNECTED);
// Attempts to discover services after successful connection.
List<BluetoothGattService> cachedServices = gatt.getServices();
@@ -563,7 +563,7 @@ public final class BtLEQueue {
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (!checkCorrectGattInstance(gatt, "services discovered: " + getStatusString(status))) {
if (!checkCorrectGattInstance(gatt, "services discovered: " + BleNamesResolver.getStatusString(status))) {
return;
}
@@ -582,7 +582,7 @@ public final class BtLEQueue {
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
LOG.debug("characteristic write: {}{}", characteristic.getUuid(), getStatusString(status));
LOG.debug("characteristic write: {} {}", characteristic.getUuid(), BleNamesResolver.getStatusString(status));
if (!checkCorrectGattInstance(gatt, "characteristic write")) {
return;
}
@@ -598,7 +598,7 @@ public final class BtLEQueue {
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
LOG.debug("mtu changed to {}{}", mtu, getStatusString(status));
LOG.debug("mtu changed to {} {}", mtu, BleNamesResolver.getStatusString(status));
if(getCallbackToUse() != null){
getCallbackToUse().onMtuChanged(gatt, mtu, status);
@@ -614,9 +614,9 @@ public final class BtLEQueue {
BluetoothGattCharacteristic characteristic,
int status) {
LOG.debug(
"characteristic read: {}{}{}",
"characteristic read: {} {} {}",
characteristic.getUuid(),
getStatusString(status),
BleNamesResolver.getStatusString(status),
status == BluetoothGatt.GATT_SUCCESS ? ": " + Logging.formatBytes(characteristic.getValue()) : ""
);
if (!checkCorrectGattInstance(gatt, "characteristic read")) {
@@ -634,7 +634,7 @@ public final class BtLEQueue {
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
LOG.debug("descriptor read: {}{}", descriptor.getUuid(), getStatusString(status));
LOG.debug("descriptor read: {} {}", descriptor.getUuid(), BleNamesResolver.getStatusString(status));
if (!checkCorrectGattInstance(gatt, "descriptor read")) {
return;
}
@@ -650,7 +650,7 @@ public final class BtLEQueue {
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
LOG.debug("descriptor write: {}{}", descriptor.getUuid(), getStatusString(status));
LOG.debug("descriptor write: {} {}", descriptor.getUuid(), BleNamesResolver.getStatusString(status));
if (!checkCorrectGattInstance(gatt, "descriptor write")) {
return;
}
@@ -687,7 +687,7 @@ public final class BtLEQueue {
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
LOG.debug("remote rssi: {}{}", rssi, getStatusString(status));
LOG.debug("remote rssi: {} {}", rssi, BleNamesResolver.getStatusString(status));
if (!checkCorrectGattInstance(gatt, "remote rssi")) {
return;
}
@@ -703,7 +703,7 @@ public final class BtLEQueue {
private void checkWaitingCharacteristic(BluetoothGattCharacteristic characteristic, int status) {
if (status != BluetoothGatt.GATT_SUCCESS) {
if (characteristic != null) {
LOG.debug("failed btle action, aborting transaction: {}{}", characteristic.getUuid(), getStatusString(status));
LOG.debug("failed btle action, aborting transaction: {} {}", characteristic.getUuid(), BleNamesResolver.getStatusString(status));
}
mAbortTransaction = true;
}
@@ -721,10 +721,6 @@ public final class BtLEQueue {
}
}
private String getStatusString(int status) {
return status == BluetoothGatt.GATT_SUCCESS ? " (success)" : " (failed: " + status + ")";
}
public void reset() {
if (LOG.isDebugEnabled()) {
LOG.debug("internal gatt callback set to null");
@@ -758,7 +754,7 @@ public final class BtLEQueue {
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
LOG.debug("gatt server connection state change, newState: {}{}", newState, getStatusString(status));
LOG.debug("gatt server connection state change, newState: {} {}", newState, BleNamesResolver.getStatusString(status));
if(!checkCorrectBluetoothDevice(device)) {
return;
@@ -769,10 +765,6 @@ public final class BtLEQueue {
}
}
private String getStatusString(int status) {
return status == BluetoothGatt.GATT_SUCCESS ? " (success)" : " (failed: " + status + ")";
}
@Override
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
if(!checkCorrectBluetoothDevice(device)) {