747 lines
24 KiB
Java
747 lines
24 KiB
Java
/*
|
|
* Copyright (C) 2013 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package android.bluetooth;
|
|
|
|
import android.annotation.IntDef;
|
|
import android.annotation.NonNull;
|
|
import android.compat.annotation.UnsupportedAppUsage;
|
|
import android.os.Parcel;
|
|
import android.os.ParcelUuid;
|
|
import android.os.Parcelable;
|
|
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* Represents a Bluetooth GATT Characteristic
|
|
*
|
|
* <p>A GATT characteristic is a basic data element used to construct a GATT service, {@link
|
|
* BluetoothGattService}. The characteristic contains a value as well as additional information and
|
|
* optional GATT descriptors, {@link BluetoothGattDescriptor}.
|
|
*/
|
|
public class BluetoothGattCharacteristic implements Parcelable {
|
|
|
|
/** Characteristic property: Characteristic is broadcastable. */
|
|
public static final int PROPERTY_BROADCAST = 0x01;
|
|
|
|
/** Characteristic property: Characteristic is readable. */
|
|
public static final int PROPERTY_READ = 0x02;
|
|
|
|
/** Characteristic property: Characteristic can be written without response. */
|
|
public static final int PROPERTY_WRITE_NO_RESPONSE = 0x04;
|
|
|
|
/** Characteristic property: Characteristic can be written. */
|
|
public static final int PROPERTY_WRITE = 0x08;
|
|
|
|
/** Characteristic property: Characteristic supports notification */
|
|
public static final int PROPERTY_NOTIFY = 0x10;
|
|
|
|
/** Characteristic property: Characteristic supports indication */
|
|
public static final int PROPERTY_INDICATE = 0x20;
|
|
|
|
/** Characteristic property: Characteristic supports write with signature */
|
|
public static final int PROPERTY_SIGNED_WRITE = 0x40;
|
|
|
|
/** Characteristic property: Characteristic has extended properties */
|
|
public static final int PROPERTY_EXTENDED_PROPS = 0x80;
|
|
|
|
/** Characteristic read permission */
|
|
public static final int PERMISSION_READ = 0x01;
|
|
|
|
/** Characteristic permission: Allow encrypted read operations */
|
|
public static final int PERMISSION_READ_ENCRYPTED = 0x02;
|
|
|
|
/** Characteristic permission: Allow reading with person-in-the-middle protection */
|
|
public static final int PERMISSION_READ_ENCRYPTED_MITM = 0x04;
|
|
|
|
/** Characteristic write permission */
|
|
public static final int PERMISSION_WRITE = 0x10;
|
|
|
|
/** Characteristic permission: Allow encrypted writes */
|
|
public static final int PERMISSION_WRITE_ENCRYPTED = 0x20;
|
|
|
|
/** Characteristic permission: Allow encrypted writes with person-in-the-middle protection */
|
|
public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 0x40;
|
|
|
|
/** Characteristic permission: Allow signed write operations */
|
|
public static final int PERMISSION_WRITE_SIGNED = 0x80;
|
|
|
|
/**
|
|
* Characteristic permission: Allow signed write operations with person-in-the-middle protection
|
|
*/
|
|
public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
|
|
|
|
/** @hide */
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
@IntDef(
|
|
prefix = "WRITE_TYPE_",
|
|
value = {WRITE_TYPE_DEFAULT, WRITE_TYPE_NO_RESPONSE, WRITE_TYPE_SIGNED})
|
|
public @interface WriteType {}
|
|
|
|
/** Write characteristic, requesting acknowledgement by the remote device */
|
|
public static final int WRITE_TYPE_DEFAULT = 0x02;
|
|
|
|
/** Write characteristic without requiring a response by the remote device */
|
|
public static final int WRITE_TYPE_NO_RESPONSE = 0x01;
|
|
|
|
/** Write characteristic including authentication signature */
|
|
public static final int WRITE_TYPE_SIGNED = 0x04;
|
|
|
|
/** Characteristic value format type uint8 */
|
|
public static final int FORMAT_UINT8 = 0x11;
|
|
|
|
/** Characteristic value format type uint16 */
|
|
public static final int FORMAT_UINT16 = 0x12;
|
|
|
|
/** Characteristic value format type uint32 */
|
|
public static final int FORMAT_UINT32 = 0x14;
|
|
|
|
/** Characteristic value format type sint8 */
|
|
public static final int FORMAT_SINT8 = 0x21;
|
|
|
|
/** Characteristic value format type sint16 */
|
|
public static final int FORMAT_SINT16 = 0x22;
|
|
|
|
/** Characteristic value format type sint32 */
|
|
public static final int FORMAT_SINT32 = 0x24;
|
|
|
|
/** Characteristic value format type sfloat (16-bit float) */
|
|
public static final int FORMAT_SFLOAT = 0x32;
|
|
|
|
/** Characteristic value format type float (32-bit float) */
|
|
public static final int FORMAT_FLOAT = 0x34;
|
|
|
|
/**
|
|
* The UUID of this characteristic.
|
|
*
|
|
* @hide
|
|
*/
|
|
protected UUID mUuid;
|
|
|
|
/**
|
|
* Instance ID for this characteristic.
|
|
*
|
|
* @hide
|
|
*/
|
|
@UnsupportedAppUsage protected int mInstance;
|
|
|
|
/**
|
|
* Characteristic properties.
|
|
*
|
|
* @hide
|
|
*/
|
|
protected int mProperties;
|
|
|
|
/**
|
|
* Characteristic permissions.
|
|
*
|
|
* @hide
|
|
*/
|
|
protected int mPermissions;
|
|
|
|
/**
|
|
* Key size (default = 16).
|
|
*
|
|
* @hide
|
|
*/
|
|
protected int mKeySize = 16;
|
|
|
|
/**
|
|
* Write type for this characteristic. See WRITE_TYPE_* constants.
|
|
*
|
|
* @hide
|
|
*/
|
|
protected int mWriteType;
|
|
|
|
/**
|
|
* Back-reference to the service this characteristic belongs to.
|
|
*
|
|
* @hide
|
|
*/
|
|
@UnsupportedAppUsage protected BluetoothGattService mService;
|
|
|
|
/**
|
|
* The cached value of this characteristic.
|
|
*
|
|
* @hide
|
|
*/
|
|
protected byte[] mValue;
|
|
|
|
/** List of descriptors included in this characteristic. */
|
|
protected List<BluetoothGattDescriptor> mDescriptors;
|
|
|
|
/**
|
|
* Create a new BluetoothGattCharacteristic.
|
|
*
|
|
* @param uuid The UUID for this characteristic
|
|
* @param properties Properties of this characteristic
|
|
* @param permissions Permissions for this characteristic
|
|
*/
|
|
public BluetoothGattCharacteristic(UUID uuid, int properties, int permissions) {
|
|
initCharacteristic(null, uuid, 0, properties, permissions);
|
|
}
|
|
|
|
/**
|
|
* Create a new BluetoothGattCharacteristic
|
|
*
|
|
* @hide
|
|
*/
|
|
/*package*/ BluetoothGattCharacteristic(
|
|
BluetoothGattService service,
|
|
UUID uuid,
|
|
int instanceId,
|
|
int properties,
|
|
int permissions) {
|
|
initCharacteristic(service, uuid, instanceId, properties, permissions);
|
|
}
|
|
|
|
/**
|
|
* Create a new BluetoothGattCharacteristic
|
|
*
|
|
* @hide
|
|
*/
|
|
public BluetoothGattCharacteristic(UUID uuid, int instanceId, int properties, int permissions) {
|
|
initCharacteristic(null, uuid, instanceId, properties, permissions);
|
|
}
|
|
|
|
private void initCharacteristic(
|
|
BluetoothGattService service,
|
|
UUID uuid,
|
|
int instanceId,
|
|
int properties,
|
|
int permissions) {
|
|
mUuid = uuid;
|
|
mInstance = instanceId;
|
|
mProperties = properties;
|
|
mPermissions = permissions;
|
|
mService = service;
|
|
mValue = null;
|
|
mDescriptors = new ArrayList<BluetoothGattDescriptor>();
|
|
|
|
if ((mProperties & PROPERTY_WRITE_NO_RESPONSE) != 0) {
|
|
mWriteType = WRITE_TYPE_NO_RESPONSE;
|
|
} else {
|
|
mWriteType = WRITE_TYPE_DEFAULT;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(Parcel out, int flags) {
|
|
out.writeParcelable(new ParcelUuid(mUuid), 0);
|
|
out.writeInt(mInstance);
|
|
out.writeInt(mProperties);
|
|
out.writeInt(mPermissions);
|
|
out.writeInt(mKeySize);
|
|
out.writeInt(mWriteType);
|
|
out.writeTypedList(mDescriptors);
|
|
}
|
|
|
|
public static final @NonNull Creator<BluetoothGattCharacteristic> CREATOR =
|
|
new Creator<>() {
|
|
public BluetoothGattCharacteristic createFromParcel(Parcel in) {
|
|
return new BluetoothGattCharacteristic(in);
|
|
}
|
|
|
|
public BluetoothGattCharacteristic[] newArray(int size) {
|
|
return new BluetoothGattCharacteristic[size];
|
|
}
|
|
};
|
|
|
|
private BluetoothGattCharacteristic(Parcel in) {
|
|
mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
|
|
mInstance = in.readInt();
|
|
mProperties = in.readInt();
|
|
mPermissions = in.readInt();
|
|
mKeySize = in.readInt();
|
|
mWriteType = in.readInt();
|
|
|
|
mDescriptors = new ArrayList<BluetoothGattDescriptor>();
|
|
|
|
ArrayList<BluetoothGattDescriptor> descs =
|
|
in.createTypedArrayList(BluetoothGattDescriptor.CREATOR);
|
|
if (descs != null) {
|
|
for (BluetoothGattDescriptor desc : descs) {
|
|
desc.setCharacteristic(this);
|
|
mDescriptors.add(desc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the desired key size.
|
|
*
|
|
* @hide
|
|
*/
|
|
public int getKeySize() {
|
|
return mKeySize;
|
|
}
|
|
|
|
/**
|
|
* Adds a descriptor to this characteristic.
|
|
*
|
|
* @param descriptor Descriptor to be added to this characteristic.
|
|
* @return true, if the descriptor was added to the characteristic
|
|
*/
|
|
public boolean addDescriptor(BluetoothGattDescriptor descriptor) {
|
|
mDescriptors.add(descriptor);
|
|
descriptor.setCharacteristic(this);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get a descriptor by UUID and instance id.
|
|
*
|
|
* @hide
|
|
*/
|
|
/*package*/ BluetoothGattDescriptor getDescriptor(UUID uuid, int instanceId) {
|
|
for (BluetoothGattDescriptor descriptor : mDescriptors) {
|
|
if (descriptor.getUuid().equals(uuid) && descriptor.getInstanceId() == instanceId) {
|
|
return descriptor;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Returns the service this characteristic belongs to.
|
|
*
|
|
* @return The associated service
|
|
*/
|
|
public BluetoothGattService getService() {
|
|
return mService;
|
|
}
|
|
|
|
/**
|
|
* Sets the service associated with this device.
|
|
*
|
|
* @hide
|
|
*/
|
|
@UnsupportedAppUsage
|
|
/*package*/ void setService(BluetoothGattService service) {
|
|
mService = service;
|
|
}
|
|
|
|
/**
|
|
* Returns the UUID of this characteristic
|
|
*
|
|
* @return UUID of this characteristic
|
|
*/
|
|
public UUID getUuid() {
|
|
return mUuid;
|
|
}
|
|
|
|
/**
|
|
* Returns the instance ID for this characteristic.
|
|
*
|
|
* <p>If a remote device offers multiple characteristics with the same UUID, the instance ID is
|
|
* used to distuinguish between characteristics.
|
|
*
|
|
* @return Instance ID of this characteristic
|
|
*/
|
|
public int getInstanceId() {
|
|
return mInstance;
|
|
}
|
|
|
|
/**
|
|
* Force the instance ID.
|
|
*
|
|
* @hide
|
|
*/
|
|
public void setInstanceId(int instanceId) {
|
|
mInstance = instanceId;
|
|
}
|
|
|
|
/**
|
|
* Returns the properties of this characteristic.
|
|
*
|
|
* <p>The properties contain a bit mask of property flags indicating the features of this
|
|
* characteristic.
|
|
*
|
|
* @return Properties of this characteristic
|
|
*/
|
|
public int getProperties() {
|
|
return mProperties;
|
|
}
|
|
|
|
/**
|
|
* Returns the permissions for this characteristic.
|
|
*
|
|
* @return Permissions of this characteristic
|
|
*/
|
|
public int getPermissions() {
|
|
return mPermissions;
|
|
}
|
|
|
|
/**
|
|
* Gets the write type for this characteristic.
|
|
*
|
|
* @return Write type for this characteristic
|
|
*/
|
|
public int getWriteType() {
|
|
return mWriteType;
|
|
}
|
|
|
|
/**
|
|
* Set the write type for this characteristic
|
|
*
|
|
* <p>Setting the write type of a characteristic determines how the {@link
|
|
* BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)} function write
|
|
* this characteristic.
|
|
*
|
|
* @param writeType The write type to for this characteristic. Can be one of: {@link
|
|
* #WRITE_TYPE_DEFAULT}, {@link #WRITE_TYPE_NO_RESPONSE} or {@link #WRITE_TYPE_SIGNED}.
|
|
*/
|
|
public void setWriteType(int writeType) {
|
|
mWriteType = writeType;
|
|
}
|
|
|
|
/**
|
|
* Set the desired key size.
|
|
*
|
|
* @hide
|
|
*/
|
|
@UnsupportedAppUsage
|
|
public void setKeySize(int keySize) {
|
|
mKeySize = keySize;
|
|
}
|
|
|
|
/**
|
|
* Returns a list of descriptors for this characteristic.
|
|
*
|
|
* @return Descriptors for this characteristic
|
|
*/
|
|
public List<BluetoothGattDescriptor> getDescriptors() {
|
|
return mDescriptors;
|
|
}
|
|
|
|
/**
|
|
* Returns a descriptor with a given UUID out of the list of descriptors for this
|
|
* characteristic.
|
|
*
|
|
* @return GATT descriptor object or null if no descriptor with the given UUID was found.
|
|
*/
|
|
public BluetoothGattDescriptor getDescriptor(UUID uuid) {
|
|
for (BluetoothGattDescriptor descriptor : mDescriptors) {
|
|
if (descriptor.getUuid().equals(uuid)) {
|
|
return descriptor;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get the stored value for this characteristic.
|
|
*
|
|
* <p>This function returns the stored value for this characteristic as retrieved by calling
|
|
* {@link BluetoothGatt#readCharacteristic}. The cached value of the characteristic is updated
|
|
* as a result of a read characteristic operation or if a characteristic update notification has
|
|
* been received.
|
|
*
|
|
* @return Cached value of the characteristic
|
|
* @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} instead
|
|
*/
|
|
@Deprecated
|
|
public byte[] getValue() {
|
|
return mValue;
|
|
}
|
|
|
|
/**
|
|
* Return the stored value of this characteristic.
|
|
*
|
|
* <p>The formatType parameter determines how the characteristic value is to be interpreted. For
|
|
* example, setting formatType to {@link #FORMAT_UINT16} specifies that the first two bytes of
|
|
* the characteristic value at the given offset are interpreted to generate the return value.
|
|
*
|
|
* @param formatType The format type used to interpret the characteristic value.
|
|
* @param offset Offset at which the integer value can be found.
|
|
* @return Cached value of the characteristic or null of offset exceeds value size.
|
|
* @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} to get
|
|
* the characteristic value
|
|
*/
|
|
@Deprecated
|
|
public Integer getIntValue(int formatType, int offset) {
|
|
if ((offset + getTypeLen(formatType)) > mValue.length) return null;
|
|
|
|
switch (formatType) {
|
|
case FORMAT_UINT8:
|
|
return unsignedByteToInt(mValue[offset]);
|
|
|
|
case FORMAT_UINT16:
|
|
return unsignedBytesToInt(mValue[offset], mValue[offset + 1]);
|
|
|
|
case FORMAT_UINT32:
|
|
return unsignedBytesToInt(
|
|
mValue[offset], mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]);
|
|
case FORMAT_SINT8:
|
|
return unsignedToSigned(unsignedByteToInt(mValue[offset]), 8);
|
|
|
|
case FORMAT_SINT16:
|
|
return unsignedToSigned(unsignedBytesToInt(mValue[offset], mValue[offset + 1]), 16);
|
|
|
|
case FORMAT_SINT32:
|
|
return unsignedToSigned(
|
|
unsignedBytesToInt(
|
|
mValue[offset],
|
|
mValue[offset + 1],
|
|
mValue[offset + 2],
|
|
mValue[offset + 3]),
|
|
32);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Return the stored value of this characteristic.
|
|
*
|
|
* <p>See {@link #getValue} for details.
|
|
*
|
|
* @param formatType The format type used to interpret the characteristic value.
|
|
* @param offset Offset at which the float value can be found.
|
|
* @return Cached value of the characteristic at a given offset or null if the requested offset
|
|
* exceeds the value size.
|
|
* @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} to get
|
|
* the characteristic value
|
|
*/
|
|
@Deprecated
|
|
public Float getFloatValue(int formatType, int offset) {
|
|
if ((offset + getTypeLen(formatType)) > mValue.length) return null;
|
|
|
|
switch (formatType) {
|
|
case FORMAT_SFLOAT:
|
|
return bytesToFloat(mValue[offset], mValue[offset + 1]);
|
|
|
|
case FORMAT_FLOAT:
|
|
return bytesToFloat(
|
|
mValue[offset], mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Return the stored value of this characteristic.
|
|
*
|
|
* <p>See {@link #getValue} for details.
|
|
*
|
|
* @param offset Offset at which the string value can be found.
|
|
* @return Cached value of the characteristic
|
|
* @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} to get
|
|
* the characteristic value
|
|
*/
|
|
@Deprecated
|
|
public String getStringValue(int offset) {
|
|
if (mValue == null || offset > mValue.length) return null;
|
|
byte[] strBytes = new byte[mValue.length - offset];
|
|
for (int i = 0; i != (mValue.length - offset); ++i) strBytes[i] = mValue[offset + i];
|
|
return new String(strBytes);
|
|
}
|
|
|
|
/**
|
|
* Updates the locally stored value of this characteristic.
|
|
*
|
|
* <p>This function modifies the locally stored cached value of this characteristic. To send the
|
|
* value to the remote device, call {@link BluetoothGatt#writeCharacteristic} to send the value
|
|
* to the remote device.
|
|
*
|
|
* @param value New value for this characteristic
|
|
* @return true if the locally stored value has been set, false if the requested value could not
|
|
* be stored locally.
|
|
* @deprecated Pass the characteristic value directly into {@link
|
|
* BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
|
|
*/
|
|
@Deprecated
|
|
public boolean setValue(byte[] value) {
|
|
mValue = value;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set the locally stored value of this characteristic.
|
|
*
|
|
* <p>See {@link #setValue(byte[])} for details.
|
|
*
|
|
* @param value New value for this characteristic
|
|
* @param formatType Integer format type used to transform the value parameter
|
|
* @param offset Offset at which the value should be placed
|
|
* @return true if the locally stored value has been set
|
|
* @deprecated Pass the characteristic value directly into {@link
|
|
* BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
|
|
*/
|
|
@Deprecated
|
|
public boolean setValue(int value, int formatType, int offset) {
|
|
int len = offset + getTypeLen(formatType);
|
|
if (mValue == null) mValue = new byte[len];
|
|
if (len > mValue.length) return false;
|
|
|
|
switch (formatType) {
|
|
case FORMAT_SINT8:
|
|
value = intToSignedBits(value, 8);
|
|
// Fall-through intended
|
|
case FORMAT_UINT8:
|
|
mValue[offset] = (byte) (value & 0xFF);
|
|
break;
|
|
|
|
case FORMAT_SINT16:
|
|
value = intToSignedBits(value, 16);
|
|
// Fall-through intended
|
|
case FORMAT_UINT16:
|
|
mValue[offset++] = (byte) (value & 0xFF);
|
|
mValue[offset] = (byte) ((value >> 8) & 0xFF);
|
|
break;
|
|
|
|
case FORMAT_SINT32:
|
|
value = intToSignedBits(value, 32);
|
|
// Fall-through intended
|
|
case FORMAT_UINT32:
|
|
mValue[offset++] = (byte) (value & 0xFF);
|
|
mValue[offset++] = (byte) ((value >> 8) & 0xFF);
|
|
mValue[offset++] = (byte) ((value >> 16) & 0xFF);
|
|
mValue[offset] = (byte) ((value >> 24) & 0xFF);
|
|
break;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set the locally stored value of this characteristic.
|
|
*
|
|
* <p>See {@link #setValue(byte[])} for details.
|
|
*
|
|
* @param mantissa Mantissa for this characteristic
|
|
* @param exponent exponent value for this characteristic
|
|
* @param formatType Float format type used to transform the value parameter
|
|
* @param offset Offset at which the value should be placed
|
|
* @return true if the locally stored value has been set
|
|
* @deprecated Pass the characteristic value directly into {@link
|
|
* BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
|
|
*/
|
|
@Deprecated
|
|
public boolean setValue(int mantissa, int exponent, int formatType, int offset) {
|
|
int len = offset + getTypeLen(formatType);
|
|
if (mValue == null) mValue = new byte[len];
|
|
if (len > mValue.length) return false;
|
|
|
|
switch (formatType) {
|
|
case FORMAT_SFLOAT:
|
|
mantissa = intToSignedBits(mantissa, 12);
|
|
exponent = intToSignedBits(exponent, 4);
|
|
mValue[offset++] = (byte) (mantissa & 0xFF);
|
|
mValue[offset] = (byte) ((mantissa >> 8) & 0x0F);
|
|
mValue[offset] += (byte) ((exponent & 0x0F) << 4);
|
|
break;
|
|
|
|
case FORMAT_FLOAT:
|
|
mantissa = intToSignedBits(mantissa, 24);
|
|
exponent = intToSignedBits(exponent, 8);
|
|
mValue[offset++] = (byte) (mantissa & 0xFF);
|
|
mValue[offset++] = (byte) ((mantissa >> 8) & 0xFF);
|
|
mValue[offset++] = (byte) ((mantissa >> 16) & 0xFF);
|
|
mValue[offset] += (byte) (exponent & 0xFF);
|
|
break;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set the locally stored value of this characteristic.
|
|
*
|
|
* <p>See {@link #setValue(byte[])} for details.
|
|
*
|
|
* @param value New value for this characteristic
|
|
* @return true if the locally stored value has been set
|
|
* @deprecated Pass the characteristic value directly into {@link
|
|
* BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
|
|
*/
|
|
@Deprecated
|
|
public boolean setValue(String value) {
|
|
mValue = value.getBytes();
|
|
return true;
|
|
}
|
|
|
|
/** Returns the size of a give value type. */
|
|
private int getTypeLen(int formatType) {
|
|
return formatType & 0xF;
|
|
}
|
|
|
|
/** Convert a signed byte to an unsigned int. */
|
|
private int unsignedByteToInt(byte b) {
|
|
return b & 0xFF;
|
|
}
|
|
|
|
/** Convert signed bytes to a 16-bit unsigned int. */
|
|
private int unsignedBytesToInt(byte b0, byte b1) {
|
|
return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8));
|
|
}
|
|
|
|
/** Convert signed bytes to a 32-bit unsigned int. */
|
|
private int unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3) {
|
|
return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8))
|
|
+ (unsignedByteToInt(b2) << 16)
|
|
+ (unsignedByteToInt(b3) << 24);
|
|
}
|
|
|
|
/** Convert signed bytes to a 16-bit short float value. */
|
|
private float bytesToFloat(byte b0, byte b1) {
|
|
int mantissa =
|
|
unsignedToSigned(unsignedByteToInt(b0) + ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
|
|
int exponent = unsignedToSigned(unsignedByteToInt(b1) >> 4, 4);
|
|
return (float) (mantissa * Math.pow(10, exponent));
|
|
}
|
|
|
|
/** Convert signed bytes to a 32-bit short float value. */
|
|
private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
|
|
int mantissa =
|
|
unsignedToSigned(
|
|
unsignedByteToInt(b0)
|
|
+ (unsignedByteToInt(b1) << 8)
|
|
+ (unsignedByteToInt(b2) << 16),
|
|
24);
|
|
return (float) (mantissa * Math.pow(10, b3));
|
|
}
|
|
|
|
/** Convert an unsigned integer value to a two's-complement encoded signed value. */
|
|
private int unsignedToSigned(int unsigned, int size) {
|
|
if ((unsigned & (1 << (size - 1))) != 0) {
|
|
unsigned = -1 * ((1 << (size - 1)) - (unsigned & ((1 << (size - 1)) - 1)));
|
|
}
|
|
return unsigned;
|
|
}
|
|
|
|
/** Convert an integer into the signed bits of a given length. */
|
|
private int intToSignedBits(int i, int size) {
|
|
if (i < 0) {
|
|
i = (1 << (size - 1)) + (i & ((1 << (size - 1)) - 1));
|
|
}
|
|
return i;
|
|
}
|
|
}
|