BluetoothSocket.java revision bd022f423a33f0794bb53e5b0720da2d67e4631c
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 exposing L2CAP sockets.
33 * TODO: Clean up javadoc grammer and formatting.
34 * TODO: Remove @hide
35 * @hide
36 */
37public final class BluetoothSocket implements Closeable {
38    /** Keep TYPE_RFCOMM etc in sync with BluetoothSocket.cpp */
39    /*package*/ static final int TYPE_RFCOMM = 1;
40    /*package*/ static final int TYPE_SCO = 2;
41    /*package*/ static final int TYPE_L2CAP = 3;
42
43    private final int mType;  /* one of TYPE_RFCOMM etc */
44    private final int mPort;  /* RFCOMM channel or L2CAP psm */
45    private final BluetoothDevice mDevice;    /* remote device */
46    private final String mAddress;    /* remote address */
47    private final boolean mAuth;
48    private final boolean mEncrypt;
49    private final BluetoothInputStream mInputStream;
50    private final BluetoothOutputStream mOutputStream;
51
52    private int mSocketData;    /* used by native code only */
53
54    /**
55     * Construct a BluetoothSocket.
56     * @param type    type of socket
57     * @param fd      fd to use for connected socket, or -1 for a new socket
58     * @param auth    require the remote device to be authenticated
59     * @param encrypt require the connection to be encrypted
60     * @param device  remote device that this socket can connect to
61     * @param port    remote port
62     * @throws IOException On error, for example Bluetooth not available, or
63     *                     insufficient priveleges
64     */
65    /*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
66            BluetoothDevice device, int port) throws IOException {
67        mType = type;
68        mAuth = auth;
69        mEncrypt = encrypt;
70        mDevice = device;
71        if (device == null) {
72            mAddress = null;
73        } else {
74            mAddress = device.getAddress();
75        }
76        mPort = port;
77        if (fd == -1) {
78            initSocketNative();
79        } else {
80            initSocketFromFdNative(fd);
81        }
82        mInputStream = new BluetoothInputStream(this);
83        mOutputStream = new BluetoothOutputStream(this);
84    }
85
86    /**
87     * Construct a BluetoothSocket from address.
88     * @param type    type of socket
89     * @param fd      fd to use for connected socket, or -1 for a new socket
90     * @param auth    require the remote device to be authenticated
91     * @param encrypt require the connection to be encrypted
92     * @param address remote device that this socket can connect to
93     * @param port    remote port
94     * @throws IOException On error, for example Bluetooth not available, or
95     *                     insufficient priveleges
96     */
97    private BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address,
98            int port) throws IOException {
99        this(type, fd, auth, encrypt, new BluetoothDevice(address), port);
100    }
101
102    @Override
103    protected void finalize() throws Throwable {
104        try {
105            close();
106        } finally {
107            super.finalize();
108        }
109    }
110
111    /**
112     * Attempt to connect to a remote device.
113     * This method will block until a connection is made or the connection
114     * fails. If this method returns without an exception then this socket
115     * is now connected. #close can be used to abort this call from another
116     * thread.
117     * @throws IOException On error, for example connection failure
118     */
119    public void connect() throws IOException {
120        connectNative();
121    }
122
123    /**
124     * Closes this socket.
125     * This will cause other blocking calls on this socket to immediately
126     * throw an IOException.
127     */
128    public void close() throws IOException {
129        closeNative();
130    }
131
132    /**
133     * Return the remote device we are connecting, or connected, to.
134     * @return remote device, or null if this socket has not yet attempted
135     *         or established a connection.
136     */
137    public BluetoothDevice getRemoteDevice() {
138        return mDevice;
139    }
140
141    /**
142     * Get the input stream associated with this socket.
143     * The input stream will be returned even if the socket is not yet
144     * connected, but operations on that stream will throw IOException until
145     * the associated socket is connected.
146     * @return InputStream
147     */
148    public InputStream getInputStream() throws IOException {
149        return mInputStream;
150    }
151
152    /**
153     * Get the output stream associated with this socket.
154     * The output stream will be returned even if the socket is not yet
155     * connected, but operations on that stream will throw IOException until
156     * the associated socket is connected.
157     * @return OutputStream
158     */
159    public OutputStream getOutputStream() throws IOException {
160        return mOutputStream;
161    }
162
163    private native void initSocketNative() throws IOException;
164    private native void initSocketFromFdNative(int fd) throws IOException;
165    private native void connectNative() throws IOException;
166    /*package*/ native void bindListenNative() throws IOException;
167    /*package*/ native BluetoothSocket acceptNative(int timeout) throws IOException;
168    /*package*/ native int availableNative() throws IOException;
169    /*package*/ native int readNative(byte[] b, int offset, int length) throws IOException;
170    /*package*/ native int writeNative(byte[] b, int offset, int length) throws IOException;
171    /*package*/ native void closeNative() throws IOException;
172    private native void destroyNative() throws IOException;
173}
174