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 19b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowskiimport android.os.Handler; 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 * 34d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * <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 449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private IBluetoothGatt mService; 45d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski private BluetoothGattCallback mCallback; 46b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski private Handler mHandler; 479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private int mClientIf; 48ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private BluetoothDevice mDevice; 49ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private boolean mAutoConnect; 503854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung private int mAuthRetryState; 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; 55db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski private int mPhy; 56ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie 573854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung private static final int AUTH_RETRY_STATE_IDLE = 0; 583854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung private static final int AUTH_RETRY_STATE_NO_MITM = 1; 593854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung private static final int AUTH_RETRY_STATE_MITM = 2; 603854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung 61ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_IDLE = 0; 62ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_CONNECTING = 1; 63ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_CONNECTED = 2; 64ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_DISCONNECTING = 3; 6533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie private static final int CONN_STATE_CLOSED = 4; 669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private List<BluetoothGattService> mServices; 689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 69ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /** A GATT operation completed successfully */ 709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_SUCCESS = 0; 719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 72ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /** GATT read operation is not permitted */ 739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_READ_NOT_PERMITTED = 0x2; 749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 75ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /** GATT write operation is not permitted */ 769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_WRITE_NOT_PERMITTED = 0x3; 779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** Insufficient authentication for a given operation */ 799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INSUFFICIENT_AUTHENTICATION = 0x5; 809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** The given request is not supported */ 829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_REQUEST_NOT_SUPPORTED = 0x6; 839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** Insufficient encryption for a given operation */ 859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INSUFFICIENT_ENCRYPTION = 0xf; 869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** A read or write operation was requested with an invalid offset */ 889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INVALID_OFFSET = 0x7; 899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** A write operation exceeds the maximum length of the attribute */ 919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 0xd; 929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9345a0a1a689518df7e2c904b902e28f6d68b76e2aAndre Eisenbach /** A remote device connection is congested. */ 94dadefdad8ef424991feb45f02f923a2f8224285bAndre Eisenbach public static final int GATT_CONNECTION_CONGESTED = 0x8f; 95dadefdad8ef424991feb45f02f923a2f8224285bAndre Eisenbach 9690ca807f7b2037499112d1c49c4b0793cc780540Matthew Xie /** A GATT operation failed, errors other than the above */ 9790ca807f7b2037499112d1c49c4b0793cc780540Matthew Xie public static final int GATT_FAILURE = 0x101; 9890ca807f7b2037499112d1c49c4b0793cc780540Matthew Xie 999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1006ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * Connection paramter update - Use the connection paramters recommended by the 1016ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * Bluetooth SIG. This is the default value if no connection parameter update 1026ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * is requested. 1036ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach */ 1044072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public static final int CONNECTION_PRIORITY_BALANCED = 0; 1056ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 1066ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach /** 1076ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * Connection paramter update - Request a high priority, low latency connection. 1086ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * An application should only request high priority connection paramters to transfer 1096ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * large amounts of data over LE quickly. Once the transfer is complete, the application 1104072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * should request {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED} connectoin parameters 1116ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * to reduce energy use. 1126ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach */ 1134072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public static final int CONNECTION_PRIORITY_HIGH = 1; 1146ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 1156ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach /** Connection paramter update - Request low power, reduced data rate connection parameters. */ 1164072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public static final int CONNECTION_PRIORITY_LOW_POWER = 2; 1176ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 1186ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach /** 1199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * No authentication required. 1209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ static final int AUTHENTICATION_NONE = 0; 1239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Authentication requested; no man-in-the-middle protection required. 1269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ static final int AUTHENTICATION_NO_MITM = 1; 1299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Authentication with man-in-the-middle protection requested. 1329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ static final int AUTHENTICATION_MITM = 2; 1359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 137d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation. 1389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 139d7116bea0698f58e93003d2046411a2624dd1ab1Jakub Pawlowski private final IBluetoothGattCallback mBluetoothGattCallback = 140d7116bea0698f58e93003d2046411a2624dd1ab1Jakub Pawlowski new IBluetoothGattCallback.Stub() { 1419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Application interface registered - app is ready to go 1439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 145326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 1469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onClientRegistered(int status, int clientIf) { 1479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status 1489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " clientIf=" + clientIf); 149ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (VDBG) { 150ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 151ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (mConnState != CONN_STATE_CONNECTING) { 152ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG, "Bad connection state: " + mConnState); 153ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 154ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 155ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 1569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mClientIf = clientIf; 157ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (status != GATT_SUCCESS) { 1586bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 159b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 160b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 1610e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 1620e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE, 1630e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski BluetoothProfile.STATE_DISCONNECTED); 1640e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 165b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 166b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 167b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski 168ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 169ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 170ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 171ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 172ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 1739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 174ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.clientConnect(mClientIf, mDevice.getAddress(), 175db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski !mAutoConnect, mTransport, mPhy); // autoConnect is inverse of "isDirect" 176ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } catch (RemoteException e) { 177ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG,"",e); 1789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 1799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 1809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 182db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * Phy update callback 183db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * @hide 184db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski */ 185db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski @Override 186db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) { 187db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski if (DBG) Log.d(TAG, "onPhyUpdate() - status=" + status 188db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski + " address=" + address + " txPhy=" + txPhy + " rxPhy=" + rxPhy); 189db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski if (!address.equals(mDevice.getAddress())) { 190db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski return; 191db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } 192db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski 1936bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 194b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 195b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 1960e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 1970e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status); 1980e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 199b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 200b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 201db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } 202db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski 203db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski /** 204db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * Phy read callback 205db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * @hide 206db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski */ 207db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski @Override 208db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski public void onPhyRead(String address, int txPhy, int rxPhy, int status) { 209db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski if (DBG) Log.d(TAG, "onPhyRead() - status=" + status 210db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski + " address=" + address + " txPhy=" + txPhy + " rxPhy=" + rxPhy); 211db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski if (!address.equals(mDevice.getAddress())) { 212db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski return; 213db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } 214db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski 2156bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 216b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 217b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 2180e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 2190e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status); 2200e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 221b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 222b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 223db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } 224db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski 225db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski /** 2269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Client connection state changed 2279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 2289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 229326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 2309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onClientConnectionState(int status, int clientIf, 2319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta boolean connected, String address) { 2329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onClientConnectionState() - status=" + status 2339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " clientIf=" + clientIf + " device=" + address); 234ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 235ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 236ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 237ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie int profileState = connected ? BluetoothProfile.STATE_CONNECTED : 238ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothProfile.STATE_DISCONNECTED; 239b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski 2406bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 241b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 242b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 2430e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 2440e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onConnectionStateChange(BluetoothGatt.this, status, 2450e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski profileState); 2460e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 247b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 248b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 249ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie 250ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 251ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (connected) { 252ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_CONNECTED; 253ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } else { 254ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 255ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 256ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 257cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 258cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 259cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 260cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 2619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 2649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote search has been completed. 2659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * The internal object structure should now reflect the state 2669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * of the remote device database. Let the application know that 2679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * we are done at this point. 2689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 2699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 270326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 271bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski public void onSearchComplete(String address, List<BluetoothGattService> services, 272bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski int status) { 2739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onSearchComplete() = Device=" + address + " Status=" + status); 274ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 275ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 276ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 277bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 278bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski for (BluetoothGattService s : services) { 279bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski //services we receive don't have device set properly. 280bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski s.setDevice(mDevice); 281bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } 282bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 283bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski mServices.addAll(services); 284bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 285bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski // Fix references to included services, as they doesn't point to right objects. 286bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski for (BluetoothGattService fixedService : mServices) { 287bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski ArrayList<BluetoothGattService> includedServices = 288bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski new ArrayList(fixedService.getIncludedServices()); 289bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski fixedService.getIncludedServices().clear(); 290bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 291bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski for(BluetoothGattService brokenRef : includedServices) { 292bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski BluetoothGattService includedService = getService(mDevice, 293bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski brokenRef.getUuid(), brokenRef.getInstanceId(), brokenRef.getType()); 294bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski if (includedService != null) { 295bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski fixedService.addIncludedService(includedService); 296bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } else { 297bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski Log.e(TAG, "Broken GATT database: can't find included service."); 298bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } 299bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } 300bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski } 301bf0faed3597b92d950febafcf555ad05529559d6Jakub Pawlowski 3026bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 303b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 304b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 3050e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 3060e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onServicesDiscovered(BluetoothGatt.this, status); 3070e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 308b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 309b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 3109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 3139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote characteristic has been read. 3149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Updates the internal value. 3159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 3169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 317326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 318c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onCharacteristicRead(String address, int status, int handle, byte[] value) { 31955d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address 320c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski + " handle=" + handle + " Status=" + status); 321c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski 322ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 323ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 324ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 325cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 326cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 327cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 328cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 329cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 3309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 3319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 3323854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) { 3339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 3343854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ? 3353854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM; 3363854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mService.readCharacteristic(mClientIf, address, handle, authReq); 3373854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState++; 3389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return; 3399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 3409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 3419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3443854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState = AUTH_RETRY_STATE_IDLE; 3459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 346c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle); 347c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (characteristic == null) { 348c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski Log.w(TAG, "onCharacteristicRead() failed to find characteristic!"); 349c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return; 350c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 3519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (status == 0) characteristic.setValue(value); 3539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3546bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 355b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 356b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 3570e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 3580e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, 3590e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski status); 3600e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 361b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 362b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 3639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 3669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Characteristic has been written to the remote device. 3679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Let the app know how we did... 3689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 3699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 370326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 371c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onCharacteristicWrite(String address, int status, int handle) { 37255d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address 373c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski + " handle=" + handle + " Status=" + status); 3749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 375ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 376ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 377ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 378cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 379cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 380cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 381cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 382cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 383c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle); 3849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 3859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 3879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 3883854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) { 3899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 3903854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ? 3913854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM; 392c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.writeCharacteristic(mClientIf, address, handle, 3933854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung characteristic.getWriteType(), authReq, characteristic.getValue()); 3943854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState++; 3959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return; 3969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 3979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 3989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4013854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState = AUTH_RETRY_STATE_IDLE; 4029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4036bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 404b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 405b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 4060e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 4070e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, 4080e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski status); 4090e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 410b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 411b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 4129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 4159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote characteristic has been updated. 4169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Updates the internal value. 4179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 4189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 419326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 420c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onNotify(String address, int handle, byte[] value) { 421c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (VDBG) Log.d(TAG, "onNotify() - Device=" + address + " handle=" + handle); 4229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 423ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 424ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 425ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 4269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 427c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle); 4289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 4299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.setValue(value); 4319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4326bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 433b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 434b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 4350e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 4360e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic); 4370e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 438b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 439b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 4409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 4439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Descriptor has been read. 4449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 4459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 446326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 447c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onDescriptorRead(String address, int status, int handle, byte[] value) { 448c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (VDBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " handle=" + handle); 4499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 450ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 451ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 452ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 453cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 454cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 455cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 456cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 457cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 458c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle); 4599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (descriptor == null) return; 4609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (status == 0) descriptor.setValue(value); 4629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 4649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 4653854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) { 4669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 4673854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ? 4683854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM; 4693854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mService.readDescriptor(mClientIf, address, handle, authReq); 4703854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState++; 471d65e8f4b6b37b274fcd5b7701a73eaef7c4ba8b4Andre Eisenbach return; 4729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 4739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 4749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4773854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState = AUTH_RETRY_STATE_IDLE; 4789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4796bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 480b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 481b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 4820e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 4830e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status); 4840e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 485b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 486b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 4879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 4909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Descriptor write operation complete. 4919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 4929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 493326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 494c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski public void onDescriptorWrite(String address, int status, int handle) { 495c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (VDBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " handle=" + handle); 4969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 497ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 498ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 499ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 500cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 501cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 502cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 503cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 504cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 505c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle); 5069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (descriptor == null) return; 5079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 5099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 5103854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) { 5119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 5123854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ? 5133854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM; 514c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.writeDescriptor(mClientIf, address, handle, 5153854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung authReq, descriptor.getValue()); 5163854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState++; 517d65e8f4b6b37b274fcd5b7701a73eaef7c4ba8b4Andre Eisenbach return; 5189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 5199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 5209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5233854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState = AUTH_RETRY_STATE_IDLE; 5249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5256bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 526b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 527b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 5280e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 5290e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status); 5300e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 531b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 532b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 5339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 5369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Prepared write transaction completed (or aborted) 5379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 5389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 539326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 5409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onExecuteWrite(String address, int status) { 54155d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "onExecuteWrite() - Device=" + address 5429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " status=" + status); 543ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 544ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 545ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 546cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 547cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 548cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 549cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 550cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 5516bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 552b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 553b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 5540e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 5550e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onReliableWriteCompleted(BluetoothGatt.this, status); 5560e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 557b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 558b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 5599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 5629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote device RSSI has been read 5639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 5649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 565326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 5669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onReadRemoteRssi(String address, int rssi, int status) { 56755d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address + 5689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta " rssi=" + rssi + " status=" + status); 569ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 570ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 571ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 5726bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 573b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 574b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 5750e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 5760e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status); 5770e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 578b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 579b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 5809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 581f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang 582f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang /** 583580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * Callback invoked when the MTU for a given connection changes 584580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * @hide 585580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach */ 586326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 587580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach public void onConfigureMTU(String address, int mtu, int status) { 588580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (DBG) Log.d(TAG, "onConfigureMTU() - Device=" + address + 589580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach " mtu=" + mtu + " status=" + status); 590580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (!address.equals(mDevice.getAddress())) { 591580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return; 592580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 593b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski 5946bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 595b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 596b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 5970e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 5980e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onMtuChanged(BluetoothGatt.this, mtu, status); 5990e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 600b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 601b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 602f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang } 603326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski 604326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski /** 605326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski * Callback invoked when the given connection is updated 606326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski * @hide 607326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski */ 608326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski @Override 609326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski public void onConnectionUpdated(String address, int interval, int latency, 610326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski int timeout, int status) { 611326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski if (DBG) Log.d(TAG, "onConnectionUpdated() - Device=" + address + 612326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski " interval=" + interval + " latency=" + latency + 613326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski " timeout=" + timeout + " status=" + status); 614326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski if (!address.equals(mDevice.getAddress())) { 615326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski return; 616326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski } 617b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski 6186bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk runOrQueueCallback(new Runnable() { 619b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski @Override 620b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski public void run() { 6210e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski if (mCallback != null) { 6220e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski mCallback.onConnectionUpdated(BluetoothGatt.this, interval, latency, 6230e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski timeout, status); 6240e0e75793decad48ba210c46718ab97545397096Jakub Pawlowski } 625b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski } 626b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski }); 627326f7b31b9ab7bf82e3c05f9b606d10ece306dc0Jakub Pawlowski } 6289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta }; 6299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 630adc26ec1b4060358d918d1bdf491f5192b35c2d3Jeremy Klein /*package*/ BluetoothGatt(IBluetoothGatt iGatt, BluetoothDevice device, 631db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski int transport, int phy) { 632ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService = iGatt; 633ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mDevice = device; 634b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta mTransport = transport; 635db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski mPhy = phy; 6369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mServices = new ArrayList<BluetoothGattService>(); 6379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 638ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 6393854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState = AUTH_RETRY_STATE_IDLE; 6409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 64333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Close this Bluetooth GATT client. 644b30f91e38c19f6728d836293446d4b9c76705e7fMatthew Xie * 645b30f91e38c19f6728d836293446d4b9c76705e7fMatthew Xie * Application should call this method as early as possible after it is done with 646b30f91e38c19f6728d836293446d4b9c76705e7fMatthew Xie * this GATT client. 6479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 64833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public void close() { 6499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "close()"); 6509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta unregisterApp(); 65233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mConnState = CONN_STATE_CLOSED; 6533854e2267487ecd129bdd0711c6d9dfbf8f7ed0dJacky Cheung mAuthRetryState = AUTH_RETRY_STATE_IDLE; 6549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 6579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a service by UUID, instance and type. 6589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 6599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 6609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ BluetoothGattService getService(BluetoothDevice device, UUID uuid, 6619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int instanceId, int type) { 6629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for(BluetoothGattService svc : mServices) { 6639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (svc.getDevice().equals(device) && 6649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta svc.getType() == type && 6659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta svc.getInstanceId() == instanceId && 6669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta svc.getUuid().equals(uuid)) { 6679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return svc; 6689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return null; 6719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 675c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * Returns a characteristic with id equal to instanceId. 676c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * @hide 677c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski */ 678c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /*package*/ BluetoothGattCharacteristic getCharacteristicById(BluetoothDevice device, int instanceId) { 679c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattService svc : mServices) { 680c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) { 681c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (charac.getInstanceId() == instanceId) 682c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return charac; 683c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 684c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 685c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return null; 686c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 687c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski 688c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /** 689c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * Returns a descriptor with id equal to instanceId. 690c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski * @hide 691c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski */ 692c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /*package*/ BluetoothGattDescriptor getDescriptorById(BluetoothDevice device, int instanceId) { 693c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattService svc : mServices) { 694c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) { 695c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski for(BluetoothGattDescriptor desc : charac.getDescriptors()) { 696c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski if (desc.getInstanceId() == instanceId) 697c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return desc; 698c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 699c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 700c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 701c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski return null; 702c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski } 703c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski 704c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski /** 7056bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk * Queue the runnable on a {@link Handler} provided by the user, or execute the runnable 7066bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk * immediately if no Handler was provided. 7076bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk */ 7086bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk private void runOrQueueCallback(final Runnable cb) { 7096bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk if (mHandler == null) { 7106bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk try { 7116bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk cb.run(); 7126bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk } catch (Exception ex) { 7136bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk Log.w(TAG, "Unhandled exception in callback", ex); 7146bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk } 7156bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk } else { 7166bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk mHandler.post(cb); 7176bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk } 7186bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk } 7196bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk 7206bdc550e27e2c4e7b32bb91085eaac898d7d1156Ruben Brunk /** 721ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Register an application callback to start using GATT. 7229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 723d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered} 724ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * is used to notify success or failure if the function returns true. 7259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 728ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @param callback GATT callback handler that will receive asynchronous callbacks. 729ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @return If true, the callback will be called to notify success or failure, 730ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * false on immediate error 7319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 732b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski private boolean registerApp(BluetoothGattCallback callback, Handler handler) { 7339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "registerApp()"); 7349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null) return false; 7359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mCallback = callback; 737b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski mHandler = handler; 7389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta UUID uuid = UUID.randomUUID(); 7399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid); 7409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 742d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback); 7439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 7449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 7459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 7469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 7499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Unregister the current application and callbacks. 7539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 754ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private void unregisterApp() { 7559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf); 7569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 7579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 7599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mCallback = null; 7609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.unregisterClient(mClientIf); 7619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mClientIf = 0; 7629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 7639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 7649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 768ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Initiate a connection to a Bluetooth GATT capable device. 7699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>The connection may not be established right away, but will be 7719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * completed when the remote device is available. A 772d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * {@link BluetoothGattCallback#onConnectionStateChange} callback will be 7739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked when the connection state changes as a result of this function. 7749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7756ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * <p>The autoConnect parameter determines whether to actively connect to 7769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * the remote device, or rather passively scan and finalize the connection 7779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * when the remote device is in range/available. Generally, the first ever 7789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * connection to a device should be direct (autoConnect set to false) and 7799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * subsequent connections to known devices should be invoked with the 780ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * autoConnect parameter set to true. 7819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param device Remote device to connect to 7859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param autoConnect Whether to directly connect to the remote device (false) 7869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * or to automatically connect as soon as the remote 7879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * device becomes available (true). 7889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the connection attempt was initiated successfully 7899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 790b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback, 791b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski Handler handler) { 792ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect); 793ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 794ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (mConnState != CONN_STATE_IDLE) { 795ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new IllegalStateException("Not idle"); 796ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 797ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_CONNECTING; 798ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 799d35167adcaa40cb54df8e392379dfdfe98bcdba2Sungki Kim 800d35167adcaa40cb54df8e392379dfdfe98bcdba2Sungki Kim mAutoConnect = autoConnect; 801d35167adcaa40cb54df8e392379dfdfe98bcdba2Sungki Kim 802b0f647492f6d262d13825b14bbada140effe8394Jakub Pawlowski if (!registerApp(callback, handler)) { 803ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 804ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 805ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 806ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG, "Failed to register callback"); 8079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 8089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 810d35167adcaa40cb54df8e392379dfdfe98bcdba2Sungki Kim // The connection will continue in the onClientRegistered callback 8119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 8129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 8159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Disconnects an established connection, or cancels a connection attempt 8169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * currently in progress. 8179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 8199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 820ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public void disconnect() { 821ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress()); 8229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 8239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 825ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.clientDisconnect(mClientIf, mDevice.getAddress()); 8269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 8279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 8289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 82933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 83033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie 83133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie /** 83233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Connect back to remote device. 83333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 83433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * <p>This method is used to re-connect to a remote device after the 83533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * connection has been dropped. If the device is not in range, the 83633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * re-connection will be triggered once the device is back in range. 83733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 83833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * @return true, if the connection attempt was initiated successfully 83933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie */ 84033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public boolean connect() { 84133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie try { 84233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mService.clientConnect(mClientIf, mDevice.getAddress(), 843db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski false, mTransport, mPhy); // autoConnect is inverse of "isDirect" 84433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return true; 84533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } catch (RemoteException e) { 84633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie Log.e(TAG,"",e); 84733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return false; 84833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 84933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 85033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie 85133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie /** 852db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * Set the preferred connection PHY for this app. Please note that this is just a 853f752ace75a931f7a645a8e65462b91a7185ed1d4Jakub Pawlowski * recommendation, whether the PHY change will happen depends on other applications peferences, 854db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * local and remote controller capabilities. Controller can override these settings. 855db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * <p> 856d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * {@link BluetoothGattCallback#onPhyUpdate} will be triggered as a result of this call, even 857db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * if no PHY change happens. It is also triggered when remote device updates the PHY. 858db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * 859db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * @param txPhy preferred transmitter PHY. Bitwise OR of any of 860a51513747aee764628871d2919f434dcbe38b67cJakub Pawlowski * {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, 861a51513747aee764628871d2919f434dcbe38b67cJakub Pawlowski * and {@link BluetoothDevice#PHY_LE_CODED_MASK}. 862db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * @param rxPhy preferred receiver PHY. Bitwise OR of any of 863a51513747aee764628871d2919f434dcbe38b67cJakub Pawlowski * {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, 864a51513747aee764628871d2919f434dcbe38b67cJakub Pawlowski * and {@link BluetoothDevice#PHY_LE_CODED_MASK}. 865db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one 866db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, 867db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * {@link BluetoothDevice#PHY_OPTION_S2} or {@link BluetoothDevice#PHY_OPTION_S8} 868db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski */ 869db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski public void setPreferredPhy(int txPhy, int rxPhy, int phyOptions) { 870db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski try { 871db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski mService.clientSetPreferredPhy(mClientIf, mDevice.getAddress(), txPhy, rxPhy, 872db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski phyOptions); 873db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } catch (RemoteException e) { 874db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski Log.e(TAG,"",e); 875db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } 876db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } 877db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski 878db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski /** 879db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski * Read the current transmitter PHY and receiver PHY of the connection. The values are returned 880d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * in {@link BluetoothGattCallback#onPhyRead} 881db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski */ 882db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski public void readPhy() { 883db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski try { 884db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski mService.clientReadPhy(mClientIf, mDevice.getAddress()); 885db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } catch (RemoteException e) { 886db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski Log.e(TAG,"",e); 887db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } 888db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski } 889db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski 890db5a87d50db9d4b3d642603f6c329b83ee5851f6Jakub Pawlowski /** 89133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Return the remote bluetooth device this GATT client targets to 89233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 89333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * @return remote bluetooth device 89433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie */ 89533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public BluetoothDevice getDevice() { 89633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return mDevice; 8979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 9009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Discovers services offered by a remote device as well as their 9019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * characteristics and descriptors. 9029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This is an asynchronous operation. Once service discovery is completed, 904d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * the {@link BluetoothGattCallback#onServicesDiscovered} callback is 9059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered. If the discovery was successful, the remote services can be 9069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * retrieved using the {@link #getServices} function. 9079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 9099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the remote service discovery has been started 9119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 912ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean discoverServices() { 913ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress()); 9149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 9159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mServices.clear(); 9179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 919ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.discoverServices(mClientIf, mDevice.getAddress()); 9209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 9229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 9239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 9269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 92909ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski * Discovers a service by UUID. This is exposed only for passing PTS tests. 93009ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski * It should never be used by real applications. The service is not searched 93109ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski * for characteristics and descriptors, or returned in any callback. 93209ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski * 93309ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 93409ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski * 93509ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski * @return true, if the remote service discovery has been started 93609ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski * @hide 93709ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski */ 93809ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski public boolean discoverServiceByUuid(UUID uuid) { 93909ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski if (DBG) Log.d(TAG, "discoverServiceByUuid() - device: " + mDevice.getAddress()); 94009ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski if (mService == null || mClientIf == 0) return false; 94109ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski 94209ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski mServices.clear(); 94309ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski 94409ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski try { 94509ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski mService.discoverServiceByUuid(mClientIf, mDevice.getAddress(), new ParcelUuid(uuid)); 94609ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski } catch (RemoteException e) { 94709ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski Log.e(TAG, "", e); 94809ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski return false; 94909ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski } 95009ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski return true; 95109ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski } 95209ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski 95309ad0b27bbc7d2ca2acacd9ef3b1e855eaef9ea9Jakub Pawlowski /** 9549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a list of GATT services offered by the remote device. 9559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function requires that service discovery has been completed 9579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for the given device. 9589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 9609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return List of services on the remote device. Returns an empty list 9629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * if service discovery has not yet been performed. 9639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 964ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public List<BluetoothGattService> getServices() { 9659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta List<BluetoothGattService> result = 9669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ArrayList<BluetoothGattService>(); 9679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for (BluetoothGattService service : mServices) { 969ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (service.getDevice().equals(mDevice)) { 9709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta result.add(service); 9719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return result; 9759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 9789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a {@link BluetoothGattService}, if the requested UUID is 9799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * supported by the remote device. 9809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function requires that service discovery has been completed 9829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for the given device. 9839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>If multiple instances of the same service (as identified by UUID) 9859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * exist, the first instance of the service is returned. 9869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 9889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param uuid UUID of the requested service 9909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return BluetoothGattService if supported, or null if the requested 9919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * service is not offered by the remote device. 9929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 993ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public BluetoothGattService getService(UUID uuid) { 9949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for (BluetoothGattService service : mServices) { 995ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (service.getDevice().equals(mDevice) && 9969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service.getUuid().equals(uuid)) { 9979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return service; 9989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return null; 10029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 10059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Reads the requested characteristic from the associated remote device. 10069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This is an asynchronous operation. The result of the read operation 1008d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * is reported by the {@link BluetoothGattCallback#onCharacteristicRead} 10099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * callback. 10109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic Characteristic to read from the remote device 10149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the read operation was initiated successfully 10159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 10169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) { 10179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((characteristic.getProperties() & 10189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false; 10199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 102055d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid()); 10219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 10229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 10249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 10259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 10279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 10289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1029cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 1030cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 1031cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 1032cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1033cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 10349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 10359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.readCharacteristic(mClientIf, device.getAddress(), 1036c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getInstanceId(), AUTHENTICATION_NONE); 10379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 1039cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 10409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 10419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 10449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1047ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * Reads the characteristic using its UUID from the associated remote device. 1048ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * 1049ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * <p>This is an asynchronous operation. The result of the read operation 1050ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * is reported by the {@link BluetoothGattCallback#onCharacteristicRead} 1051ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * callback. 1052ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * 1053ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 1054ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * 1055ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * @param uuid UUID of characteristic to read from the remote device 1056ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * @return true, if the read operation was initiated successfully 1057ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski * @hide 1058ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski */ 1059ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski public boolean readUsingCharacteristicUuid(UUID uuid, int startHandle, int endHandle) { 1060ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski if (VDBG) Log.d(TAG, "readUsingCharacteristicUuid() - uuid: " + uuid); 1061ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski if (mService == null || mClientIf == 0) return false; 1062ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski 1063ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski synchronized(mDeviceBusy) { 1064ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski if (mDeviceBusy) return false; 1065ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski mDeviceBusy = true; 1066ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski } 1067ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski 1068ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski try { 1069ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski mService.readUsingCharacteristicUuid(mClientIf, mDevice.getAddress(), 1070ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski new ParcelUuid(uuid), startHandle, endHandle, AUTHENTICATION_NONE); 1071ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski } catch (RemoteException e) { 1072ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski Log.e(TAG,"",e); 1073ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski mDeviceBusy = false; 1074ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski return false; 1075ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski } 1076ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski 1077ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski return true; 1078ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski } 1079ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski 1080ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski 1081ce21cb903ceaf8a5d916a89c4d07689887007be2Jakub Pawlowski /** 1082ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Writes a given characteristic and its values to the associated remote device. 10839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once the write operation has been completed, the 1085d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked, 10869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * reporting the result of the operation. 10879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic Characteristic to write on the remote device 10919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the write operation was initiated successfully 10929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 10939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) { 10949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 10959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && (characteristic.getProperties() & 10969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false; 10979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 109855d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid()); 1099ff5e5db319785d23d672af95ac2dff3f37827cfdPrerepa Viswanadham if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false; 11009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 11029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 11039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 11059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 11069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1107cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 1108cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 1109cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 1110cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1111cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 11129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 11139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.writeCharacteristic(mClientIf, device.getAddress(), 1114c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getInstanceId(), characteristic.getWriteType(), 1115c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski AUTHENTICATION_NONE, characteristic.getValue()); 11169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 11179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 1118cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 11199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 11209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 11239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 11269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Reads the value for a given descriptor from the associated remote device. 11279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once the read operation has been completed, the 1129d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * {@link BluetoothGattCallback#onDescriptorRead} callback is 11309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered, signaling the result of the operation. 11319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 11339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param descriptor Descriptor value to read from the remote device 11359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the read operation was initiated successfully 11369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 11379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean readDescriptor(BluetoothGattDescriptor descriptor) { 113855d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid()); 11399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 11409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); 11429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return false; 11439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 11459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 11469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 11489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 11499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1150cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 1151cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 1152cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 1153cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1154cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 11559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1156c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.readDescriptor(mClientIf, device.getAddress(), 1157c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski descriptor.getInstanceId(), AUTHENTICATION_NONE); 11589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 11599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 1160cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 11619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 11629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 11659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 11689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Write the value of a given descriptor to the associated remote device. 11699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1170d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is 11719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered to report the result of the write operation. 11729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 11749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param descriptor Descriptor to write to the associated remote device 11769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the write operation was initiated successfully 11779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 11789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean writeDescriptor(BluetoothGattDescriptor descriptor) { 117955d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid()); 1180ff5e5db319785d23d672af95ac2dff3f37827cfdPrerepa Viswanadham if (mService == null || mClientIf == 0 || descriptor.getValue() == null) return false; 11819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); 11839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return false; 11849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 11869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 11879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 11899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 11909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1191cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 1192cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 1193cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 1194cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1195cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 11969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1197c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski mService.writeDescriptor(mClientIf, device.getAddress(), descriptor.getInstanceId(), 11988e970d6ab4850ca23163bad5773cf5cc2e7ff896Jakub Pawlowski AUTHENTICATION_NONE, descriptor.getValue()); 11999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 12009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 1201cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 12029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 12039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 12069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 12099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Initiates a reliable write transaction for a given remote device. 12109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once a reliable write transaction has been initiated, all calls 12129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * to {@link #writeCharacteristic} are sent to the remote device for 12139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * verification and queued up for atomic execution. The application will 1214d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * receive an {@link BluetoothGattCallback#onCharacteristicWrite} callback 12159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * in response to every {@link #writeCharacteristic} call and is responsible 12169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for verifying if the value has been transmitted accurately. 12179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>After all characteristics have been queued up and verified, 12199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link #executeReliableWrite} will execute all writes. If a characteristic 12209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * was not written correctly, calling {@link #abortReliableWrite} will 12219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * cancel the current transaction without commiting any values on the 12229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * remote device. 12239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 12259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the reliable write transaction has been initiated 12279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1228ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean beginReliableWrite() { 122955d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress()); 12309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 12319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1233ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.beginReliableWrite(mClientIf, mDevice.getAddress()); 12349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 12359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 12369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 12379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 12409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 12439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Executes a reliable write transaction for a given remote device. 12449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function will commit all queued up characteristic write 12469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * operations for a given remote device. 12479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1248d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * <p>A {@link BluetoothGattCallback#onReliableWriteCompleted} callback is 12499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked to indicate whether the transaction has been executed correctly. 12509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 12529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the request to execute the transaction has been sent 12549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1255ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean executeReliableWrite() { 125655d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress()); 12579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 12589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1259cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 1260cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 1261cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 1262cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1263cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 12649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1265ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.endReliableWrite(mClientIf, mDevice.getAddress(), true); 12669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 12679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 1268cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 12699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 12709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 12739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 12769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Cancels a reliable write transaction for a given device. 12779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Calling this function will discard all queued characteristic write 12799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * operations for a given remote device. 12809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 12829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 128348f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du public void abortReliableWrite() { 128455d19e495e2b3cd744724f2d12c399217e3c565cAndre Eisenbach if (VDBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress()); 12859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 12869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1288ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.endReliableWrite(mClientIf, mDevice.getAddress(), false); 12899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 12909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 12919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1295b7b7d7a05c164a56dd4155de4e84fc25ba706728John Du * @deprecated Use {@link #abortReliableWrite()} 129648f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du */ 1297514c5ef8d5774d8820ed1bf90fe53af1606cf106Aurimas Liutikas @Deprecated 129848f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du public void abortReliableWrite(BluetoothDevice mDevice) { 129948f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du abortReliableWrite(); 130048f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du } 130148f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du 130248f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du /** 13039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Enable or disable notifications/indications for a given characteristic. 13049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 13059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once notifications are enabled for a characteristic, a 1306d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * {@link BluetoothGattCallback#onCharacteristicChanged} callback will be 13079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered if the remote device indicates that the given characteristic 13089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * has changed. 13099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 13109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 13119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 13129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic The characteristic for which to enable notifications 13139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param enable Set to true to enable notifications/indications 13149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the requested notification status was set successfully 13159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 13169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic, 13179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta boolean enable) { 13189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "setCharacteristicNotification() - uuid: " + characteristic.getUuid() 13199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " enable: " + enable); 13209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 13219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 13239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 13249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 13269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 13279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 13299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.registerForNotification(mClientIf, device.getAddress(), 1330c9d13c3e3eab9c6568abaef55ab86fb5d2c46ad1Jakub Pawlowski characteristic.getInstanceId(), enable); 13319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 13329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 13339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 13349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 13359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 13379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 13389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 13409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Clears the internal cache and forces a refresh of the services from the 13419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * remote device. 13429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 13439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1344ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean refresh() { 1345ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress()); 13469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 13479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1349ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.refreshDevice(mClientIf, mDevice.getAddress()); 13509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 13519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 13529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 13539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 13549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 13569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 13579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 13599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Read the RSSI for a connected remote device. 13609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1361d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * <p>The {@link BluetoothGattCallback#onReadRemoteRssi} callback will be 13629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked when the RSSI value has been read. 13639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 13649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 13659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 13669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the RSSI value has been requested successfully 13679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1368ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean readRemoteRssi() { 1369ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress()); 13709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 13719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1373ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.readRemoteRssi(mClientIf, mDevice.getAddress()); 13749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 13759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 13769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 13779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 13789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 13809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 13819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 13829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 13834072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * Request an MTU size used for a given connection. 1384580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1385580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * <p>When performing a write request operation (write without response), 1386580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * the data sent is truncated to the MTU size. This function may be used 13874072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * to request a larger MTU size to be able to send more data at once. 1388580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1389d64bb883d822e1db445e09e77150ffd281e83cbeJakub Pawlowski * <p>A {@link BluetoothGattCallback#onMtuChanged} callback will indicate 1390580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * whether this operation was successful. 1391580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1392580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 1393580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1394580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * @return true, if the new MTU value has been requested successfully 1395580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach */ 13964072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public boolean requestMtu(int mtu) { 1397580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (DBG) Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress() 1398580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach + " mtu: " + mtu); 1399580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (mService == null || mClientIf == 0) return false; 1400580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1401580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach try { 1402580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach mService.configureMTU(mClientIf, mDevice.getAddress(), mtu); 1403580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } catch (RemoteException e) { 1404580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach Log.e(TAG,"",e); 1405580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return false; 1406580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 1407580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1408580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return true; 1409580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 1410580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1411580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach /** 14126ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * Request a connection parameter update. 14136ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * 14146ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * <p>This function will send a connection parameter update request to the 14156ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * remote device. 14166ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * 14176ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * @param connectionPriority Request a specific connection priority. Must be one of 14184072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED}, 14194072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * {@link BluetoothGatt#CONNECTION_PRIORITY_HIGH} 14204072da041da2911dd56635b530b276671ce0199dAndre Eisenbach * or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}. 14216ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * @throws IllegalArgumentException If the parameters are outside of their 14226ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach * specified range. 14236ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach */ 14244072da041da2911dd56635b530b276671ce0199dAndre Eisenbach public boolean requestConnectionPriority(int connectionPriority) { 14254072da041da2911dd56635b530b276671ce0199dAndre Eisenbach if (connectionPriority < CONNECTION_PRIORITY_BALANCED || 14264072da041da2911dd56635b530b276671ce0199dAndre Eisenbach connectionPriority > CONNECTION_PRIORITY_LOW_POWER) { 14276ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach throw new IllegalArgumentException("connectionPriority not within valid range"); 14286ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } 14296ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 14304072da041da2911dd56635b530b276671ce0199dAndre Eisenbach if (DBG) Log.d(TAG, "requestConnectionPriority() - params: " + connectionPriority); 14316ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach if (mService == null || mClientIf == 0) return false; 14326ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 14336ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach try { 14346ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach mService.connectionParameterUpdate(mClientIf, mDevice.getAddress(), connectionPriority); 14356ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } catch (RemoteException e) { 14366ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach Log.e(TAG,"",e); 14376ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach return false; 14386ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } 14396ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 14406ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach return true; 14416ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach } 14426ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach 14436ce4db0acf9dea297d96424e526092e799f6da84Andre Eisenbach /** 1444ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} 1445ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as argument 14469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1447ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 14489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 14499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 14509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public int getConnectionState(BluetoothDevice device) { 1451ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead."); 14529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 14539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 14549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1455ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} 1456ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as argument 14579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1458ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 14599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 14609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 14619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public List<BluetoothDevice> getConnectedDevices() { 1462ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException 1463ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie ("Use BluetoothManager#getConnectedDevices instead."); 14649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 14659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 14669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1467ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use 1468ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])} 1469ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as first argument 14709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1471ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 14729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 14739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 14749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 1475ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException 1476ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie ("Use BluetoothManager#getDevicesMatchingConnectionStates instead."); 14779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 14789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta} 1479