summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNitin Shivpure <nshivpur@codeaurora.org>2015-07-20 13:22:28 +0530
committerLinux Build Service Account <lnxbuild@localhost>2015-10-06 03:26:45 -0600
commit86020e9a599c3ceaef2a7dc9c744918e9b7f1ce4 (patch)
tree5c8a5d519c8ac4d7d07b089ceeaf6cca4854a5fb
parenta63a2505e74e6955d54629c488699c7f9c52cf18 (diff)
downloadframeworks_base-86020e9a599c3ceaef2a7dc9c744918e9b7f1ce4.zip
frameworks_base-86020e9a599c3ceaef2a7dc9c744918e9b7f1ce4.tar.gz
frameworks_base-86020e9a599c3ceaef2a7dc9c744918e9b7f1ce4.tar.bz2
Bluetooth: Add support for Map client over L2cap
- Adding the support for Map client(MAP1.2). - Add support to create & remove MNS sdp records. - Add support to enable & disable srm, Fews Message Access Profile opreations don't require SRM header in their pdu. Eg. UpdateInbox, SetMessageStatus. SetNotificationRegistration. - If obex based profile explicitly sets GET with final flag, then GET should always be sent as single packet request with final flag set. Change-Id: I89f51ecf8b7834f0b131d043a5f49811914e9635 CRs-Fixed: 754956
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java54
-rw-r--r--core/java/android/bluetooth/IBluetooth.aidl4
-rw-r--r--obex/javax/obex/ClientOperation.java49
-rw-r--r--obex/javax/obex/ClientSession.java7
4 files changed, 98 insertions, 16 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 05dfacd..70f478a 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1784,6 +1784,60 @@ public final class BluetoothAdapter {
}
/**
+ * Create a client side Message Access Profile Service Record.
+ * Create the record once, and reuse it for all connections.
+ * If changes to a record is needed remove the old record using {@link removeSdpRecord}
+ * and then create a new one.
+ * WARNING: This API requires removeSdpRecord() to be called, to avoid leaking resources!
+ * A second call to this function - either from two different apps or from the
+ * same app, without first calling removeSdpRecord() - will make the device
+ * break the Bluetooth spec, which could lead to severe IOP issues.
+ * @param serviceName The textual name of the service
+ * @param rfcommChannel The RFCOMM channel that clients can connect to
+ * (obtain from BluetoothServerSocket)
+ * @param l2capPsm The L2CAP PSM channel that clients can connect to
+ * (obtain from BluetoothServerSocket)
+ * Supply -1 to omit the L2CAP PSM from the record.
+ * @param version The Profile version number (As specified in the Bluetooth
+ * MAP specification)
+ * @param features The feature bit mask (As specified in the Bluetooth
+ * MAP specification)
+ * @return a handle to the record created. The record can be removed again
+ * using {@link removeSdpRecord}(). The record is not linked to the
+ * creation/destruction of BluetoothSockets, hence SDP record cleanup
+ * is a separate process.
+ * returns -1 if an error occure and the record was not created.
+ * @hide
+ */
+ public int createMapMnsSdpRecord(String serviceName, int rfcommChannel,
+ int l2capPsm, int version, int features) {
+ try {
+ return mService.createMapMnsSdpRecord(serviceName, rfcommChannel,
+ l2capPsm, version, features);
+ } catch (RemoteException e) {
+ Log.e(TAG, "createMapMnsSdpRecord: ", e);
+ }
+ return -1;
+ }
+
+ /**
+ * Remove a SDP record created using createSdpRecord().
+ * This function shall be called before a new call to createSdpRecord for the same record
+ * type can be made, unless the record type created supports multiple instances.
+ * @param recordHandle handle of the record to remove - provided by createSdpRecord()
+ * @return true if success
+ * @hide
+ */
+ public boolean removeSdpRecord(int recordHandle){
+ try {
+ return mService.removeSdpRecord(recordHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "createMapMnsSdpRecord: ", e);
+ }
+ return false;
+ }
+
+ /**
* Read the local Out of Band Pairing Data
* <p>Requires {@link android.Manifest.permission#BLUETOOTH}
*
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 3ca32b6..8cdc7bf 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -70,6 +70,10 @@ interface IBluetooth
boolean fetchRemoteUuids(in BluetoothDevice device);
boolean sdpSearch(in BluetoothDevice device, in ParcelUuid uuid);
+ int createMapMnsSdpRecord(in String serviceName, in int rfcommChannel,
+ in int l2capPsm, in int version, in int features);
+ boolean removeSdpRecord(in int recordHandle);
+
boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode);
boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[]
passkey);
diff --git a/obex/javax/obex/ClientOperation.java b/obex/javax/obex/ClientOperation.java
index 883c8c6..eb7e280 100644
--- a/obex/javax/obex/ClientOperation.java
+++ b/obex/javax/obex/ClientOperation.java
@@ -632,21 +632,32 @@ public final class ClientOperation implements Operation, BaseStream {
if (mGetOperation) {
if (!mOperationDone) {
- mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
- while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
- more = sendRequest(ObexHelper.OBEX_OPCODE_GET);
- }
- // For GET we need to loop until all headers have been sent,
- // And then we wait for the first continue package with the
- // reply.
- if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
- mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL,
- null, mReplyHeader, mPrivateInput, mSrmActive);
- }
- if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
- mOperationDone = true;
+ if (!mGetFinalFlag) {
+ mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
+ while ((more) && (mReplyHeader.responseCode ==
+ ResponseCodes.OBEX_HTTP_CONTINUE)) {
+ more = sendRequest(ObexHelper.OBEX_OPCODE_GET);
+ }
+ // For GET we need to loop until all headers have been sent,
+ // And then we wait for the first continue package with the
+ // reply.
+ if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
+ mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL,
+ null, mReplyHeader, mPrivateInput, mSrmActive);
+ }
+ if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
+ mOperationDone = true;
+ } else {
+ checkForSrm();
+ }
} else {
- checkForSrm();
+ more = sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL);
+
+ if (more) {
+ throw new IOException("FINAL_GET forced, data didn't fit into one packet");
+ }
+
+ mOperationDone = true;
}
}
} else {
@@ -705,7 +716,15 @@ public final class ClientOperation implements Operation, BaseStream {
if (mPrivateInput == null) {
mPrivateInput = new PrivateInputStream(this);
}
- sendRequest(ObexHelper.OBEX_OPCODE_GET);
+
+ if (!mGetFinalFlag) {
+ sendRequest(ObexHelper.OBEX_OPCODE_GET);
+ } else {
+ sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL);
+ }
+ if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
+ mOperationDone = true;
+ }
return true;
} else if (mOperationDone) {
diff --git a/obex/javax/obex/ClientSession.java b/obex/javax/obex/ClientSession.java
index 272a920..8f7a680 100644
--- a/obex/javax/obex/ClientSession.java
+++ b/obex/javax/obex/ClientSession.java
@@ -68,7 +68,7 @@ public final class ClientSession extends ObexSession {
private final OutputStream mOutput;
- private final boolean mLocalSrmSupported;
+ private boolean mLocalSrmSupported;
private final ObexTransport mTransport;
@@ -613,4 +613,9 @@ public final class ClientSession extends ObexSession {
public boolean isSrmSupported() {
return mLocalSrmSupported;
}
+
+ public void setLocalSrmStatus(boolean SrmEnabled) {
+ mLocalSrmSupported = SrmEnabled;
+ Log.v(TAG, "setLocalSrmStatus: " + mLocalSrmSupported);
+ }
}