BluetoothGatt.java revision c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1
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, 425c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski descriptor.getCharacteristic().getWriteType(), 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 Log.w(TAG, "getCharacteristicById() comparing " + charac.getInstanceId() + " and " + instanceId); 549c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (charac.getInstanceId() == instanceId) 550c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return charac; 551c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 552c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 553c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return null; 554c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 555c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski 556c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /** 557c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * Returns a descriptor with id equal to instanceId. 558c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * @hide 559c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski */ 560c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /*package*/ BluetoothGattDescriptor getDescriptorById(BluetoothDevice device, int instanceId) { 561c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattService svc : mServices) { 562c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) { 563c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattDescriptor desc : charac.getDescriptors()) { 564c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (desc.getInstanceId() == instanceId) 565c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return desc; 566c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 567c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 568c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 569c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return null; 570c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 571c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski 572c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /** 573ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Register an application callback to start using GATT. 5749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 575ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered} 576ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * is used to notify success or failure if the function returns true. 5779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 5789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 5799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 580ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @param callback GATT callback handler that will receive asynchronous callbacks. 581ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @return If true, the callback will be called to notify success or failure, 582ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * false on immediate error 5839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 584ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private boolean registerApp(BluetoothGattCallback callback) { 5859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "registerApp()"); 5869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null) return false; 5879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mCallback = callback; 5899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta UUID uuid = UUID.randomUUID(); 5909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid); 5919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 5939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback); 5949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 5959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 5969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 5979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 6009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 6039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Unregister the current application and callbacks. 6049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 605ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private void unregisterApp() { 6069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf); 6079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 6089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 6109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mCallback = null; 6119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.unregisterClient(mClientIf); 6129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mClientIf = 0; 6139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 6149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 6159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 619ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Initiate a connection to a Bluetooth GATT capable device. 6209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>The connection may not be established right away, but will be 6229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * completed when the remote device is available. A 6239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onConnectionStateChange} callback will be 6249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked when the connection state changes as a result of this function. 6259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6266ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * <p>The autoConnect parameter determines whether to actively connect to 6279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * the remote device, or rather passively scan and finalize the connection 6289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * when the remote device is in range/available. Generally, the first ever 6299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * connection to a device should be direct (autoConnect set to false) and 6309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * subsequent connections to known devices should be invoked with the 631ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * autoConnect parameter set to true. 6329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 6349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param device Remote device to connect to 6369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param autoConnect Whether to directly connect to the remote device (false) 6379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * or to automatically connect as soon as the remote 6389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * device becomes available (true). 6399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the connection attempt was initiated successfully 6409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 641ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) { 642ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect); 643ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 644ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (mConnState != CONN_STATE_IDLE) { 645ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new IllegalStateException("Not idle"); 646ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 647ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_CONNECTING; 648ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 649ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!registerApp(callback)) { 650ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 651ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 652ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 653ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG, "Failed to register callback"); 6549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 6559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 657ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie // the connection will continue after successful callback registration 658ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mAutoConnect = autoConnect; 6599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 6609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 6639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Disconnects an established connection, or cancels a connection attempt 6649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * currently in progress. 6659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 6679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 668ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public void disconnect() { 669ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress()); 6709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 6719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 673ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.clientDisconnect(mClientIf, mDevice.getAddress()); 6749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 6759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 6769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 67733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 67833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie 67933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie /** 68033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Connect back to remote device. 68133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 68233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * <p>This method is used to re-connect to a remote device after the 68333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * connection has been dropped. If the device is not in range, the 68433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * re-connection will be triggered once the device is back in range. 68533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 68633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * @return true, if the connection attempt was initiated successfully 68733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie */ 68833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public boolean connect() { 68933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie try { 69033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mService.clientConnect(mClientIf, mDevice.getAddress(), 691b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta false, mTransport); // autoConnect is inverse of "isDirect" 69233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return true; 69333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } catch (RemoteException e) { 69433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie Log.e(TAG,"",e); 69533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return false; 69633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 69733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 69833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie 69933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie /** 70033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Return the remote bluetooth device this GATT client targets to 70133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 70233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * @return remote bluetooth device 70333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie */ 70433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public BluetoothDevice getDevice() { 70533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return mDevice; 7069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Discovers services offered by a remote device as well as their 7109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * characteristics and descriptors. 7119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This is an asynchronous operation. Once service discovery is completed, 7139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * the {@link BluetoothGattCallback#onServicesDiscovered} callback is 7149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered. If the discovery was successful, the remote services can be 7159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * retrieved using the {@link #getServices} function. 7169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the remote service discovery has been started 7209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 721ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean discoverServices() { 722ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress()); 7239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 7249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mServices.clear(); 7269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 728ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.discoverServices(mClientIf, mDevice.getAddress()); 7299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 7309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 7319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 7329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 7359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a list of GATT services offered by the remote device. 7399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function requires that service discovery has been completed 7419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for the given device. 7429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return List of services on the remote device. Returns an empty list 7469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * if service discovery has not yet been performed. 7479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 748ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public List<BluetoothGattService> getServices() { 7499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta List<BluetoothGattService> result = 7509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ArrayList<BluetoothGattService>(); 7519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for (BluetoothGattService service : mServices) { 753ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (service.getDevice().equals(mDevice)) { 7549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta result.add(service); 7559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return result; 7599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a {@link BluetoothGattService}, if the requested UUID is 7639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * supported by the remote device. 7649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function requires that service discovery has been completed 7669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for the given device. 7679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>If multiple instances of the same service (as identified by UUID) 7699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * exist, the first instance of the service is returned. 7709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param uuid UUID of the requested service 7749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return BluetoothGattService if supported, or null if the requested 7759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * service is not offered by the remote device. 7769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 777ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public BluetoothGattService getService(UUID uuid) { 7789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for (BluetoothGattService service : mServices) { 779ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (service.getDevice().equals(mDevice) && 7809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service.getUuid().equals(uuid)) { 7819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return service; 7829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return null; 7869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Reads the requested characteristic from the associated remote device. 7909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This is an asynchronous operation. The result of the read operation 7929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * is reported by the {@link BluetoothGattCallback#onCharacteristicRead} 7939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * callback. 7949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic Characteristic to read from the remote device 7989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the read operation was initiated successfully 7999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 8009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) { 8019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((characteristic.getProperties() & 8029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false; 8039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 80455d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid()); 8059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 8069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 8089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 8099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 8119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 8129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 813cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 814cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 815cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 816cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 817cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 8189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 8199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.readCharacteristic(mClientIf, device.getAddress(), 820c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getInstanceId(), AUTHENTICATION_NONE); 8219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 8229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 823cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 8249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 8259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 8289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 831ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Writes a given characteristic and its values to the associated remote device. 8329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once the write operation has been completed, the 8349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked, 8359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * reporting the result of the operation. 8369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 8389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic Characteristic to write on the remote device 8409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the write operation was initiated successfully 8419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 8429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) { 8439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 8449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && (characteristic.getProperties() & 8459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false; 8469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 84755d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid()); 848ff5e5db319785d23d672af95ac2dff3f37827cfdPrerepa Viswanadham if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false; 8499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 8519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 8529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 8549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 8559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 856cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 857cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 858cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 859cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 860cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 8619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 8629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.writeCharacteristic(mClientIf, device.getAddress(), 863c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getInstanceId(), characteristic.getWriteType(), 864c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski AUTHENTICATION_NONE, characteristic.getValue()); 8659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 8669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 867cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 8689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 8699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 8729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 8759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Reads the value for a given descriptor from the associated remote device. 8769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once the read operation has been completed, the 8789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onDescriptorRead} callback is 8799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered, signaling the result of the operation. 8809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 8829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param descriptor Descriptor value to read from the remote device 8849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the read operation was initiated successfully 8859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 8869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean readDescriptor(BluetoothGattDescriptor descriptor) { 88755d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid()); 8889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 8899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); 8919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return false; 8929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 8949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 8959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 8979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 8989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 899cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 900cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 901cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 902cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 903cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 9049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 905c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.readDescriptor(mClientIf, device.getAddress(), 906c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski descriptor.getInstanceId(), AUTHENTICATION_NONE); 9079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 909cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 9109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 9119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 9149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 9179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Write the value of a given descriptor to the associated remote device. 9189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is 9209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered to report the result of the write operation. 9219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 9239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param descriptor Descriptor to write to the associated remote device 9259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the write operation was initiated successfully 9269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 9279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean writeDescriptor(BluetoothGattDescriptor descriptor) { 92855d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid()); 929ff5e5db319785d23d672af95ac2dff3f37827cfdPrerepa Viswanadham if (mService == null || mClientIf == 0 || descriptor.getValue() == null) return false; 9309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); 9329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return false; 9339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 9359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 9369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 9389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 9399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 940cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 941cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 942cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 943cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 944cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 9459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 946c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.writeDescriptor(mClientIf, device.getAddress(), descriptor.getInstanceId(), 947c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getWriteType(), AUTHENTICATION_NONE, descriptor.getValue()); 9489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 950cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 9519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 9529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 9559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 9589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Initiates a reliable write transaction for a given remote device. 9599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once a reliable write transaction has been initiated, all calls 9619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * to {@link #writeCharacteristic} are sent to the remote device for 9629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * verification and queued up for atomic execution. The application will 9639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * receive an {@link BluetoothGattCallback#onCharacteristicWrite} callback 9649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * in response to every {@link #writeCharacteristic} call and is responsible 9659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for verifying if the value has been transmitted accurately. 9669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>After all characteristics have been queued up and verified, 9689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link #executeReliableWrite} will execute all writes. If a characteristic 9699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * was not written correctly, calling {@link #abortReliableWrite} will 9709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * cancel the current transaction without commiting any values on the 9719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * remote device. 9729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 9749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the reliable write transaction has been initiated 9769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 977ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean beginReliableWrite() { 97855d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress()); 9799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 9809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 982ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.beginReliableWrite(mClientIf, mDevice.getAddress()); 9839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 9859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 9869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 9899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 9929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Executes a reliable write transaction for a given remote device. 9939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function will commit all queued up characteristic write 9959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * operations for a given remote device. 9969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>A {@link BluetoothGattCallback#onReliableWriteCompleted} callback is 9989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked to indicate whether the transaction has been executed correctly. 9999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the request to execute the transaction has been sent 10039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1004ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean executeReliableWrite() { 100555d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress()); 10069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 10079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1008cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 1009cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 1010cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 1011cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1012cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 10139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1014ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.endReliableWrite(mClientIf, mDevice.getAddress(), true); 10159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 1017cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 10189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 10199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 10229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 10259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Cancels a reliable write transaction for a given device. 10269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Calling this function will discard all queued characteristic write 10289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * operations for a given remote device. 10299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 103248f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du public void abortReliableWrite() { 103355d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress()); 10349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 10359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1037ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.endReliableWrite(mClientIf, mDevice.getAddress(), false); 10389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 10409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1044b7b7d7a05c164a56dd4155de4e84fc25ba706728John Du * @deprecated Use {@link #abortReliableWrite()} 104548f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du */ 104648f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du public void abortReliableWrite(BluetoothDevice mDevice) { 104748f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du abortReliableWrite(); 104848f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du } 104948f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du 105048f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du /** 10519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Enable or disable notifications/indications for a given characteristic. 10529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once notifications are enabled for a characteristic, a 10549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onCharacteristicChanged} callback will be 10559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered if the remote device indicates that the given characteristic 10569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * has changed. 10579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic The characteristic for which to enable notifications 10619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param enable Set to true to enable notifications/indications 10629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the requested notification status was set successfully 10639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 10649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic, 10659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta boolean enable) { 10669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "setCharacteristicNotification() - uuid: " + characteristic.getUuid() 10679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " enable: " + enable); 10689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 10699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 10719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 10729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 10749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 10759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 10779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.registerForNotification(mClientIf, device.getAddress(), 1078c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getInstanceId(), enable); 10799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 10819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 10829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 10859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 10889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Clears the internal cache and forces a refresh of the services from the 10899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * remote device. 10909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 10919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1092ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean refresh() { 1093ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress()); 10949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 10959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1097ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.refreshDevice(mClientIf, mDevice.getAddress()); 10989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 11009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 11019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 11049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 11079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Read the RSSI for a connected remote device. 11089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>The {@link BluetoothGattCallback#onReadRemoteRssi} callback will be 11109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked when the RSSI value has been read. 11119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 11139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the RSSI value has been requested successfully 11159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1116ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean readRemoteRssi() { 1117ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress()); 11189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 11199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1121ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.readRemoteRssi(mClientIf, mDevice.getAddress()); 11229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 11239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 11249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 11259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 11289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 11314072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * Request an MTU size used for a given connection. 1132580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1133580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * <p>When performing a write request operation (write without response), 1134580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * the data sent is truncated to the MTU size. This function may be used 11354072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * to request a larger MTU size to be able to send more data at once. 1136580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 11374072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * <p>A {@link BluetoothGattCallback#onMtuChanged} callback will indicate 1138580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * whether this operation was successful. 1139580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1140580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 1141580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1142580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * @return true, if the new MTU value has been requested successfully 1143580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach */ 11444072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public boolean requestMtu(int mtu) { 1145580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (DBG) Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress() 1146580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach + " mtu: " + mtu); 1147580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (mService == null || mClientIf == 0) return false; 1148580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1149580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach try { 1150580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach mService.configureMTU(mClientIf, mDevice.getAddress(), mtu); 1151580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } catch (RemoteException e) { 1152580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach Log.e(TAG,"",e); 1153580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return false; 1154580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 1155580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1156580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return true; 1157580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 1158580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1159580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach /** 11606ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * Request a connection parameter update. 11616ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * 11626ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * <p>This function will send a connection parameter update request to the 11636ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * remote device. 11646ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * 11656ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * @param connectionPriority Request a specific connection priority. Must be one of 11664072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED}, 11674072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * {@link BluetoothGatt#CONNECTION_PRIORITY_HIGH} 11684072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}. 11696ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * @throws IllegalArgumentException If the parameters are outside of their 11706ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * specified range. 11716ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach */ 11724072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public boolean requestConnectionPriority(int connectionPriority) { 11734072da041da2911dd56635b530b276671ce0199dAndre Eisenbach if (connectionPriority < CONNECTION_PRIORITY_BALANCED || 11744072da041da2911dd56635b530b276671ce0199dAndre Eisenbach connectionPriority > CONNECTION_PRIORITY_LOW_POWER) { 11756ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach throw new IllegalArgumentException("connectionPriority not within valid range"); 11766ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } 11776ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 11784072da041da2911dd56635b530b276671ce0199dAndre Eisenbach if (DBG) Log.d(TAG, "requestConnectionPriority() - params: " + connectionPriority); 11796ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach if (mService == null || mClientIf == 0) return false; 11806ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 11816ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach try { 11826ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach mService.connectionParameterUpdate(mClientIf, mDevice.getAddress(), connectionPriority); 11836ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } catch (RemoteException e) { 11846ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach Log.e(TAG,"",e); 11856ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach return false; 11866ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } 11876ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 11886ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach return true; 11896ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } 11906ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 11916ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach /** 1192ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} 1193ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as argument 11949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1195ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 11969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 11979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 11989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public int getConnectionState(BluetoothDevice device) { 1199ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead."); 12009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1203ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} 1204ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as argument 12059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1206ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 12079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 12089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 12099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public List<BluetoothDevice> getConnectedDevices() { 1210ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException 1211ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie ("Use BluetoothManager#getConnectedDevices instead."); 12129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1215ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use 1216ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])} 1217ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as first argument 12189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1219ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 12209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 12219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 12229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 1223ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException 1224ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie ("Use BluetoothManager#getDevicesMatchingConnectionStates instead."); 12259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta} 1227