BluetoothGatt.java revision 514c5ef8d5774d8820ed1bf90fe53af1606cf106
19908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta/* 29908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Copyright (C) 2013 The Android Open Source Project 39908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 49908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Licensed under the Apache License, Version 2.0 (the "License"); 59908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * you may not use this file except in compliance with the License. 69908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * You may obtain a copy of the License at 79908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 89908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * http://www.apache.org/licenses/LICENSE-2.0 99908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Unless required by applicable law or agreed to in writing, software 119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * distributed under the License is distributed on an "AS IS" BASIS, 129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * See the License for the specific language governing permissions and 149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * limitations under the License. 159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battapackage android.bluetooth; 189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport android.content.Context; 209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport android.os.ParcelUuid; 219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport android.os.RemoteException; 229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport android.util.Log; 239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport java.util.ArrayList; 259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport java.util.List; 269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport java.util.UUID; 279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta/** 29ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Public API for the Bluetooth GATT Profile. 309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 31ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * <p>This class provides Bluetooth GATT functionality to enable communication 329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * with Bluetooth Smart or Smart Ready devices. 339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>To connect to a remote peripheral device, create a {@link BluetoothGattCallback} 3533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * and call {@link BluetoothDevice#connectGatt} to get a instance of this class. 36ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * GATT capable devices can be discovered using the Bluetooth device discovery or BLE 37ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * scan process. 389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battapublic final class BluetoothGatt implements BluetoothProfile { 409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private static final String TAG = "BluetoothGatt"; 419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private static final boolean DBG = true; 4255d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach private static final boolean VDBG = false; 439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 44ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private final Context mContext; 459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private IBluetoothGatt mService; 469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private BluetoothGattCallback mCallback; 479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private int mClientIf; 489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private boolean mAuthRetry = false; 49ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private BluetoothDevice mDevice; 50ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private boolean mAutoConnect; 51ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private int mConnState; 52ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private final Object mStateLock = new Object(); 53cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach private Boolean mDeviceBusy = false; 54b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta private int mTransport; 55ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie 56ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_IDLE = 0; 57ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_CONNECTING = 1; 58ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_CONNECTED = 2; 59ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_DISCONNECTING = 3; 6033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie private static final int CONN_STATE_CLOSED = 4; 619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private List<BluetoothGattService> mServices; 639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 64ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /** A GATT operation completed successfully */ 659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_SUCCESS = 0; 669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 67ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /** GATT read operation is not permitted */ 689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_READ_NOT_PERMITTED = 0x2; 699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 70ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /** GATT write operation is not permitted */ 719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_WRITE_NOT_PERMITTED = 0x3; 729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** Insufficient authentication for a given operation */ 749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INSUFFICIENT_AUTHENTICATION = 0x5; 759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** The given request is not supported */ 779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_REQUEST_NOT_SUPPORTED = 0x6; 789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** Insufficient encryption for a given operation */ 809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INSUFFICIENT_ENCRYPTION = 0xf; 819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** A read or write operation was requested with an invalid offset */ 839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INVALID_OFFSET = 0x7; 849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** A write operation exceeds the maximum length of the attribute */ 869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 0xd; 879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8845a0a1a689518df7e2c904b902e28f6d68b76e2aAndre Eisenbach /** A remote device connection is congested. */ 89dadefdad8ef424991feb45f02f923a2f8224285bAndre Eisenbach public static final int GATT_CONNECTION_CONGESTED = 0x8f; 90dadefdad8ef424991feb45f02f923a2f8224285bAndre Eisenbach 9190ca807f7b2037499112d1c49c4b0793cc780540Matthew Xie /** A GATT operation failed, errors other than the above */ 9290ca807f7b2037499112d1c49c4b0793cc780540Matthew Xie public static final int GATT_FAILURE = 0x101; 9390ca807f7b2037499112d1c49c4b0793cc780540Matthew Xie 949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 956ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * Connection paramter update - Use the connection paramters recommended by the 966ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * Bluetooth SIG. This is the default value if no connection parameter update 976ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * is requested. 986ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach */ 994072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public static final int CONNECTION_PRIORITY_BALANCED = 0; 1006ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 1016ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach /** 1026ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * Connection paramter update - Request a high priority, low latency connection. 1036ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * An application should only request high priority connection paramters to transfer 1046ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * large amounts of data over LE quickly. Once the transfer is complete, the application 1054072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * should request {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED} connectoin parameters 1066ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * to reduce energy use. 1076ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach */ 1084072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public static final int CONNECTION_PRIORITY_HIGH = 1; 1096ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 1106ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach /** Connection paramter update - Request low power, reduced data rate connection parameters. */ 1114072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public static final int CONNECTION_PRIORITY_LOW_POWER = 2; 1126ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 1136ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach /** 1149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * No authentication required. 1159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ static final int AUTHENTICATION_NONE = 0; 1189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Authentication requested; no man-in-the-middle protection required. 1219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ static final int AUTHENTICATION_NO_MITM = 1; 1249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Authentication with man-in-the-middle protection requested. 1279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ static final int AUTHENTICATION_MITM = 2; 1309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 132e0d4afb2d4caecb264852a35f6e3cfc1248e08c4Wei Wang * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation. 1339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private final IBluetoothGattCallback mBluetoothGattCallback = 135e0d4afb2d4caecb264852a35f6e3cfc1248e08c4Wei Wang new BluetoothGattCallbackWrapper() { 1369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Application interface registered - app is ready to go 1389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onClientRegistered(int status, int clientIf) { 1419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status 1429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " clientIf=" + clientIf); 143ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (VDBG) { 144ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 145ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (mConnState != CONN_STATE_CONNECTING) { 146ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG, "Bad connection state: " + mConnState); 147ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 148ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 149ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 1509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mClientIf = clientIf; 151ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (status != GATT_SUCCESS) { 15233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE, 153ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothProfile.STATE_DISCONNECTED); 154ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 155ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 156ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 157ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 158ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 1599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 160ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.clientConnect(mClientIf, mDevice.getAddress(), 161b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta !mAutoConnect, mTransport); // autoConnect is inverse of "isDirect" 162ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } catch (RemoteException e) { 163ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG,"",e); 1649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 1659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 1669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Client connection state changed 1699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onClientConnectionState(int status, int clientIf, 1729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta boolean connected, String address) { 1739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onClientConnectionState() - status=" + status 1749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " clientIf=" + clientIf + " device=" + address); 175ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 176ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 177ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 178ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie int profileState = connected ? BluetoothProfile.STATE_CONNECTED : 179ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothProfile.STATE_DISCONNECTED; 1809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 18133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState); 1829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 1830998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 1849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 185ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie 186ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 187ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (connected) { 188ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_CONNECTED; 189ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } else { 190ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 191ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 192ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 193cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 194cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 195cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 196cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 1989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 2009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote search has been completed. 2019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * The internal object structure should now reflect the state 2029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * of the remote device database. Let the application know that 2039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * we are done at this point. 2049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 2059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 206bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski public void onSearchComplete(String address, List<BluetoothGattService> services, 207bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski int status) { 2089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onSearchComplete() = Device=" + address + " Status=" + status); 209ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 210ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 211ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 212bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 213bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski for (BluetoothGattService s : services) { 214bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski //services we receive don't have device set properly. 215bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski s.setDevice(mDevice); 216bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } 217bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 218bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski mServices.addAll(services); 219bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 220bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski // Fix references to included services, as they doesn't point to right objects. 221bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski for (BluetoothGattService fixedService : mServices) { 222bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski ArrayList<BluetoothGattService> includedServices = 223bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski new ArrayList(fixedService.getIncludedServices()); 224bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski fixedService.getIncludedServices().clear(); 225bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 226bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski for(BluetoothGattService brokenRef : includedServices) { 227bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski BluetoothGattService includedService = getService(mDevice, 228bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski brokenRef.getUuid(), brokenRef.getInstanceId(), brokenRef.getType()); 229bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski if (includedService != null) { 230bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski fixedService.addIncludedService(includedService); 231bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } else { 232bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski Log.e(TAG, "Broken GATT database: can't find included service."); 233bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } 234bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } 235bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } 236bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 2379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 23833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onServicesDiscovered(BluetoothGatt.this, status); 2399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 2400998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 2419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 2459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote characteristic has been read. 2469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Updates the internal value. 2479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 2489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 249c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onCharacteristicRead(String address, int status, int handle, byte[] value) { 25055d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address 251c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski + " handle=" + handle + " Status=" + status); 252c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski 253c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski Log.w(TAG, "onCharacteristicRead() - Device=" + address 254c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski + " handle=" + handle + " Status=" + status); 2559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 256ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 257ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 258ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 259cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 260cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 261cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 262cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 263cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 2649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 2659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 2669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && mAuthRetry == false) { 2679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 2689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 269c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.readCharacteristic(mClientIf, address, handle, AUTHENTICATION_MITM); 2709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return; 2719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 2729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 2739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = false; 2779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 278c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle); 279c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (characteristic == null) { 280c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski Log.w(TAG, "onCharacteristicRead() failed to find characteristic!"); 281c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return; 282c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 2839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (status == 0) characteristic.setValue(value); 2859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 28733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status); 2889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 2890998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 2909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 2949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Characteristic has been written to the remote device. 2959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Let the app know how we did... 2969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 2979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 298c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onCharacteristicWrite(String address, int status, int handle) { 29955d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address 300c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski + " handle=" + handle + " Status=" + status); 3019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 302ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 303ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 304ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 305cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 306cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 307cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 308cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 309cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 310c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle); 3119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 3129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 3149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 3159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && mAuthRetry == false) { 3169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 3179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 318c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.writeCharacteristic(mClientIf, address, handle, 3199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.getWriteType(), AUTHENTICATION_MITM, 3209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.getValue()); 3219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return; 3229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 3239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 3249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = false; 3289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 33033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status); 3319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 3320998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 3339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 3379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote characteristic has been updated. 3389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Updates the internal value. 3399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 3409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 341c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onNotify(String address, int handle, byte[] value) { 342c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (VDBG) Log.d(TAG, "onNotify() - Device=" + address + " handle=" + handle); 3439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 344ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 345ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 346ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 3479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 348c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle); 3499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 3509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.setValue(value); 3529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 35433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic); 3559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 3560998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 3579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 3619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Descriptor has been read. 3629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 3639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 364c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onDescriptorRead(String address, int status, int handle, byte[] value) { 365c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (VDBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " handle=" + handle); 3669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 367ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 368ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 369ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 370cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 371cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 372cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 373cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 374cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 375c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle); 3769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (descriptor == null) return; 3779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (status == 0) descriptor.setValue(value); 3799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 3819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 3829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && mAuthRetry == false) { 3839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 3849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 385c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.readDescriptor(mClientIf, address, handle, AUTHENTICATION_MITM); 386d65e8f4b6b37b274fcd5b7701a73eaef7c4ba8b4Andre Eisenbach return; 3879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 3889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 3899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 3939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 39533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status); 3969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 3970998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 3989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 4029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Descriptor write operation complete. 4039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 4049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 405c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onDescriptorWrite(String address, int status, int handle) { 406c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (VDBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " handle=" + handle); 4079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 408ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 409ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 410ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 411cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 412cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 413cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 414cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 415cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 416c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle); 4179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (descriptor == null) return; 4189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 4209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 4219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && mAuthRetry == false) { 4229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 4239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 424c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.writeDescriptor(mClientIf, address, handle, 425613f43017736580a1625cda3c5a3ed1ea7c79238Andre Eisenbach BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT, 4269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta AUTHENTICATION_MITM, descriptor.getValue()); 427d65e8f4b6b37b274fcd5b7701a73eaef7c4ba8b4Andre Eisenbach return; 4289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 4299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 4309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = false; 4349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 43633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status); 4379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 4380998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 4399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 4439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Prepared write transaction completed (or aborted) 4449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 4459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 4469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onExecuteWrite(String address, int status) { 44755d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "onExecuteWrite() - Device=" + address 4489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " status=" + status); 449ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 450ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 451ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 452cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 453cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 454cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 455cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 456cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 4579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 45833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onReliableWriteCompleted(BluetoothGatt.this, status); 4599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 4600998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 4619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 4659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote device RSSI has been read 4669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 4679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 4689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onReadRemoteRssi(String address, int rssi, int status) { 46955d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address + 4709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta " rssi=" + rssi + " status=" + status); 471ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 472ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 473ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 4749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 47533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status); 4769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 4770998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 4789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 480f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang 481f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang /** 482580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * Callback invoked when the MTU for a given connection changes 483580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * @hide 484580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach */ 485580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach public void onConfigureMTU(String address, int mtu, int status) { 486580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (DBG) Log.d(TAG, "onConfigureMTU() - Device=" + address + 487580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach " mtu=" + mtu + " status=" + status); 488580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (!address.equals(mDevice.getAddress())) { 489580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return; 490580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 491580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach try { 4924072da041da2911dd56635b530b276671ce0199dAndre Eisenbach mCallback.onMtuChanged(BluetoothGatt.this, mtu, status); 493580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } catch (Exception ex) { 494580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach Log.w(TAG, "Unhandled exception in callback", ex); 495580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 496f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang } 4979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta }; 4989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 499b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta /*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device, 500b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta int transport) { 5019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mContext = context; 502ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService = iGatt; 503ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mDevice = device; 504b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta mTransport = transport; 5059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mServices = new ArrayList<BluetoothGattService>(); 5069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 507ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 5089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 51133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Close this Bluetooth GATT client. 512b30f91e38c19f6728d836293446d4b9c76705e7fMatthew Xie * 513b30f91e38c19f6728d836293446d4b9c76705e7fMatthew Xie * Application should call this method as early as possible after it is done with 514b30f91e38c19f6728d836293446d4b9c76705e7fMatthew Xie * this GATT client. 5159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 51633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public void close() { 5179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "close()"); 5189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta unregisterApp(); 52033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mConnState = CONN_STATE_CLOSED; 5219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 5249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a service by UUID, instance and type. 5259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 5269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 5279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ BluetoothGattService getService(BluetoothDevice device, UUID uuid, 5289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int instanceId, int type) { 5299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for(BluetoothGattService svc : mServices) { 5309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (svc.getDevice().equals(device) && 5319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta svc.getType() == type && 5329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta svc.getInstanceId() == instanceId && 5339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta svc.getUuid().equals(uuid)) { 5349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return svc; 5359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return null; 5389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 542c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * Returns a characteristic with id equal to instanceId. 543c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * @hide 544c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski */ 545c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /*package*/ BluetoothGattCharacteristic getCharacteristicById(BluetoothDevice device, int instanceId) { 546c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattService svc : mServices) { 547c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) { 548c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (charac.getInstanceId() == instanceId) 549c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return charac; 550c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 551c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 552c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return null; 553c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 554c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski 555c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /** 556c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * Returns a descriptor with id equal to instanceId. 557c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * @hide 558c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski */ 559c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /*package*/ BluetoothGattDescriptor getDescriptorById(BluetoothDevice device, int instanceId) { 560c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattService svc : mServices) { 561c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) { 562c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattDescriptor desc : charac.getDescriptors()) { 563c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (desc.getInstanceId() == instanceId) 564c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return desc; 565c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 566c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 567c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 568c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return null; 569c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 570c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski 571c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /** 572ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Register an application callback to start using GATT. 5739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 574ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered} 575ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * is used to notify success or failure if the function returns true. 5769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 5779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 5789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 579ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @param callback GATT callback handler that will receive asynchronous callbacks. 580ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @return If true, the callback will be called to notify success or failure, 581ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * false on immediate error 5829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 583ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private boolean registerApp(BluetoothGattCallback callback) { 5849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "registerApp()"); 5859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null) return false; 5869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mCallback = callback; 5889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta UUID uuid = UUID.randomUUID(); 5899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid); 5909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 5929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback); 5939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 5949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 5959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 5969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 5999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 6029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Unregister the current application and callbacks. 6039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 604ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private void unregisterApp() { 6059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf); 6069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 6079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 6099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mCallback = null; 6109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.unregisterClient(mClientIf); 6119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mClientIf = 0; 6129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 6139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 6149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 618ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Initiate a connection to a Bluetooth GATT capable device. 6199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>The connection may not be established right away, but will be 6219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * completed when the remote device is available. A 6229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onConnectionStateChange} callback will be 6239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked when the connection state changes as a result of this function. 6249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6256ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * <p>The autoConnect parameter determines whether to actively connect to 6269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * the remote device, or rather passively scan and finalize the connection 6279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * when the remote device is in range/available. Generally, the first ever 6289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * connection to a device should be direct (autoConnect set to false) and 6299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * subsequent connections to known devices should be invoked with the 630ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * autoConnect parameter set to true. 6319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 6339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param device Remote device to connect to 6359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param autoConnect Whether to directly connect to the remote device (false) 6369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * or to automatically connect as soon as the remote 6379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * device becomes available (true). 6389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the connection attempt was initiated successfully 6399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 640ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) { 641ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect); 642ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 643ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (mConnState != CONN_STATE_IDLE) { 644ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new IllegalStateException("Not idle"); 645ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 646ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_CONNECTING; 647ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 648d35167adcaa40cb54df8e392379dfdfe98bcdba2Sungki Kim 649d35167adcaa40cb54df8e392379dfdfe98bcdba2Sungki Kim mAutoConnect = autoConnect; 650d35167adcaa40cb54df8e392379dfdfe98bcdba2Sungki Kim 651ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!registerApp(callback)) { 652ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 653ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 654ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 655ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG, "Failed to register callback"); 6569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 6579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 659d35167adcaa40cb54df8e392379dfdfe98bcdba2Sungki Kim // The connection will continue in the onClientRegistered callback 6609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 6619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 6649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Disconnects an established connection, or cancels a connection attempt 6659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * currently in progress. 6669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 6689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 669ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public void disconnect() { 670ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress()); 6719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 6729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 674ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.clientDisconnect(mClientIf, mDevice.getAddress()); 6759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 6769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 6779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 67833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 67933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie 68033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie /** 68133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Connect back to remote device. 68233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 68333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * <p>This method is used to re-connect to a remote device after the 68433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * connection has been dropped. If the device is not in range, the 68533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * re-connection will be triggered once the device is back in range. 68633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 68733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * @return true, if the connection attempt was initiated successfully 68833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie */ 68933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public boolean connect() { 69033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie try { 69133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mService.clientConnect(mClientIf, mDevice.getAddress(), 692b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta false, mTransport); // autoConnect is inverse of "isDirect" 69333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return true; 69433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } catch (RemoteException e) { 69533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie Log.e(TAG,"",e); 69633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return false; 69733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 69833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 69933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie 70033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie /** 70133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Return the remote bluetooth device this GATT client targets to 70233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 70333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * @return remote bluetooth device 70433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie */ 70533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public BluetoothDevice getDevice() { 70633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return mDevice; 7079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Discovers services offered by a remote device as well as their 7119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * characteristics and descriptors. 7129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This is an asynchronous operation. Once service discovery is completed, 7149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * the {@link BluetoothGattCallback#onServicesDiscovered} callback is 7159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered. If the discovery was successful, the remote services can be 7169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * retrieved using the {@link #getServices} function. 7179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the remote service discovery has been started 7219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 722ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean discoverServices() { 723ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress()); 7249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 7259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mServices.clear(); 7279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 729ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.discoverServices(mClientIf, mDevice.getAddress()); 7309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 7319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 7329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 7339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 7369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a list of GATT services offered by the remote device. 7409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function requires that service discovery has been completed 7429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for the given device. 7439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return List of services on the remote device. Returns an empty list 7479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * if service discovery has not yet been performed. 7489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 749ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public List<BluetoothGattService> getServices() { 7509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta List<BluetoothGattService> result = 7519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ArrayList<BluetoothGattService>(); 7529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for (BluetoothGattService service : mServices) { 754ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (service.getDevice().equals(mDevice)) { 7559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta result.add(service); 7569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return result; 7609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a {@link BluetoothGattService}, if the requested UUID is 7649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * supported by the remote device. 7659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function requires that service discovery has been completed 7679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for the given device. 7689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>If multiple instances of the same service (as identified by UUID) 7709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * exist, the first instance of the service is returned. 7719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param uuid UUID of the requested service 7759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return BluetoothGattService if supported, or null if the requested 7769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * service is not offered by the remote device. 7779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 778ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public BluetoothGattService getService(UUID uuid) { 7799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for (BluetoothGattService service : mServices) { 780ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (service.getDevice().equals(mDevice) && 7819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service.getUuid().equals(uuid)) { 7829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return service; 7839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return null; 7879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Reads the requested characteristic from the associated remote device. 7919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This is an asynchronous operation. The result of the read operation 7939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * is reported by the {@link BluetoothGattCallback#onCharacteristicRead} 7949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * callback. 7959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic Characteristic to read from the remote device 7999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the read operation was initiated successfully 8009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 8019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) { 8029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((characteristic.getProperties() & 8039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false; 8049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 80555d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid()); 8069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 8079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 8099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 8109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 8129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 8139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 814cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 815cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 816cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 817cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 818cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 8199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 8209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.readCharacteristic(mClientIf, device.getAddress(), 821c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getInstanceId(), AUTHENTICATION_NONE); 8229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 8239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 824cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 8259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 8269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 8299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 832ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Writes a given characteristic and its values to the associated remote device. 8339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once the write operation has been completed, the 8359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked, 8369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * reporting the result of the operation. 8379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 8399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic Characteristic to write on the remote device 8419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the write operation was initiated successfully 8429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 8439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) { 8449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 8459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && (characteristic.getProperties() & 8469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false; 8479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 84855d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid()); 849ff5e5db319785d23d672af95ac2dff3f37827cfdPrerepa Viswanadham if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false; 8509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 8529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 8539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 8559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 8569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 857cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 858cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 859cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 860cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 861cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 8629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 8639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.writeCharacteristic(mClientIf, device.getAddress(), 864c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getInstanceId(), characteristic.getWriteType(), 865c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski AUTHENTICATION_NONE, characteristic.getValue()); 8669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 8679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 868cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 8699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 8709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 8739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 8769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Reads the value for a given descriptor from the associated remote device. 8779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once the read operation has been completed, the 8799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onDescriptorRead} callback is 8809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered, signaling the result of the operation. 8819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 8839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param descriptor Descriptor value to read from the remote device 8859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the read operation was initiated successfully 8869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 8879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean readDescriptor(BluetoothGattDescriptor descriptor) { 88855d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid()); 8899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 8909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); 8929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return false; 8939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 8959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 8969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 8989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 8999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 900cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 901cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 902cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 903cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 904cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 9059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 906c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.readDescriptor(mClientIf, device.getAddress(), 907c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski descriptor.getInstanceId(), AUTHENTICATION_NONE); 9089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 910cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 9119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 9129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 9159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 9189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Write the value of a given descriptor to the associated remote device. 9199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is 9219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered to report the result of the write operation. 9229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 9249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param descriptor Descriptor to write to the associated remote device 9269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the write operation was initiated successfully 9279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 9289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean writeDescriptor(BluetoothGattDescriptor descriptor) { 92955d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid()); 930ff5e5db319785d23d672af95ac2dff3f37827cfdPrerepa Viswanadham if (mService == null || mClientIf == 0 || descriptor.getValue() == null) return false; 9319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); 9339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return false; 9349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 9369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 9379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 9399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 9409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 941cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 942cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 943cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 944cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 945cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 9469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 947c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.writeDescriptor(mClientIf, device.getAddress(), descriptor.getInstanceId(), 948613f43017736580a1625cda3c5a3ed1ea7c79238Andre Eisenbach BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT, AUTHENTICATION_NONE, 949613f43017736580a1625cda3c5a3ed1ea7c79238Andre Eisenbach descriptor.getValue()); 9509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 952cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 9539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 9549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 9579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 9609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Initiates a reliable write transaction for a given remote device. 9619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once a reliable write transaction has been initiated, all calls 9639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * to {@link #writeCharacteristic} are sent to the remote device for 9649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * verification and queued up for atomic execution. The application will 9659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * receive an {@link BluetoothGattCallback#onCharacteristicWrite} callback 9669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * in response to every {@link #writeCharacteristic} call and is responsible 9679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for verifying if the value has been transmitted accurately. 9689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>After all characteristics have been queued up and verified, 9709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link #executeReliableWrite} will execute all writes. If a characteristic 9719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * was not written correctly, calling {@link #abortReliableWrite} will 9729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * cancel the current transaction without commiting any values on the 9739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * remote device. 9749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 9769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the reliable write transaction has been initiated 9789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 979ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean beginReliableWrite() { 98055d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress()); 9819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 9829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 984ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.beginReliableWrite(mClientIf, mDevice.getAddress()); 9859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 9879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 9889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 9919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 9949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Executes a reliable write transaction for a given remote device. 9959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function will commit all queued up characteristic write 9979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * operations for a given remote device. 9989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>A {@link BluetoothGattCallback#onReliableWriteCompleted} callback is 10009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked to indicate whether the transaction has been executed correctly. 10019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the request to execute the transaction has been sent 10059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1006ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean executeReliableWrite() { 100755d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress()); 10089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 10099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1010cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 1011cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 1012cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 1013cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1014cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 10159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1016ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.endReliableWrite(mClientIf, mDevice.getAddress(), true); 10179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 1019cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 10209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 10219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 10249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 10279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Cancels a reliable write transaction for a given device. 10289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Calling this function will discard all queued characteristic write 10309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * operations for a given remote device. 10319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 103448f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du public void abortReliableWrite() { 103555d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress()); 10369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 10379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1039ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.endReliableWrite(mClientIf, mDevice.getAddress(), false); 10409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 10429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1046b7b7d7a05c164a56dd4155de4e84fc25ba706728John Du * @deprecated Use {@link #abortReliableWrite()} 104748f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du */ 1048514c5ef8d5774d8820ed1bf90fe53af1606cf106Aurimas Liutikas @Deprecated 104948f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du public void abortReliableWrite(BluetoothDevice mDevice) { 105048f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du abortReliableWrite(); 105148f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du } 105248f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du 105348f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du /** 10549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Enable or disable notifications/indications for a given characteristic. 10559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once notifications are enabled for a characteristic, a 10579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onCharacteristicChanged} callback will be 10589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered if the remote device indicates that the given characteristic 10599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * has changed. 10609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic The characteristic for which to enable notifications 10649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param enable Set to true to enable notifications/indications 10659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the requested notification status was set successfully 10669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 10679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic, 10689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta boolean enable) { 10699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "setCharacteristicNotification() - uuid: " + characteristic.getUuid() 10709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " enable: " + enable); 10719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 10729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 10749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 10759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 10779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 10789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 10809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.registerForNotification(mClientIf, device.getAddress(), 1081c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getInstanceId(), enable); 10829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 10849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 10859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 10889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 10919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Clears the internal cache and forces a refresh of the services from the 10929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * remote device. 10939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 10949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1095ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean refresh() { 1096ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress()); 10979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 10989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1100ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.refreshDevice(mClientIf, mDevice.getAddress()); 11019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 11029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 11039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 11049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 11079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 11109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Read the RSSI for a connected remote device. 11119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>The {@link BluetoothGattCallback#onReadRemoteRssi} callback will be 11139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked when the RSSI value has been read. 11149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 11169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the RSSI value has been requested successfully 11189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1119ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean readRemoteRssi() { 1120ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress()); 11219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 11229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1124ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.readRemoteRssi(mClientIf, mDevice.getAddress()); 11259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 11269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 11279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 11289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 11319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 11344072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * Request an MTU size used for a given connection. 1135580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1136580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * <p>When performing a write request operation (write without response), 1137580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * the data sent is truncated to the MTU size. This function may be used 11384072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * to request a larger MTU size to be able to send more data at once. 1139580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 11404072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * <p>A {@link BluetoothGattCallback#onMtuChanged} callback will indicate 1141580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * whether this operation was successful. 1142580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1143580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 1144580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1145580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * @return true, if the new MTU value has been requested successfully 1146580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach */ 11474072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public boolean requestMtu(int mtu) { 1148580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (DBG) Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress() 1149580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach + " mtu: " + mtu); 1150580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (mService == null || mClientIf == 0) return false; 1151580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1152580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach try { 1153580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach mService.configureMTU(mClientIf, mDevice.getAddress(), mtu); 1154580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } catch (RemoteException e) { 1155580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach Log.e(TAG,"",e); 1156580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return false; 1157580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 1158580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1159580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return true; 1160580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 1161580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1162580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach /** 11636ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * Request a connection parameter update. 11646ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * 11656ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * <p>This function will send a connection parameter update request to the 11666ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * remote device. 11676ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * 11686ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * @param connectionPriority Request a specific connection priority. Must be one of 11694072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED}, 11704072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * {@link BluetoothGatt#CONNECTION_PRIORITY_HIGH} 11714072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}. 11726ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * @throws IllegalArgumentException If the parameters are outside of their 11736ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * specified range. 11746ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach */ 11754072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public boolean requestConnectionPriority(int connectionPriority) { 11764072da041da2911dd56635b530b276671ce0199dAndre Eisenbach if (connectionPriority < CONNECTION_PRIORITY_BALANCED || 11774072da041da2911dd56635b530b276671ce0199dAndre Eisenbach connectionPriority > CONNECTION_PRIORITY_LOW_POWER) { 11786ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach throw new IllegalArgumentException("connectionPriority not within valid range"); 11796ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } 11806ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 11814072da041da2911dd56635b530b276671ce0199dAndre Eisenbach if (DBG) Log.d(TAG, "requestConnectionPriority() - params: " + connectionPriority); 11826ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach if (mService == null || mClientIf == 0) return false; 11836ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 11846ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach try { 11856ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach mService.connectionParameterUpdate(mClientIf, mDevice.getAddress(), connectionPriority); 11866ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } catch (RemoteException e) { 11876ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach Log.e(TAG,"",e); 11886ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach return false; 11896ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } 11906ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 11916ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach return true; 11926ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } 11936ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 11946ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach /** 1195ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} 1196ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as argument 11979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1198ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 11999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 12009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 12019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public int getConnectionState(BluetoothDevice device) { 1202ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead."); 12039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1206ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} 1207ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as argument 12089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1209ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 12109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 12119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 12129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public List<BluetoothDevice> getConnectedDevices() { 1213ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException 1214ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie ("Use BluetoothManager#getConnectedDevices instead."); 12159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1218ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use 1219ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])} 1220ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as first argument 12219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1222ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 12239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 12249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 12259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 1226ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException 1227ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie ("Use BluetoothManager#getDevicesMatchingConnectionStates instead."); 12289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta} 1230