Merge "Initial version of BLE support for Bluedroid" into jb-mr2-dev

This commit is contained in:
Matthew Xie
2013-02-28 18:43:32 +00:00
committed by Android (Google) Code Review
16 changed files with 4054 additions and 2 deletions

View File

@@ -102,6 +102,9 @@ LOCAL_SRC_FILES += \
core/java/android/bluetooth/IBluetoothManagerCallback.aidl \
core/java/android/bluetooth/IBluetoothPbap.aidl \
core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
core/java/android/bluetooth/IBluetoothGatt.aidl \
core/java/android/bluetooth/IBluetoothGattCallback.aidl \
core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \
core/java/android/content/IClipboard.aidl \
core/java/android/content/IContentService.aidl \
core/java/android/content/IIntentReceiver.aidl \

19
core/java/android/bluetooth/BluetoothAdapter.java Executable file → Normal file
View File

@@ -1136,8 +1136,9 @@ public final class BluetoothAdapter {
/**
* Get the profile proxy object associated with the profile.
*
* <p>Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET} or
* {@link BluetoothProfile#A2DP}. Clients must implements
* <p>Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET},
* {@link BluetoothProfile#A2DP}, {@link BluetoothProfile#GATT},
* or {@link BluetoothProfile#GATT_SERVER}. Clients must implements
* {@link BluetoothProfile.ServiceListener} to get notified of
* the connection status and to get the proxy object.
*
@@ -1166,6 +1167,12 @@ public final class BluetoothAdapter {
} else if (profile == BluetoothProfile.HEALTH) {
BluetoothHealth health = new BluetoothHealth(context, listener);
return true;
} else if (profile == BluetoothProfile.GATT) {
BluetoothGatt gatt = new BluetoothGatt(context, listener);
return true;
} else if (profile == BluetoothProfile.GATT_SERVER) {
BluetoothGattServer gattServer = new BluetoothGattServer(context, listener);
return true;
} else {
return false;
}
@@ -1206,6 +1213,14 @@ public final class BluetoothAdapter {
BluetoothHealth health = (BluetoothHealth)proxy;
health.close();
break;
case BluetoothProfile.GATT:
BluetoothGatt gatt = (BluetoothGatt)proxy;
gatt.close();
break;
case BluetoothProfile.GATT_SERVER:
BluetoothGattServer gattServer = (BluetoothGattServer)proxy;
gattServer.close();
break;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,157 @@
/*
* 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.bluetooth.BluetoothDevice;
import android.util.Log;
/**
* This abstract class is used to implement {@link BluetoothGatt} callbacks.
* @hide
*/
public abstract class BluetoothGattCallback {
/**
* Callback to inform change in registration state of the application.
*
* @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the application
* was successfully registered.
*/
public void onAppRegistered(int status) {
}
/**
* Callback reporting an LE device found during a device scan initiated
* by the {@link BluetoothGatt#startScan} function.
*
* @param device Identifies the remote device
* @param rssi The RSSI value for the remote device as reported by the
* Bluetooth hardware. 0 if no RSSI value is available.
* @param scanRecord The content of the advertisement record offered by
* the remote device.
*/
public void onScanResult(BluetoothDevice device, int rssi, byte[] scanRecord) {
}
/**
* Callback indicating when a remote device has been connected or disconnected.
*
* @param device Remote device that has been connected or disconnected.
* @param status Status of the connect or disconnect operation.
* @param newState Returns the new connection state. Can be one of
* {@link BluetoothProfile#STATE_DISCONNECTED} or
* {@link BluetoothProfile#STATE_CONNECTED}
*/
public void onConnectionStateChange(BluetoothDevice device, int status,
int newState) {
}
/**
* Callback invoked when the list of remote services, characteristics and
* descriptors for the remote device have been updated.
*
* @param device Remote device
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device
* has been explored successfully.
*/
public void onServicesDiscovered(BluetoothDevice device, int status) {
}
/**
* Callback reporting the result of a characteristic read operation.
*
* @param characteristic Characteristic that was read from the associated
* remote device.
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
* was completed successfully.
*/
public void onCharacteristicRead(BluetoothGattCharacteristic characteristic,
int status) {
}
/**
* Callback indicating the result of a characteristic write operation.
*
* <p>If this callback is invoked while a reliable write transaction is
* in progress, the value of the characteristic represents the value
* reported by the remote device. An application should compare this
* value to the desired value to be written. If the values don't match,
* the application must abort the reliable write transaction.
*
* @param characteristic Characteristic that was written to the associated
* remote device.
* @param status The result of the write operation
*/
public void onCharacteristicWrite(BluetoothGattCharacteristic characteristic,
int status) {
}
/**
* Callback triggered as a result of a remote characteristic notification.
*
* @param characteristic Characteristic that has been updated as a result
* of a remote notification event.
*/
public void onCharacteristicChanged(BluetoothGattCharacteristic characteristic) {
}
/**
* Callback reporting the result of a descriptor read operation.
*
* @param descriptor Descriptor that was read from the associated
* remote device.
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
* was completed successfully
*/
public void onDescriptorRead(BluetoothGattDescriptor descriptor,
int status) {
}
/**
* Callback indicating the result of a descriptor write operation.
*
* @param descriptor Descriptor that was writte to the associated
* remote device.
* @param status The result of the write operation
*/
public void onDescriptorWrite(BluetoothGattDescriptor descriptor,
int status) {
}
/**
* Callback invoked when a reliable write transaction has been completed.
*
* @param device Remote device
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the reliable write
* transaction was executed successfully
*/
public void onReliableWriteCompleted(BluetoothDevice device, int status) {
}
/**
* Callback reporting the RSSI for a remote device connection.
*
* This callback is triggered in response to the
* {@link BluetoothGatt#readRemoteRssi} function.
*
* @param device Identifies the remote device
* @param rssi The RSSI value for the remote device
* @param status 0 if the RSSI was read successfully
*/
public void onReadRemoteRssi(BluetoothDevice device, int rssi, int status) {
}
}

View File

@@ -0,0 +1,670 @@
/*
* 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 java.util.ArrayList;
import java.util.IllegalFormatConversionException;
import java.util.List;
import java.util.UUID;
/**
* Represents a Bluetooth Gatt Characteristic
* @hide
*/
public class BluetoothGattCharacteristic {
/**
* Characteristic proprty: 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 man-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 man-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
* man-in-the-middle protection
*/
public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
/**
* Write characteristic, requesting acknoledgement by the remote device
*/
public static final int WRITE_TYPE_DEFAULT = 0x02;
/**
* Wrtite characteristic without requiring a response by the remote device
*/
public static final int WRITE_TYPE_NO_RESPONSE = 0x01;
/**
* Write characteristic including and authenticated 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
*/
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
*/
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
* @hide
*/
/*package*/ BluetoothGattCharacteristic(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;
}
}
/**
* Returns the deisred key size.
* @hide
*/
/*package*/ int getKeySize() {
return mKeySize;
}
/**
* Add a descriptor to this characteristic
* @hide
*/
/*package*/ void addDescriptor(BluetoothGattDescriptor descriptor) {
mDescriptors.add(descriptor);
}
/**
* Returns the service this characteristic belongs to.
* @return The asscociated service
*/
public BluetoothGattService getService() {
return mService;
}
/**
* Returns the UUID of this characteristic
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @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.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return Instance ID of this characteristic
*/
public int getInstanceId() {
return mInstance;
}
/**
* Returns the properties of this characteristic.
*
* <p>The properties contain a bit mask of property flags indicating
* the features of this characteristic.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return Properties of this characteristic
*/
public int getProperties() {
return mProperties;
}
/**
* Returns the permissions for this characteristic.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return Permissions of this characteristic
*/
public int getPermissions() {
return mPermissions;
}
/**
* Gets the write type for this characteristic.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @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} function write this
* characteristic.
*
* <p>The default write type for a characteristic is
* {@link #WRITE_TYPE_DEFAULT}.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @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;
}
/**
* Returns a list of descriptors for this characteristic.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @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.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @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}. To cached
* value of the characteristic is updated as a result of a read characteristic
* operation or if a characteristic update notification has been received.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return Cached value of the characteristic
*/
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, settting 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.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @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.
*/
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.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @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.
*/
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.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
* @param offset Offset at which the string value can be found.
* @return Cached value of the characteristic
*/
public String getStringValue(int offset) {
if (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.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @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.
*/
public boolean setValue(byte[] value) {
mValue = value;
return true;
}
/**
* Set the locally stored value of this characteristic.
* <p>See {@link #setValue(byte[])} for details.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @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
*/
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);
break;
default:
return false;
}
return true;
}
/**
* Set the locally stored value of this characteristic.
* <p>See {@link #setValue(byte[])} for details.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
* @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
*/
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.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
* @param value New value for this characteristic
* @return true if the locally stored value has been set
*/
public boolean setValue(String value) {
mValue = value.getBytes();
return true;
}
/**
* Returns the size of a give value type.
* @hide
*/
private int getTypeLen(int formatType) {
return formatType & 0xF;
}
/**
* Convert a signed byte to an unsigned int.
* @hide
*/
private int unsignedByteToInt(byte b) {
return b & 0xFF;
}
/**
* Convert signed bytes to a 16-bit unsigned int.
* @hide
*/
private int unsignedBytesToInt(byte b0, byte b1) {
return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8));
}
/**
* Convert signed bytes to a 32-bit unsigned int.
* @hide
*/
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.
* @hide
*/
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.
* @hide
*/
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.
* @hide
*/
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.
* @hide
*/
private int intToSignedBits(int i, int size) {
if (i < 0) {
i = (1 << size-1) + (i & ((1 << size-1) - 1));
}
return i;
}
}

View File

@@ -0,0 +1,185 @@
/*
* 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 java.util.UUID;
/**
* Represents a Bluetooth Gatt Descriptor
* @hide
*/
public class BluetoothGattDescriptor {
/**
* Value used to enable notification for a client configuration descriptor
*/
public static final byte[] ENABLE_NOTIFICATION_VALUE = {0x01, 0x00};
/**
* Value used to enable indication for a client configuration descriptor
*/
public static final byte[] ENABLE_INDICATION_VALUE = {0x02, 0x00};
/**
* Value used to disable notifications or indicatinos
*/
public static final byte[] DISABLE_NOTIFICATION_VALUE = {0x00, 0x00};
/**
* Descriptor read permission
*/
public static final int PERMISSION_READ = 0x01;
/**
* Descriptor permission: Allow encrypted read operations
*/
public static final int PERMISSION_READ_ENCRYPTED = 0x02;
/**
* Descriptor permission: Allow reading with man-in-the-middle protection
*/
public static final int PERMISSION_READ_ENCRYPTED_MITM = 0x04;
/**
* Descriptor write permission
*/
public static final int PERMISSION_WRITE = 0x10;
/**
* Descriptor permission: Allow encrypted writes
*/
public static final int PERMISSION_WRITE_ENCRYPTED = 0x20;
/**
* Descriptor permission: Allow encrypted writes with man-in-the-middle
* protection
*/
public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 0x40;
/**
* Descriptor permission: Allow signed write operations
*/
public static final int PERMISSION_WRITE_SIGNED = 0x80;
/**
* Descriptor permission: Allow signed write operations with
* man-in-the-middle protection
*/
public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
/**
* The UUID of this descriptor.
* @hide
*/
protected UUID mUuid;
/**
* Permissions for this descriptor
* @hide
*/
protected int mPermissions;
/**
* Back-reference to the characteristic this descriptor belongs to.
* @hide
*/
protected BluetoothGattCharacteristic mCharacteristic;
/**
* The value for this descriptor.
* @hide
*/
protected byte[] mValue;
/**
* Create a new BluetoothGattDescriptor.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param characteristic The characteristic this descriptor belongs to
* @param uuid The UUID for this descriptor
* @param permissions Permissions for this descriptor
*/
/*package*/ BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
int permissions) {
mCharacteristic = characteristic;
mUuid = uuid;
mPermissions = permissions;
}
/**
* Returns the characteristic this descriptor belongs to.
* @return The characteristic.
*/
public BluetoothGattCharacteristic getCharacteristic() {
return mCharacteristic;
}
/**
* Returns the UUID of this descriptor.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return UUID of this descriptor
*/
public UUID getUuid() {
return mUuid;
}
/**
* Returns the permissions for this descriptor.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return Permissions of this descriptor
*/
public int getPermissions() {
return mPermissions;
}
/**
* Returns the stored value for this descriptor
*
* <p>This function returns the stored value for this descriptor as
* retrieved by calling {@link BluetoothGatt#readDescriptor}. To cached
* value of the descriptor is updated as a result of a descriptor read
* operation.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return Cached value of the descriptor
*/
public byte[] getValue() {
return mValue;
}
/**
* Updates the locally stored value of this descriptor.
*
* <p>This function modifies the locally stored cached value of this
* descriptor. To send the value to the remote device, call
* {@link BluetoothGatt#writeDescriptor} to send the value to the
* remote device.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param value New value for this descriptor
* @return true if the locally stored value has been set, false if the
* requested value could not be stored locally.
*/
public boolean setValue(byte[] value) {
mValue = value;
return true;
}
}

View File

@@ -0,0 +1,900 @@
/*
* 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.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile.ServiceListener;
import android.bluetooth.IBluetoothManager;
import android.bluetooth.IBluetoothStateChangeCallback;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* Public API for the Bluetooth Gatt Profile server role.
*
* <p>This class provides Bluetooth Gatt server role functionality,
* allowing applications to create and advertise Bluetooth Smart services
* and characteristics.
*
* <p>BluetoothGattServer is a proxy object for controlling the Bluetooth Service
* via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get the
* BluetoothGatt proxy object.
* @hide
*/
public final class BluetoothGattServer implements BluetoothProfile {
private static final String TAG = "BluetoothGattServer";
private static final boolean DBG = true;
private Context mContext;
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
private IBluetoothGatt mService;
private BluetoothGattServerCallback mCallback;
private int mServerIf;
private List<BluetoothGattService> mServices;
/**
* Bluetooth state change handlers
*/
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (DBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (DBG) Log.d(TAG,"Binding service...");
if (!mContext.bindService(new
Intent(IBluetoothGatt.class.getName()),
mConnection, 0)) {
Log.e(TAG, "Could not bind to Bluetooth GATT Service");
}
}
} catch (Exception re) {
Log.e(TAG,"",re);
}
}
}
}
};
/**
* Service binder handling
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothGatt.Stub.asInterface(service);
ServiceListener serviceListner = mServiceListener;
if (serviceListner != null) {
serviceListner.onServiceConnected(BluetoothProfile.GATT_SERVER,
BluetoothGattServer.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
ServiceListener serviceListner = mServiceListener;
if (serviceListner != null) {
serviceListner.onServiceDisconnected(BluetoothProfile.GATT_SERVER);
}
}
};
/**
* Bluetooth GATT interface callbacks
*/
private final IBluetoothGattServerCallback mBluetoothGattServerCallback =
new IBluetoothGattServerCallback.Stub() {
/**
* Application interface registered - app is ready to go
* @hide
*/
public void onServerRegistered(int status, int serverIf) {
if (DBG) Log.d(TAG, "onServerRegistered() - status=" + status
+ " serverIf=" + serverIf);
mServerIf = serverIf;
try {
mCallback.onAppRegistered(status);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
/**
* Callback reporting an LE scan result.
* @hide
*/
public void onScanResult(String address, int rssi, byte[] advData) {
if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
try {
mCallback.onScanResult(mAdapter.getRemoteDevice(address),
rssi, advData);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
/**
* Server connection state changed
* @hide
*/
public void onServerConnectionState(int status, int serverIf,
boolean connected, String address) {
if (DBG) Log.d(TAG, "onServerConnectionState() - status=" + status
+ " serverIf=" + serverIf + " device=" + address);
try {
mCallback.onConnectionStateChange(mAdapter.getRemoteDevice(address), status,
connected ? BluetoothProfile.STATE_CONNECTED :
BluetoothProfile.STATE_DISCONNECTED);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
/**
* Service has been added
* @hide
*/
public void onServiceAdded(int status, int srvcType,
int srvcInstId, ParcelUuid srvcId) {
UUID srvcUuid = srvcId.getUuid();
if (DBG) Log.d(TAG, "onServiceAdded() - service=" + srvcUuid
+ "status=" + status);
BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
if (service == null) return;
try {
mCallback.onServiceAdded((int)status, service);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
/**
* Remote client characteristic read request.
* @hide
*/
public void onCharacteristicReadRequest(String address, int transId,
int offset, boolean isLong, int srvcType, int srvcInstId,
ParcelUuid srvcId, int charInstId, ParcelUuid charId) {
UUID srvcUuid = srvcId.getUuid();
UUID charUuid = charId.getUuid();
if (DBG) Log.d(TAG, "onCharacteristicReadRequest() - "
+ "service=" + srvcUuid + ", characteristic=" + charUuid);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
if (service == null) return;
BluetoothGattCharacteristic characteristic = service.getCharacteristic(
charUuid);
if (characteristic == null) return;
try {
mCallback.onCharacteristicReadRequest(device, transId, offset, characteristic);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
/**
* Remote client descriptor read request.
* @hide
*/
public void onDescriptorReadRequest(String address, int transId,
int offset, boolean isLong, int srvcType, int srvcInstId,
ParcelUuid srvcId, int charInstId, ParcelUuid charId,
ParcelUuid descrId) {
UUID srvcUuid = srvcId.getUuid();
UUID charUuid = charId.getUuid();
UUID descrUuid = descrId.getUuid();
if (DBG) Log.d(TAG, "onCharacteristicReadRequest() - "
+ "service=" + srvcUuid + ", characteristic=" + charUuid
+ "descriptor=" + descrUuid);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
if (service == null) return;
BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid);
if (characteristic == null) return;
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(descrUuid);
if (descriptor == null) return;
try {
mCallback.onDescriptorReadRequest(device, transId, offset, descriptor);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
/**
* Remote client characteristic write request.
* @hide
*/
public void onCharacteristicWriteRequest(String address, int transId,
int offset, int length, boolean isPrep, boolean needRsp,
int srvcType, int srvcInstId, ParcelUuid srvcId,
int charInstId, ParcelUuid charId, byte[] value) {
UUID srvcUuid = srvcId.getUuid();
UUID charUuid = charId.getUuid();
if (DBG) Log.d(TAG, "onCharacteristicWriteRequest() - "
+ "service=" + srvcUuid + ", characteristic=" + charUuid);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
if (service == null) return;
BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid);
if (characteristic == null) return;
try {
mCallback.onCharacteristicWriteRequest(device, transId, characteristic,
isPrep, needRsp, offset, value);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
/**
* Remote client descriptor write request.
* @hide
*/
public void onDescriptorWriteRequest(String address, int transId,
int offset, int length, boolean isPrep, boolean needRsp,
int srvcType, int srvcInstId, ParcelUuid srvcId,
int charInstId, ParcelUuid charId, ParcelUuid descrId,
byte[] value) {
UUID srvcUuid = srvcId.getUuid();
UUID charUuid = charId.getUuid();
UUID descrUuid = descrId.getUuid();
if (DBG) Log.d(TAG, "onDescriptorWriteRequest() - "
+ "service=" + srvcUuid + ", characteristic=" + charUuid
+ "descriptor=" + descrUuid);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
if (service == null) return;
BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid);
if (characteristic == null) return;
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(descrUuid);
if (descriptor == null) return;
try {
mCallback.onDescriptorWriteRequest(device, transId, descriptor,
isPrep, needRsp, offset, value);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
/**
* Execute pending writes.
* @hide
*/
public void onExecuteWrite(String address, int transId,
boolean execWrite) {
if (DBG) Log.d(TAG, "onExecuteWrite() - "
+ "device=" + address + ", transId=" + transId
+ "execWrite=" + execWrite);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
try {
mCallback.onExecuteWrite(device, transId, execWrite);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
};
/**
* Create a BluetoothGattServer proxy object.
*/
/*package*/ BluetoothGattServer(Context context, ServiceListener l) {
mContext = context;
mServiceListener = l;
mAdapter = BluetoothAdapter.getDefaultAdapter();
mServices = new ArrayList<BluetoothGattService>();
IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE);
if (b != null) {
IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b);
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException re) {
Log.e(TAG, "Unable to register BluetoothStateChangeCallback", re);
}
} else {
Log.e(TAG, "Unable to get BluetoothManager interface.");
throw new RuntimeException("BluetoothManager inactive");
}
//Bind to the service only if the Bluetooth is ON
if(mAdapter.isEnabled()){
if (!context.bindService(new Intent(IBluetoothGatt.class.getName()), mConnection, 0)) {
Log.e(TAG, "Could not bind to Bluetooth Gatt Service");
}
}
}
/**
* Close the connection to the gatt service.
*/
/*package*/ void close() {
if (DBG) Log.d(TAG, "close()");
unregisterApp();
mServiceListener = null;
IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE);
if (b != null) {
IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b);
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException re) {
Log.e(TAG, "Unable to unregister BluetoothStateChangeCallback", re);
}
}
synchronized (mConnection) {
if (mService != null) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
}
}
}
}
/**
* Returns a service by UUID, instance and type.
* @hide
*/
/*package*/ BluetoothGattService getService(UUID uuid, int instanceId, int type) {
for(BluetoothGattService svc : mServices) {
if (svc.getType() == type &&
svc.getInstanceId() == instanceId &&
svc.getUuid().equals(uuid)) {
return svc;
}
}
return null;
}
/**
* Register an application callback to start using Gatt.
*
* <p>This is an asynchronous call. The callback is used to notify
* success or failure if the function returns true.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param callback Gatt callback handler that will receive asynchronous
* callbacks.
* @return true, if application was successfully registered.
*/
public boolean registerApp(BluetoothGattServerCallback callback) {
if (DBG) Log.d(TAG, "registerApp()");
if (mService == null) return false;
mCallback = callback;
UUID uuid = UUID.randomUUID();
if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);
try {
mService.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
}
return true;
}
/**
* Unregister the current application and callbacks.
*/
public void unregisterApp() {
if (DBG) Log.d(TAG, "unregisterApp() - mServerIf=" + mServerIf);
if (mService == null || mServerIf == 0) return;
try {
mCallback = null;
mService.unregisterServer(mServerIf);
mServerIf = 0;
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
}
/**
* Starts a scan for Bluetooth LE devices.
*
* <p>Results of the scan are reported using the
* {@link BluetoothGattServerCallback#onScanResult} callback.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return true, if the scan was started successfully
*/
public boolean startScan() {
if (DBG) Log.d(TAG, "startScan()");
if (mService == null || mServerIf == 0) return false;
try {
mService.startScan(mServerIf, true);
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
}
return true;
}
/**
* Starts a scan for Bluetooth LE devices, looking for devices that
* advertise given services.
*
* <p>Devices which advertise all specified services are reported using the
* {@link BluetoothGattServerCallback#onScanResult} callback.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param serviceUuids Array of services to look for
* @return true, if the scan was started successfully
*/
public boolean startScan(UUID[] serviceUuids) {
if (DBG) Log.d(TAG, "startScan() - with UUIDs");
if (mService == null || mServerIf == 0) return false;
try {
ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length];
for(int i = 0; i != uuids.length; ++i) {
uuids[i] = new ParcelUuid(serviceUuids[i]);
}
mService.startScanWithUuids(mServerIf, true, uuids);
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
}
return true;
}
/**
* Stops an ongoing Bluetooth LE device scan.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*/
public void stopScan() {
if (DBG) Log.d(TAG, "stopScan()");
if (mService == null || mServerIf == 0) return;
try {
mService.stopScan(mServerIf, true);
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
}
/**
* Initiate a connection to a Bluetooth Gatt capable device.
*
* <p>The connection may not be established right away, but will be
* completed when the remote device is available. A
* {@link BluetoothGattCallback#onConnectionStateChange} callback will be
* invoked when the connection state changes as a result of this function.
*
* <p>The autoConnect paramter determines whether to actively connect to
* the remote device, or rather passively scan and finalize the connection
* when the remote device is in range/available. Generally, the first ever
* connection to a device should be direct (autoConnect set to false) and
* subsequent connections to known devices should be invoked with the
* autoConnect parameter set to false.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device Remote device to connect to
* @param autoConnect Whether to directly connect to the remote device (false)
* or to automatically connect as soon as the remote
* device becomes available (true).
* @return true, if the connection attempt was initiated successfully
*/
public boolean connect(BluetoothDevice device, boolean autoConnect) {
if (DBG) Log.d(TAG, "connect: " + device.getAddress() + ", auto: " + autoConnect);
if (mService == null || mServerIf == 0) return false;
try {
mService.serverConnect(mServerIf, device.getAddress(),
autoConnect ? false : true); // autoConnect is inverse of "isDirect"
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
}
return true;
}
/**
* Disconnects an established connection, or cancels a connection attempt
* currently in progress.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device Remote device
*/
public void cancelConnection(BluetoothDevice device) {
if (DBG) Log.d(TAG, "cancelConnection() - device: " + device.getAddress());
if (mService == null || mServerIf == 0) return;
try {
mService.serverDisconnect(mServerIf, device.getAddress());
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
}
/**
* Send a response to a read or write request to a remote device.
*
* <p>This function must be invoked in when a remote read/write request
* is received by one of these callback methots:
*
* <ul>
* <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest}
* <li>{@link BluetoothGattServerCallback#onCharacteristicWriteRequest}
* <li>{@link BluetoothGattServerCallback#onDescriptorReadRequest}
* <li>{@link BluetoothGattServerCallback#onDescriptorWriteRequest}
* </ul>
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device The remote device to send this response to
* @param requestId The ID of the request that was received with the callback
* @param status The status of the request to be sent to the remote devices
* @param offset Value offset for partial read/write response
* @param value The value of the attribute that was read/written (optional)
*/
public boolean sendResponse(BluetoothDevice device, int requestId,
int status, int offset, byte[] value) {
if (DBG) Log.d(TAG, "sendResponse() - device: " + device.getAddress());
if (mService == null || mServerIf == 0) return false;
try {
mService.sendResponse(mServerIf, device.getAddress(), requestId,
status, offset, value);
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
}
return true;
}
/**
* Send a notification or indication that a local characteristic has been
* updated.
*
* <p>A notification or indication is sent to the remote device to signal
* that the characteristic has been updated. This function should be invoked
* for every client that requests notifications/indications by writing
* to the "Client Configuration" descriptor for the given characteristic.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device The remote device to receive the notification/indication
* @param characteristic The local characteristic that has been updated
* @param confirm true to request confirmation from the client (indication),
* false to send a notification
* @return true, if the notification has been triggered successfully
*/
public boolean notifyCharacteristicChanged(BluetoothDevice device,
BluetoothGattCharacteristic characteristic, boolean confirm) {
if (DBG) Log.d(TAG, "notifyCharacteristicChanged() - device: " + device.getAddress());
if (mService == null || mServerIf == 0) return false;
BluetoothGattService service = characteristic.getService();
if (service == null) return false;
try {
mService.sendNotification(mServerIf, device.getAddress(),
service.getType(), service.getInstanceId(),
new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
new ParcelUuid(characteristic.getUuid()), confirm,
characteristic.getValue());
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
}
return true;
}
/**
* Add a service to the list of services to be advertised.
*
* <p>Once a service has been addded to the the list, the service and it's
* included characteristics will be advertised by the local device.
*
* <p>If the local device is already advertising services when this function
* is called, a service update notification will be sent to all clients.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param service Service to be added to the list of services advertised
* by this device.
* @return true, if the service has been added successfully
*/
public boolean addService(BluetoothGattService service) {
if (DBG) Log.d(TAG, "addService() - service: " + service.getUuid());
if (mService == null || mServerIf == 0) return false;
mServices.add(service);
try {
mService.beginServiceDeclaration(mServerIf, service.getType(),
service.getInstanceId(), service.getHandles(),
new ParcelUuid(service.getUuid()));
List<BluetoothGattService> includedServices = service.getIncludedServices();
for (BluetoothGattService includedService : includedServices) {
mService.addIncludedService(mServerIf,
includedService.getType(),
includedService.getInstanceId(),
new ParcelUuid(includedService.getUuid()));
}
List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
for (BluetoothGattCharacteristic characteristic : characteristics) {
int permission = ((characteristic.getKeySize() - 7) << 12)
+ characteristic.getPermissions();
mService.addCharacteristic(mServerIf,
new ParcelUuid(characteristic.getUuid()),
characteristic.getProperties(), permission);
List<BluetoothGattDescriptor> descriptors = characteristic.getDescriptors();
for (BluetoothGattDescriptor descriptor: descriptors) {
mService.addDescriptor(mServerIf,
new ParcelUuid(descriptor.getUuid()),
descriptor.getPermissions());
}
}
mService.endServiceDeclaration(mServerIf);
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
}
return true;
}
/**
* Removes a service from the list of services to be advertised.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param service Service to beremoved.
* @return true, if the service has been removed
*/
public boolean removeService(BluetoothGattService service) {
if (DBG) Log.d(TAG, "removeService() - service: " + service.getUuid());
if (mService == null || mServerIf == 0) return false;
BluetoothGattService intService = getService(service.getUuid(),
service.getInstanceId(), service.getType());
if (intService == null) return false;
try {
mService.removeService(mServerIf, service.getType(),
service.getInstanceId(), new ParcelUuid(service.getUuid()));
mServices.remove(intService);
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
}
return true;
}
/**
* Remove all services from the list of advertised services.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*/
public void clearServices() {
if (DBG) Log.d(TAG, "clearServices()");
if (mService == null || mServerIf == 0) return;
try {
mService.clearServices(mServerIf);
mServices.clear();
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
}
/**
* Returns a list of GATT services offered bu this device.
*
* <p>An application must call {@link #addService} to add a serice to the
* list of services offered by this device.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return List of services. Returns an empty list
* if no services have been added yet.
*/
public List<BluetoothGattService> getServices() {
return mServices;
}
/**
* Returns a {@link BluetoothGattService} from the list of services offered
* by this device.
*
* <p>If multiple instances of the same service (as identified by UUID)
* exist, the first instance of the service is returned.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param uuid UUID of the requested service
* @return BluetoothGattService if supported, or null if the requested
* service is not offered by this device.
*/
public BluetoothGattService getService(UUID uuid) {
for (BluetoothGattService service : mServices) {
if (service.getUuid().equals(uuid)) {
return service;
}
}
return null;
}
/**
* Get the current connection state of the profile.
*
* <p>This is not specific to any application configuration but represents
* the connection state of the local Bluetooth adapter for this profile.
* This can be used by applications like status bar which would just like
* to know the state of the local adapter.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device Remote bluetooth device.
* @return State of the profile connection. One of
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
*/
@Override
public int getConnectionState(BluetoothDevice device) {
if (DBG) Log.d(TAG,"getConnectionState()");
if (mService == null) return STATE_DISCONNECTED;
List<BluetoothDevice> connectedDevices = getConnectedDevices();
for(BluetoothDevice connectedDevice : connectedDevices) {
if (device.equals(connectedDevice)) {
return STATE_CONNECTED;
}
}
return STATE_DISCONNECTED;
}
/**
* Get connected devices for the Gatt profile.
*
* <p> Return the set of devices which are in state {@link #STATE_CONNECTED}
*
* <p>This is not specific to any application configuration but represents
* the connection state of the local Bluetooth adapter for this profile.
* This can be used by applications like status bar which would just like
* to know the state of the local adapter.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return List of devices. The list will be empty on error.
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) Log.d(TAG,"getConnectedDevices");
List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>();
if (mService == null) return connectedDevices;
try {
connectedDevices = mService.getDevicesMatchingConnectionStates(
new int[] { BluetoothProfile.STATE_CONNECTED });
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
return connectedDevices;
}
/**
* Get a list of devices that match any of the given connection
* states.
*
* <p> If none of the devices match any of the given states,
* an empty list will be returned.
*
* <p>This is not specific to any application configuration but represents
* the connection state of the local Bluetooth adapter for this profile.
* This can be used by applications like status bar which would just like
* to know the state of the local adapter.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param states Array of states. States can be one of
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
* @return List of devices. The list will be empty on error.
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates");
List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
if (mService == null) return devices;
try {
devices = mService.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
return devices;
}
}

View File

@@ -0,0 +1,158 @@
/*
* 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.bluetooth.BluetoothDevice;
import android.util.Log;
/**
* This abstract class is used to implement {@link BluetoothGattServer} callbacks.
* @hide
*/
public abstract class BluetoothGattServerCallback {
/**
* Callback to inform change in registration state of the application.
*
* @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the application
* was successfully registered.
*/
public void onAppRegistered(int status) {
}
/**
* Callback reporting an LE device found during a device scan initiated
* by the {@link BluetoothGattServer#startScan} function.
*
* @param device Identifies the remote device
* @param rssi The RSSI value for the remote device as reported by the
* Bluetooth hardware. 0 if no RSSI value is available.
* @param scanRecord The content of the advertisement record offered by
* the remote device.
*/
public void onScanResult(BluetoothDevice device, int rssi, byte[] scanRecord) {
}
/**
* Callback indicating when a remote device has been connected or disconnected.
*
* @param device Remote device that has been connected or disconnected.
* @param status Status of the connect or disconnect operation.
* @param newState Returns the new connection state. Can be one of
* {@link BluetoothProfile#STATE_DISCONNECTED} or
* {@link BluetoothProfile#STATE_CONNECTED}
*/
public void onConnectionStateChange(BluetoothDevice device, int status,
int newState) {
}
/**
* Indicates whether a local service has been added successfully.
*
* @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the service
* was added successfully.
* @param service The service that has been added
*/
public void onServiceAdded(int status, BluetoothGattService service) {
}
/**
* A remote client has requested to read a local characteristic.
*
* <p>An application must call {@link BluetoothGattServer#sendResponse}
* to complete the request.
*
* @param device The remote device that has requested the read operation
* @param requestId The Id of the request
* @param offset Offset into the value of the characteristic
* @param characteristic Characteristic to be read
*/
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
int offset, BluetoothGattCharacteristic characteristic) {
}
/**
* A remote client has requested to write to a local characteristic.
*
* <p>An application must call {@link BluetoothGattServer#sendResponse}
* to complete the request.
*
* @param device The remote device that has requested the write operation
* @param requestId The Id of the request
* @param characteristic Characteristic to be written to.
* @param preparedWrite true, if this write operation should be queued for
* later execution.
* @param responseNeeded true, if the remote device requires a response
* @param offset The offset given for the value
* @param value The value the client wants to assign to the characteristic
*/
public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
BluetoothGattCharacteristic characteristic,
boolean preparedWrite, boolean responseNeeded,
int offset, byte[] value) {
}
/**
* A remote client has requested to read a local descriptor.
*
* <p>An application must call {@link BluetoothGattServer#sendResponse}
* to complete the request.
*
* @param device The remote device that has requested the read operation
* @param requestId The Id of the request
* @param offset Offset into the value of the characteristic
* @param descriptor Descriptor to be read
*/
public void onDescriptorReadRequest(BluetoothDevice device, int requestId,
int offset, BluetoothGattDescriptor descriptor) {
}
/**
* A remote client has requested to write to a local descriptor.
*
* <p>An application must call {@link BluetoothGattServer#sendResponse}
* to complete the request.
*
* @param device The remote device that has requested the write operation
* @param requestId The Id of the request
* @param descriptor Descriptor to be written to.
* @param preparedWrite true, if this write operation should be queued for
* later execution.
* @param responseNeeded true, if the remote device requires a response
* @param offset The offset given for the value
* @param value The value the client wants to assign to the descriptor
*/
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
BluetoothGattDescriptor descriptor,
boolean preparedWrite, boolean responseNeeded,
int offset, byte[] value) {
}
/**
* Execute all pending write operations for this device.
*
* <p>An application must call {@link BluetoothGattServer#sendResponse}
* to complete the request.
*
* @param device The remote device that has requested the write operations
* @param requestId The Id of the request
* @param execute Whether the pending writes should be executed (true) or
* cancelled (false)
*/
public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
}
}

View File

@@ -0,0 +1,232 @@
/*
* 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.bluetooth.BluetoothDevice;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* Represents a Bluetooth Gatt Service
* @hide
*/
public class BluetoothGattService {
/**
* Primary service
*/
public static final int SERVICE_TYPE_PRIMARY = 0;
/**
* Secondary service (included by primary services)
*/
public static final int SERVICE_TYPE_SECONDARY = 1;
/**
* The remote device his service is associated with.
* This applies to client applications only.
* @hide
*/
protected BluetoothDevice mDevice;
/**
* The UUID of this service.
* @hide
*/
protected UUID mUuid;
/**
* Instance ID for this service.
* @hide
*/
protected int mInstanceId;
/**
* Handle counter override (for conformance testing).
* @hide
*/
protected int mHandles = 0;
/**
* Service type (Primary/Secondary).
* @hide
*/
protected int mServiceType;
/**
* List of characteristics included in this service.
*/
protected List<BluetoothGattCharacteristic> mCharacteristics;
/**
* List of included services for this service.
*/
protected List<BluetoothGattService> mIncludedServices;
/**
* Create a new BluetoothGattService.
* @hide
*/
/*package*/ BluetoothGattService(UUID uuid, int serviceType) {
mDevice = null;
mUuid = uuid;
mInstanceId = 0;
mServiceType = serviceType;
mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
mIncludedServices = new ArrayList<BluetoothGattService>();
}
/**
* Create a new BluetoothGattService
* @hide
*/
/*package*/ BluetoothGattService(BluetoothDevice device, UUID uuid,
int instanceId, int serviceType) {
mDevice = device;
mUuid = uuid;
mInstanceId = instanceId;
mServiceType = serviceType;
mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
mIncludedServices = new ArrayList<BluetoothGattService>();
}
/**
* Returns the device associated with this service.
* @hide
*/
/*package*/ BluetoothDevice getDevice() {
return mDevice;
}
/**
* Add a characteristic to this service.
* @hide
*/
/*package*/ void addCharacteristic(BluetoothGattCharacteristic characteristic) {
mCharacteristics.add(characteristic);
}
/**
* Get characteristic by UUID and instanceId.
* @hide
*/
/*package*/ BluetoothGattCharacteristic getCharacteristic(UUID uuid, int instanceId) {
for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
if (uuid.equals(characteristic.getUuid()) &&
mInstanceId == instanceId)
return characteristic;
}
return null;
}
/**
* Get the handle count override (conformance testing.
* @hide
*/
/*package*/ int getHandles() {
return mHandles;
}
/**
* Add an included service to the internal map.
* @hide
*/
/*package*/ void addIncludedService(BluetoothGattService includedService) {
mIncludedServices.add(includedService);
}
/**
* Returns the UUID of this service
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return UUID of this service
*/
public UUID getUuid() {
return mUuid;
}
/**
* Returns the instance ID for this service
*
* <p>If a remote device offers multiple services with the same UUID
* (ex. multiple battery services for different batteries), the instance
* ID is used to distuinguish services.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return Instance ID of this service
*/
public int getInstanceId() {
return mInstanceId;
}
/**
* Get the type of this service (primary/secondary)
* @hide
*/
public int getType() {
return mServiceType;
}
/**
* Get the list of included Gatt services for this service.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return List of included services or empty list if no included services
* were discovered.
*/
public List<BluetoothGattService> getIncludedServices() {
return mIncludedServices;
}
/**
* Returns a list of characteristics included in this service.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return Characteristics included in this service
*/
public List<BluetoothGattCharacteristic> getCharacteristics() {
return mCharacteristics;
}
/**
* Returns a characteristic with a given UUID out of the list of
* characteristics offered by this service.
*
* <p>This is a convenience function to allow access to a given characteristic
* without enumerating over the list returned by {@link #getCharacteristics}
* manually.
*
* <p>If a remote service offers multiple characteristics with the same
* UUID, the first instance of a characteristic with the given UUID
* is returned.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return Gatt characteristic object or null if no characteristic with the
* given UUID was found.
*/
public BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
if (uuid.equals(characteristic.getUuid()))
return characteristic;
}
return null;
}
}

12
core/java/android/bluetooth/BluetoothProfile.java Executable file → Normal file
View File

@@ -87,6 +87,18 @@ public interface BluetoothProfile {
*/
public static final int PBAP = 6;
/**
* GATT
* @hide
*/
static public final int GATT = 7;
/**
* GATT_SERVER
* @hide
*/
static public final int GATT_SERVER = 8;
/**
* Default priority for devices that we try to auto-connect to and
* and allow incoming connections for the profile

View File

@@ -0,0 +1,90 @@
/*
* 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.bluetooth.BluetoothDevice;
import android.os.ParcelUuid;
import android.bluetooth.IBluetoothGattCallback;
import android.bluetooth.IBluetoothGattServerCallback;
/**
* API for interacting with BLE / GATT
* @hide
*/
interface IBluetoothGatt {
List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
void startScan(in int appIf, in boolean isServer);
void startScanWithUuids(in int appIf, in boolean isServer, in ParcelUuid[] ids);
void stopScan(in int appIf, in boolean isServer);
void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback);
void unregisterClient(in int clientIf);
void clientConnect(in int clientIf, in String address, in boolean isDirect);
void clientDisconnect(in int clientIf, in String address);
void refreshDevice(in int clientIf, in String address);
void discoverServices(in int clientIf, in String address);
void readCharacteristic(in int clientIf, in String address, in int srvcType,
in int srvcInstanceId, in ParcelUuid srvcId,
in int charInstanceId, in ParcelUuid charId,
in int authReq);
void writeCharacteristic(in int clientIf, in String address, in int srvcType,
in int srvcInstanceId, in ParcelUuid srvcId,
in int charInstanceId, in ParcelUuid charId,
in int writeType, in int authReq, in byte[] value);
void readDescriptor(in int clientIf, in String address, in int srvcType,
in int srvcInstanceId, in ParcelUuid srvcId,
in int charInstanceId, in ParcelUuid charId,
in ParcelUuid descrUuid, in int authReq);
void writeDescriptor(in int clientIf, in String address, in int srvcType,
in int srvcInstanceId, in ParcelUuid srvcId,
in int charInstanceId, in ParcelUuid charId,
in ParcelUuid descrId, in int writeType,
in int authReq, in byte[] value);
void registerForNotification(in int clientIf, in String address, in int srvcType,
in int srvcInstanceId, in ParcelUuid srvcId,
in int charInstanceId, in ParcelUuid charId,
in boolean enable);
void beginReliableWrite(in int clientIf, in String address);
void endReliableWrite(in int clientIf, in String address, in boolean execute);
void readRemoteRssi(in int clientIf, in String address);
void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallback callback);
void unregisterServer(in int serverIf);
void serverConnect(in int servertIf, in String address, in boolean isDirect);
void serverDisconnect(in int serverIf, in String address);
void beginServiceDeclaration(in int serverIf, in int srvcType,
in int srvcInstanceId, in int minHandles,
in ParcelUuid srvcId);
void addIncludedService(in int serverIf, in int srvcType,
in int srvcInstanceId, in ParcelUuid srvcId);
void addCharacteristic(in int serverIf, in ParcelUuid charId,
in int properties, in int permissions);
void addDescriptor(in int serverIf, in ParcelUuid descId,
in int permissions);
void endServiceDeclaration(in int serverIf);
void removeService(in int serverIf, in int srvcType,
in int srvcInstanceId, in ParcelUuid srvcId);
void clearServices(in int serverIf);
void sendResponse(in int serverIf, in String address, in int requestId,
in int status, in int offset, in byte[] value);
void sendNotification(in int serverIf, in String address, in int srvcType,
in int srvcInstanceId, in ParcelUuid srvcId,
in int charInstanceId, in ParcelUuid charId,
in boolean confirm, in byte[] value);
}

View File

@@ -0,0 +1,65 @@
/*
* 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.os.ParcelUuid;
/**
* Callback definitions for interacting with BLE / GATT
* @hide
*/
interface IBluetoothGattCallback {
void onClientRegistered(in int status, in int clientIf);
void onClientConnectionState(in int status, in int clientIf,
in boolean connected, in String address);
void onScanResult(in String address, in int rssi, in byte[] advData);
void onGetService(in String address, in int srvcType, in int srvcInstId,
in ParcelUuid srvcUuid);
void onGetIncludedService(in String address, in int srvcType, in int srvcInstId,
in ParcelUuid srvcUuid, in int inclSrvcType,
in int inclSrvcInstId, in ParcelUuid inclSrvcUuid);
void onGetCharacteristic(in String address, in int srvcType,
in int srvcInstId, in ParcelUuid srvcUuid,
in int charInstId, in ParcelUuid charUuid,
in int charProps);
void onGetDescriptor(in String address, in int srvcType,
in int srvcInstId, in ParcelUuid srvcUuid,
in int charInstId, in ParcelUuid charUuid,
in ParcelUuid descrUuid);
void onSearchComplete(in String address, in int status);
void onCharacteristicRead(in String address, in int status, in int srvcType,
in int srvcInstId, in ParcelUuid srvcUuid,
in int charInstId, in ParcelUuid charUuid,
in byte[] value);
void onCharacteristicWrite(in String address, in int status, in int srvcType,
in int srvcInstId, in ParcelUuid srvcUuid,
in int charInstId, in ParcelUuid charUuid);
void onExecuteWrite(in String address, in int status);
void onDescriptorRead(in String address, in int status, in int srvcType,
in int srvcInstId, in ParcelUuid srvcUuid,
in int charInstId, in ParcelUuid charUuid,
in ParcelUuid descrUuid, in byte[] value);
void onDescriptorWrite(in String address, in int status, in int srvcType,
in int srvcInstId, in ParcelUuid srvcUuid,
in int charInstId, in ParcelUuid charUuid,
in ParcelUuid descrUuid);
void onNotify(in String address, in int srvcType,
in int srvcInstId, in ParcelUuid srvcUuid,
in int charInstId, in ParcelUuid charUuid,
in byte[] value);
void onReadRemoteRssi(in String address, in int rssi, in int status);
}

View File

@@ -0,0 +1,61 @@
/*
* 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.os.ParcelUuid;
/**
* Callback definitions for interacting with BLE / GATT
* @hide
*/
interface IBluetoothGattServerCallback {
void onServerRegistered(in int status, in int serverIf);
void onScanResult(in String address, in int rssi, in byte[] advData);
void onServerConnectionState(in int status, in int serverIf,
in boolean connected, in String address);
void onServiceAdded(in int status, in int srvcType,
in int srvcInstId, in ParcelUuid srvcId);
void onCharacteristicReadRequest(in String address, in int transId,
in int offset, in boolean isLong,
in int srvcType,
in int srvcInstId, in ParcelUuid srvcId,
in int charInstId, in ParcelUuid charId);
void onDescriptorReadRequest(in String address, in int transId,
in int offset, in boolean isLong,
in int srvcType,
in int srvcInstId, in ParcelUuid srvcId,
in int charInstId, in ParcelUuid charId,
in ParcelUuid descrId);
void onCharacteristicWriteRequest(in String address, in int transId,
in int offset, in int length,
in boolean isPrep,
in boolean needRsp,
in int srvcType,
in int srvcInstId, in ParcelUuid srvcId,
in int charInstId, in ParcelUuid charId,
in byte[] value);
void onDescriptorWriteRequest(in String address, in int transId,
in int offset, in int length,
in boolean isPrep,
in boolean needRsp,
in int srvcType,
in int srvcInstId, in ParcelUuid srvcId,
in int charInstId, in ParcelUuid charId,
in ParcelUuid descrId,
in byte[] value);
void onExecuteWrite(in String address, in int transId, in boolean execWrite);
}

View File

@@ -0,0 +1,67 @@
/*
* 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 java.util.ArrayList;
import java.util.IllegalFormatConversionException;
import java.util.List;
import java.util.UUID;
/**
* Mutable variant of a Bluetooth Gatt Characteristic
* @hide
*/
public class MutableBluetoothGattCharacteristic extends BluetoothGattCharacteristic {
/**
* Create a new MutableBluetoothGattCharacteristic.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param uuid The UUID for this characteristic
* @param properties Properties of this characteristic
* @param permissions Permissions for this characteristic
*/
public MutableBluetoothGattCharacteristic(UUID uuid, int properties, int permissions) {
super(null, uuid, 0, properties, permissions);
}
/**
* Adds a descriptor to this characteristic.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param descriptor Descriptor to be added to this characteristic.
*/
public void addDescriptor(MutableBluetoothGattDescriptor descriptor) {
mDescriptors.add(descriptor);
descriptor.setCharacteristic(this);
}
/**
* Set the desired key size.
* @hide
*/
public void setKeySize(int keySize) {
mKeySize = keySize;
}
/**
* Sets the service associated with this device.
* @hide
*/
/*package*/ void setService(BluetoothGattService service) {
mService = service;
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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 java.util.UUID;
/**
* Mutable variant of a Bluetooth Gatt Descriptor
* @hide
*/
public class MutableBluetoothGattDescriptor extends BluetoothGattDescriptor {
/**
* Create a new BluetoothGattDescriptor.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param uuid The UUID for this descriptor
* @param permissions Permissions for this descriptor
*/
public MutableBluetoothGattDescriptor(UUID uuid, int permissions) {
super(null, uuid, permissions);
}
/**
* Set the back-reference to the associated characteristic
* @hide
*/
/*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) {
mCharacteristic = characteristic;
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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.bluetooth.BluetoothDevice;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* Represents a Bluetooth Gatt Service
* @hide
*/
public class MutableBluetoothGattService extends BluetoothGattService {
/**
* Create a new MutableBluetoothGattService.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param uuid The UUID for this service
* @param serviceType The type of this service (primary/secondary)
*/
public MutableBluetoothGattService(UUID uuid, int serviceType) {
super(uuid, serviceType);
}
/**
* Add an included service to this service.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param service The service to be added
* @return true, if the included service was added to the service
*/
public boolean addService(BluetoothGattService service) {
mIncludedServices.add(service);
return true;
}
/**
* Add a characteristic to this service.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param characteristic The characteristics to be added
* @return true, if the characteristic was added to the service
*/
public boolean addCharacteristic(MutableBluetoothGattCharacteristic characteristic) {
mCharacteristics.add(characteristic);
characteristic.setService(this);
return true;
}
/**
* Force the instance ID.
* This is needed for conformance testing only.
* @hide
*/
public void setInstanceId(int instanceId) {
mInstanceId = instanceId;
}
/**
* Force the number of handles to reserve for this service.
* This is needed for conformance testing only.
* @hide
*/
public void setHandles(int handles) {
mHandles = handles;
}
}