GattCallback: memory safe onCharacteristicChanged and onCharacteristicRead

Change the method signatures of GattCallback.onCharacteristicChanged and GattCallback.onCharacteristicRead to be memory safe. See Android 13 (Tiramisu, API 33) documentation for background.

To be memory safe onCharacteristicChanged and onCharacteristicRead should always evaluate the `value` parameter, potential in combination with BLETypeConversions, and not use:
- BluetoothGattCharacteristic.getValue
- BluetoothGattCharacteristic.getIntValue
- BluetoothGattCharacteristic.getFloatValue
- BluetoothGattCharacteristic.getStringValue
This commit is contained in:
Thomas Kuehne
2025-05-10 15:36:14 +00:00
committed by José Rebelo
parent 92318edb7d
commit 488c789e15
122 changed files with 601 additions and 569 deletions
@@ -79,12 +79,13 @@ public class SMAQ2OSSSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
BluetoothGattCharacteristic characteristic,
byte[] value) {
super.onCharacteristicChanged(gatt, characteristic, value);
UUID characteristicUUID = characteristic.getUuid();
if (SMAQ2OSSConstants.UUID_CHARACTERISTIC_NOTIFY_NORMAL.equals(characteristicUUID)) {
handleDeviceEvent(characteristic.getValue());
handleDeviceEvent(value);
}
return true;
}
@@ -377,13 +377,14 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
if(bleApi != null && status == BluetoothGatt.GATT_SUCCESS) {
bleApi.onCharacteristicChanged(characteristic);
bleApi.onCharacteristicChanged(characteristic, value);
}
for (AbstractBleProfile<?> profile : mSupportedProfiles) {
if (profile.onCharacteristicRead(gatt, characteristic, status)) {
if (profile.onCharacteristicRead(gatt, characteristic, value, status)) {
return true;
}
}
@@ -423,13 +424,13 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic, byte[] value) {
if(bleApi != null) {
bleApi.onCharacteristicChanged(characteristic);
bleApi.onCharacteristicChanged(characteristic, value);
}
for (AbstractBleProfile<?> profile : mSupportedProfiles) {
if (profile.onCharacteristicChanged(gatt, characteristic)) {
if (profile.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
}
@@ -460,15 +460,16 @@ public abstract class AbstractBTLEMultiDeviceSupport extends AbstractDeviceSuppo
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
int deviceIdx = getDeviceIndexForAddress(gatt.getDevice().getAddress());
if (bleApis[deviceIdx] != null) {
bleApis[deviceIdx].onCharacteristicChanged(characteristic);
bleApis[deviceIdx].onCharacteristicChanged(characteristic, value);
}
for (AbstractBleProfile<?> profile : mSupportedProfiles) {
if (profile.onCharacteristicRead(gatt, characteristic, status)) {
if (profile.onCharacteristicRead(gatt, characteristic, value, status)) {
return true;
}
}
@@ -510,14 +511,14 @@ public abstract class AbstractBTLEMultiDeviceSupport extends AbstractDeviceSuppo
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic, byte[] value) {
int deviceIdx = getDeviceIndexForAddress(gatt.getDevice().getAddress());
if (bleApis[deviceIdx] != null) {
bleApis[deviceIdx].onCharacteristicChanged(characteristic);
bleApis[deviceIdx].onCharacteristicChanged(characteristic, value);
}
for (AbstractBleProfile<?> profile : mSupportedProfiles) {
if (profile.onCharacteristicChanged(gatt, characteristic)) {
if (profile.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
}
@@ -182,8 +182,8 @@ public abstract class AbstractBTLEOperation<T extends AbstractBTLEDeviceSupport>
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
return mSupport.onCharacteristicRead(gatt, characteristic, status);
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value, int status) {
return mSupport.onCharacteristicRead(gatt, characteristic, value, status);
}
@Override
@@ -192,8 +192,8 @@ public abstract class AbstractBTLEOperation<T extends AbstractBTLEDeviceSupport>
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
return mSupport.onCharacteristicChanged(gatt, characteristic);
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
return mSupport.onCharacteristicChanged(gatt, characteristic, value);
}
@Override
@@ -33,7 +33,7 @@ public abstract class AbstractGattCallback implements GattCallback {
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value, int status) {
return false;
}
@@ -43,7 +43,7 @@ public abstract class AbstractGattCallback implements GattCallback {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
return false;
}
@@ -419,4 +419,24 @@ public class BLETypeConversions {
}
return AlertCategory.Simple;
}
/// compatible with {@link android.bluetooth.BluetoothGattCharacteristic#getFloatValue(int, int)}
public static float toFloat32(byte[] bytes, int offset){
int raw = toUint32(bytes, offset);
return Float.intBitsToFloat(raw);
}
/// compatible with {@link android.bluetooth.BluetoothGattCharacteristic#getStringValue(int)}
public static String getStringValue(final byte[] bytes, final int offset) {
if (bytes == null || offset > bytes.length) {
return null;
}
final byte[] str = new byte[bytes.length - offset];
for (int i = 0; i < (bytes.length - offset); i++) {
str[i] = bytes[offset + i];
}
//noinspection ImplicitDefaultCharsetUsage
return new String(str);
}
}
@@ -123,7 +123,7 @@ public class BleIntentApi {
return intentApiEnabledReadWrite | intentApiEnabledNotifications | intentApiEnabledDeviceState;
}
public void onCharacteristicChanged(BluetoothGattCharacteristic characteristic) {
public void onCharacteristicChanged(BluetoothGattCharacteristic characteristic, byte[] value) {
if(!intentApiEnabledNotifications) {
return;
}
@@ -135,7 +135,7 @@ public class BleIntentApi {
intent.setPackage(intentApiPackage);
}
intent.putExtra("EXTRA_CHARACTERISTIC", characteristic.getUuid().toString());
intent.putExtra("EXTRA_PAYLOAD", StringUtils.bytesToHex(characteristic.getValue()));
intent.putExtra("EXTRA_PAYLOAD", StringUtils.bytesToHex(value));
getContext().sendBroadcast(intent);
}
@@ -1,6 +1,6 @@
/* Copyright (C) 2015-2024 Andreas Böhler, Andreas Shimokawa, Carsten
/* Copyright (C) 2015-2025 Andreas Böhler, Andreas Shimokawa, Carsten
Pfeiffer, Cre3per, Daniel Dakhno, Daniele Gobbetti, Gordon Williams, José
Rebelo, Sergey Trofimov, Taavi Eomäe, Uwe Hermann, Yoran Vulker
Rebelo, Sergey Trofimov, Taavi Eomäe, Uwe Hermann, Yoran Vulker, Thomas Kuehne
This file is part of Gadgetbridge.
@@ -34,6 +34,7 @@ import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
@@ -60,6 +61,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction;
@SuppressLint("MissingPermission") // if we're using this, we have bluetooth permissions
public final class BtLEQueue {
private static final Logger LOG = LoggerFactory.getLogger(BtLEQueue.class);
private static final byte[] EMPTY = new byte[0];
private final Object mGattMonitor = new Object();
private final GBDevice mGbDevice;
@@ -123,7 +125,7 @@ public final class BtLEQueue {
break;
}
if (LOG.isDebugEnabled()) {
LOG.debug("About to run server action: " + action);
LOG.debug("About to run server action: {}", action);
}
if (action.run(mBluetoothGattServer)) {
// check again, maybe due to some condition, action did not need to write, so we can't wait
@@ -160,14 +162,14 @@ public final class BtLEQueue {
try {
Thread.sleep(100);
} catch (Exception e) {
LOG.info("Exception during pause: {}", e);
LOG.info("Exception during pause", e);
break;
}
}
mWaitCharacteristic = action.getCharacteristic();
mWaitForActionResultLatch = new CountDownLatch(1);
if (LOG.isDebugEnabled()) {
LOG.debug("About to run action: " + action);
LOG.debug("About to run action: {}", action);
}
if (action instanceof GattListenerAction) {
// this special action overwrites the transaction gatt listener (if any), it must
@@ -259,7 +261,7 @@ public final class BtLEQueue {
if (mBluetoothGatt != null) {
// Tribal knowledge says you're better off not reusing existing BluetoothGatt connections,
// so create a new one.
LOG.info("connect() requested -- disconnecting previous connection: " + mGbDevice.getName());
LOG.info("connect() requested -- disconnecting previous connection: {}", mGbDevice.getName());
disconnect();
}
}
@@ -613,18 +615,26 @@ public final class BtLEQueue {
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
byte[] value = emulateMemorySafeValue(characteristic, status);
onCharacteristicRead(gatt, characteristic, value, status);
}
@Override
public void onCharacteristicRead(@NonNull BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
@NonNull byte[] value, int status) {
LOG.debug(
"characteristic read: {} {} {}",
characteristic.getUuid(),
BleNamesResolver.getStatusString(status),
status == BluetoothGatt.GATT_SUCCESS ? ": " + Logging.formatBytes(characteristic.getValue()) : ""
status == BluetoothGatt.GATT_SUCCESS ? ": " + Logging.formatBytes(value) : ""
);
if (!checkCorrectGattInstance(gatt, "characteristic read")) {
return;
}
if (getCallbackToUse() != null) {
try {
getCallbackToUse().onCharacteristicRead(gatt, characteristic, status);
getCallbackToUse().onCharacteristicRead(gatt, characteristic, value, status);
} catch (Throwable ex) {
LOG.error("onCharacteristicRead: {}", ex.getMessage(), ex);
}
@@ -667,8 +677,16 @@ public final class BtLEQueue {
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
byte[] value = emulateMemorySafeValue(characteristic, BluetoothGatt.GATT_SUCCESS);
onCharacteristicChanged(gatt, characteristic, value);
}
@Override
public void onCharacteristicChanged(@NonNull BluetoothGatt gatt,
@NonNull BluetoothGattCharacteristic characteristic,
@NonNull byte[] value) {
if (LOG.isDebugEnabled()) {
String content = Logging.formatBytes(characteristic.getValue());
String content = Logging.formatBytes(value);
LOG.debug("characteristic changed: {} value: {}", characteristic.getUuid(), content);
}
if (!checkCorrectGattInstance(gatt, "characteristic changed")) {
@@ -676,7 +694,7 @@ public final class BtLEQueue {
}
if (getCallbackToUse() != null) {
try {
getCallbackToUse().onCharacteristicChanged(gatt, characteristic);
getCallbackToUse().onCharacteristicChanged(gatt, characteristic, value);
} catch (Throwable ex) {
LOG.error("onCharacteristicChanged failed", ex);
}
@@ -727,6 +745,18 @@ public final class BtLEQueue {
}
mTransactionGattCallback = null;
}
/// helper to emulate Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU on older APIs
private byte[] emulateMemorySafeValue(BluetoothGattCharacteristic characteristic,
int status){
if(status == BluetoothGatt.GATT_SUCCESS) {
byte[] value = characteristic.getValue();
if (value != null) {
return value.clone();
}
}
return EMPTY;
}
}
// Implements callback methods for GATT server events that the app cares about. For example,
@@ -28,7 +28,7 @@ import android.bluetooth.BluetoothGattDescriptor;
*
* Note: the boolean return values indicate whether this callback "consumed" this event
* or not. True means, the event was consumed by this instance and no further instances
* shall be notified. Fallse means, this instance could not handle the event.
* shall be notified. False means, this instance could not handle the event.
*/
public interface GattCallback {
@@ -49,10 +49,12 @@ public interface GattCallback {
/**
* @param gatt
* @param characteristic
* @param value
* @param status
* @see BluetoothGattCallback#onCharacteristicRead(BluetoothGatt, BluetoothGattCharacteristic, int)
* @see BluetoothGattCallback#onCharacteristicRead(BluetoothGatt, BluetoothGattCharacteristic, byte[], int)
*/
boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status);
boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
byte[] value, int status);
/**
* @param gatt
@@ -66,10 +68,11 @@ public interface GattCallback {
/**
* @param gatt
* @param characteristic
* @see BluetoothGattCallback#onCharacteristicChanged(BluetoothGatt, BluetoothGattCharacteristic)
* @param value
* @see BluetoothGattCallback#onCharacteristicChanged(BluetoothGatt, BluetoothGattCharacteristic, byte[])
*/
boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic);
BluetoothGattCharacteristic characteristic, byte[] value);
/**
* @param gatt
@@ -39,11 +39,11 @@ public abstract class AbstractGattListenerWriteAction extends WriteAction implem
public GattCallback getGattCallback() {
return new AbstractGattCallback() {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
return AbstractGattListenerWriteAction.this.onCharacteristicChanged(gatt, characteristic);
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
return AbstractGattListenerWriteAction.this.onCharacteristicChanged(gatt, characteristic, value);
}
};
}
protected abstract boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic);
protected abstract boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value);
}
@@ -21,17 +21,18 @@ import android.bluetooth.BluetoothGattCharacteristic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
public class ValueDecoder {
private static final Logger LOG = LoggerFactory.getLogger(ValueDecoder.class);
public static int decodeInt(BluetoothGattCharacteristic characteristic) {
return characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
public static int decodeInt(BluetoothGattCharacteristic characteristic, byte[] value) {
return BLETypeConversions.toUnsigned(value, 0);
}
public static int decodePercent(BluetoothGattCharacteristic characteristic) {
int percent = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
public static int decodePercent(BluetoothGattCharacteristic characteristic, byte[] value) {
int percent = BLETypeConversions.toUnsigned(value, 0);
if (percent > 100 || percent < 0) {
LOG.warn("Unexpected percent value: " + percent + ": " + GattCharacteristic.toString(characteristic));
percent = Math.min(100, Math.max(0, percent));
@@ -59,11 +59,11 @@ public class BatteryInfoProfile<T extends AbstractBTLEDeviceSupport> extends Abs
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
UUID charUuid = characteristic.getUuid();
if (charUuid.equals(UUID_CHARACTERISTIC_BATTERY_LEVEL)) {
handleBatteryLevel(gatt, characteristic);
handleBatteryLevel(gatt, characteristic, value);
return true;
} else {
LOG.info("Unexpected onCharacteristicRead: " + GattCharacteristic.toString(characteristic));
@@ -75,12 +75,12 @@ public class BatteryInfoProfile<T extends AbstractBTLEDeviceSupport> extends Abs
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
return onCharacteristicRead(gatt, characteristic, BluetoothGatt.GATT_SUCCESS);
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
return onCharacteristicRead(gatt, characteristic, value, BluetoothGatt.GATT_SUCCESS);
}
private void handleBatteryLevel(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
int percent = ValueDecoder.decodePercent(characteristic);
private void handleBatteryLevel(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
int percent = ValueDecoder.decodePercent(characteristic, value);
batteryInfo.setPercentCharged(percent);
notify(createIntent(batteryInfo));
@@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
@@ -69,36 +70,36 @@ public class DeviceInfoProfile<T extends AbstractBTLEDeviceSupport> extends Abst
}
@Override
public boolean onCharacteristicRead(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) {
public boolean onCharacteristicRead(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final byte[] value, final int status) {
final UUID charUuid = characteristic.getUuid();
if (status == BluetoothGatt.GATT_SUCCESS) {
if (charUuid.equals(UUID_CHARACTERISTIC_MANUFACTURER_NAME_STRING)) {
handleManufacturerName(characteristic);
handleManufacturerName(value);
return true;
} else if (charUuid.equals(UUID_CHARACTERISTIC_MODEL_NUMBER_STRING)) {
handleModelNumber(characteristic);
handleModelNumber(value);
return true;
} else if (charUuid.equals(UUID_CHARACTERISTIC_SERIAL_NUMBER_STRING)) {
handleSerialNumber(characteristic);
handleSerialNumber(value);
return true;
} else if (charUuid.equals(UUID_CHARACTERISTIC_HARDWARE_REVISION_STRING)) {
handleHardwareRevision(characteristic);
handleHardwareRevision(value);
return true;
} else if (charUuid.equals(UUID_CHARACTERISTIC_FIRMWARE_REVISION_STRING)) {
handleFirmwareRevision(characteristic);
handleFirmwareRevision(value);
return true;
} else if (charUuid.equals(UUID_CHARACTERISTIC_SOFTWARE_REVISION_STRING)) {
handleSoftwareRevision(characteristic);
handleSoftwareRevision(value);
return true;
} else if (charUuid.equals(UUID_CHARACTERISTIC_SYSTEM_ID)) {
handleSystemId(characteristic);
handleSystemId(value);
return true;
} else if (charUuid.equals(UUID_CHARACTERISTIC_IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST)) {
handleRegulatoryCertificationData(characteristic);
handleRegulatoryCertificationData(value);
return true;
} else if (charUuid.equals(UUID_CHARACTERISTIC_PNP_ID)) {
handlePnpId(characteristic);
handlePnpId(value);
return true;
}
} else {
@@ -117,57 +118,56 @@ public class DeviceInfoProfile<T extends AbstractBTLEDeviceSupport> extends Abst
return false;
}
private void handleManufacturerName(final BluetoothGattCharacteristic characteristic) {
String name = characteristic.getStringValue(0).trim();
private void handleManufacturerName(final byte[] value) {
String name = BLETypeConversions.getStringValue(value, 0).trim();
deviceInfo.setManufacturerName(name);
notify(createIntent(deviceInfo));
}
private void handleModelNumber(final BluetoothGattCharacteristic characteristic) {
String modelNumber = characteristic.getStringValue(0).trim();
private void handleModelNumber(final byte[] value) {
String modelNumber = BLETypeConversions.getStringValue(value, 0).trim();
deviceInfo.setModelNumber(modelNumber);
notify(createIntent(deviceInfo));
}
private void handleSerialNumber(final BluetoothGattCharacteristic characteristic) {
String serialNumber = characteristic.getStringValue(0).trim();
private void handleSerialNumber(final byte[] value) {
String serialNumber = BLETypeConversions.getStringValue(value, 0).trim();
deviceInfo.setSerialNumber(serialNumber);
notify(createIntent(deviceInfo));
}
private void handleHardwareRevision(final BluetoothGattCharacteristic characteristic) {
String hardwareRevision = characteristic.getStringValue(0).trim();
private void handleHardwareRevision(final byte[] value) {
String hardwareRevision = BLETypeConversions.getStringValue(value, 0).trim();
deviceInfo.setHardwareRevision(hardwareRevision);
notify(createIntent(deviceInfo));
}
private void handleFirmwareRevision(final BluetoothGattCharacteristic characteristic) {
String firmwareRevision = characteristic.getStringValue(0).trim();
private void handleFirmwareRevision(final byte[] value) {
String firmwareRevision = BLETypeConversions.getStringValue(value, 0).trim();
deviceInfo.setFirmwareRevision(firmwareRevision);
notify(createIntent(deviceInfo));
}
private void handleSoftwareRevision(final BluetoothGattCharacteristic characteristic) {
String softwareRevision = characteristic.getStringValue(0).trim();
private void handleSoftwareRevision(final byte[] value) {
String softwareRevision = BLETypeConversions.getStringValue(value, 0).trim();
deviceInfo.setSoftwareRevision(softwareRevision);
notify(createIntent(deviceInfo));
}
private void handleSystemId(final BluetoothGattCharacteristic characteristic) {
String systemId = characteristic.getStringValue(0).trim();
private void handleSystemId(final byte[] value) {
String systemId = BLETypeConversions.getStringValue(value, 0).trim();
deviceInfo.setSystemId(systemId);
notify(createIntent(deviceInfo));
}
private void handleRegulatoryCertificationData(final BluetoothGattCharacteristic characteristic) {
private void handleRegulatoryCertificationData(final byte[] value) {
// TODO: regulatory certification data list not supported yet
// String regulatoryCertificationData = characteristic.getStringValue(0).trim();
// deviceInfo.setRegulatoryCertificationDataList(regulatoryCertificationData);
// notify(createIntent(deviceInfo));
}
private void handlePnpId(final BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
private void handlePnpId(final byte[] value) {
if (value.length == 7) {
// int vendorSource
//
@@ -29,6 +29,7 @@ import java.util.GregorianCalendar;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
@@ -71,14 +72,14 @@ public class HealthThermometerProfile <T extends AbstractBTLEDeviceSupport> exte
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
UUID charUuid = characteristic.getUuid();
if (charUuid.equals(UUID_CHARACTERISTIC_MEASUREMENT_INTERVAL)) {
handleMeasurementInterval(gatt, characteristic);
handleMeasurementInterval(gatt, characteristic, value);
return true;
} else if (charUuid.equals(UUID_CHARACTERISTIC_TEMPERATURE_MEASUREMENT)) {
handleTemperatureMeasurement(gatt, characteristic);
handleTemperatureMeasurement(gatt, characteristic, value);
return true;
} else {
LOG.info("Unexpected onCharacteristicRead: " + GattCharacteristic.toString(characteristic));
@@ -90,39 +91,39 @@ public class HealthThermometerProfile <T extends AbstractBTLEDeviceSupport> exte
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
return onCharacteristicRead(gatt, characteristic, BluetoothGatt.GATT_SUCCESS);
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
return onCharacteristicRead(gatt, characteristic, value, BluetoothGatt.GATT_SUCCESS);
}
private void handleMeasurementInterval(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
private void handleMeasurementInterval(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
// todo: not implemented
LOG.debug("Health thermometer received Measurement Interval: " + ValueDecoder.decodeInt(characteristic));
LOG.debug("Health thermometer received Measurement Interval: " + ValueDecoder.decodeInt(characteristic, value));
}
private void handleTemperatureMeasurement(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
private void handleTemperatureMeasurement(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] raw) {
/*
* This metadata contains as bits:
* the unit (celsius (0) or fahrenheit (1)) (bit 7 (last bit))
* if a timestamp is present (1) or not present (0) (bit 6)
* if a temperature type is present (1) or not present (0) (bit 5)
*/
byte metadata = characteristic.getValue()[0];
byte metadata = raw[0];
// todo: evaluate this byte to enable support for devices without timestamp or temperature-type
int year = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 5);
int month = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 7);
int day = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 8);
int hour = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 9);
int minute = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 10);
int second = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 11);
int year = BLETypeConversions.toUint16(raw, 5);
int month = BLETypeConversions.toUnsigned(raw, 7);
int day = BLETypeConversions.toUnsigned(raw, 8);
int hour = BLETypeConversions.toUnsigned(raw, 9);
int minute = BLETypeConversions.toUnsigned(raw, 10);
int second = BLETypeConversions.toUnsigned(raw, 11);
Calendar c = GregorianCalendar.getInstance();
c.set(year, month - 1, day, hour, minute, second);
Date date = c.getTime();
float temperature = characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_FLOAT, 1); // bytes 1 - 4
int temperature_type = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 12); // encodes where the measurement was taken
float temperature = BLETypeConversions.toFloat32(raw, 1); // bytes 1 - 4
int temperature_type = BLETypeConversions.toUnsigned(raw, 12); // encodes where the measurement was taken
LOG.debug("Received measurement of " + temperature + "° with Timestamp " + date + ", metadata is " + Integer.toBinaryString((metadata & 0xFF) + 0x100).substring(1));
@@ -24,6 +24,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile;
@@ -60,16 +61,15 @@ public class HeartRateProfile<T extends AbstractBTLEDeviceSupport> extends Abstr
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
int flag = characteristic.getProperties();
int format = -1;
final int heartRate;
if ((flag & 0x01) != 0) {
format = BluetoothGattCharacteristic.FORMAT_UINT16;
heartRate = BLETypeConversions.toUint16(value, 1);
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;
heartRate = BLETypeConversions.toUnsigned(value, 1);
}
final int heartRate = characteristic.getIntValue(format, 1);
LOG.info("Heart rate: " + heartRate);
}
return false;
@@ -86,19 +86,21 @@ public class AsteroidOSDeviceSupport extends AbstractBTLEDeviceSupport {
handleGBDeviceEvent(batteryCmd);
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
BluetoothGattCharacteristic characteristic,
byte[] value) {
super.onCharacteristicChanged(gatt, characteristic, value);
UUID characteristicUUID = characteristic.getUuid();
if (characteristicUUID.equals(AsteroidOSConstants.MEDIA_COMMANDS_CHAR)) {
handleMediaCommand(characteristic);
handleMediaCommand(characteristic, value);
return true;
}
LOG.info("Characteristic changed UUID: " + characteristicUUID);
LOG.info("Characteristic changed value: " + Arrays.toString(characteristic.getValue()));
LOG.info("Characteristic changed value: " + Arrays.toString(value));
return false;
}
@@ -258,8 +260,9 @@ public class AsteroidOSDeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (super.onCharacteristicRead(gatt, characteristic, status)) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
if (super.onCharacteristicRead(gatt, characteristic, value, status)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
@@ -273,9 +276,9 @@ public class AsteroidOSDeviceSupport extends AbstractBTLEDeviceSupport {
* Handles a media command sent from the AsteroidOS device
* @param characteristic The Characteristic information
*/
public void handleMediaCommand (BluetoothGattCharacteristic characteristic) {
public void handleMediaCommand (BluetoothGattCharacteristic characteristic, byte[] value) {
LOG.info("handle media command");
AsteroidOSMediaCommand command = new AsteroidOSMediaCommand(characteristic.getValue(), getContext());
AsteroidOSMediaCommand command = new AsteroidOSMediaCommand(value, getContext());
GBDeviceEventMusicControl event = command.toMusicControlEvent();
if (event != null)
evaluateGBDeviceEvent(event);
@@ -83,19 +83,20 @@ public class BandWPSeriesDeviceSupport extends AbstractBTLEDeviceSupport {
return builder;
}
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
super.onCharacteristicChanged(gatt, characteristic, value);
UUID characteristicUUID = characteristic.getUuid();
if (UUID_RPC_RESPONSE_CHARACTERISTIC.equals(characteristicUUID) || UUID_RPC_NOTIFICATION_CHARACTERISTIC.equals(characteristicUUID)) {
return handleRPCResponse(characteristic);
return handleRPCResponse(characteristic, value);
}
return false;
}
private boolean handleRPCResponse(BluetoothGattCharacteristic characteristic) {
BandWPSeriesResponse response = new BandWPSeriesResponse(characteristic.getValue());
private boolean handleRPCResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
BandWPSeriesResponse response = new BandWPSeriesResponse(value);
LOG.debug("Got RPC response: Type {}, commandID {}, namespace {}, errorCode {}, payload {}",
response.messageType,
response.commandId,
@@ -1193,12 +1193,12 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] chars) {
if (super.onCharacteristicChanged(gatt, characteristic, chars)) {
return true;
}
if (BangleJSConstants.UUID_CHARACTERISTIC_NORDIC_UART_RX.equals(characteristic.getUuid())) {
byte[] chars = characteristic.getValue();
// check to see if we get more data - if so, increase out MTU for sending
if (allowHighMTU && chars.length > mtuSize)
mtuSize = chars.length;
@@ -87,9 +87,9 @@ public class BinarySensorSupport extends BinarySensorBaseSupport {
};
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
if (characteristic.getUuid().toString().equals(BINARY_SENSOR_RESPONSE_CHARACTERISTIC_UUID)) {
handleResponseValue(characteristic.getValue());
handleResponseValue(value);
return true;
}
@@ -91,9 +91,9 @@ public abstract class BasicCasio2C2DSupport extends Casio2C2DSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -109,6 +109,6 @@ public abstract class BasicCasio2C2DSupport extends Casio2C2DSupport {
return true;
}
}
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, data);
}
}
@@ -296,11 +296,11 @@ public abstract class Casio2C2DSupport extends CasioSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] response) {
UUID characteristicUUID = characteristic.getUuid();
if (characteristicUUID.equals(CasioConstants.CASIO_ALL_FEATURES_CHARACTERISTIC_UUID)) {
byte[] response = characteristic.getValue();
Iterator<RequestWithHandler> it = requests.iterator();
while (it.hasNext()) {
RequestWithHandler rh = it.next();
@@ -313,7 +313,7 @@ public abstract class Casio2C2DSupport extends CasioSupport {
LOG.warn("unhandled response: " + Logging.formatBytes(response));
}
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, response);
}
public void writeCurrentTime(TransactionBuilder builder, ZonedDateTime time) {
@@ -379,10 +379,10 @@ public class CasioGB6900DeviceSupport extends CasioSupport {
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BluetoothGattCharacteristic characteristic, byte[] data,
int status) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if(data.length == 0)
return true;
@@ -395,7 +395,7 @@ public class CasioGB6900DeviceSupport extends CasioSupport {
LOG.info(str.toString());
}
else {
return super.onCharacteristicRead(gatt, characteristic, status);
return super.onCharacteristicRead(gatt, characteristic, data, status);
}
return true;
@@ -403,11 +403,11 @@ public class CasioGB6900DeviceSupport extends CasioSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
boolean handled = false;
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -443,7 +443,7 @@ public class CasioGB6900DeviceSupport extends CasioSupport {
if(!handled) {
LOG.info("Unhandled characteristic change: " + characteristicUUID + " code: " + String.format("0x%1x ...", data[0]));
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, data);
}
return true;
}
@@ -61,10 +61,11 @@ public class InitOperation extends AbstractBTLEOperation<CasioGB6900DeviceSuppor
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
UUID characteristicUUID = characteristic.getUuid();
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
private void configureBleSettings() {
@@ -94,10 +95,10 @@ public class InitOperation extends AbstractBTLEOperation<CasioGB6900DeviceSuppor
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BluetoothGattCharacteristic characteristic, byte[] data,
int status) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if(data.length == 0)
return true;
@@ -160,7 +161,7 @@ public class InitOperation extends AbstractBTLEOperation<CasioGB6900DeviceSuppor
writeBleSettings();
}
else {
return super.onCharacteristicRead(gatt, characteristic, status);
return super.onCharacteristicRead(gatt, characteristic, data, status);
}
return true;
@@ -84,10 +84,10 @@ public class SetAlarmOperation extends AbstractBTLEOperation<CasioGB6900DeviceSu
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BluetoothGattCharacteristic characteristic, byte[] data,
int status) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if(data.length == 0)
return true;
@@ -127,7 +127,7 @@ public class SetAlarmOperation extends AbstractBTLEOperation<CasioGB6900DeviceSu
operationFinished();
}
else {
return super.onCharacteristicRead(gatt, characteristic, status);
return super.onCharacteristicRead(gatt, characteristic, data, status);
}
return true;
@@ -137,15 +137,15 @@ public class CasioGBX100DeviceSupport extends Casio2C2DSupport implements Shared
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BluetoothGattCharacteristic characteristic, byte[] data,
int status) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if(data.length == 0)
return true;
return super.onCharacteristicRead(gatt, characteristic, status);
return super.onCharacteristicRead(gatt, characteristic, data, status);
}
public CasioGBX100ActivitySample getSumWithinRange(int timestamp_from, int timestamp_to) {
@@ -211,9 +211,9 @@ public class CasioGBX100DeviceSupport extends Casio2C2DSupport implements Shared
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -240,7 +240,7 @@ public class CasioGBX100DeviceSupport extends Casio2C2DSupport implements Shared
}
LOG.info("Unhandled characteristic change: " + characteristicUUID + " code: " + String.format("0x%1x ...", data[0]));
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, data);
}
public void syncProfile() {
@@ -120,9 +120,9 @@ public class FetchStepCountDataOperation extends AbstractBTLEOperation<CasioGBX
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -282,7 +282,7 @@ public class FetchStepCountDataOperation extends AbstractBTLEOperation<CasioGBX
return true;
} else {
LOG.warn("Unhandled characteristic changed: {}", characteristicUUID);
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, data);
}
}
@@ -99,9 +99,9 @@ public class GetConfigurationOperation extends AbstractBTLEOperation<CasioGBX100
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -162,13 +162,14 @@ public class GetConfigurationOperation extends AbstractBTLEOperation<CasioGBX100
}
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, data);
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
return super.onCharacteristicRead(gatt, characteristic, status);
return super.onCharacteristicRead(gatt, characteristic, value, status);
}
}
@@ -280,9 +280,9 @@ public class InitOperation extends AbstractBTLEOperation<CasioGBX100DeviceSuppor
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if(data.length == 0)
return true;
@@ -372,14 +372,15 @@ public class InitOperation extends AbstractBTLEOperation<CasioGBX100DeviceSuppor
return true;
} else {
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, data);
}
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
return super.onCharacteristicRead(gatt, characteristic, status);
return super.onCharacteristicRead(gatt, characteristic, value, status);
}
}
@@ -75,9 +75,9 @@ public class SetConfigurationOperation extends AbstractBTLEOperation<CasioGBX10
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
final byte[] data) {
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -251,7 +251,7 @@ public class SetConfigurationOperation extends AbstractBTLEOperation<CasioGBX10
}
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, data);
}
@Override
@@ -208,13 +208,13 @@ public class CmfWatchProSupport extends AbstractBTLEDeviceSupport implements Cmf
@Override
public boolean onCharacteristicChanged(final BluetoothGatt gatt,
final BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
final BluetoothGattCharacteristic characteristic,
final byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
final UUID characteristicUUID = characteristic.getUuid();
final byte[] value = characteristic.getValue();
if (characteristicUUID.equals(characteristicCommandRead.getCharacteristicUUID())) {
characteristicCommandRead.onCharacteristicChanged(value);
@@ -177,15 +177,14 @@ public class ColmiR0xDeviceSupport extends AbstractBTLEDeviceSupport {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
byte[] value = characteristic.getValue();
LOG.debug("Characteristic {} changed, value: {}", characteristicUUID, StringUtils.bytesToHex(characteristic.getValue()));
LOG.debug("Characteristic {} changed, value: {}", characteristicUUID, StringUtils.bytesToHex(value));
if (characteristicUUID.equals(ColmiR0xConstants.CHARACTERISTIC_NOTIFY_V1)) {
switch (value[0]) {
@@ -149,8 +149,7 @@ public class CyclingSensorSupport extends CyclingSensorBaseSupport {
return builder;
}
private void handleMeasurementCharacteristic(BluetoothGattCharacteristic characteristic){
byte[] value = characteristic.getValue();
private void handleMeasurementCharacteristic(byte[] value){
if(value == null || value.length < 7){
logger.error("Measurement characteristic value length smaller than 7");
return;
@@ -245,12 +244,10 @@ public class CyclingSensorSupport extends CyclingSensorBaseSupport {
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
byte[] value = characteristic.getValue();
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value, int status) {
if(characteristic.equals(batteryCharacteristic) && value != null && value.length == 1){
GBDeviceEventBatteryInfo info = new GBDeviceEventBatteryInfo();
info.level = characteristic.getValue()[0];
info.level = value[0];
handleGBDeviceEvent(info);
}
@@ -258,9 +255,9 @@ public class CyclingSensorSupport extends CyclingSensorBaseSupport {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
if(characteristic.getUuid().equals(UUID_CYCLING_SENSOR_CSC_MEASUREMENT)){
handleMeasurementCharacteristic(characteristic);
handleMeasurementCharacteristic(value);
return true;
}
return false;
@@ -216,15 +216,15 @@ public class DomyosT540Support extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
if (super.onCharacteristicChanged(gatt, characteristic, data)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
if (characteristicUUID.equals(UUUD_CHARACTERISTICS_NOTIFY)) {
byte[] data = characteristic.getValue();
if (data.length == 6) { // FIXME: this is assumed the tail of the data below which does not fit inside the MTU
System.arraycopy(data, 0, last_data, 20, 6);
ByteBuffer buf = ByteBuffer.wrap(last_data);
@@ -283,8 +283,9 @@ public class DomyosT540Support extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (super.onCharacteristicRead(gatt, characteristic, status)) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
if (super.onCharacteristicRead(gatt, characteristic, value, status)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
@@ -115,15 +115,15 @@ public class G1DeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] payload) {
// Super already handled this.
if (super.onCharacteristicChanged(gatt, characteristic)) {
if (super.onCharacteristicChanged(gatt, characteristic, payload)) {
return true;
}
// If this is the correct UART RX message, parse it.
if (G1DeviceConstants.UUID_CHARACTERISTIC_NORDIC_UART_RX.equals(characteristic.getUuid())) {
byte[] payload = characteristic.getValue();
if (payload[0] == G1DeviceConstants.CommandId.BATTERY_LEVEL.id) {
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
batteryInfo.state = BatteryState.BATTERY_NORMAL;
@@ -269,10 +269,10 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
BluetoothGattCharacteristic characteristic,
byte[] data) {
super.onCharacteristicChanged(gatt, characteristic, data);
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
debugPrintArray(data, "FitPro received value");
if (data[0] != FitProConstants.DATA_HEADER) {
if (debugEnabled) {
@@ -32,6 +32,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
@@ -143,13 +144,13 @@ public class FlipperZeroSupport extends FlipperZeroBaseSupport{
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value, int status) {
if(characteristic.getUuid().equals(GattCharacteristic.UUID_CHARACTERISTIC_FIRMWARE_REVISION_STRING)){
String revision = characteristic.getStringValue(0);
String revision = BLETypeConversions.getStringValue(value, 0);
getDevice().setFirmwareVersion(revision);
getDevice().sendDeviceUpdateIntent(getContext());
}
return super.onCharacteristicRead(gatt, characteristic, status);
return super.onCharacteristicRead(gatt, characteristic, value, status);
}
@Override
@@ -194,14 +194,14 @@ public class GarminSupport extends AbstractBTLEDeviceSupport implements ICommuni
}
@Override
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final byte[] value) {
final UUID characteristicUUID = characteristic.getUuid();
if (super.onCharacteristicChanged(gatt, characteristic)) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
LOG.debug("Change of characteristic {} handled by parent", characteristicUUID);
return true;
}
return communicator.onCharacteristicChanged(gatt, characteristic);
return communicator.onCharacteristicChanged(gatt, characteristic, value);
}
@Override
@@ -12,7 +12,7 @@ public interface ICommunicator {
boolean initializeDevice(TransactionBuilder builder);
boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic);
boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value);
void onHeartRateTest();
@@ -91,9 +91,9 @@ public class CommunicatorV1 implements ICommunicator {
}
@Override
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final byte[] value) {
if (characteristic.getUuid().equals(characteristicReceive.getUuid())) {
this.cobsCoDec.receivedBytes(characteristic.getValue());
this.cobsCoDec.receivedBytes(value);
this.mSupport.onMessage(this.cobsCoDec.retrieveMessage());
return true;
@@ -125,13 +125,13 @@ public class CommunicatorV2 implements ICommunicator {
}
@Override
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final byte[] value) {
if (!characteristic.getUuid().equals(characteristicReceive.getUuid())) {
// Not ML
return false;
}
final ByteBuffer message = ByteBuffer.wrap(characteristic.getValue()).order(ByteOrder.LITTLE_ENDIAN);
final ByteBuffer message = ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN);
final byte handle = message.get();
if (0x00 == handle) {
@@ -151,7 +151,7 @@ public class CommunicatorV2 implements ICommunicator {
} else if (this.realtimeHrvHandle == handle) {
processRealtimeHrv(message);
} else {
LOG.warn("Got message for unknown handle {}: {}", handle, GB.hexdump(characteristic.getValue()));
LOG.warn("Got message for unknown handle {}: {}", handle, GB.hexdump(value));
}
return true;
@@ -13,6 +13,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
@@ -34,17 +35,17 @@ public class BleGattClientSupport extends AbstractBTLEDeviceSupport {
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value, int status) {
if(characteristic.getUuid().equals(GattCharacteristic.UUID_CHARACTERISTIC_BATTERY_LEVEL)) {
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
batteryInfo.level = characteristic.getValue()[0];
batteryInfo.level = value[0];
handleGBDeviceEvent(batteryInfo);
}else if(characteristic.getUuid().equals(GattCharacteristic.UUID_CHARACTERISTIC_FIRMWARE_REVISION_STRING)) {
String firmwareVersion = characteristic.getStringValue(0);
String firmwareVersion = BLETypeConversions.getStringValue(value,0);
getDevice().setFirmwareVersion(firmwareVersion);
getDevice().sendDeviceUpdateIntent(getContext());
}
return super.onCharacteristicRead(gatt, characteristic, status);
return super.onCharacteristicRead(gatt, characteristic, value, status);
}
void readCharacteristicIfAvailable(UUID characteristicUUID, TransactionBuilder builder) {
@@ -75,13 +75,12 @@ public class GreeAcSupport extends AbstractBTLEDeviceSupport {
}
@Override
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
final UUID characteristicUUID = characteristic.getUuid();
final byte[] value = characteristic.getValue();
if (UUID_CHARACTERISTIC_PACK_RX.equals(characteristicUUID)) {
final String packMessageJson = new String(value, StandardCharsets.UTF_8);
@@ -164,8 +164,9 @@ public final class HamaFit6900DeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] receivedData) {
if (super.onCharacteristicChanged(gatt, characteristic, receivedData)) {
return true;
}
@@ -173,8 +174,6 @@ public final class HamaFit6900DeviceSupport extends AbstractBTLEDeviceSupport {
return false;
}
byte[] receivedData = characteristic.getValue();
Message.CommandMessage cmdMsg = Message.decodeCommandMessage(receivedData);
if (cmdMsg == null) {
return false;
@@ -841,13 +841,13 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
if (super.onCharacteristicChanged(gatt, characteristic, data)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -2006,53 +2006,54 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
// handled upstream
return true;
}
final UUID characteristicUUID = characteristic.getUuid();
if (HuamiService.UUID_CHARACTERISTIC_6_BATTERY_INFO.equals(characteristicUUID)) {
handleBatteryInfo(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
handleBatteryInfo(value, BluetoothGatt.GATT_SUCCESS);
return true;
} else if (MiBandService.UUID_CHARACTERISTIC_REALTIME_STEPS.equals(characteristicUUID)) {
handleRealtimeSteps(characteristic.getValue());
handleRealtimeSteps(value);
return true;
} else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
handleHeartrate(characteristic.getValue());
handleHeartrate(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) {
LOG.info("AUTHENTICATION?? " + characteristicUUID);
logMessageContent(characteristic.getValue());
logMessageContent(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT.equals(characteristicUUID)) {
handleDeviceEvent(characteristic.getValue());
handleDeviceEvent(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_WORKOUT.equals(characteristicUUID)) {
handleDeviceWorkoutEvent(characteristic.getValue());
handleDeviceWorkoutEvent(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) {
handleRealtimeSteps(characteristic.getValue());
handleRealtimeSteps(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION.equals(characteristicUUID)) {
handleConfigurationInfo(characteristic.getValue());
handleConfigurationInfo(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_CHUNKEDTRANSFER_2021_READ.equals(characteristicUUID)) {
handleChunked(characteristic.getValue());
handleChunked(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_RAW_SENSOR_DATA.equals(characteristicUUID)) {
handleRawSensorData(characteristic.getValue());
handleRawSensorData(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_5_ACTIVITY_DATA.equals(characteristicUUID)) {
fetcher.onActivityData(characteristic.getValue());
fetcher.onActivityData(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_5_ACTIVITY_CONTROL.equals(characteristicUUID)) {
fetcher.onActivityControl(characteristic.getValue());
fetcher.onActivityControl(value);
return true;
} else {
LOG.warn("Unhandled characteristic changed: {}", characteristicUUID);
logMessageContent(characteristic.getValue());
logMessageContent(value);
}
return false;
@@ -2060,34 +2061,35 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (super.onCharacteristicRead(gatt, characteristic, status)) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
if (super.onCharacteristicRead(gatt, characteristic, value, status)) {
// handled upstream
return true;
}
UUID characteristicUUID = characteristic.getUuid();
if (GattCharacteristic.UUID_CHARACTERISTIC_DEVICE_NAME.equals(characteristicUUID)) {
handleDeviceName(characteristic.getValue(), status);
handleDeviceName(value, status);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_6_BATTERY_INFO.equals(characteristicUUID)) {
handleBatteryInfo(characteristic.getValue(), status);
handleBatteryInfo(value, status);
return true;
} else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
logHeartrate(characteristic.getValue(), status);
logHeartrate(value, status);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) {
handleRealtimeSteps(characteristic.getValue());
handleRealtimeSteps(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT.equals(characteristicUUID)) {
handleDeviceEvent(characteristic.getValue());
handleDeviceEvent(value);
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_WORKOUT.equals(characteristicUUID)) {
handleDeviceWorkoutEvent(characteristic.getValue());
handleDeviceWorkoutEvent(value);
return true;
} else {
LOG.info("Unhandled characteristic read: " + characteristicUUID);
logMessageContent(characteristic.getValue());
logMessageContent(value);
}
return false;
@@ -114,19 +114,19 @@ public class InitOperation extends AbstractBTLEOperation<HuamiSupport> {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
UUID characteristicUUID = characteristic.getUuid();
if (!HuamiService.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) {
LOG.info("Unhandled characteristic changed: {}", characteristicUUID);
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
try {
final byte[] value = characteristic.getValue();
huamiSupport.logMessageContent(value);
if (value[0] != HuamiService.AUTH_RESPONSE) {
LOG.warn("Got a non-response: {}", GB.hexdump(value));
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
if (value[1] == HuamiService.AUTH_SEND_KEY && value[2] == HuamiService.AUTH_SUCCESS) {
@@ -161,10 +161,10 @@ public class InitOperation extends AbstractBTLEOperation<HuamiSupport> {
GBApplication.deviceService(device).disconnect();
}
} else {
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
} else {
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
} catch (Exception e) {
GB.toast(getContext(), "Error authenticating Huami device", Toast.LENGTH_LONG, GB.ERROR, e);
@@ -93,17 +93,17 @@ public class InitOperation2021 extends InitOperation implements Huami2021Handler
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
final byte[] value) {
final UUID characteristicUUID = characteristic.getUuid();
if (!HuamiService.UUID_CHARACTERISTIC_CHUNKEDTRANSFER_2021_READ.equals(characteristicUUID)) {
LOG.warn("Unhandled characteristic changed: {}", characteristicUUID);
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
final byte[] value = characteristic.getValue();
if (value.length <= 1 || value[0] != 0x03) {
// Not chunked
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
final boolean needsAck = huami2021ChunkedDecoder.decode(value);
@@ -110,13 +110,14 @@ public class UpdateFirmwareOperation extends AbstractMiBandOperation<HuamiSuppor
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
UUID characteristicUUID = characteristic.getUuid();
if (fwCControlChar.getUuid().equals(characteristicUUID)) {
handleNotificationNotif(characteristic.getValue());
handleNotificationNotif(value);
return true; // don't let anyone else handle it
} else {
super.onCharacteristicChanged(gatt, characteristic);
super.onCharacteristicChanged(gatt, characteristic, value);
}
return false;
}
@@ -135,13 +135,14 @@ public class ZeppOsBtleSupport extends AbstractBTLEDeviceSupport implements Zepp
@Override
public boolean onCharacteristicChanged(final BluetoothGatt gatt,
final BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
final BluetoothGattCharacteristic characteristic,
final byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
// handled upstream
return true;
}
return zeppOsSupport.onCharacteristicChanged(characteristic.getUuid(), characteristic.getValue());
return zeppOsSupport.onCharacteristicChanged(characteristic.getUuid(), value);
}
@Override
@@ -78,8 +78,8 @@ public class HuaweiLESupport extends AbstractBTLEDeviceSupport {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
supportProvider.onCharacteristicChanged(characteristic);
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] data) {
supportProvider.onCharacteristicChanged(characteristic, data);
return true;
}
@@ -1051,8 +1051,7 @@ public class HuaweiSupportProvider {
}
}
public boolean onCharacteristicChanged(BluetoothGattCharacteristic characteristic) {
byte[] data = characteristic.getValue();
public boolean onCharacteristicChanged(BluetoothGattCharacteristic characteristic, byte[] data) {
responseManager.handleData(data);
return true;
}
@@ -72,13 +72,14 @@ public abstract class AbstractID115Operation extends AbstractBTLEOperation<ID115
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
UUID characteristicUUID = characteristic.getUuid();
if (notifyCharacteristic.getUuid().equals(characteristicUUID)) {
handleResponse(characteristic.getValue());
handleResponse(value);
return true;
} else {
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
}
@@ -140,26 +140,26 @@ public class IdasenDeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
if (characteristic.getUuid().equals(IdasenConstants.CHARACTERISTIC_HEIGHT)) {
getDeskValues(characteristic);
getDeskValues(value);
announceDeskValues();
return true;
}
return super.onCharacteristicRead(gatt, characteristic, status);
return super.onCharacteristicRead(gatt, characteristic, value, status);
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
if (characteristic.getUuid().equals(IdasenConstants.CHARACTERISTIC_HEIGHT)) {
getDeskValues(characteristic);
getDeskValues(value);
announceDeskValues();
return true;
}
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
private void readCharacteristic(String taskName, UUID charac) {
@@ -182,8 +182,7 @@ public class IdasenDeviceSupport extends AbstractBTLEDeviceSupport {
broadcastManager.registerReceiver(commandReceiver, filter);
}
private void getDeskValues(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
private void getDeskValues(byte[] value) {
final ByteBuffer buf = ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN);
int hh = BLETypeConversions.toUnsigned(buf.getShort());
deskHeight = (float) IdasenConstants.MIN_HEIGHT + hh / 10000F;
@@ -124,8 +124,9 @@ public class ITagSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
@@ -136,8 +137,9 @@ public class ITagSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (super.onCharacteristicRead(gatt, characteristic, status)) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
if (super.onCharacteristicRead(gatt, characteristic, value, status)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
@@ -127,13 +127,13 @@ public class BFH16DeviceSupport extends AbstractBTLEDeviceSupport {
//TODO check TODOs in method
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
if (super.onCharacteristicChanged(gatt, characteristic, data)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -84,8 +84,9 @@ public class JYouSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
return super.onCharacteristicChanged(gatt, characteristic);
BluetoothGattCharacteristic characteristic,
byte[] value) {
return super.onCharacteristicChanged(gatt, characteristic, value);
}
protected void syncDateAndTime(TransactionBuilder builder) {
@@ -40,13 +40,13 @@ public class TeclastH30Support extends JYouSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
if (super.onCharacteristicChanged(gatt, characteristic, data)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -57,13 +57,13 @@ public class Y5Support extends JYouSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
if (super.onCharacteristicChanged(gatt, characteristic, data)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -658,9 +658,8 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] data) {
if (characteristic.getUuid().equals(LefunConstants.UUID_CHARACTERISTIC_LEFUN_NOTIFY)) {
byte[] data = characteristic.getValue();
// Parse response
if (data.length >= LefunConstants.CMD_HEADER_LENGTH && data[0] == LefunConstants.CMD_RESPONSE_ID) {
// Note: full validation is done within the request
@@ -693,7 +692,7 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport {
return false;
}
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, data);
}
/**
@@ -75,9 +75,8 @@ public abstract class MultiFetchRequest extends Request {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] data) {
if (characteristic.getUuid().equals(LefunConstants.UUID_CHARACTERISTIC_LEFUN_NOTIFY)) {
byte[] data = characteristic.getValue();
// Parse response
if (data.length >= LefunConstants.CMD_HEADER_LENGTH && data[0] == LefunConstants.CMD_RESPONSE_ID) {
try {
@@ -94,7 +93,7 @@ public abstract class MultiFetchRequest extends Request {
return false;
}
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, data);
}
@Override
@@ -64,11 +64,11 @@ public class InitOperation extends AbstractBTLEOperation<WatchXPlusDeviceSupport
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
UUID characteristicUUID = characteristic.getUuid();
if (Watch9Constants.UUID_CHARACTERISTIC_WRITE.equals(characteristicUUID) && needsAuth) {
try {
byte[] value = characteristic.getValue();
getSupport().logMessageContent(value);
if (ArrayUtils.equals(value, Watch9Constants.RESP_AUTHORIZATION_TASK, 5) && value[8] == 0x01) {
TransactionBuilder builder = getSupport().createTransactionBuilder("authInit");
@@ -76,7 +76,7 @@ public class InitOperation extends AbstractBTLEOperation<WatchXPlusDeviceSupport
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()));
getSupport().initialize(builder).performImmediately(builder);
} else {
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
} catch (Exception e) {
GB.toast(getContext(), "Error authenticating Watch X Plus", Toast.LENGTH_LONG, GB.ERROR, e);
@@ -84,7 +84,7 @@ public class InitOperation extends AbstractBTLEOperation<WatchXPlusDeviceSupport
return true;
} else {
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
}
@@ -1381,11 +1381,11 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
BluetoothGattCharacteristic characteristic,
byte[] value) {
super.onCharacteristicChanged(gatt, characteristic, value);
UUID characteristicUUID = characteristic.getUuid();
byte[] value = characteristic.getValue();
if (WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE.equals(characteristicUUID)) {
if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_FIRMWARE_INFO, 5)) {
handleFirmwareInfo(value);
@@ -1440,7 +1440,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
LOG.info(" Received notification settings status ");
} else {
LOG.info(" Unhandled value change for characteristic: " + characteristicUUID);
logMessageContent(characteristic.getValue());
logMessageContent(value);
}
return true;
@@ -1450,7 +1450,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
return true;
} else {
LOG.info(" Unhandled characteristic changed: " + characteristicUUID + " value " + Arrays.toString(value));
logMessageContent(characteristic.getValue());
logMessageContent(value);
}
return false;
@@ -649,13 +649,13 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
byte[] data = characteristic.getValue();
if (data.length < 6)
if (value.length < 6)
return true;
this.fetch(false);
@@ -663,7 +663,6 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
UUID characteristicUuid = characteristic.getUuid();
if (characteristicUuid.equals(mReportCharacteristic.getUuid())) {
byte[] value = characteristic.getValue();
byte[] arguments = new byte[value.length - 6];
if (arguments.length >= 0) {
@@ -75,10 +75,8 @@ public class MarstekB2500DeviceSupport extends AbstractBTLEDeviceSupport {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
byte[] value = characteristic.getValue();
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
super.onCharacteristicChanged(gatt, characteristic, value);
if (value[0] == COMMAND_PREFIX) {
if ((value[1] == 0x10) && (value[2] == COMMAND) && (value[3] == OPCODE_INFO1)) {
@@ -805,55 +805,57 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
BluetoothGattCharacteristic characteristic,
byte[] value) {
super.onCharacteristicChanged(gatt, characteristic, value);
UUID characteristicUUID = characteristic.getUuid();
if (MiBandService.UUID_CHARACTERISTIC_BATTERY.equals(characteristicUUID)) {
handleBatteryInfo(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
handleBatteryInfo(value, BluetoothGatt.GATT_SUCCESS);
return true;
} else if (MiBandService.UUID_CHARACTERISTIC_NOTIFICATION.equals(characteristicUUID)) {
handleNotificationNotif(characteristic.getValue());
handleNotificationNotif(value);
return true;
} else if (MiBandService.UUID_CHARACTERISTIC_REALTIME_STEPS.equals(characteristicUUID)) {
handleRealtimeSteps(characteristic.getValue());
handleRealtimeSteps(value);
return true;
} else if (MiBandService.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
handleHeartrate(characteristic.getValue());
handleHeartrate(value);
return true;
} else if (MiBandService.UUID_CHARACTERISTIC_SENSOR_DATA.equals(characteristicUUID)) {
handleSensorData(characteristic.getValue());
handleSensorData(value);
} else {
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
logMessageContent(characteristic.getValue());
logMessageContent(value);
}
return false;
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
super.onCharacteristicRead(gatt, characteristic, value, status);
UUID characteristicUUID = characteristic.getUuid();
if (MiBandService.UUID_CHARACTERISTIC_DEVICE_INFO.equals(characteristicUUID)) {
handleDeviceInfo(characteristic.getValue(), status);
handleDeviceInfo(value, status);
return true;
} else if (GattCharacteristic.UUID_CHARACTERISTIC_DEVICE_NAME.equals(characteristicUUID)) {
handleDeviceName(characteristic.getValue(), status);
handleDeviceName(value, status);
return true;
} else if (MiBandService.UUID_CHARACTERISTIC_BATTERY.equals(characteristicUUID)) {
handleBatteryInfo(characteristic.getValue(), status);
handleBatteryInfo(value, status);
return true;
} else if (MiBandService.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
logHeartrate(characteristic.getValue(), status);
logHeartrate(value, status);
return true;
} else if (MiBandService.UUID_CHARACTERISTIC_DATE_TIME.equals(characteristicUUID)) {
logDate(characteristic.getValue(), status);
logDate(value, status);
return true;
} else {
LOG.info("Unhandled characteristic read: " + characteristicUUID);
logMessageContent(characteristic.getValue());
logMessageContent(value);
}
return false;
}
@@ -185,13 +185,14 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
UUID characteristicUUID = characteristic.getUuid();
if (MiBandService.UUID_CHARACTERISTIC_ACTIVITY_DATA.equals(characteristicUUID)) {
handleActivityNotif(characteristic.getValue());
handleActivityNotif(value);
return true;
} else {
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
}
@@ -96,12 +96,13 @@ public class UpdateFirmwareOperation extends AbstractMiBand1Operation {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
UUID characteristicUUID = characteristic.getUuid();
if (MiBandService.UUID_CHARACTERISTIC_NOTIFICATION.equals(characteristicUUID)) {
handleNotificationNotif(characteristic.getValue());
handleNotificationNotif(value);
} else {
super.onCharacteristicChanged(gatt, characteristic);
super.onCharacteristicChanged(gatt, characteristic, value);
}
return false;
}
@@ -421,25 +421,26 @@ public class MijiaLywsdSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
final UUID characteristicUUID = characteristic.getUuid();
if (MijiaLywsdSupport.UUID_HISTORY.equals(characteristicUUID)) {
handleHistory(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
handleHistory(value, BluetoothGatt.GATT_SUCCESS);
return true;
}
if (MijiaLywsdSupport.UUID_LIVE_DATA.equals(characteristicUUID)) {
handleLiveData(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
handleLiveData(value, BluetoothGatt.GATT_SUCCESS);
return true;
}
if (MijiaLywsdSupport.UUID_TIME.equals(characteristicUUID)) {
handleTime(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
handleTime(value, BluetoothGatt.GATT_SUCCESS);
return true;
}
@@ -449,34 +450,35 @@ public class MijiaLywsdSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (super.onCharacteristicRead(gatt, characteristic, status)) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
if (super.onCharacteristicRead(gatt, characteristic, value, status)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
if (MijiaLywsdSupport.UUID_BATTERY.equals(characteristicUUID)) {
handleBatteryInfo(characteristic.getValue(), status);
handleBatteryInfo(value, status);
return true;
}
if (MijiaLywsdSupport.UUID_COMFORT_LEVEL.equals(characteristicUUID)) {
handleComfortLevel(characteristic.getValue(), status);
handleComfortLevel(value, status);
return true;
}
if (MijiaLywsdSupport.UUID_HISTORY.equals(characteristicUUID)) {
handleHistory(characteristic.getValue(), status);
handleHistory(value, status);
return true;
}
if (MijiaLywsdSupport.UUID_LIVE_DATA.equals(characteristicUUID)) {
handleLiveData(characteristic.getValue(), status);
handleLiveData(value, status);
return true;
}
if (MijiaLywsdSupport.UUID_TIME.equals(characteristicUUID)) {
handleTime(characteristic.getValue(), status);
handleTime(value, status);
return true;
}
@@ -39,6 +39,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miscale.MiScaleSampleProvide
import nodomain.freeyourgadget.gadgetbridge.entities.MiScaleWeightSample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
@@ -91,31 +92,29 @@ public class MiCompositionScaleDeviceSupport extends AbstractBTLEDeviceSupport {
}
@Override
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final byte[] data) {
if (super.onCharacteristicChanged(gatt, characteristic, data)) {
return true;
}
final UUID characteristicUUID = characteristic.getUuid();
if (characteristicUUID.equals(GattCharacteristic.UUID_CHARACTERISTIC_BODY_COMPOSITION_MEASUREMENT)) {
final byte[] data = characteristic.getValue();
final byte flags = data[1];
final boolean stabilized = testBit(flags, 5) && !testBit(flags, 7);
if (stabilized) {
final int year = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 2);
final int month = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 4);
final int day = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 5);
final int hour = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 6);
final int minute = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 7);
final int second = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 8);
final int year = BLETypeConversions.toUint16(data, 2);
final int month = BLETypeConversions.toUnsigned(data, 4);
final int day = BLETypeConversions.toUnsigned(data, 5);
final int hour = BLETypeConversions.toUnsigned(data, 6);
final int minute = BLETypeConversions.toUnsigned(data, 7);
final int second = BLETypeConversions.toUnsigned(data, 8);
final Calendar c = GregorianCalendar.getInstance();
c.set(year, month - 1, day, hour, minute, second);
final Date date = c.getTime();
float weightKg = WeightMeasurement.weightToKg(
characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 11),
BLETypeConversions.toUint16(data, 11),
flags
);
handleWeightInfo(date, weightKg);
@@ -130,8 +130,8 @@ public class MiSmartScaleDeviceSupport extends AbstractBTLEDeviceSupport {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic))
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] data) {
if (super.onCharacteristicChanged(gatt, characteristic, data))
return true;
UUID uuid = characteristic.getUuid();
@@ -140,8 +140,6 @@ public class MiSmartScaleDeviceSupport extends AbstractBTLEDeviceSupport {
!uuid.equals(UUID_CHARACTERISTIC_WEIGHT_HISTORY))
return false;
byte[] data = characteristic.getValue();
if (data.length == 1 && data[0] == CMD_HISTORY_COMPLETE) {
TransactionBuilder builder = createTransactionBuilder("ack");
@@ -154,7 +152,7 @@ public class MiSmartScaleDeviceSupport extends AbstractBTLEDeviceSupport {
GB.updateTransferNotification(null, "", false, 100, getContext());
getDevice().sendDeviceUpdateIntent(getContext());
} else {
ByteBuffer buf = ByteBuffer.wrap(characteristic.getValue());
ByteBuffer buf = ByteBuffer.wrap(data);
List<WeightMeasurement> measurements = new ArrayList<>();
WeightMeasurement measurement = WeightMeasurement.decode(buf);
@@ -102,13 +102,13 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] data) {
if (super.onCharacteristicChanged(gatt, characteristic, data)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
byte[] data = characteristic.getValue();
if (data.length == 0)
return true;
@@ -178,14 +178,15 @@ public class NutSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
if (characteristicUUID.equals(NutConstants.CHARAC_AUTH_STATUS)) {
handleAuthResult(characteristic.getValue());
handleAuthResult(value);
return true;
}
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
@@ -194,9 +195,9 @@ public class NutSupport extends AbstractBTLEDeviceSupport {
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
if (super.onCharacteristicRead(gatt, characteristic, status)) {
if (super.onCharacteristicRead(gatt, characteristic, value, status)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
@@ -587,8 +587,9 @@ public class PineTimeJFSupport extends AbstractBTLEDeviceSupport implements DfuL
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (super.onCharacteristicRead(gatt, characteristic, status)) {
BluetoothGattCharacteristic characteristic, byte[] value,
int status) {
if (super.onCharacteristicRead(gatt, characteristic, value, status)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
@@ -651,14 +652,14 @@ public class PineTimeJFSupport extends AbstractBTLEDeviceSupport implements DfuL
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
BluetoothGattCharacteristic characteristic,
byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
if (characteristicUUID.equals(PineTimeJFConstants.UUID_CHARACTERISTICS_MUSIC_EVENT)) {
byte[] value = characteristic.getValue();
GBDeviceEventMusicControl deviceEventMusicControl = new GBDeviceEventMusicControl();
switch (value[0]) {
@@ -686,7 +687,6 @@ public class PineTimeJFSupport extends AbstractBTLEDeviceSupport implements DfuL
evaluateGBDeviceEvent(deviceEventMusicControl);
return true;
} else if (characteristicUUID.equals(PineTimeJFConstants.UUID_CHARACTERISTIC_ALERT_NOTIFICATION_EVENT)) {
byte[] value = characteristic.getValue();
GBDeviceEventCallControl deviceEventCallControl = new GBDeviceEventCallControl();
switch (value[0]) {
case 0:
@@ -704,14 +704,14 @@ public class PineTimeJFSupport extends AbstractBTLEDeviceSupport implements DfuL
evaluateGBDeviceEvent(deviceEventCallControl);
return true;
} else if (characteristicUUID.equals(PineTimeJFConstants.UUID_CHARACTERISTIC_MOTION_STEP_COUNT)) {
int steps = BLETypeConversions.toUint32(characteristic.getValue());
int steps = BLETypeConversions.toUint32(value);
if (LOG.isDebugEnabled()) {
LOG.debug("onCharacteristicChanged: MotionService:Steps=" + steps);
}
onReceiveStepsSample(steps);
return true;
} else if (characteristicUUID.equals(PineTimeJFConstants.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT)) {
int heartrate = Byte.toUnsignedInt(characteristic.getValue()[1]);
int heartrate = Byte.toUnsignedInt(value[1]);
if (LOG.isDebugEnabled()) {
LOG.debug("onCharacteristicChanged: HeartRateMeasurement:HeartRate=" + heartrate);
}
@@ -97,13 +97,13 @@ public class PolarH10DeviceSupport extends AbstractBTLEDeviceSupport {
return builder;
}
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic)) {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
if (super.onCharacteristicChanged(gatt, characteristic, value)) {
return true;
}
UUID characteristicUUID = characteristic.getUuid();
byte[] value = characteristic.getValue();
if (characteristicUUID.equals(UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT)) {
int heartrate = Byte.toUnsignedInt(value[1]);
@@ -64,6 +64,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NavigationInfoSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
@@ -747,10 +748,10 @@ public class QHybridSupport extends QHybridBaseSupport {
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value, int status) {
switch (characteristic.getUuid().toString()) {
case "00002a26-0000-1000-8000-00805f9b34fb": {
String firmwareVersion = characteristic.getStringValue(0);
String firmwareVersion = BLETypeConversions.getStringValue(value, 0);
gbDevice.setFirmwareVersion(firmwareVersion);
Matcher matcher = Pattern
@@ -766,7 +767,7 @@ public class QHybridSupport extends QHybridBaseSupport {
break;
}
case "00002a24-0000-1000-8000-00805f9b34fb": {
String modelNumber = characteristic.getStringValue(0);
String modelNumber = BLETypeConversions.getStringValue(value, 0);
gbDevice.setModel(modelNumber);
gbDevice.setName(watchAdapter.getModelName());
try {
@@ -779,7 +780,7 @@ public class QHybridSupport extends QHybridBaseSupport {
break;
}
case "00002a19-0000-1000-8000-00805f9b34fb": {
short level = characteristic.getValue()[0];
short level = value[0];
gbDevice.setBatteryLevel(level);
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
@@ -796,9 +797,9 @@ public class QHybridSupport extends QHybridBaseSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic
characteristic) {
if(watchAdapter == null) return super.onCharacteristicChanged(gatt, characteristic);
return watchAdapter.onCharacteristicChanged(gatt, characteristic);
characteristic, byte[] value) {
if(watchAdapter == null) return super.onCharacteristicChanged(gatt, characteristic, value);
return watchAdapter.onCharacteristicChanged(gatt, characteristic, value);
}
@Override
@@ -100,7 +100,7 @@ public abstract class WatchAdapter {
public abstract void onSendConfiguration(String config);
public abstract boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic);
public abstract boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value);
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status){};
@@ -638,14 +638,14 @@ public class FossilWatchAdapter extends WatchAdapter {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
switch (characteristic.getUuid().toString()) {
case "3dda0006-957f-7d4a-34a6-74696673696d": {
handleBackgroundCharacteristic(characteristic);
handleBackgroundCharacteristic(characteristic, value);
break;
}
case "00002a37-0000-1000-8000-00805f9b34fb": {
handleHeartRateCharacteristic(characteristic);
handleHeartRateCharacteristic(characteristic, value);
break;
}
case "3dda0002-957f-7d4a-34a6-74696673696d":
@@ -656,14 +656,14 @@ public class FossilWatchAdapter extends WatchAdapter {
boolean requestFinished;
try {
if (characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) {
byte requestType = (byte) (characteristic.getValue()[0] & 0x0F);
byte requestType = (byte) (value[0] & 0x0F);
if (requestType != 0x0A && requestType != fossilRequest.getType()) {
// throw new RuntimeException("Answer type " + requestType + " does not match current request " + fossilRequest.getType());
}
}
fossilRequest.handleResponse(characteristic);
fossilRequest.handleResponse(characteristic, value);
requestFinished = fossilRequest.isFinished();
} catch (RuntimeException e) {
if (characteristic.getUuid().toString().equals("3dda0005-957f-7d4a-34a6-74696673696d")) {
@@ -692,7 +692,7 @@ public class FossilWatchAdapter extends WatchAdapter {
return true;
}
public void handleHeartRateCharacteristic(BluetoothGattCharacteristic characteristic) {
public void handleHeartRateCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value) {
}
@Override
@@ -741,8 +741,7 @@ public class FossilWatchAdapter extends WatchAdapter {
}
}
protected void handleBackgroundCharacteristic(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
protected void handleBackgroundCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value) {
switch (value[1]) {
case 2: {
byte syncId = value[2];
@@ -434,12 +434,11 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
}
}
private void handleVoiceStatusCharacteristic(BluetoothGattCharacteristic characteristic){
byte[] value = characteristic.getValue();
private void handleVoiceStatusCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value){
handleVoiceStatus(value[0]);
}
private void handleVoiceDataCharacteristic(BluetoothGattCharacteristic characteristic){
private void handleVoiceDataCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value){
if(voiceMessenger == null){
return;
}
@@ -448,7 +447,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
MESSAGE_WHAT_VOICE_DATA_RECEIVED
);
Bundle dataBundle = new Bundle(1);
dataBundle.putByteArray("VOICE_DATA", characteristic.getValue());
dataBundle.putByteArray("VOICE_DATA", value);
dataBundle.putString("VOICE_ENCODING", "OPUS");
message.setData(dataBundle);
try {
@@ -463,16 +462,16 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
switch (characteristic.getUuid().toString()){
case "010541ae-efe8-11c0-91c0-105d1a1155f0":
handleVoiceStatusCharacteristic(characteristic);
handleVoiceStatusCharacteristic(characteristic, value);
return true;
case "842d2791-0d20-4ce4-1ada-105d1a1155f0":
handleVoiceDataCharacteristic(characteristic);
handleVoiceDataCharacteristic(characteristic, value);
return true;
}
return super.onCharacteristicChanged(gatt, characteristic);
return super.onCharacteristicChanged(gatt, characteristic, value);
}
private void initializeAfterWatchConfirmation(boolean authenticated) {
@@ -1837,10 +1836,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
}
@Override
public void handleHeartRateCharacteristic(BluetoothGattCharacteristic characteristic) {
super.handleHeartRateCharacteristic(characteristic);
byte[] value = characteristic.getValue();
public void handleHeartRateCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleHeartRateCharacteristic(characteristic, value);
int heartRate = value[1];
@@ -1848,10 +1845,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
}
@Override
protected void handleBackgroundCharacteristic(BluetoothGattCharacteristic characteristic) {
super.handleBackgroundCharacteristic(characteristic);
byte[] value = characteristic.getValue();
protected void handleBackgroundCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleBackgroundCharacteristic(characteristic, value);
byte requestType = value[1];
@@ -150,24 +150,24 @@ public class MisfitWatchAdapter extends WatchAdapter {
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, final byte[] value) {
GBDevice gbDevice = getDeviceSupport().getDevice();
switch (characteristic.getUuid().toString()) {
case "3dda0004-957f-7d4a-34a6-74696673696d":
case "3dda0003-957f-7d4a-34a6-74696673696d": {
return handleFileDownloadCharacteristic(characteristic);
return handleFileDownloadCharacteristic(characteristic, value);
}
case "3dda0007-957f-7d4a-34a6-74696673696d": {
return handleFileUploadCharacteristic(characteristic);
return handleFileUploadCharacteristic(characteristic, value);
}
case "3dda0002-957f-7d4a-34a6-74696673696d": {
return handleBasicCharacteristic(characteristic);
return handleBasicCharacteristic(characteristic, value);
}
case "3dda0006-957f-7d4a-34a6-74696673696d": {
return handleButtonCharacteristic(characteristic);
return handleButtonCharacteristic(characteristic, value);
}
case "00002a19-0000-1000-8000-00805f9b34fb": {
short level = characteristic.getValue()[0];
short level = value[0];
gbDevice.setBatteryLevel(level);
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
@@ -177,11 +177,11 @@ public class MisfitWatchAdapter extends WatchAdapter {
break;
}
default: {
log("unknown shit on " + characteristic.getUuid().toString() + ": " + arrayToString(characteristic.getValue()));
log("unknown shit on " + characteristic.getUuid().toString() + ": " + arrayToString(value));
try {
File charLog = FileUtils.getExternalFile("qFiles/charLog.txt");
try (FileOutputStream fos = new FileOutputStream(charLog, true)) {
fos.write((new Date().toString() + ": " + characteristic.getUuid().toString() + ": " + arrayToString(characteristic.getValue())).getBytes());
fos.write((new Date().toString() + ": " + characteristic.getUuid().toString() + ": " + arrayToString(value)).getBytes());
}
} catch (IOException e) {
GB.log("error", GB.ERROR, e);
@@ -189,7 +189,7 @@ public class MisfitWatchAdapter extends WatchAdapter {
break;
}
}
return getDeviceSupport().onCharacteristicChanged(gatt, characteristic);
return getDeviceSupport().onCharacteristicChanged(gatt, characteristic, value);
}
private void fillResponseList() {
@@ -218,21 +218,20 @@ public class MisfitWatchAdapter extends WatchAdapter {
}
}
private boolean handleBasicCharacteristic(BluetoothGattCharacteristic characteristic) {
byte[] values = characteristic.getValue();
Request request = resolveAnswer(characteristic);
private boolean handleBasicCharacteristic(BluetoothGattCharacteristic characteristic, byte[] values) {
Request request = resolveAnswer(characteristic, values);
GBDevice gbDevice = getDeviceSupport().getDevice();
if (request == null) {
StringBuilder valueString = new StringBuilder(String.valueOf(values[0]));
for (int i = 1; i < characteristic.getValue().length; i++) {
for (int i = 1; i < values.length; i++) {
valueString.append(", ").append(values[i]);
}
log("unable to resolve " + characteristic.getUuid().toString() + ": " + valueString);
return true;
}
log("response: " + request.getClass().getSimpleName());
request.handleResponse(characteristic);
request.handleResponse(characteristic, values);
if (request instanceof GetStepGoalRequest) {
gbDevice.addDeviceInfo(new GenericItem(ITEM_STEP_GOAL, String.valueOf(((GetStepGoalRequest) request).stepGoal)));
@@ -270,16 +269,15 @@ public class MisfitWatchAdapter extends WatchAdapter {
}
private Request resolveAnswer(BluetoothGattCharacteristic characteristic) {
byte[] values = characteristic.getValue();
private Request resolveAnswer(BluetoothGattCharacteristic characteristic, byte[] values) {
if (values[0] != 3) return null;
return responseFilters.get(values[1]);
}
private boolean handleFileDownloadCharacteristic(BluetoothGattCharacteristic characteristic) {
private boolean handleFileDownloadCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value) {
Request request;
request = fileRequest;
request.handleResponse(characteristic);
request.handleResponse(characteristic, value);
if (request instanceof ListFilesRequest) {
if (((ListFilesRequest) request).completed) {
logger.debug("File count: " + ((ListFilesRequest) request).fileCount + " size: " + ((ListFilesRequest) request).size);
@@ -300,13 +298,13 @@ public class MisfitWatchAdapter extends WatchAdapter {
}
private boolean handleFileUploadCharacteristic(BluetoothGattCharacteristic characteristic) {
private boolean handleFileUploadCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value) {
if (uploadFileRequest == null) {
logger.debug("no uploadFileRequest to handle response");
return true;
}
uploadFileRequest.handleResponse(characteristic);
uploadFileRequest.handleResponse(characteristic, value);
switch (uploadFileRequest.state) {
case ERROR:
@@ -329,8 +327,7 @@ public class MisfitWatchAdapter extends WatchAdapter {
return true;
}
private boolean handleButtonCharacteristic(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
private boolean handleButtonCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value) {
if (value.length != 11) {
logger.debug("wrong button message");
return true;
@@ -59,7 +59,7 @@ public abstract class Request {
public abstract byte[] getStartSequence();
public void handleResponse(BluetoothGattCharacteristic characteristic) {}
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {}
public String getName(){
Class thisClass = getClass();
@@ -36,8 +36,8 @@ public class SetConnectionParametersRequest extends FossilRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
this.finished = true;
}
@@ -44,15 +44,13 @@ public class FileCloseRequest extends FossilRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
if(!characteristic.getUuid().toString().equals(this.getRequestUUID().toString())){
throw new RuntimeException("wrong response UUID");
}
byte[] value = characteristic.getValue();
byte type = (byte)(value[0] & 0x0F);
if(type != 9) throw new RuntimeException("wrong response type");
@@ -44,11 +44,10 @@ public class FileDeleteRequest extends FossilRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
if(!characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d"))
throw new RuntimeException("wrong response UUID");
byte[] value = characteristic.getValue();
if(value.length != 4) throw new RuntimeException("wrong response length");
@@ -72,8 +72,7 @@ public abstract class FileGetRawRequest extends FossilRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
byte first = value[0];
if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")){
if((first & 0x0F) == 1){
@@ -67,8 +67,7 @@ public abstract class FileLookupRequest extends FossilRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
byte first = value[0];
if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")){
if((first & 0x0F) == 2){
@@ -72,8 +72,7 @@ public class FilePutRawRequest extends FossilRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
if (characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) {
int responseType = value[0] & 0x0F;
log("response: " + responseType);
@@ -42,15 +42,13 @@ public class FileVerifyRequest extends FossilRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
if(!characteristic.getUuid().toString().equals(this.getRequestUUID().toString())){
throw new RuntimeException("wrong response UUID");
}
byte[] value = characteristic.getValue();
byte type = (byte)(value[0] & 0x0F);
if(type == 0x0A) return;
@@ -26,11 +26,10 @@ public abstract class CheckDeviceNeedsConfirmationRequest extends Authentication
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
if(!characteristic.getUuid().equals(getRequestUUID())){
throw new RuntimeException("wrong characteristic responded to authentication");
}
byte[] value = characteristic.getValue();
if(value.length != 3){
throw new RuntimeException("wrong authentication response length");
}
@@ -31,11 +31,10 @@ public class CheckDevicePairingRequest extends FossilRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
if(!characteristic.getUuid().equals(getRequestUUID())){
throw new RuntimeException("wrong characteristic responded to pairing");
}
byte[] value = characteristic.getValue();
if(value.length != 3){
throw new RuntimeException("wrong pairing response length");
}
@@ -27,11 +27,10 @@ public class ConfirmOnDeviceRequest extends AuthenticationRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
if(!characteristic.getUuid().equals(getRequestUUID())){
throw new RuntimeException("wrong characteristic responded to authentication");
}
byte[] value = characteristic.getValue();
if(value.length != 4){
throw new RuntimeException("wrong authentication response length");
}
@@ -49,9 +49,8 @@ public class VerifyPrivateKeyRequest extends AuthenticationRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
ByteBuffer buffer = ByteBuffer.wrap(value);
@@ -127,8 +127,7 @@ public abstract class FileEncryptedGetRequest extends FossilRequest implements F
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
byte first = value[0];
if (characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) {
if ((first & 0x0F) == 1) {
@@ -74,8 +74,7 @@ public class FileEncryptedPutRequest extends FossilRequest implements FileEncryp
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
if (characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) {
int responseType = value[0] & 0x0F;
log("response: " + responseType);
@@ -32,10 +32,8 @@ public class ActivityPointGetRequest extends Request {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
if (value.length != 6) return;
@@ -31,10 +31,8 @@ public class BatteryLevelRequest extends Request {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
if (value.length >= 3) {
ByteBuffer buffer = ByteBuffer.wrap(value);
@@ -60,9 +60,8 @@ public class DownloadFileRequest extends FileRequest {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
byte[] data = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] data) {
super.handleResponse(characteristic, data);
if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")){
if(buffer == null){
buffer = ByteBuffer.allocate(4096);
@@ -33,13 +33,13 @@ public class EraseFileRequest extends FileRequest{
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
if(!characteristic.getUuid().toString().equals(getRequestUUID().toString())){
log("wrong descriptor");
return;
}
ByteBuffer buffer = ByteBuffer.wrap(characteristic.getValue());
ByteBuffer buffer = ByteBuffer.wrap(value);
buffer.order(ByteOrder.LITTLE_ENDIAN);
deletedHandle = buffer.getShort(1);
status = buffer.get(3);
@@ -30,8 +30,7 @@ public class GetCountdownSettingsRequest extends Request {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
if (value.length != 14) {
return;
}
@@ -32,10 +32,8 @@ public class GetCurrentStepCountRequest extends Request {
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
if (value.length >= 6) {
ByteBuffer buffer = ByteBuffer.wrap(value);
@@ -26,9 +26,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Req
public class GetStepGoalRequest extends Request {
public int stepGoal = -1;
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
byte[] value = characteristic.getValue();
public void handleResponse(BluetoothGattCharacteristic characteristic, byte[] value) {
super.handleResponse(characteristic, value);
if (value.length < 6) {
return;
} else {

Some files were not shown because too many files have changed in this diff Show More