diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothDebug.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothDebug.java index f5bdd0d7..1efdfb2c 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothDebug.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothDebug.java @@ -88,14 +88,14 @@ public class BluetoothDebug extends BluetoothCommunication { } private void logService(BluetoothGattService service, boolean included) { - Timber.d("Service %s%s", service.getUuid(), included ? " (included)" : ""); + Timber.d("Service %s%s", BluetoothGattUuid.prettyPrint(service.getUuid()), + included ? " (included)" : ""); for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) { Timber.d("|- characteristic %s (instance %d): %s, write type: %s (permissions=0x%x)", - characteristic.getUuid(), characteristic.getInstanceId(), - propertiesToString(characteristic.getProperties()), - writeTypeToString(characteristic.getWriteType()), - characteristic.getPermissions()); + BluetoothGattUuid.prettyPrint(characteristic.getUuid()), + characteristic.getInstanceId(), propertiesToString(characteristic.getProperties()), + writeTypeToString(characteristic.getWriteType()), characteristic.getPermissions()); byte[] value = characteristic.getValue(); if (value != null && value.length > 0) { Timber.d("|--> value: %s (%s)", byteInHex(value), @@ -104,7 +104,8 @@ public class BluetoothDebug extends BluetoothCommunication { for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) { Timber.d("|--- descriptor %s (permissions=0x%x)", - descriptor.getUuid(), descriptor.getPermissions()); + BluetoothGattUuid.prettyPrint(descriptor.getUuid()), + descriptor.getPermissions()); value = descriptor.getValue(); if (value != null && value.length > 0) { diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothGattUuid.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothGattUuid.java new file mode 100644 index 00000000..d5af508f --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothGattUuid.java @@ -0,0 +1,83 @@ +/* Copyright (C) 2018 Erik Johansson + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +package com.health.openscale.core.bluetooth; + +import java.lang.reflect.Field; +import java.util.UUID; + +public class BluetoothGattUuid { + private static final String STANDARD_SUFFIX = "-0000-1000-8000-00805f9b34fb"; + + public static final UUID fromShortCode(long code) { + return UUID.fromString(String.format("%08x%s", code, STANDARD_SUFFIX)); + } + + public static final String prettyPrint(UUID uuid) { + for (Field field : BluetoothGattUuid.class.getFields()) { + try { + if (uuid.equals(field.get(null))) { + final String name = field.getName(); + return name.substring(name.indexOf('_') + 1); + } + } + catch (IllegalAccessException e) { + // Ignore + } + } + + final String str = uuid.toString(); + if (str.endsWith(STANDARD_SUFFIX)) { + String code = str.substring(0, str.length() - STANDARD_SUFFIX.length()); + if (code.startsWith("0000")) { + code = code.substring(4); + } + return "0x" + code; + } + + return str; + } + + // https://www.bluetooth.com/specifications/gatt/services + public static final UUID SERVICE_BODY_COMPOSITION = fromShortCode(0x181b); + public static final UUID SERVICE_DEVICE_INFORMATION = fromShortCode(0x180a); + public static final UUID SERVICE_GENERIC_ACCESS = fromShortCode(0x1800); + public static final UUID SERVICE_GENERIC_ATTRIBUTE = fromShortCode(0x1801); + public static final UUID SERVICE_WEIGHT_SCALE = fromShortCode(0x181d); + + // https://www.bluetooth.com/specifications/gatt/characteristics + public static final UUID CHARACTERISTIC_APPEARANCE = fromShortCode(0x2a01); + public static final UUID CHARACTERISTIC_BODY_COMPOSITION_MEASUREMENT = fromShortCode(0x2a9c); + public static final UUID CHARACTERISTIC_CURRENT_TIME = fromShortCode(0x2a2b); + public static final UUID CHARACTERISTIC_DEVICE_NAME = fromShortCode(0x2a00); + public static final UUID CHARACTERISTIC_FIRMWARE_REVISION_STRING = fromShortCode(0x2a26); + public static final UUID CHARACTERISTIC_HARDWARE_REVISION_STRING = fromShortCode(0x2a27); + public static final UUID CHARACTERISTIC_MANUFACTURER_NAME_STRING = fromShortCode(0x2a29); + public static final UUID CHARACTERISTIC_MODEL_NUMBER_STRING = fromShortCode(0x2a24); + public static final UUID CHARACTERISTIC_PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS = fromShortCode(0x2a04); + public static final UUID CHARACTERISTIC_PERIPHERAL_PRIVACY_FLAG = fromShortCode(0x2a02); + public static final UUID CHARACTERISTIC_PNP_ID = fromShortCode(0x2a50); + public static final UUID CHARACTERISTIC_RECONNECTION_ADDRESS = fromShortCode(0x2a03); + public static final UUID CHARACTERISTIC_SERIAL_NUMBER_STRING = fromShortCode(0x2a25); + public static final UUID CHARACTERISTIC_SERVICE_CHANGED = fromShortCode(0x2a05); + public static final UUID CHARACTERISTIC_SOFTWARE_REVISION_STRING = fromShortCode(0x2a28); + public static final UUID CHARACTERISTIC_SYSTEM_ID = fromShortCode(0x2a23); + public static final UUID CHARACTERISTIC_WEIGHT_MEASUREMENT = fromShortCode(0x2a9d); + + // https://www.bluetooth.com/specifications/gatt/descriptors + public static final UUID DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION = fromShortCode(0x2902); + public static final UUID DESCRIPTOR_CHARACTERISTIC_USER_DESCRIPTION = fromShortCode(0x2901); +} diff --git a/android_app/app/src/test/java/com/health/openscale/BluetoothGattUuidTest.java b/android_app/app/src/test/java/com/health/openscale/BluetoothGattUuidTest.java new file mode 100644 index 00000000..fc58176d --- /dev/null +++ b/android_app/app/src/test/java/com/health/openscale/BluetoothGattUuidTest.java @@ -0,0 +1,47 @@ +/* Copyright (C) 2018 Erik Johansson + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +package com.health.openscale; + +import com.health.openscale.core.bluetooth.BluetoothGattUuid; + +import org.junit.Test; + +import java.util.UUID; + +import static junit.framework.Assert.assertEquals; + +public class BluetoothGattUuidTest { + + @Test + public void prettyPrint() throws Exception { + assertEquals("GENERIC_ACCESS", + BluetoothGattUuid.prettyPrint(BluetoothGattUuid.SERVICE_GENERIC_ACCESS)); + assertEquals("CURRENT_TIME", + BluetoothGattUuid.prettyPrint(BluetoothGattUuid.CHARACTERISTIC_CURRENT_TIME)); + assertEquals("CLIENT_CHARACTERISTIC_CONFIGURATION", + BluetoothGattUuid.prettyPrint(BluetoothGattUuid.DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION)); + assertEquals("GENERIC_ATTRIBUTE", + BluetoothGattUuid.prettyPrint(BluetoothGattUuid.fromShortCode(0x1801))); + assertEquals("0x0001", + BluetoothGattUuid.prettyPrint(BluetoothGattUuid.fromShortCode(0x1))); + assertEquals("0x00010000", + BluetoothGattUuid.prettyPrint(BluetoothGattUuid.fromShortCode(0x10000))); + + final UUID uuid = UUID.randomUUID(); + assertEquals(uuid.toString(), BluetoothGattUuid.prettyPrint(uuid)); + } +}