BluetoothSocket.java revision 47e82dee6b18c33fab8c2cdf4f68b20d3663079e
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.bluetooth;
18
19import java.io.Closeable;
20import java.io.IOException;
21import java.io.InputStream;
22import java.io.OutputStream;
23
24/**
25 * Represents a connected or connecting Bluetooth Socket.
26 *
27 * Currently only supports RFCOMM sockets.
28 *
29 * RFCOMM is a connection orientated, streaming transport over Bluetooth. It is
30 * also known as the Serial Port Profile (SPP).
31 *
32 * TODO: Consider implementing SCO and L2CAP sockets.
33 * TODO: Clean up javadoc grammer and formatting.
34 * TODO: Remove @hide
35 * @hide
36 */
37public final class BluetoothSocket implements Closeable {
38    private final int mPort;
39    private final String mAddress;    /* remote address */
40    private final boolean mAuth;
41    private final boolean mEncrypt;
42    private final BluetoothInputStream mInputStream;
43    private final BluetoothOutputStream mOutputStream;
44
45    private int mSocketData;    /* used by native code only */
46
47    /**
48     * Construct a secure RFCOMM socket ready to start an outgoing connection.
49     * Call #connect on the returned #BluetoothSocket to begin the connection.
50     * The remote device will be authenticated and communication on this socket
51     * will be encrypted.
52     * @param address remote Bluetooth address that this socket can connect to
53     * @param port    remote port
54     * @return an RFCOMM BluetoothSocket
55     * @throws IOException on error, for example Bluetooth not available, or
56     *                     insufficient permissions.
57     */
58    public static BluetoothSocket createRfcommSocket(String address, int port)
59            throws IOException {
60        return new BluetoothSocket(-1, true, true, address, port);
61    }
62
63    /**
64     * Construct an insecure RFCOMM socket ready to start an outgoing
65     * connection.
66     * Call #connect on the returned #BluetoothSocket to begin the connection.
67     * The remote device will not be authenticated and communication on this
68     * socket will not be encrypted.
69     * @param address remote Bluetooth address that this socket can connect to
70     * @param port    remote port
71     * @return An RFCOMM BluetoothSocket
72     * @throws IOException On error, for example Bluetooth not available, or
73     *                     insufficient permissions.
74     */
75    public static BluetoothSocket createInsecureRfcommSocket(String address, int port)
76            throws IOException {
77        return new BluetoothSocket(-1, false, false, address, port);
78    }
79
80    /**
81     * Construct a Bluetooth.
82     * @param fd      fd to use for connected socket, or -1 for a new socket
83     * @param auth    require the remote device to be authenticated
84     * @param encrypt require the connection to be encrypted
85     * @param address remote Bluetooth address that this socket can connect to
86     * @param port    remote port
87     * @throws IOException On error, for example Bluetooth not available, or
88     *                     insufficient priveleges
89     */
90    /*package*/ BluetoothSocket(int fd, boolean auth, boolean encrypt, String address, int port)
91            throws IOException {
92        mAuth = auth;
93        mEncrypt = encrypt;
94        mAddress = address;
95        mPort = port;
96        if (fd == -1) {
97            initSocketNative();
98        } else {
99            initSocketFromFdNative(fd);
100        }
101        mInputStream = new BluetoothInputStream(this);
102        mOutputStream = new BluetoothOutputStream(this);
103    }
104
105    @Override
106    protected void finalize() throws Throwable {
107        try {
108            close();
109        } finally {
110            super.finalize();
111        }
112    }
113
114    /**
115     * Attempt to connect to a remote device.
116     * This method will block until a connection is made or the connection
117     * fails. If this method returns without an exception then this socket
118     * is now connected. #close can be used to abort this call from another
119     * thread.
120     * @throws IOException On error, for example connection failure
121     */
122    public void connect() throws IOException {
123        connectNative(mAddress, mPort, -1);
124    }
125
126    /**
127     * Closes this socket.
128     * This will cause other blocking calls on this socket to immediately
129     * throw an IOException.
130     */
131    public void close() throws IOException {
132        closeNative();
133    }
134
135    /**
136     * Return the address we are connecting, or connected, to.
137     * @return Bluetooth address, or null if this socket has not yet attempted
138     *         or established a connection.
139     */
140    public String getAddress() {
141        return mAddress;
142    }
143
144    /**
145     * Get the input stream associated with this socket.
146     * The input stream will be returned even if the socket is not yet
147     * connected, but operations on that stream will throw IOException until
148     * the associated socket is connected.
149     * @return InputStream
150     */
151    public InputStream getInputStream() throws IOException {
152        return mInputStream;
153    }
154
155    /**
156     * Get the output stream associated with this socket.
157     * The output stream will be returned even if the socket is not yet
158     * connected, but operations on that stream will throw IOException until
159     * the associated socket is connected.
160     * @return OutputStream
161     */
162    public OutputStream getOutputStream() throws IOException {
163        return mOutputStream;
164    }
165
166    private native void initSocketNative();
167    private native void initSocketFromFdNative(int fd);
168    private native void connectNative(String address, int port, int timeout);
169    /*package*/ native void bindListenNative(int port) throws IOException;
170    /*package*/ native BluetoothSocket acceptNative(int timeout) throws IOException;
171    /*package*/ native int availableNative();
172    /*package*/ native int readNative(byte[] b, int offset, int length);
173    /*package*/ native int writeNative(byte[] b, int offset, int length);
174    /*package*/ native void closeNative();
175    private native void destroyNative();
176}
177