BluetoothSocket.java revision bd022f423a33f0794bb53e5b0720da2d67e4631c
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 190b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellyimport java.io.Closeable; 200b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellyimport java.io.IOException; 210b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellyimport java.io.InputStream; 220b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellyimport java.io.OutputStream; 230b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 240b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly/** 250b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Represents a connected or connecting Bluetooth Socket. 260b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * 270b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Currently only supports RFCOMM sockets. 280b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * 290b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * RFCOMM is a connection orientated, streaming transport over Bluetooth. It is 300b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * also known as the Serial Port Profile (SPP). 310b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * 326a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * TODO: Consider exposing L2CAP sockets. 330b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * TODO: Clean up javadoc grammer and formatting. 340b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * TODO: Remove @hide 350b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @hide 360b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 370b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pellypublic final class BluetoothSocket implements Closeable { 386a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly /** Keep TYPE_RFCOMM etc in sync with BluetoothSocket.cpp */ 396a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly /*package*/ static final int TYPE_RFCOMM = 1; 406a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly /*package*/ static final int TYPE_SCO = 2; 416a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly /*package*/ static final int TYPE_L2CAP = 3; 426a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly 436a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly private final int mType; /* one of TYPE_RFCOMM etc */ 446a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly private final int mPort; /* RFCOMM channel or L2CAP psm */ 45bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly private final BluetoothDevice mDevice; /* remote device */ 460b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly private final String mAddress; /* remote address */ 470b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly private final boolean mAuth; 480b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly private final boolean mEncrypt; 490b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly private final BluetoothInputStream mInputStream; 500b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly private final BluetoothOutputStream mOutputStream; 510b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 520b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly private int mSocketData; /* used by native code only */ 530b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 540b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 55bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * Construct a BluetoothSocket. 566a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * @param type type of socket 570b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @param fd fd to use for connected socket, or -1 for a new socket 580b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @param auth require the remote device to be authenticated 590b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @param encrypt require the connection to be encrypted 60bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @param device remote device that this socket can connect to 610b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @param port remote port 620b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @throws IOException On error, for example Bluetooth not available, or 630b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * insufficient priveleges 640b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 65bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly /*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, 66bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly BluetoothDevice device, int port) throws IOException { 676a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly mType = type; 680b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly mAuth = auth; 690b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly mEncrypt = encrypt; 70bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly mDevice = device; 71bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly if (device == null) { 72bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly mAddress = null; 73bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly } else { 74bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly mAddress = device.getAddress(); 75bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly } 760b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly mPort = port; 770b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly if (fd == -1) { 780b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly initSocketNative(); 790b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } else { 800b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly initSocketFromFdNative(fd); 810b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 820b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly mInputStream = new BluetoothInputStream(this); 830b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly mOutputStream = new BluetoothOutputStream(this); 840b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 850b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 86bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly /** 87bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * Construct a BluetoothSocket from address. 88bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @param type type of socket 89bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @param fd fd to use for connected socket, or -1 for a new socket 90bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @param auth require the remote device to be authenticated 91bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @param encrypt require the connection to be encrypted 92bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @param address remote device that this socket can connect to 93bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @param port remote port 94bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @throws IOException On error, for example Bluetooth not available, or 95bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * insufficient priveleges 96bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly */ 97bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly private BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address, 98bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly int port) throws IOException { 99bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly this(type, fd, auth, encrypt, new BluetoothDevice(address), port); 100bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly } 101bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly 1020b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly @Override 1030b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly protected void finalize() throws Throwable { 1040b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly try { 1050b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly close(); 1060b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } finally { 1070b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly super.finalize(); 1080b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1090b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1100b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1110b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 1120b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Attempt to connect to a remote device. 1130b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * This method will block until a connection is made or the connection 1140b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * fails. If this method returns without an exception then this socket 1150b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * is now connected. #close can be used to abort this call from another 1160b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * thread. 1170b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @throws IOException On error, for example connection failure 1180b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1190b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public void connect() throws IOException { 1206a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly connectNative(); 1210b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1220b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1230b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 1240b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Closes this socket. 1250b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * This will cause other blocking calls on this socket to immediately 1260b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * throw an IOException. 1270b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1280b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public void close() throws IOException { 1290b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly closeNative(); 1300b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1310b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1320b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 133bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * Return the remote device we are connecting, or connected, to. 134bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @return remote device, or null if this socket has not yet attempted 1350b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * or established a connection. 1360b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 137bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly public BluetoothDevice getRemoteDevice() { 138bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly return mDevice; 1390b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1400b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1410b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 1420b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Get the input stream associated with this socket. 1430b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * The input stream will be returned even if the socket is not yet 1440b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * connected, but operations on that stream will throw IOException until 1450b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * the associated socket is connected. 1460b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @return InputStream 1470b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1480b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public InputStream getInputStream() throws IOException { 1490b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly return mInputStream; 1500b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1510b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1520b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 1530b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Get the output stream associated with this socket. 1540b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * The output stream will be returned even if the socket is not yet 1550b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * connected, but operations on that stream will throw IOException until 1560b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * the associated socket is connected. 1570b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @return OutputStream 1580b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1590b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public OutputStream getOutputStream() throws IOException { 1600b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly return mOutputStream; 1610b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1620b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1636a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly private native void initSocketNative() throws IOException; 1646a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly private native void initSocketFromFdNative(int fd) throws IOException; 1656a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly private native void connectNative() throws IOException; 1666a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly /*package*/ native void bindListenNative() throws IOException; 1670b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /*package*/ native BluetoothSocket acceptNative(int timeout) throws IOException; 1686a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly /*package*/ native int availableNative() throws IOException; 1696a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly /*package*/ native int readNative(byte[] b, int offset, int length) throws IOException; 1706a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly /*package*/ native int writeNative(byte[] b, int offset, int length) throws IOException; 1716a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly /*package*/ native void closeNative() throws IOException; 1726a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly private native void destroyNative() throws IOException; 1730b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly} 174