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 3941ef8d494511c040451f2f887cb31c3100746b61Nick Pellyimport android.bluetooth.BluetoothAdapter; 4009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.bluetooth.BluetoothServerSocket; 4109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.bluetooth.BluetoothSocket; 429f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredcimport android.bluetooth.BluetoothUuid; 4309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Handler; 4409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Message; 4509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.util.Log; 4609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 4709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/** 486769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun * This class listens on OPUSH channel for incoming connection 4909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 5009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypublic class BluetoothOppRfcommListener { 51ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final String TAG = "BtOppRfcommListener"; 52888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 53ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final boolean V = Constants.VERBOSE; 5409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 551ac5507790a87810061a19dadec36eb328a222eaTao Liejun public static final int MSG_INCOMING_BTOPP_CONNECTION = 100; 561ac5507790a87810061a19dadec36eb328a222eaTao Liejun 5709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private volatile boolean mInterrupted; 5809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 5909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Thread mSocketAcceptThread; 6009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Handler mCallback; 6209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private static final int CREATE_RETRY_TIME = 10; 6409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6541ef8d494511c040451f2f887cb31c3100746b61Nick Pelly private final BluetoothAdapter mAdapter; 6641ef8d494511c040451f2f887cb31c3100746b61Nick Pelly 67888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun private BluetoothServerSocket mBtServerSocket = null; 68888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 69888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun private ServerSocket mTcpServerSocket = null; 70888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 7141ef8d494511c040451f2f887cb31c3100746b61Nick Pelly public BluetoothOppRfcommListener(BluetoothAdapter adapter) { 7241ef8d494511c040451f2f887cb31c3100746b61Nick Pelly mAdapter = adapter; 7309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 7409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 759f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc 7609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public synchronized boolean start(Handler callback) { 7709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mSocketAcceptThread == null) { 7809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mCallback = callback; 791ac5507790a87810061a19dadec36eb328a222eaTao Liejun 8009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread = new Thread(TAG) { 8109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 8209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void run() { 8309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (Constants.USE_TCP_DEBUG) { 8409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 85888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "Create TCP ServerSocket"); 86888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mTcpServerSocket = new ServerSocket(Constants.TCP_DEBUG_PORT, 1); 8709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 8809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Error listing on port" + Constants.TCP_DEBUG_PORT); 8909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 9009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 9109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly while (!mInterrupted) { 9209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 93888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Socket clientSocket = mTcpServerSocket.accept(); 94888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 95888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "Socket connected!"); 96888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun TestTcpTransport transport = new TestTcpTransport(clientSocket); 97888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Message msg = Message.obtain(); 98888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.setTarget(mCallback); 99888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.what = MSG_INCOMING_BTOPP_CONNECTION; 100888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.obj = transport; 101888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.sendToTarget(); 102888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 10309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 104888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error accept connection " + e); 10509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 10609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 107888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "TCP listen thread finished"); 10809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 10909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly boolean serverOK = true; 11009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 11109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 11209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * it's possible that create will fail in some cases. 11309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * retry for 10 times 11409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 11509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) { 11609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 1179f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc if (V) Log.v(TAG, "Starting RFCOMM listener...."); 1189f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc mBtServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord("OBEX Object Push", BluetoothUuid.ObexObjectPush.getUuid()); 1199f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc if (V) Log.v(TAG, "Started RFCOMM listener...."); 12009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e1) { 1211ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.e(TAG, "Error create RfcommServerSocket " + e1); 12209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly serverOK = false; 1239f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc } 12415d36984a79d6e35c659edb0efdf929f0b526bd5Fred 12509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!serverOK) { 12609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly synchronized (this) { 12709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 12815d36984a79d6e35c659edb0efdf929f0b526bd5Fred if (V) Log.v(TAG, "Wait 300 ms"); 12915d36984a79d6e35c659edb0efdf929f0b526bd5Fred Thread.sleep(300); 13009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (InterruptedException e) { 13109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "socketAcceptThread thread was interrupted (3)"); 13209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 13309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 13609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly break; 13709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!serverOK) { 14009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Error start listening after " + CREATE_RETRY_TIME + " try"); 14109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 14209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 1431ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (!mInterrupted) { 1449f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc Log.i(TAG, "Accept thread started."); 1451ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 14609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothSocket clientSocket; 14709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly while (!mInterrupted) { 14809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 1499f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc if (V) Log.v(TAG, "Accepting connection..."); 150b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if (mBtServerSocket == null) { 151b5cc776c9353a203cdde97e62b25f05d9633d14cfredc 152b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 153b5cc776c9353a203cdde97e62b25f05d9633d14cfredc BluetoothServerSocket sSocket = mBtServerSocket; 154b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if (sSocket ==null) { 155b5cc776c9353a203cdde97e62b25f05d9633d14cfredc mInterrupted = true; 156b5cc776c9353a203cdde97e62b25f05d9633d14cfredc 157b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } else { 1584852c5686229f1014e9851f4e9a3a19547581b45fredc clientSocket = sSocket.accept(); 159b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if (V) Log.v(TAG, "Accepted connection from " 160888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun + clientSocket.getRemoteDevice()); 161b5cc776c9353a203cdde97e62b25f05d9633d14cfredc BluetoothOppRfcommTransport transport = new BluetoothOppRfcommTransport( 16209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly clientSocket); 163b5cc776c9353a203cdde97e62b25f05d9633d14cfredc Message msg = Message.obtain(); 164b5cc776c9353a203cdde97e62b25f05d9633d14cfredc msg.setTarget(mCallback); 165b5cc776c9353a203cdde97e62b25f05d9633d14cfredc msg.what = MSG_INCOMING_BTOPP_CONNECTION; 166b5cc776c9353a203cdde97e62b25f05d9633d14cfredc msg.obj = transport; 167b5cc776c9353a203cdde97e62b25f05d9633d14cfredc msg.sendToTarget(); 168b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 16909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 170888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error accept connection " + e); 17115d36984a79d6e35c659edb0efdf929f0b526bd5Fred try { 17215d36984a79d6e35c659edb0efdf929f0b526bd5Fred Thread.sleep(500); 17315d36984a79d6e35c659edb0efdf929f0b526bd5Fred } catch (InterruptedException ie) {} 17409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 1759f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc } 1761ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "BluetoothSocket listen thread finished"); 17709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 17809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 17909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly }; 18009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = false; 181888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if(!Constants.USE_TCP_SIMPLE_SERVER) { 182888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mSocketAcceptThread.start(); 183888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 18409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 18509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return true; 18609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 18709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 18809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public synchronized void stop() { 18909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mSocketAcceptThread != null) { 1901ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "stopping Accept Thread"); 1911ac5507790a87810061a19dadec36eb328a222eaTao Liejun 19209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 193b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if (Constants.USE_TCP_DEBUG) { 194888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "close mTcpServerSocket"); 195888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (mTcpServerSocket != null) { 196888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun try { 197888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mTcpServerSocket.close(); 1983fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mTcpServerSocket = null; 199888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } catch (IOException e) { 200888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error close mTcpServerSocket"); 201888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 202888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 203888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } else { 204888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "close mBtServerSocket"); 205888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 206888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (mBtServerSocket != null) { 207888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun try { 208888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mBtServerSocket.close(); 2093fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mBtServerSocket = null; 210888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } catch (IOException e) { 211888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error close mBtServerSocket"); 212888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 213888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 214888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 21509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 21609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread.interrupt(); 217ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "waiting for thread to terminate"); 218d288c0dac06748780916bf438b7c84482545672ffredc //mSocketAcceptThread.join(JOIN_TIMEOUT_MS); 219d288c0dac06748780916bf438b7c84482545672ffredc mSocketAcceptThread.join(); 22031ba132491053bc86d419a7d51fc04af3299c076fredc if (V) Log.v(TAG, "done waiting for thread to terminate"); 22109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread = null; 22209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mCallback = null; 22309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (InterruptedException e) { 224ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Interrupted waiting for Accept Thread to join"); 22509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 22609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 22709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 22809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly} 229