summaryrefslogtreecommitdiff
path: root/framework/java/android/bluetooth/BluetoothAdapter.java
diff options
context:
space:
mode:
authorStanley Tng <stng@google.com>2017-11-22 16:04:40 -0800
committerStanley Tng <stng@google.com>2018-01-12 07:26:14 -0800
commitd67d5e4f1e8c1afd98f11b11ca8ca26792da9d6b (patch)
tree7fb461e3e595c9929ecb2259eee51e3e12c194bc /framework/java/android/bluetooth/BluetoothAdapter.java
parent35258da3867dd10d4c3e2f2ab5c99cbbac206d44 (diff)
Added APIs for Connection-oriented channels
Experimental and hidden APIs are defined for the Connection-oriented Channel (CoC) features. The APIs using PSM are implemented. Test: Can compile Bug: 70683224 Change-Id: Icdb5fa190b0e21881a60437fa48cd575371ee1e4
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothAdapter.java')
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java126
1 files changed, 121 insertions, 5 deletions
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index 158aebb478..4775bde420 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -79,8 +79,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
* {@link BluetoothDevice} objects representing all paired devices with
* {@link #getBondedDevices()}; start device discovery with
* {@link #startDiscovery()}; or create a {@link BluetoothServerSocket} to
- * listen for incoming connection requests with
- * {@link #listenUsingRfcommWithServiceRecord(String, UUID)}; or start a scan for
+ * listen for incoming RFComm connection requests with {@link
+ * #listenUsingRfcommWithServiceRecord(String, UUID)}; listen for incoming L2CAP Connection-oriented
+ * Channels (CoC) connection requests with listenUsingL2capCoc(int)}; or start a scan for
* Bluetooth LE devices with {@link #startLeScan(LeScanCallback callback)}.
* </p>
* <p>This class is thread safe.</p>
@@ -210,6 +211,14 @@ public final class BluetoothAdapter {
public static final int STATE_BLE_TURNING_OFF = 16;
/**
+ * UUID of the GATT Read Characteristics for LE_PSM value.
+ *
+ * @hide
+ */
+ public static final UUID LE_PSM_CHARACTERISTIC_UUID =
+ UUID.fromString("2d410339-82b6-42aa-b34e-e2e01df8cc1a");
+
+ /**
* Human-readable string helper for AdapterState
*
* @hide
@@ -2135,7 +2144,9 @@ public final class BluetoothAdapter {
min16DigitPin);
int errno = socket.mSocket.bindListen();
if (port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
- socket.setChannel(socket.mSocket.getPort());
+ int assignedChannel = socket.mSocket.getPort();
+ if (DBG) Log.d(TAG, "listenUsingL2capOn: set assigned channel to " + assignedChannel);
+ socket.setChannel(assignedChannel);
}
if (errno != 0) {
//TODO(BT): Throw the same exception error code
@@ -2176,12 +2187,18 @@ public final class BluetoothAdapter {
* @hide
*/
public BluetoothServerSocket listenUsingInsecureL2capOn(int port) throws IOException {
+ Log.d(TAG, "listenUsingInsecureL2capOn: port=" + port);
BluetoothServerSocket socket =
new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP, false, false, port, false,
- false);
+ false);
int errno = socket.mSocket.bindListen();
if (port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
- socket.setChannel(socket.mSocket.getPort());
+ int assignedChannel = socket.mSocket.getPort();
+ if (DBG) {
+ Log.d(TAG, "listenUsingInsecureL2capOn: set assigned channel to "
+ + assignedChannel);
+ }
+ socket.setChannel(assignedChannel);
}
if (errno != 0) {
//TODO(BT): Throw the same exception error code
@@ -2738,4 +2755,103 @@ public final class BluetoothAdapter {
scanner.stopScan(scanCallback);
}
}
+
+ /**
+ * Create a secure L2CAP Connection-oriented Channel (CoC) {@link BluetoothServerSocket} and
+ * assign a dynamic protocol/service multiplexer (PSM) value. This socket can be used to listen
+ * for incoming connections.
+ * <p>A remote device connecting to this socket will be authenticated and communication on this
+ * socket will be encrypted.
+ * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
+ * {@link BluetoothServerSocket}.
+ * <p>The system will assign a dynamic PSM value. This PSM value can be read from the {#link
+ * BluetoothServerSocket#getPsm()} and this value will be released when this server socket is
+ * closed, Bluetooth is turned off, or the application exits unexpectedly.
+ * <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
+ * defined and performed by the application.
+ * <p>Use {@link BluetoothDevice#createL2capCocSocket(int, int)} to connect to this server
+ * socket from another Android device that is given the PSM value.
+ *
+ * @param transport Bluetooth transport to use, must be {@link BluetoothDevice#TRANSPORT_LE}
+ * @return an L2CAP CoC BluetoothServerSocket
+ * @throws IOException on error, for example Bluetooth not available, or insufficient
+ * permissions, or unable to start this CoC
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public BluetoothServerSocket listenUsingL2capCoc(int transport)
+ throws IOException {
+ if (transport != BluetoothDevice.TRANSPORT_LE) {
+ throw new IllegalArgumentException("Unsupported transport: " + transport);
+ }
+ BluetoothServerSocket socket =
+ new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, true, true,
+ SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false, false);
+ int errno = socket.mSocket.bindListen();
+ if (errno != 0) {
+ throw new IOException("Error: " + errno);
+ }
+
+ int assignedPsm = socket.mSocket.getPort();
+ if (assignedPsm == 0) {
+ throw new IOException("Error: Unable to assign PSM value");
+ }
+ if (DBG) {
+ Log.d(TAG, "listenUsingL2capCoc: set assigned PSM to "
+ + assignedPsm);
+ }
+ socket.setChannel(assignedPsm);
+
+ return socket;
+ }
+
+ /**
+ * Create an insecure L2CAP Connection-oriented Channel (CoC) {@link BluetoothServerSocket} and
+ * assign a dynamic PSM value. This socket can be used to listen for incoming connections.
+ * <p>The link key is not required to be authenticated, i.e the communication may be vulnerable
+ * to man-in-the-middle attacks. Use {@link #listenUsingL2capCoc}, if an encrypted and
+ * authenticated communication channel is desired.
+ * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
+ * {@link BluetoothServerSocket}.
+ * <p>The system will assign a dynamic protocol/service multiplexer (PSM) value. This PSM value
+ * can be read from the {#link BluetoothServerSocket#getPsm()} and this value will be released
+ * when this server socket is closed, Bluetooth is turned off, or the application exits
+ * unexpectedly.
+ * <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
+ * defined and performed by the application.
+ * <p>Use {@link BluetoothDevice#createInsecureL2capCocSocket(int, int)} to connect to this
+ * server socket from another Android device that is given the PSM value.
+ *
+ * @param transport Bluetooth transport to use, must be {@link BluetoothDevice#TRANSPORT_LE}
+ * @return an L2CAP CoC BluetoothServerSocket
+ * @throws IOException on error, for example Bluetooth not available, or insufficient
+ * permissions, or unable to start this CoC
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public BluetoothServerSocket listenUsingInsecureL2capCoc(int transport)
+ throws IOException {
+ if (transport != BluetoothDevice.TRANSPORT_LE) {
+ throw new IllegalArgumentException("Unsupported transport: " + transport);
+ }
+ BluetoothServerSocket socket =
+ new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, false, false,
+ SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false, false);
+ int errno = socket.mSocket.bindListen();
+ if (errno != 0) {
+ throw new IOException("Error: " + errno);
+ }
+
+ int assignedPsm = socket.mSocket.getPort();
+ if (assignedPsm == 0) {
+ throw new IOException("Error: Unable to assign PSM value");
+ }
+ if (DBG) {
+ Log.d(TAG, "listenUsingInsecureL2capOn: set assigned PSM to "
+ + assignedPsm);
+ }
+ socket.setChannel(assignedPsm);
+
+ return socket;
+ }
}