BluetoothServerSocket.java revision 6d95fc0a2ca910212a43c4547c0ef000659b72dc
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;
2024bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly
210b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellyimport java.io.Closeable;
220b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellyimport java.io.IOException;
230b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly
240b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly/**
2545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * A listening Bluetooth socket.
260b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly *
2745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>The interface for Bluetooth Sockets is similar to that of TCP sockets:
2845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * {@link java.net.Socket} and {@link java.net.ServerSocket}. On the server
2945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * side, use a {@link BluetoothServerSocket} to create a listening server
309fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * socket. When a connection is accepted by the {@link BluetoothServerSocket},
319fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * it will return a new {@link BluetoothSocket} to manage the connection.
329fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * On the client side, use a single {@link BluetoothSocket} to both intiate
339fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * an outgoing connection and to manage the connection.
340b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly *
359fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * <p>The most common type of Bluetooth socket is RFCOMM, which is the type
369fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * supported by the Android APIs. RFCOMM is a connection-oriented, streaming
379fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * transport over Bluetooth. It is also known as the Serial Port Profile (SPP).
380b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly *
399fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * <p>To create a listenting {@link BluetoothServerSocket} that's ready for
409fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * incoming connections, use
419fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * {@link BluetoothAdapter#listenUsingRfcommWithServiceRecord
429fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * BluetoothAdapter.listenUsingRfcommWithServiceRecord()}. Then call
439fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * {@link #accept()} to listen for incoming connection requests. This call
449fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * will block until a connection is established, at which point, it will return
456d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * a {@link BluetoothSocket} to manage the connection. Once the {@link
466d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * BluetoothSocket} is acquired, it's a good idea to call {@link #close()} on
476d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * the {@link BluetoothServerSocket} when it's no longer needed for accepting
486d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * connections. Closing the {@link BluetoothServerSocket} will <em>not</em>
496d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * close the returned {@link BluetoothSocket}.
5045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly *
519fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * <p>{@link BluetoothServerSocket} is thread
5245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * safe. In particular, {@link #close} will always immediately abort ongoing
539fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * operations and close the server socket.
549fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main *
559fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * <p class="note"><strong>Note:</strong>
569fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * Requires the {@link android.Manifest.permission#BLUETOOTH} permission.
57cf44059813539bf7f36dabd278cef93ba3122c56Nick Pelly *
589fab0aef19a4633d2e4670564e5d7ae9e52fe11fScott Main * {@see BluetoothSocket}
590b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */
600b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellypublic final class BluetoothServerSocket implements Closeable {
6171c3c7806acb2b2b7b8441817c26a2101d447bbeNick Pelly
62bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    /*package*/ final BluetoothSocket mSocket;
6324bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly    private Handler mHandler;
6424bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly    private int mMessage;
650b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly
660b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    /**
670b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     * Construct a socket for incoming connections.
686a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly     * @param type    type of socket
696a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly     * @param auth    require the remote device to be authenticated
706a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly     * @param encrypt require the connection to be encrypted
716a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly     * @param port    remote port
720b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     * @throws IOException On error, for example Bluetooth not available, or
730b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     *                     insufficient priveleges
740b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     */
75bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
766a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly            throws IOException {
7716fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null);
780b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    }
790b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly
800b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    /**
810b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     * Block until a connection is established.
8245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>Returns a connected {@link BluetoothSocket} on successful connection.
8345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>Once this call returns, it can be called again to accept subsequent
8445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * incoming connections.
8545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>{@link #close} can be used to abort this call from another thread.
8645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @return a connected {@link BluetoothSocket}
8745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @throws IOException on error, for example this call was aborted, or
8845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     *                     timeout
890b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     */
900b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    public BluetoothSocket accept() throws IOException {
910b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly        return accept(-1);
920b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    }
930b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly
940b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    /**
950b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     * Block until a connection is established, with timeout.
9645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>Returns a connected {@link BluetoothSocket} on successful connection.
9745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>Once this call returns, it can be called again to accept subsequent
9845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * incoming connections.
9945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>{@link #close} can be used to abort this call from another thread.
10045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @return a connected {@link BluetoothSocket}
10145e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @throws IOException on error, for example this call was aborted, or
1020b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     *                     timeout
1030b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     */
1040b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    public BluetoothSocket accept(int timeout) throws IOException {
10571c3c7806acb2b2b7b8441817c26a2101d447bbeNick Pelly        return mSocket.accept(timeout);
1060b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    }
1070b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly
1080b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    /**
10945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * Immediately close this socket, and release all associated resources.
11045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>Causes blocked calls on this socket in other threads to immediately
1110b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     * throw an IOException.
1126d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main     * <p>Closing the {@link BluetoothServerSocket} will <em>not</em>
1136d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main     * close any {@link BluetoothSocket} received from {@link #accept()}.
1140b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly     */
1150b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    public void close() throws IOException {
11624bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly        synchronized (this) {
11724bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly            if (mHandler != null) {
11824bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly                mHandler.obtainMessage(mMessage).sendToTarget();
11924bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly            }
12024bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly        }
12171c3c7806acb2b2b7b8441817c26a2101d447bbeNick Pelly        mSocket.close();
1220b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly    }
12324bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly
12424bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly    /*package*/ synchronized void setCloseHandler(Handler handler, int message) {
12524bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly        mHandler = handler;
12624bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly        mMessage = message;
12724bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly    }
1280b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly}
129