diff options
author | Nitin Shivpure <nshivpur@codeaurora.org> | 2015-07-20 13:22:28 +0530 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2015-10-06 03:26:45 -0600 |
commit | 86020e9a599c3ceaef2a7dc9c744918e9b7f1ce4 (patch) | |
tree | 5c8a5d519c8ac4d7d07b089ceeaf6cca4854a5fb | |
parent | a63a2505e74e6955d54629c488699c7f9c52cf18 (diff) | |
download | frameworks_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.java | 54 | ||||
-rw-r--r-- | core/java/android/bluetooth/IBluetooth.aidl | 4 | ||||
-rw-r--r-- | obex/javax/obex/ClientOperation.java | 49 | ||||
-rw-r--r-- | obex/javax/obex/ClientSession.java | 7 |
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); + } } |