109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/* 209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc. 309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * All rights reserved. 509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Redistribution and use in source and binary forms, with or without 709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * modification, are permitted provided that the following conditions are met: 809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions of source code must retain the above copyright notice, 1009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer. 1109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 1209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice, 1309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer in the documentation 1409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * and/or other materials provided with the distribution. 1509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 1609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors 1709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * may be used to endorse or promote products derived from this software 1809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * without specific prior written permission. 1909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 2009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * POSSIBILITY OF SUCH DAMAGE. 3109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 3209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypackage com.android.bluetooth.opp; 3409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.IOException; 3609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.net.ServerSocket; 3709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.net.Socket; 3809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 39bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport com.android.bluetooth.BluetoothObexTransport; 40bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 4141ef8d494511c040451f2f887cb31c3100746b61Nick Pellyimport android.bluetooth.BluetoothAdapter; 4209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.bluetooth.BluetoothServerSocket; 4309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.bluetooth.BluetoothSocket; 449f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredcimport android.bluetooth.BluetoothUuid; 4509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Handler; 4609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Message; 4709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.util.Log; 4809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 4909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/** 506769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun * This class listens on OPUSH channel for incoming connection 5109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 5209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypublic class BluetoothOppRfcommListener { 53ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final String TAG = "BtOppRfcommListener"; 54888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 55ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final boolean V = Constants.VERBOSE; 5609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 571ac5507790a87810061a19dadec36eb328a222eaTao Liejun public static final int MSG_INCOMING_BTOPP_CONNECTION = 100; 581ac5507790a87810061a19dadec36eb328a222eaTao Liejun 5909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private volatile boolean mInterrupted; 6009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Thread mSocketAcceptThread; 6209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Handler mCallback; 6409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private static final int CREATE_RETRY_TIME = 10; 6609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6741ef8d494511c040451f2f887cb31c3100746b61Nick Pelly private final BluetoothAdapter mAdapter; 6841ef8d494511c040451f2f887cb31c3100746b61Nick Pelly 69888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun private BluetoothServerSocket mBtServerSocket = null; 70888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 71888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun private ServerSocket mTcpServerSocket = null; 72888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 7341ef8d494511c040451f2f887cb31c3100746b61Nick Pelly public BluetoothOppRfcommListener(BluetoothAdapter adapter) { 7441ef8d494511c040451f2f887cb31c3100746b61Nick Pelly mAdapter = adapter; 7509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 7609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 779f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc 7809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public synchronized boolean start(Handler callback) { 7909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mSocketAcceptThread == null) { 8009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mCallback = callback; 811ac5507790a87810061a19dadec36eb328a222eaTao Liejun 8209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread = new Thread(TAG) { 8309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 8409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void run() { 8509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (Constants.USE_TCP_DEBUG) { 8609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 87888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "Create TCP ServerSocket"); 88888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mTcpServerSocket = new ServerSocket(Constants.TCP_DEBUG_PORT, 1); 8909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 9009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Error listing on port" + Constants.TCP_DEBUG_PORT); 9109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 9209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 9309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly while (!mInterrupted) { 9409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 95888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Socket clientSocket = mTcpServerSocket.accept(); 96888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 97888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "Socket connected!"); 98888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun TestTcpTransport transport = new TestTcpTransport(clientSocket); 99888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Message msg = Message.obtain(); 100888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.setTarget(mCallback); 101888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.what = MSG_INCOMING_BTOPP_CONNECTION; 102888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.obj = transport; 103888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.sendToTarget(); 104888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 10509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 106888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error accept connection " + e); 10709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 10809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 109888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "TCP listen thread finished"); 11009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 11109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly boolean serverOK = true; 11209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 11309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 11409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * it's possible that create will fail in some cases. 11509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * retry for 10 times 11609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 11709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) { 11809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 1199f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc if (V) Log.v(TAG, "Starting RFCOMM listener...."); 1209f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc mBtServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord("OBEX Object Push", BluetoothUuid.ObexObjectPush.getUuid()); 1219f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc if (V) Log.v(TAG, "Started RFCOMM listener...."); 12209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e1) { 1231ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.e(TAG, "Error create RfcommServerSocket " + e1); 12409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly serverOK = false; 1259f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc } 12615d36984a79d6e35c659edb0efdf929f0b526bd5Fred 12709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!serverOK) { 12809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly synchronized (this) { 12909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 13015d36984a79d6e35c659edb0efdf929f0b526bd5Fred if (V) Log.v(TAG, "Wait 300 ms"); 13115d36984a79d6e35c659edb0efdf929f0b526bd5Fred Thread.sleep(300); 13209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (InterruptedException e) { 13309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "socketAcceptThread thread was interrupted (3)"); 13409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 13509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 13809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly break; 13909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 14009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 14109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!serverOK) { 14209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Error start listening after " + CREATE_RETRY_TIME + " try"); 14309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 14409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 1451ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (!mInterrupted) { 1469f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc Log.i(TAG, "Accept thread started."); 1471ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 14809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothSocket clientSocket; 14909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly while (!mInterrupted) { 15009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 1519f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc if (V) Log.v(TAG, "Accepting connection..."); 152b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if (mBtServerSocket == null) { 153bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 154b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 155b5cc776c9353a203cdde97e62b25f05d9633d14cfredc BluetoothServerSocket sSocket = mBtServerSocket; 156b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if (sSocket ==null) { 157b5cc776c9353a203cdde97e62b25f05d9633d14cfredc mInterrupted = true; 158bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 159b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } else { 1604852c5686229f1014e9851f4e9a3a19547581b45fredc clientSocket = sSocket.accept(); 161b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if (V) Log.v(TAG, "Accepted connection from " 162888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun + clientSocket.getRemoteDevice()); 163bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde BluetoothObexTransport transport = new BluetoothObexTransport( 16409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly clientSocket); 165b5cc776c9353a203cdde97e62b25f05d9633d14cfredc Message msg = Message.obtain(); 166b5cc776c9353a203cdde97e62b25f05d9633d14cfredc msg.setTarget(mCallback); 167b5cc776c9353a203cdde97e62b25f05d9633d14cfredc msg.what = MSG_INCOMING_BTOPP_CONNECTION; 168b5cc776c9353a203cdde97e62b25f05d9633d14cfredc msg.obj = transport; 169b5cc776c9353a203cdde97e62b25f05d9633d14cfredc msg.sendToTarget(); 170b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 17109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 172888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error accept connection " + e); 17315d36984a79d6e35c659edb0efdf929f0b526bd5Fred try { 17415d36984a79d6e35c659edb0efdf929f0b526bd5Fred Thread.sleep(500); 17515d36984a79d6e35c659edb0efdf929f0b526bd5Fred } catch (InterruptedException ie) {} 17609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 1779f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc } 1781ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "BluetoothSocket listen thread finished"); 17909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 18009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 18109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly }; 18209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = false; 183888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if(!Constants.USE_TCP_SIMPLE_SERVER) { 184888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mSocketAcceptThread.start(); 185888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 18609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 18709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return true; 18809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 18909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 19009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public synchronized void stop() { 19109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mSocketAcceptThread != null) { 1921ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "stopping Accept Thread"); 1931ac5507790a87810061a19dadec36eb328a222eaTao Liejun 19409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 195b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if (Constants.USE_TCP_DEBUG) { 196888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "close mTcpServerSocket"); 197888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (mTcpServerSocket != null) { 198888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun try { 199888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mTcpServerSocket.close(); 2003fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mTcpServerSocket = null; 201888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } catch (IOException e) { 202888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error close mTcpServerSocket"); 203888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 204888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 205888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } else { 206888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "close mBtServerSocket"); 207888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 208888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (mBtServerSocket != null) { 209888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun try { 210888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mBtServerSocket.close(); 2113fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mBtServerSocket = null; 212888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } catch (IOException e) { 213888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error close mBtServerSocket"); 214888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 215888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 216888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 21709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 21809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread.interrupt(); 219ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "waiting for thread to terminate"); 220d288c0dac06748780916bf438b7c84482545672ffredc //mSocketAcceptThread.join(JOIN_TIMEOUT_MS); 221d288c0dac06748780916bf438b7c84482545672ffredc mSocketAcceptThread.join(); 22231ba132491053bc86d419a7d51fc04af3299c076fredc if (V) Log.v(TAG, "done waiting for thread to terminate"); 22309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread = null; 22409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mCallback = null; 22509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (InterruptedException e) { 226ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Interrupted waiting for Accept Thread to join"); 22709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 22809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 22909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 23009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly} 231