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.ParcelUuid; 21238e0f934f1f47263b384bc745ae0678c777130dCasper Bondeimport android.util.Log; 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 63382871b03fd6d1d1207d20cf647fa73e71a8496eMarie Janssen * <a href="{@docRoot}guide/topics/connectivity/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 70238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde private static final String TAG = "BluetoothServerSocket"; 71bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly /*package*/ final BluetoothSocket mSocket; 7224bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly private Handler mHandler; 7324bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly private int mMessage; 74238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde private int mChannel; 750b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 760b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 770b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Construct a socket for incoming connections. 786a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * @param type type of socket 796a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * @param auth require the remote device to be authenticated 806a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * @param encrypt require the connection to be encrypted 816a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly * @param port remote port 820b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * @throws IOException On error, for example Bluetooth not available, or 83f51eadaf1f83abfe16a609a4ded6d789494689b2Jake Hamby * insufficient privileges 840b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 85bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port) 866a669fac385b51b8bb01844b77a9a43840dda854Nick Pelly throws IOException { 876d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson mChannel = port; 8816fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null); 892328423d19416da0c1068883c33e612d5729fc47Casper Bonde if (port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) { 902328423d19416da0c1068883c33e612d5729fc47Casper Bonde mSocket.setExcludeSdp(true); 912328423d19416da0c1068883c33e612d5729fc47Casper Bonde } 922328423d19416da0c1068883c33e612d5729fc47Casper Bonde } 932328423d19416da0c1068883c33e612d5729fc47Casper Bonde 942328423d19416da0c1068883c33e612d5729fc47Casper Bonde /** 952328423d19416da0c1068883c33e612d5729fc47Casper Bonde * Construct a socket for incoming connections. 962328423d19416da0c1068883c33e612d5729fc47Casper Bonde * @param type type of socket 972328423d19416da0c1068883c33e612d5729fc47Casper Bonde * @param auth require the remote device to be authenticated 982328423d19416da0c1068883c33e612d5729fc47Casper Bonde * @param encrypt require the connection to be encrypted 992328423d19416da0c1068883c33e612d5729fc47Casper Bonde * @param port remote port 1002328423d19416da0c1068883c33e612d5729fc47Casper Bonde * @param mitm enforce man-in-the-middle protection for authentication. 1013b3d1fea94318a4892fbd4353269749af417a81aCasper Bonde * @param min16DigitPin enforce a minimum length of 16 digits for a sec mode 2 connection 1022328423d19416da0c1068883c33e612d5729fc47Casper Bonde * @throws IOException On error, for example Bluetooth not available, or 1032328423d19416da0c1068883c33e612d5729fc47Casper Bonde * insufficient privileges 1042328423d19416da0c1068883c33e612d5729fc47Casper Bonde */ 1052328423d19416da0c1068883c33e612d5729fc47Casper Bonde /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port, 1063b3d1fea94318a4892fbd4353269749af417a81aCasper Bonde boolean mitm, boolean min16DigitPin) 1072328423d19416da0c1068883c33e612d5729fc47Casper Bonde throws IOException { 1082328423d19416da0c1068883c33e612d5729fc47Casper Bonde mChannel = port; 1093b3d1fea94318a4892fbd4353269749af417a81aCasper Bonde mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null, mitm, 1103b3d1fea94318a4892fbd4353269749af417a81aCasper Bonde min16DigitPin); 111238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) { 112238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde mSocket.setExcludeSdp(true); 113238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 1140b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1150b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1160b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 1173b147b770269173d5d711d6c33f142dc5e723824zzy * Construct a socket for incoming connections. 1183b147b770269173d5d711d6c33f142dc5e723824zzy * @param type type of socket 1193b147b770269173d5d711d6c33f142dc5e723824zzy * @param auth require the remote device to be authenticated 1203b147b770269173d5d711d6c33f142dc5e723824zzy * @param encrypt require the connection to be encrypted 1213b147b770269173d5d711d6c33f142dc5e723824zzy * @param uuid uuid 1223b147b770269173d5d711d6c33f142dc5e723824zzy * @throws IOException On error, for example Bluetooth not available, or 1233b147b770269173d5d711d6c33f142dc5e723824zzy * insufficient privileges 1243b147b770269173d5d711d6c33f142dc5e723824zzy */ 1253b147b770269173d5d711d6c33f142dc5e723824zzy /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, ParcelUuid uuid) 1263b147b770269173d5d711d6c33f142dc5e723824zzy throws IOException { 1273b147b770269173d5d711d6c33f142dc5e723824zzy mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, -1, uuid); 128238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde // TODO: This is the same as mChannel = -1 - is this intentional? 1293b147b770269173d5d711d6c33f142dc5e723824zzy mChannel = mSocket.getPort(); 1303b147b770269173d5d711d6c33f142dc5e723824zzy } 1313b147b770269173d5d711d6c33f142dc5e723824zzy 1323b147b770269173d5d711d6c33f142dc5e723824zzy 1333b147b770269173d5d711d6c33f142dc5e723824zzy /** 1340b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Block until a connection is established. 13545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Returns a connected {@link BluetoothSocket} on successful connection. 13645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Once this call returns, it can be called again to accept subsequent 13745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * incoming connections. 13845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>{@link #close} can be used to abort this call from another thread. 13945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * @return a connected {@link BluetoothSocket} 14045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * @throws IOException on error, for example this call was aborted, or 14145e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * timeout 1420b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1430b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public BluetoothSocket accept() throws IOException { 1440b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly return accept(-1); 1450b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1460b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1470b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 1480b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * Block until a connection is established, with timeout. 14945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Returns a connected {@link BluetoothSocket} on successful connection. 15045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Once this call returns, it can be called again to accept subsequent 15145e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * incoming connections. 15245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>{@link #close} can be used to abort this call from another thread. 15345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * @return a connected {@link BluetoothSocket} 15445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * @throws IOException on error, for example this call was aborted, or 1550b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * timeout 1560b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1570b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public BluetoothSocket accept(int timeout) throws IOException { 15871c3c7806acb2b2b7b8441817c26a2101d447bbeNick Pelly return mSocket.accept(timeout); 1590b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 1600b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly 1610b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly /** 16245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * Immediately close this socket, and release all associated resources. 16345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Causes blocked calls on this socket in other threads to immediately 1640b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly * throw an IOException. 1656d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * <p>Closing the {@link BluetoothServerSocket} will <em>not</em> 1666d95fc0a2ca910212a43c4547c0ef000659b72dcScott Main * close any {@link BluetoothSocket} received from {@link #accept()}. 1670b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly */ 1680b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly public void close() throws IOException { 16924bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly synchronized (this) { 17024bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly if (mHandler != null) { 17124bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly mHandler.obtainMessage(mMessage).sendToTarget(); 17224bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly } 17324bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly } 17471c3c7806acb2b2b7b8441817c26a2101d447bbeNick Pelly mSocket.close(); 1750b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly } 17624bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly 17724bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly /*package*/ synchronized void setCloseHandler(Handler handler, int message) { 17824bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly mHandler = handler; 17924bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly mMessage = message; 18024bb9b8af4ff691538fe9e517e8156016b0da6cdNick Pelly } 1813b147b770269173d5d711d6c33f142dc5e723824zzy /*package*/ void setServiceName(String ServiceName) { 1823b147b770269173d5d711d6c33f142dc5e723824zzy mSocket.setServiceName(ServiceName); 1833b147b770269173d5d711d6c33f142dc5e723824zzy } 184238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde 1856d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson /** 1866d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson * Returns the channel on which this socket is bound. 1876d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson * @hide 1886d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson */ 1896d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson public int getChannel() { 1906d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson return mChannel; 1916d8b80dd8c56dba02dcb6e64ace37fb85aeee1f5Ben Dodson } 192238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde 193238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde /** 194238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde * Sets the channel on which future sockets are bound. 195238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde * Currently used only when a channel is auto generated. 196238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde */ 197238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde /*package*/ void setChannel(int newChannel) { 198238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde /* TODO: From a design/architecture perspective this is wrong. 199238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde * The bind operation should be conducted through this class 200238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde * and the resulting port should be kept in mChannel, and 201238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde * not set from BluetoothAdapter. */ 202238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(mSocket != null) { 203238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(mSocket.getPort() != newChannel) { 204238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde Log.w(TAG,"The port set is different that the underlying port. mSocket.getPort(): " 205238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde + mSocket.getPort() + " requested newChannel: " + newChannel); 206238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 207238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 208238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde mChannel = newChannel; 209238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 210238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde 211238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde @Override 212238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde public String toString() { 213238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde StringBuilder sb = new StringBuilder(); 214238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde sb.append("ServerSocket: Type: "); 215238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde switch(mSocket.getConnectionType()) { 216238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde case BluetoothSocket.TYPE_RFCOMM: 217238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde { 218238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde sb.append("TYPE_RFCOMM"); 219238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde break; 220238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 221238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde case BluetoothSocket.TYPE_L2CAP: 222238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde { 223238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde sb.append("TYPE_L2CAP"); 224238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde break; 225238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 226238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde case BluetoothSocket.TYPE_SCO: 227238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde { 228238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde sb.append("TYPE_SCO"); 229238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde break; 230238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 231238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 232238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde sb.append(" Channel: ").append(mChannel); 233238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde return sb.toString(); 234238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 2350b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly} 236