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; 4209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Handler; 4309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Message; 4409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.util.Log; 4509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 4609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/** 476769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun * This class listens on OPUSH channel for incoming connection 4809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 4909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypublic class BluetoothOppRfcommListener { 50ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final String TAG = "BtOppRfcommListener"; 51888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 52ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final boolean V = Constants.VERBOSE; 5309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 541ac5507790a87810061a19dadec36eb328a222eaTao Liejun public static final int MSG_INCOMING_BTOPP_CONNECTION = 100; 551ac5507790a87810061a19dadec36eb328a222eaTao Liejun 5609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private volatile boolean mInterrupted; 5709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 5809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Thread mSocketAcceptThread; 5909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Handler mCallback; 6109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private static final int CREATE_RETRY_TIME = 10; 6309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 641ac5507790a87810061a19dadec36eb328a222eaTao Liejun private static final int DEFAULT_OPP_CHANNEL = 12; 6509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6641ef8d494511c040451f2f887cb31c3100746b61Nick Pelly private final int mBtOppRfcommChannel; 6709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6841ef8d494511c040451f2f887cb31c3100746b61Nick Pelly private final BluetoothAdapter mAdapter; 6941ef8d494511c040451f2f887cb31c3100746b61Nick Pelly 70888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun private BluetoothServerSocket mBtServerSocket = null; 71888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 72888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun private ServerSocket mTcpServerSocket = null; 73888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 7441ef8d494511c040451f2f887cb31c3100746b61Nick Pelly public BluetoothOppRfcommListener(BluetoothAdapter adapter) { 7541ef8d494511c040451f2f887cb31c3100746b61Nick Pelly this(adapter, DEFAULT_OPP_CHANNEL); 7609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 7709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 7841ef8d494511c040451f2f887cb31c3100746b61Nick Pelly public BluetoothOppRfcommListener(BluetoothAdapter adapter, int channel) { 7909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mBtOppRfcommChannel = channel; 8041ef8d494511c040451f2f887cb31c3100746b61Nick Pelly mAdapter = adapter; 8109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 8209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 8309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public synchronized boolean start(Handler callback) { 8409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mSocketAcceptThread == null) { 8509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mCallback = callback; 861ac5507790a87810061a19dadec36eb328a222eaTao Liejun 8709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread = new Thread(TAG) { 8809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 8909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void run() { 9009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (Constants.USE_TCP_DEBUG) { 9109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 92888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "Create TCP ServerSocket"); 93888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mTcpServerSocket = new ServerSocket(Constants.TCP_DEBUG_PORT, 1); 9409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 9509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Error listing on port" + Constants.TCP_DEBUG_PORT); 9609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 9709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 9809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly while (!mInterrupted) { 9909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 100888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Socket clientSocket = mTcpServerSocket.accept(); 101888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 102888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "Socket connected!"); 103888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun TestTcpTransport transport = new TestTcpTransport(clientSocket); 104888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Message msg = Message.obtain(); 105888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.setTarget(mCallback); 106888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.what = MSG_INCOMING_BTOPP_CONNECTION; 107888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.obj = transport; 108888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun msg.sendToTarget(); 109888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 11009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 111888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error accept connection " + e); 11209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 11309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 114888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "TCP listen thread finished"); 11509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 11609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly boolean serverOK = true; 11709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 11809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 11909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * it's possible that create will fail in some cases. 12009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * retry for 10 times 12109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 12209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) { 12309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 124888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mBtServerSocket = mAdapter 125888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun .listenUsingInsecureRfcommOn(mBtOppRfcommChannel); 12609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e1) { 1271ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.e(TAG, "Error create RfcommServerSocket " + e1); 12809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly serverOK = false; 12909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!serverOK) { 13109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly synchronized (this) { 13209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 133ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "wait 3 seconds"); 13409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Thread.sleep(3000); 13509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (InterruptedException e) { 13609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "socketAcceptThread thread was interrupted (3)"); 13709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 13809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 14009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 14109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly break; 14209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 14309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 14409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!serverOK) { 14509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Error start listening after " + CREATE_RETRY_TIME + " try"); 14609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 14709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 1481ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (!mInterrupted) { 1491ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "Accept thread started on channel " + mBtOppRfcommChannel); 1501ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 15109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothSocket clientSocket; 15209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly while (!mInterrupted) { 15309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 154888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun clientSocket = mBtServerSocket.accept(); 155888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.i(TAG, "Accepted connectoin from " 156888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun + clientSocket.getRemoteDevice()); 15709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothOppRfcommTransport transport = new BluetoothOppRfcommTransport( 15809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly clientSocket); 15909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Message msg = Message.obtain(); 16009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.setTarget(mCallback); 16109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.what = MSG_INCOMING_BTOPP_CONNECTION; 16209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.obj = transport; 16309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.sendToTarget(); 16409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 165888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error accept connection " + e); 16609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 16709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 1681ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "BluetoothSocket listen thread finished"); 16909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 17009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 17109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly }; 17209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = false; 173888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if(!Constants.USE_TCP_SIMPLE_SERVER) { 174888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mSocketAcceptThread.start(); 175888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 17609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 17709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return true; 17809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 17909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 18009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public synchronized void stop() { 18109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mSocketAcceptThread != null) { 1821ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "stopping Accept Thread"); 1831ac5507790a87810061a19dadec36eb328a222eaTao Liejun 18409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 185888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (Constants.USE_TCP_DEBUG) { 186888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "close mTcpServerSocket"); 187888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (mTcpServerSocket != null) { 188888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun try { 189888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mTcpServerSocket.close(); 190888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } catch (IOException e) { 191888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error close mTcpServerSocket"); 192888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 193888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 194888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } else { 195888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "close mBtServerSocket"); 196888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun 197888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (mBtServerSocket != null) { 198888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun try { 199888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mBtServerSocket.close(); 200888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } catch (IOException e) { 201888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.e(TAG, "Error close mBtServerSocket"); 202888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 203888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 204888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 20509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 20609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread.interrupt(); 207ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "waiting for thread to terminate"); 20809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread.join(); 20909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketAcceptThread = null; 21009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mCallback = null; 21109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (InterruptedException e) { 212ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Interrupted waiting for Accept Thread to join"); 21309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 21409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 21509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 21609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly} 217