1192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta/* 2192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * Copyright (C) 2014 The Android Open Source Project 3192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * 4192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 5192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * you may not use this file except in compliance with the License. 6192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * You may obtain a copy of the License at 7192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * 8192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * http://www.apache.org/licenses/LICENSE-2.0 9192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * 10192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * Unless required by applicable law or agreed to in writing, software 11192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * distributed under the License is distributed on an "AS IS" BASIS, 12192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * See the License for the specific language governing permissions and 14192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * limitations under the License. 15192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta */ 16192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 17192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptapackage android.bluetooth.client.pbap; 18192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 19192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport android.bluetooth.BluetoothAdapter; 20192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport android.bluetooth.BluetoothDevice; 21192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport android.bluetooth.BluetoothSocket; 22192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport android.os.Handler; 23192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport android.os.Handler.Callback; 24192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport android.os.HandlerThread; 25192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport android.os.Message; 26192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport android.os.Process; 27192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport android.util.Log; 28192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 29192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport java.io.IOException; 30192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaimport java.util.UUID; 31192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 32192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptaclass BluetoothPbapSession implements Callback { 33192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private static final String TAG = "android.bluetooth.client.pbap.BluetoothPbapSession"; 34192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 35192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* local use only */ 36192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private static final int RFCOMM_CONNECTED = 1; 37192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private static final int RFCOMM_FAILED = 2; 38192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 39192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* to BluetoothPbapClient */ 40192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int REQUEST_COMPLETED = 3; 41192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int REQUEST_FAILED = 4; 42192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int SESSION_CONNECTING = 5; 43192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int SESSION_CONNECTED = 6; 44192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int SESSION_DISCONNECTED = 7; 45192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int AUTH_REQUESTED = 8; 46192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int AUTH_TIMEOUT = 9; 47192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 48192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int ACTION_LISTING = 14; 49192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int ACTION_VCARD = 15; 50192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public static final int ACTION_PHONEBOOK_SIZE = 16; 51192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 52192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private static final String PBAP_UUID = 53192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta "0000112f-0000-1000-8000-00805f9b34fb"; 54192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 55192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private final BluetoothAdapter mAdapter; 56192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private final BluetoothDevice mDevice; 57192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 58192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private final Handler mParentHandler; 59192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 60192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private final HandlerThread mHandlerThread; 61192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private final Handler mSessionHandler; 62192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 63192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private RfcommConnectThread mConnectThread; 64192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private BluetoothPbapObexTransport mTransport; 65192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 66192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private BluetoothPbapObexSession mObexSession; 67192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 68192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private BluetoothPbapRequest mPendingRequest = null; 69192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 70192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public BluetoothPbapSession(BluetoothDevice device, Handler handler) { 71192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 72192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mAdapter = BluetoothAdapter.getDefaultAdapter(); 73192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mAdapter == null) { 74192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta throw new NullPointerException("No Bluetooth adapter in the system"); 75192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 76192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 77192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mDevice = device; 78192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler = handler; 79192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mConnectThread = null; 80192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mTransport = null; 81192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mObexSession = null; 82192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 83192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mHandlerThread = new HandlerThread("PBAP session handler", 84192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Process.THREAD_PRIORITY_BACKGROUND); 85192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mHandlerThread.start(); 86192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mSessionHandler = new Handler(mHandlerThread.getLooper(), this); 87192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 88192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 89192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta @Override 90192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public boolean handleMessage(Message msg) { 91192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.d(TAG, "Handler: msg: " + msg.what); 92192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 93192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta switch (msg.what) { 94192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta case RFCOMM_FAILED: 95192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mConnectThread = null; 96192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 97192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(SESSION_DISCONNECTED).sendToTarget(); 98192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 99192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mPendingRequest != null) { 100192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(REQUEST_FAILED, mPendingRequest).sendToTarget(); 101192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mPendingRequest = null; 102192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 103192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta break; 104192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 105192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta case RFCOMM_CONNECTED: 106192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mConnectThread = null; 107192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mTransport = (BluetoothPbapObexTransport) msg.obj; 108192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta startObexSession(); 109192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta break; 110192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 111192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta case BluetoothPbapObexSession.OBEX_SESSION_FAILED: 112192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta stopObexSession(); 113192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 114192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(SESSION_DISCONNECTED).sendToTarget(); 115192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 116192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mPendingRequest != null) { 117192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(REQUEST_FAILED, mPendingRequest).sendToTarget(); 118192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mPendingRequest = null; 119192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 120192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta break; 121192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 122192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta case BluetoothPbapObexSession.OBEX_SESSION_CONNECTED: 123192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(SESSION_CONNECTED).sendToTarget(); 124192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 125192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mPendingRequest != null) { 126192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mObexSession.schedule(mPendingRequest); 127192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mPendingRequest = null; 128192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 129192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta break; 130192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 131192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta case BluetoothPbapObexSession.OBEX_SESSION_DISCONNECTED: 132192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(SESSION_DISCONNECTED).sendToTarget(); 133192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta stopRfcomm(); 134192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta break; 135192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 136192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta case BluetoothPbapObexSession.OBEX_SESSION_REQUEST_COMPLETED: 137192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* send to parent, process there */ 138192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(REQUEST_COMPLETED, msg.obj).sendToTarget(); 139192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta break; 140192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 141192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta case BluetoothPbapObexSession.OBEX_SESSION_REQUEST_FAILED: 142192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* send to parent, process there */ 143192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(REQUEST_FAILED, msg.obj).sendToTarget(); 144192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta break; 145192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 146192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta case BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_REQUEST: 147192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* send to parent, process there */ 148192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(AUTH_REQUESTED).sendToTarget(); 149192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 150192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mSessionHandler 151192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta .sendMessageDelayed( 152192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mSessionHandler 153192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta .obtainMessage(BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_TIMEOUT), 154192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 30000); 155192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta break; 156192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 157192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta case BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_TIMEOUT: 158192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* stop authentication */ 159192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta setAuthResponse(null); 160192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 161192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(AUTH_TIMEOUT).sendToTarget(); 162192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta break; 163192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 164192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta default: 165192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta return false; 166192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 167192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 168192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta return true; 169192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 170192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 171192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public void start() { 172192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.d(TAG, "start"); 173192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 174192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta startRfcomm(); 175192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 176192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 177192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public void stop() { 178192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.d(TAG, "Stop"); 179192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 180192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta stopObexSession(); 181192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta stopRfcomm(); 182192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 183192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 184192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public void abort() { 185192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.d(TAG, "abort"); 186192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 187192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* fail pending request immediately */ 188192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mPendingRequest != null) { 189192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(REQUEST_FAILED, mPendingRequest).sendToTarget(); 190192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mPendingRequest = null; 191192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 192192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 193192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mObexSession != null) { 194192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mObexSession.abort(); 195192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 196192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 197192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 198192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public boolean makeRequest(BluetoothPbapRequest request) { 199192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.v(TAG, "makeRequest: " + request.getClass().getSimpleName()); 200192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 201192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mPendingRequest != null) { 202192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.w(TAG, "makeRequest: request already queued, exiting"); 203192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta return false; 204192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 205192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 206192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mObexSession == null) { 207192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mPendingRequest = request; 208192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 209192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* 210192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * since there is no pending request and no session it's safe to 211192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * assume that RFCOMM does not exist either and we should start 212192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * connecting it 213192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta */ 214192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta startRfcomm(); 215192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 216192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta return true; 217192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 218192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 219192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta return mObexSession.schedule(request); 220192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 221192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 222192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public boolean setAuthResponse(String key) { 223192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.d(TAG, "setAuthResponse key=" + key); 224192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 225192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mSessionHandler 226192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta .removeMessages(BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_TIMEOUT); 227192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 228192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* does not make sense to set auth response when OBEX session is down */ 229192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mObexSession == null) { 230192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta return false; 231192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 232192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 233192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta return mObexSession.setAuthReply(key); 234192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 235192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 236192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private void startRfcomm() { 237192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.d(TAG, "startRfcomm"); 238192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 239192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mConnectThread == null && mObexSession == null) { 240192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mParentHandler.obtainMessage(SESSION_CONNECTING).sendToTarget(); 241192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 242192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mConnectThread = new RfcommConnectThread(); 243192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mConnectThread.start(); 244192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 245192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 246192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta /* 247192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * don't care if mConnectThread is not null - it means RFCOMM is being 248192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * connected anyway 249192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta */ 250192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 251192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 252192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private void stopRfcomm() { 253192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.d(TAG, "stopRfcomm"); 254192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 255192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mConnectThread != null) { 256192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta try { 257192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mConnectThread.join(); 258192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } catch (InterruptedException e) { 259192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 260192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 261192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mConnectThread = null; 262192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 263192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 264192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mTransport != null) { 265192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta try { 266192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mTransport.close(); 267192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } catch (IOException e) { 268192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 269192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 270192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mTransport = null; 271192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 272192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 273192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 274192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private void startObexSession() { 275192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.d(TAG, "startObexSession"); 276192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 277192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mObexSession = new BluetoothPbapObexSession(mTransport); 278192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mObexSession.start(mSessionHandler); 279192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 280192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 281192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private void stopObexSession() { 282192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.d(TAG, "stopObexSession"); 283192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 284192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mObexSession != null) { 285192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mObexSession.stop(); 286192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mObexSession = null; 287192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 288192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 289192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 290192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private class RfcommConnectThread extends Thread { 291192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private static final String TAG = "RfcommConnectThread"; 292192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 293192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private BluetoothSocket mSocket; 294192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 295192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public RfcommConnectThread() { 296192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta super("RfcommConnectThread"); 297192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 298192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 299192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta @Override 300192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta public void run() { 301192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mAdapter.isDiscovering()) { 302192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mAdapter.cancelDiscovery(); 303192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 304192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 305192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta try { 306192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mSocket = mDevice.createRfcommSocketToServiceRecord(UUID.fromString(PBAP_UUID)); 307192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mSocket.connect(); 308192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 309192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta BluetoothPbapObexTransport transport; 310192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta transport = new BluetoothPbapObexTransport(mSocket); 311192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 312192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mSessionHandler.obtainMessage(RFCOMM_CONNECTED, transport).sendToTarget(); 313192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } catch (IOException e) { 314192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta closeSocket(); 315192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mSessionHandler.obtainMessage(RFCOMM_FAILED).sendToTarget(); 316192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 317192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 318192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 319192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta 320192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta private void closeSocket() { 321192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta try { 322192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta if (mSocket != null) { 323192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta mSocket.close(); 324192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 325192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } catch (IOException e) { 326192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta Log.e(TAG, "Error when closing socket", e); 327192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 328192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 329192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta } 330192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta} 331