Added various apis and fixed existing ones
BluetoothFacade.java
Removed unregistering reciever as it was causing crashes
BluetoothRfcommFacade.java
Cleared file descriptors on closing of a rfcomm socket
GattFacade.java
Added api gattServerGetConnectedDevices
Added api gattServerSendResponse
Fixed api gattReadCharacteristic
Change-Id: I005bf4d5c274f827f124e4a2a454a978d0acc21d
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java
index 552a775..01dcd4c 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java
@@ -307,7 +307,13 @@
@Rpc(description = "Cancel the current device discovery process.",
returns = "true on success, false on error")
public Boolean bluetoothCancelDiscovery() {
- mService.unregisterReceiver(mDiscoveryReceiver);
+ //TODO (tturney): Figure out why bluetoothStartDiscovery sometimes
+ //doesn't register the reiever.
+ try {
+ mService.unregisterReceiver(mDiscoveryReceiver);
+ } catch (IllegalArgumentException e) {
+ Log.d("IllegalArgumentExeption found when trying to unregister reciever");
+ }
return mBluetoothAdapter.cancelDiscovery();
}
@@ -332,7 +338,7 @@
return mBluetoothAdapter.configHciSnoopLog(value);
}
- @Rpc(description = "Get ")
+ @Rpc(description = "Get Bluetooth controller activity energy info.")
public String bluetoothGetControllerActivityEnergyInfo(
@RpcParameter(name = "value")
Integer value
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java
index 433be3d..bcf7b8c 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java
@@ -22,6 +22,7 @@
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.IntentFilter;
+import android.os.ParcelFileDescriptor;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.FacadeManager;
@@ -40,6 +41,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import java.lang.reflect.Field;
import org.apache.commons.codec.binary.Base64Codec;
@@ -399,9 +401,28 @@
return mDevice.getName();
}
+ private synchronized void clearFileDescriptor() {
+ try {
+ Field field = BluetoothSocket.class.getDeclaredField("mPfd");
+ field.setAccessible(true);
+ ParcelFileDescriptor mPfd = (ParcelFileDescriptor) field.get(mSocket);
+ if (mPfd == null)
+ return;
+ mPfd.close();
+ mPfd = null;
+ try { field.set(mSocket, mPfd); }
+ catch(Exception e) {
+ Log.d("Exception setting mPfd = null in cleanCloseFix(): " + e.toString());
+ }
+ } catch (Exception e) {
+ Log.w("ParcelFileDescriptor could not be cleanly closed.", e);
+ }
+ }
+
public void stop() {
if (mSocket != null) {
try {
+ clearFileDescriptor();
mSocket.close();
} catch (IOException e) {
Log.e(e);
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java
index e453906..da0bf3d 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java
@@ -46,6 +46,7 @@
private final HashMap<Integer, myBluetoothGattServerCallback> mBluetoothGattServerCallbackList;
private final HashMap<Integer, BluetoothGattService> mGattServiceList;
private final HashMap<Integer, List<BluetoothGattService>> mBluetoothGattDiscoveredServicesList;
+ private final HashMap<Integer, List<BluetoothDevice>> mGattServerDiscoveredDevicesList;
private static int GattCallbackCount;
private static int BluetoothGattDiscoveredServicesCount;
private static int BluetoothGattCount;
@@ -76,6 +77,7 @@
mBluetoothGattServerCallbackList = new HashMap<Integer, myBluetoothGattServerCallback>();
mGattServiceList = new HashMap<Integer, BluetoothGattService>();
mBluetoothGattDiscoveredServicesList = new HashMap<Integer, List<BluetoothGattService>>();
+ mGattServerDiscoveredDevicesList = new HashMap<Integer, List<BluetoothDevice>>();
}
/**
@@ -130,6 +132,67 @@
}
/**
+ * Get connected devices of the gatt server
+ * @param gattServerIndex the gatt server index
+ * @throws Exception
+ */
+ @Rpc(description = "Return a list of connected gatt devices.")
+ public List<BluetoothDevice> gattServerGetConnectedDevices(
+ @RpcParameter(name = "gattServerIndex")
+ Integer gattServerIndex) throws Exception {
+ if (mBluetoothGattServerList.get(gattServerIndex) == null) {
+ throw new Exception("Invalid gattServerIndex: "
+ + Integer.toString(gattServerIndex));
+ }
+ List<BluetoothDevice> connectedDevices = mBluetoothManager.getConnectedDevices(
+ BluetoothProfile.GATT_SERVER);
+ mGattServerDiscoveredDevicesList.put(gattServerIndex, connectedDevices);
+ return connectedDevices;
+ }
+
+ /**
+ * Get connected devices of the gatt server
+ * @param gattServerIndex the gatt server index
+ * @param bluetoothDeviceIndex the remotely connected bluetooth device
+ * @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
+ * @throws Exception
+ */
+ @Rpc(description = "Send a response after a write.")
+ public void gattServerSendResponse(
+ @RpcParameter(name = "gattServerIndex")
+ Integer gattServerIndex,
+ @RpcParameter(name = "bluetoothDeviceIndex")
+ Integer bluetoothDeviceIndex,
+ @RpcParameter(name = "requestId")
+ Integer requestId,
+ @RpcParameter(name = "status")
+ Integer status,
+ @RpcParameter(name = "offset")
+ Integer offset,
+ @RpcParameter(name = "value")
+ String value) throws Exception {
+
+ BluetoothGattServer gattServer = mBluetoothGattServerList.get(gattServerIndex);
+ if (gattServer == null)
+ throw new Exception("Invalid gattServerIndex: "
+ + Integer.toString(gattServerIndex));
+ List <BluetoothDevice> connectedDevices =
+ mGattServerDiscoveredDevicesList.get(gattServerIndex);
+ if (connectedDevices == null)
+ throw new Exception("Connected device list empty for gattServerIndex:"
+ + Integer.toString(gattServerIndex));
+ BluetoothDevice bluetoothDevice = connectedDevices.get(bluetoothDeviceIndex);
+ if (bluetoothDevice == null)
+ throw new Exception("Invalid bluetoothDeviceIndex: "
+ + Integer.toString(bluetoothDeviceIndex));
+ gattServer.sendResponse(bluetoothDevice, requestId, status, offset,
+ ConvertUtils.convertStringToByteArray(value));
+ }
+
+ /**
* Create a new bluetooth gatt service
* @param uuid the UUID that characterises the service
* @param serviceType the service type
@@ -518,30 +581,39 @@
/**
* Reads the requested characteristic from the associated remote device.
- *
- * @param index the bluetooth gatt index
- * @param characteristicIndex the characteristic index
+ * @param gattIndex the BluetoothGatt server accociated with the device
+ * @param discoveredServiceListIndex the index returned from the discovered
+ * services callback
+ * @param serviceIndex the service index of the discovered services
+ * @param characteristicUuid the characteristic uuid to read
* @return true, if the read operation was initiated successfully
* @throws Exception
*/
@Rpc(description = "Reads the requested characteristic from the associated remote device.")
public boolean gattReadCharacteristic(
- @RpcParameter(name = "index")
- Integer index,
- @RpcParameter(name = "characteristicIndex")
- Integer characteristicIndex
- ) throws Exception {
- if (mBluetoothGattList.get(index) != null) {
- if (mCharacteristicList.get(characteristicIndex) != null) {
- return mBluetoothGattList.get(index).readCharacteristic(
- mCharacteristicList.get(characteristicIndex));
- } else {
- throw new Exception("Invalid characteristicIndex input:"
- + characteristicIndex);
- }
- } else {
- throw new Exception("Invalid index input:" + index);
- }
+ @RpcParameter(name = "gattIndex") Integer gattIndex,
+ @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
+ @RpcParameter(name = "serviceIndex") Integer serviceIndex,
+ @RpcParameter(name = "characteristicUuid") String characteristicUuid) throws Exception {
+ BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
+ if (bluetoothGatt == null) {
+ throw new Exception("Invalid gattIndex " + gattIndex);
+ }
+ List<BluetoothGattService> discoveredServiceList =
+ mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
+ if (discoveredServiceList == null) {
+ throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
+ }
+ BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
+ if (gattService == null) {
+ throw new Exception("Invalid serviceIndex " + serviceIndex);
+ }
+ UUID cUuid = UUID.fromString(characteristicUuid);
+ BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
+ if (gattCharacteristic == null) {
+ throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
+ }
+ return bluetoothGatt.readCharacteristic(gattCharacteristic);
}
/**