10b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly/* 20b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Copyright (C) 2009 The Android Open Source Project 30b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * 40b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 50b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * you may not use this file except in compliance with the License. 60b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * You may obtain a copy of the License at 70b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * 80b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * http://www.apache.org/licenses/LICENSE-2.0 90b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * 100b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Unless required by applicable law or agreed to in writing, software 110b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 120b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * See the License for the specific language governing permissions and 140b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * limitations under the License. 150b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 160b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 170b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellypackage android.bluetooth; 180b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1924bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pellyimport android.os.Handler; 203b147b770269173d5d711d6c33f142dc5e723824zzyimport android.os.Message; 213b147b770269173d5d711d6c33f142dc5e723824zzyimport android.os.ParcelUuid; 2224bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly 230b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellyimport java.io.Closeable; 240b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellyimport java.io.IOException; 250b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 260b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly/** 2745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * A listening Bluetooth socket. 280b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * 2945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>The interface for Bluetooth Sockets is similar to that of TCP sockets: 3045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * {@link java.net.Socket} and {@link java.net.ServerSocket}. On the server 3145e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * side, use a {@link BluetoothServerSocket} to create a listening server 329fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * socket. When a connection is accepted by the {@link BluetoothServerSocket}, 339fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * it will return a new {@link BluetoothSocket} to manage the connection. 34f51eadaf1f83abfe16a609a4ded6d789494689b2Jake Hamby * On the client side, use a single {@link BluetoothSocket} to both initiate 359fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * an outgoing connection and to manage the connection. 360b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * 379fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * <p>The most common type of Bluetooth socket is RFCOMM, which is the type 389fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * supported by the Android APIs. RFCOMM is a connection-oriented, streaming 399fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * transport over Bluetooth. It is also known as the Serial Port Profile (SPP). 400b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * 41f51eadaf1f83abfe16a609a4ded6d789494689b2Jake Hamby * <p>To create a listening {@link BluetoothServerSocket} that's ready for 429fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * incoming connections, use 439fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * {@link BluetoothAdapter#listenUsingRfcommWithServiceRecord 449fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * BluetoothAdapter.listenUsingRfcommWithServiceRecord()}. Then call 459fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * {@link #accept()} to listen for incoming connection requests. This call 469fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * will block until a connection is established, at which point, it will return 476d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * a {@link BluetoothSocket} to manage the connection. Once the {@link 486d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * BluetoothSocket} is acquired, it's a good idea to call {@link #close()} on 496d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * the {@link BluetoothServerSocket} when it's no longer needed for accepting 506d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * connections. Closing the {@link BluetoothServerSocket} will <em>not</em> 516d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * close the returned {@link BluetoothSocket}. 5245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * 539fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * <p>{@link BluetoothServerSocket} is thread 5445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * safe. In particular, {@link #close} will always immediately abort ongoing 559fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * operations and close the server socket. 569fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * 579fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * <p class="note"><strong>Note:</strong> 589fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * Requires the {@link android.Manifest.permission#BLUETOOTH} permission. 59cf44059813539bf7f36dabd278cef93ba3122c56Nick Pelly * 603aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference"> 613aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3> 623aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about using Bluetooth, read the 633aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/wireless/bluetooth.html">Bluetooth</a> developer guide.</p> 643aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div> 653aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * 669fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * {@see BluetoothSocket} 670b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 680b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellypublic final class BluetoothServerSocket implements Closeable { 6971c3c7806acb2b2b7b8441817c26a2101d447bbeNick Pelly 70bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly /*package*/ final BluetoothSocket mSocket; 7124bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly private Handler mHandler; 7224bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly private int mMessage; 736d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson private final int mChannel; 740b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 750b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 760b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Construct a socket for incoming connections. 776a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * @param type type of socket 786a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * @param auth require the remote device to be authenticated 796a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * @param encrypt require the connection to be encrypted 806a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * @param port remote port 810b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @throws IOException On error, for example Bluetooth not available, or 82f51eadaf1f83abfe16a609a4ded6d789494689b2Jake Hamby * insufficient privileges 830b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 84bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port) 856a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly throws IOException { 866d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson mChannel = port; 8716fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null); 880b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 890b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 900b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 913b147b770269173d5d711d6c33f142dc5e723824zzy * Construct a socket for incoming connections. 923b147b770269173d5d711d6c33f142dc5e723824zzy * @param type type of socket 933b147b770269173d5d711d6c33f142dc5e723824zzy * @param auth require the remote device to be authenticated 943b147b770269173d5d711d6c33f142dc5e723824zzy * @param encrypt require the connection to be encrypted 953b147b770269173d5d711d6c33f142dc5e723824zzy * @param uuid uuid 963b147b770269173d5d711d6c33f142dc5e723824zzy * @throws IOException On error, for example Bluetooth not available, or 973b147b770269173d5d711d6c33f142dc5e723824zzy * insufficient privileges 983b147b770269173d5d711d6c33f142dc5e723824zzy */ 993b147b770269173d5d711d6c33f142dc5e723824zzy /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, ParcelUuid uuid) 1003b147b770269173d5d711d6c33f142dc5e723824zzy throws IOException { 1013b147b770269173d5d711d6c33f142dc5e723824zzy mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, -1, uuid); 1023b147b770269173d5d711d6c33f142dc5e723824zzy mChannel = mSocket.getPort(); 1033b147b770269173d5d711d6c33f142dc5e723824zzy } 1043b147b770269173d5d711d6c33f142dc5e723824zzy 1053b147b770269173d5d711d6c33f142dc5e723824zzy 1063b147b770269173d5d711d6c33f142dc5e723824zzy /** 1070b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Block until a connection is established. 10845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Returns a connected {@link BluetoothSocket} on successful connection. 10945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Once this call returns, it can be called again to accept subsequent 11045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * incoming connections. 11145e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>{@link #close} can be used to abort this call from another thread. 11245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * @return a connected {@link BluetoothSocket} 11345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * @throws IOException on error, for example this call was aborted, or 11445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * timeout 1150b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1160b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public BluetoothSocket accept() throws IOException { 1170b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly return accept(-1); 1180b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1190b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1200b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 1210b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Block until a connection is established, with timeout. 12245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Returns a connected {@link BluetoothSocket} on successful connection. 12345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Once this call returns, it can be called again to accept subsequent 12445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * incoming connections. 12545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>{@link #close} can be used to abort this call from another thread. 12645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * @return a connected {@link BluetoothSocket} 12745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * @throws IOException on error, for example this call was aborted, or 1280b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * timeout 1290b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1300b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public BluetoothSocket accept(int timeout) throws IOException { 13171c3c7806acb2b2b7b8441817c26a2101d447bbeNick Pelly return mSocket.accept(timeout); 1320b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1330b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1340b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 13545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * Immediately close this socket, and release all associated resources. 13645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Causes blocked calls on this socket in other threads to immediately 1370b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * throw an IOException. 1386d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * <p>Closing the {@link BluetoothServerSocket} will <em>not</em> 1396d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * close any {@link BluetoothSocket} received from {@link #accept()}. 1400b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1410b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public void close() throws IOException { 14224bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly synchronized (this) { 14324bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly if (mHandler != null) { 14424bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly mHandler.obtainMessage(mMessage).sendToTarget(); 14524bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly } 14624bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly } 14771c3c7806acb2b2b7b8441817c26a2101d447bbeNick Pelly mSocket.close(); 1480b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 14924bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly 15024bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly /*package*/ synchronized void setCloseHandler(Handler handler, int message) { 15124bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly mHandler = handler; 15224bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly mMessage = message; 15324bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly } 1543b147b770269173d5d711d6c33f142dc5e723824zzy /*package*/ void setServiceName(String ServiceName) { 1553b147b770269173d5d711d6c33f142dc5e723824zzy mSocket.setServiceName(ServiceName); 1563b147b770269173d5d711d6c33f142dc5e723824zzy } 1576d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson /** 1586d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson * Returns the channel on which this socket is bound. 1596d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson * @hide 1606d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson */ 1616d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson public int getChannel() { 1626d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson return mChannel; 1636d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson } 1640b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly} 165