BluetoothGatt.java revision adf6aff5b03b1e3ca4636f9887225a7f906d1238
19908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta/* 29908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Copyright (C) 2013 The Android Open Source Project 39908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 49908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Licensed under the Apache License, Version 2.0 (the "License"); 59908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * you may not use this file except in compliance with the License. 69908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * You may obtain a copy of the License at 79908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 89908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * http://www.apache.org/licenses/LICENSE-2.0 99908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Unless required by applicable law or agreed to in writing, software 119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * distributed under the License is distributed on an "AS IS" BASIS, 129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * See the License for the specific language governing permissions and 149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * limitations under the License. 159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battapackage android.bluetooth; 189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport android.content.Context; 209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport android.os.ParcelUuid; 219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport android.os.RemoteException; 229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport android.util.Log; 239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport java.util.ArrayList; 259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport java.util.List; 269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battaimport java.util.UUID; 279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta/** 29ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Public API for the Bluetooth GATT Profile. 309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 31ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * <p>This class provides Bluetooth GATT functionality to enable communication 329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * with Bluetooth Smart or Smart Ready devices. 339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>To connect to a remote peripheral device, create a {@link BluetoothGattCallback} 3533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * and call {@link BluetoothDevice#connectGatt} to get a instance of this class. 36ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * GATT capable devices can be discovered using the Bluetooth device discovery or BLE 37ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * scan process. 389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Battapublic final class BluetoothGatt implements BluetoothProfile { 409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private static final String TAG = "BluetoothGatt"; 419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private static final boolean DBG = true; 42ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final boolean VDBG = true; 439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 44ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private final Context mContext; 459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private IBluetoothGatt mService; 469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private BluetoothGattCallback mCallback; 479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private int mClientIf; 489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private boolean mAuthRetry = false; 49ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private BluetoothDevice mDevice; 50ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private boolean mAutoConnect; 51ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private int mConnState; 52ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private final Object mStateLock = new Object(); 53cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach private Boolean mDeviceBusy = false; 54b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta private int mTransport; 55ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie 56ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_IDLE = 0; 57ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_CONNECTING = 1; 58ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_CONNECTED = 2; 59ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private static final int CONN_STATE_DISCONNECTING = 3; 6033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie private static final int CONN_STATE_CLOSED = 4; 619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private List<BluetoothGattService> mServices; 639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 64ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /** A GATT operation completed successfully */ 659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_SUCCESS = 0; 669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 67ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /** GATT read operation is not permitted */ 689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_READ_NOT_PERMITTED = 0x2; 699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 70ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /** GATT write operation is not permitted */ 719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_WRITE_NOT_PERMITTED = 0x3; 729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** Insufficient authentication for a given operation */ 749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INSUFFICIENT_AUTHENTICATION = 0x5; 759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** The given request is not supported */ 779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_REQUEST_NOT_SUPPORTED = 0x6; 789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** Insufficient encryption for a given operation */ 809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INSUFFICIENT_ENCRYPTION = 0xf; 819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** A read or write operation was requested with an invalid offset */ 839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INVALID_OFFSET = 0x7; 849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** A write operation exceeds the maximum length of the attribute */ 869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 0xd; 879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8890ca807f7b2037499112d1c49c4b0793cc780540Matthew Xie /** A GATT operation failed, errors other than the above */ 8990ca807f7b2037499112d1c49c4b0793cc780540Matthew Xie public static final int GATT_FAILURE = 0x101; 9090ca807f7b2037499112d1c49c4b0793cc780540Matthew Xie 919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * No authentication required. 939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ static final int AUTHENTICATION_NONE = 0; 969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Authentication requested; no man-in-the-middle protection required. 999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ static final int AUTHENTICATION_NO_MITM = 1; 1029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Authentication with man-in-the-middle protection requested. 1059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ static final int AUTHENTICATION_MITM = 2; 1089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Bluetooth GATT interface callbacks 1119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta private final IBluetoothGattCallback mBluetoothGattCallback = 1139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new IBluetoothGattCallback.Stub() { 1149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Application interface registered - app is ready to go 1169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onClientRegistered(int status, int clientIf) { 1199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status 1209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " clientIf=" + clientIf); 121ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (VDBG) { 122ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 123ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (mConnState != CONN_STATE_CONNECTING) { 124ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG, "Bad connection state: " + mConnState); 125ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 126ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 127ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 1289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mClientIf = clientIf; 129ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (status != GATT_SUCCESS) { 13033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE, 131ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothProfile.STATE_DISCONNECTED); 132ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 133ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 134ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 135ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 136ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 1379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 138ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.clientConnect(mClientIf, mDevice.getAddress(), 139b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta !mAutoConnect, mTransport); // autoConnect is inverse of "isDirect" 140ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } catch (RemoteException e) { 141ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG,"",e); 1429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 1439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 1449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Client connection state changed 1479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onClientConnectionState(int status, int clientIf, 1509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta boolean connected, String address) { 1519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onClientConnectionState() - status=" + status 1529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " clientIf=" + clientIf + " device=" + address); 153ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 154ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 155ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 156ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie int profileState = connected ? BluetoothProfile.STATE_CONNECTED : 157ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothProfile.STATE_DISCONNECTED; 1589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 15933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState); 1609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 1610998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 1629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 163ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie 164ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 165ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (connected) { 166ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_CONNECTED; 167ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } else { 168ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 169ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 170ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 171cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 172cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 173cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 174cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 1769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Callback reporting an LE scan result. 1799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onScanResult(String address, int rssi, byte[] advData) { 182ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie // no op 1839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 1849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * A new GATT service has been discovered. 1879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * The service is added to the internal list and the search 1889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * continues. 1899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 1909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onGetService(String address, int srvcType, 1929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int srvcInstId, ParcelUuid srvcUuid) { 1939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onGetService() - Device=" + address + " UUID=" + srvcUuid); 194ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 195ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 196ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 197ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mServices.add(new BluetoothGattService(mDevice, srvcUuid.getUuid(), 1989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcInstId, srvcType)); 1999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 2029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * An included service has been found durig GATT discovery. 2039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * The included service is added to the respective parent. 2049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 2059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 2069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onGetIncludedService(String address, int srvcType, 2079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int srvcInstId, ParcelUuid srvcUuid, 2089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int inclSrvcType, int inclSrvcInstId, 2099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta ParcelUuid inclSrvcUuid) { 2109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onGetIncludedService() - Device=" + address 2119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " UUID=" + srvcUuid + " Included=" + inclSrvcUuid); 2129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 213ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 214ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 215ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 216ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothGattService service = getService(mDevice, 2179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcUuid.getUuid(), srvcInstId, srvcType); 218ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothGattService includedService = getService(mDevice, 2199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta inclSrvcUuid.getUuid(), inclSrvcInstId, inclSrvcType); 2209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service != null && includedService != null) { 2229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service.addIncludedService(includedService); 2239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 2279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * A new GATT characteristic has been discovered. 2289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Add the new characteristic to the relevant service and continue 2299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * the remote device inspection. 2309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 2319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 2329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onGetCharacteristic(String address, int srvcType, 2339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int srvcInstId, ParcelUuid srvcUuid, 2349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int charInstId, ParcelUuid charUuid, 2359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int charProps) { 2369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onGetCharacteristic() - Device=" + address + " UUID=" + 2379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta charUuid); 2389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 239ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 240ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 241ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 242ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), 2439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcInstId, srvcType); 2449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service != null) { 2459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service.addCharacteristic(new BluetoothGattCharacteristic( 2469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service, charUuid.getUuid(), charInstId, charProps, 0)); 2479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 2519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * A new GATT descriptor has been discovered. 2529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Finally, add the descriptor to the related characteristic. 2539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * This should conclude the remote device update. 2549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 2559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 2569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onGetDescriptor(String address, int srvcType, 2579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int srvcInstId, ParcelUuid srvcUuid, 2589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int charInstId, ParcelUuid charUuid, 25925b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach int descrInstId, ParcelUuid descUuid) { 2609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onGetDescriptor() - Device=" + address + " UUID=" + descUuid); 2619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 262ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 263ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 264ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 265ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), 2669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcInstId, srvcType); 2679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return; 2689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = service.getCharacteristic( 2709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta charUuid.getUuid()); 2719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 2729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.addDescriptor(new BluetoothGattDescriptor( 27425b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach characteristic, descUuid.getUuid(), descrInstId, 0)); 2759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 2789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote search has been completed. 2799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * The internal object structure should now reflect the state 2809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * of the remote device database. Let the application know that 2819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * we are done at this point. 2829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 2839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 2849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onSearchComplete(String address, int status) { 2859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onSearchComplete() = Device=" + address + " Status=" + status); 286ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 287ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 288ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 2899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 29033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onServicesDiscovered(BluetoothGatt.this, status); 2919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 2920998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 2939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 2959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 2969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 2979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote characteristic has been read. 2989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Updates the internal value. 2999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 3009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 3019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onCharacteristicRead(String address, int status, int srvcType, 3029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int srvcInstId, ParcelUuid srvcUuid, 3039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int charInstId, ParcelUuid charUuid, byte[] value) { 3049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address 3059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " UUID=" + charUuid + " Status=" + status); 3069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 307ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 308ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 309ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 310cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 311cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 312cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 313cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 314cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 3159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 3169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 3179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && mAuthRetry == false) { 3189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 3199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 3209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.readCharacteristic(mClientIf, address, 3219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcType, srvcInstId, srvcUuid, 3229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta charInstId, charUuid, AUTHENTICATION_MITM); 3239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return; 3249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 3259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 3269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = false; 3309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 331ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), 3329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcInstId, srvcType); 3339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return; 3349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = service.getCharacteristic( 3369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta charUuid.getUuid(), charInstId); 3379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 3389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (status == 0) characteristic.setValue(value); 3409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 34233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status); 3439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 3440998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 3459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 3499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Characteristic has been written to the remote device. 3509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Let the app know how we did... 3519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 3529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 3539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onCharacteristicWrite(String address, int status, int srvcType, 3549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int srvcInstId, ParcelUuid srvcUuid, 3559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int charInstId, ParcelUuid charUuid) { 3569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address 3579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " UUID=" + charUuid + " Status=" + status); 3589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 359ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 360ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 361ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 362cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 363cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 364cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 365cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 366cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 367ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), 3689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcInstId, srvcType); 3699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return; 3709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = service.getCharacteristic( 3729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta charUuid.getUuid(), charInstId); 3739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 3749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 3769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 3779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && mAuthRetry == false) { 3789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 3799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 3809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.writeCharacteristic(mClientIf, address, 3819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcType, srvcInstId, srvcUuid, charInstId, charUuid, 3829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.getWriteType(), AUTHENTICATION_MITM, 3839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.getValue()); 3849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return; 3859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 3869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 3879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = false; 3919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 39333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status); 3949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 3950998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 3969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 3989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 3999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 4009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote characteristic has been updated. 4019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Updates the internal value. 4029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 4039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 4049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onNotify(String address, int srvcType, 4059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int srvcInstId, ParcelUuid srvcUuid, 4069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int charInstId, ParcelUuid charUuid, 4079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta byte[] value) { 4089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onNotify() - Device=" + address + " UUID=" + charUuid); 4099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 410ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 411ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 412ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 413ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), 4149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcInstId, srvcType); 4159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return; 4169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = service.getCharacteristic( 4189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta charUuid.getUuid(), charInstId); 4199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 4209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.setValue(value); 4229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 42433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic); 4259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 4260998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 4279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 4319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Descriptor has been read. 4329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 4339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 4349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onDescriptorRead(String address, int status, int srvcType, 4359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int srvcInstId, ParcelUuid srvcUuid, 4369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int charInstId, ParcelUuid charUuid, 43725b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach int descrInstId, ParcelUuid descrUuid, 43825b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach byte[] value) { 4399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " UUID=" + charUuid); 4409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 441ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 442ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 443ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 444cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 445cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 446cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 447cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 448cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 449ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), 4509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcInstId, srvcType); 4519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return; 4529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = service.getCharacteristic( 4549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta charUuid.getUuid(), charInstId); 4559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 4569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattDescriptor descriptor = characteristic.getDescriptor( 45825b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach descrUuid.getUuid(), descrInstId); 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) 4659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && mAuthRetry == false) { 4669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 4679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 4689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.readDescriptor(mClientIf, address, 4699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcType, srvcInstId, srvcUuid, charInstId, charUuid, 47025b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach descrInstId, descrUuid, AUTHENTICATION_MITM); 4719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 4729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 4739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 4779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 47933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status); 4809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 4810998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 4829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 4849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 4859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 4869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Descriptor write operation complete. 4879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 4889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 4899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onDescriptorWrite(String address, int status, int srvcType, 4909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int srvcInstId, ParcelUuid srvcUuid, 4919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int charInstId, ParcelUuid charUuid, 49225b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach int descrInstId, ParcelUuid descrUuid) { 4939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " UUID=" + charUuid); 4949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 495ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 496ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 497ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 498cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 499cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 500cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 501cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 502cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 503ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), 5049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcInstId, srvcType); 5059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return; 5069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = service.getCharacteristic( 5089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta charUuid.getUuid(), charInstId); 5099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return; 5109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattDescriptor descriptor = characteristic.getDescriptor( 51225b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach descrUuid.getUuid(), descrInstId); 5139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (descriptor == null) return; 5149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((status == GATT_INSUFFICIENT_AUTHENTICATION 5169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta || status == GATT_INSUFFICIENT_ENCRYPTION) 5179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && mAuthRetry == false) { 5189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 5199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = true; 5209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.writeDescriptor(mClientIf, address, 5219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta srvcType, srvcInstId, srvcUuid, charInstId, charUuid, 52225b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach descrInstId, descrUuid, characteristic.getWriteType(), 5239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta AUTHENTICATION_MITM, descriptor.getValue()); 5249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 5259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 5269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mAuthRetry = false; 5309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 53233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status); 5339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 5340998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 5359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 5399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Prepared write transaction completed (or aborted) 5409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 5419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 5429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onExecuteWrite(String address, int status) { 5439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onExecuteWrite() - Device=" + address 5449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " status=" + status); 545ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 546ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 547ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 548cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 549cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 550cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 551cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 552cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 5539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 55433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onReliableWriteCompleted(BluetoothGatt.this, status); 5559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 5560998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 5579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 5609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 5619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Remote device RSSI has been read 5629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 5639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 5649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public void onReadRemoteRssi(String address, int rssi, int status) { 5659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address + 5669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta " rssi=" + rssi + " status=" + status); 567ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!address.equals(mDevice.getAddress())) { 568ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie return; 569ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 5709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 57133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status); 5729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (Exception ex) { 5730998ff13498ed004956d1de428eb0c4dcd33c1fbMike Lockwood Log.w(TAG, "Unhandled exception in callback", ex); 5749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 5759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 576f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang 577f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang /** 578f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang * Advertise state change callback 579f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang * @hide 580f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang */ 581f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang public void onAdvertiseStateChange(int state, int status) { 582f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang if (DBG) Log.d(TAG, "onAdvertiseStateChange() - state = " 583f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang + state + " status=" + status); 584adf6aff5b03b1e3ca4636f9887225a7f906d1238Wei Wang } 585adf6aff5b03b1e3ca4636f9887225a7f906d1238Wei Wang 586adf6aff5b03b1e3ca4636f9887225a7f906d1238Wei Wang /** 587adf6aff5b03b1e3ca4636f9887225a7f906d1238Wei Wang * @hide 588adf6aff5b03b1e3ca4636f9887225a7f906d1238Wei Wang */ 589adf6aff5b03b1e3ca4636f9887225a7f906d1238Wei Wang @Override 590adf6aff5b03b1e3ca4636f9887225a7f906d1238Wei Wang public void onMultiAdvertiseCallback(int status) { 591adf6aff5b03b1e3ca4636f9887225a7f906d1238Wei Wang // no op. 592adf6aff5b03b1e3ca4636f9887225a7f906d1238Wei Wang } 593580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 594580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach /** 595580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * Callback invoked when the MTU for a given connection changes 596580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * @hide 597580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach */ 598580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach public void onConfigureMTU(String address, int mtu, int status) { 599580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (DBG) Log.d(TAG, "onConfigureMTU() - Device=" + address + 600580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach " mtu=" + mtu + " status=" + status); 601580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (!address.equals(mDevice.getAddress())) { 602580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return; 603580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 604580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach try { 605580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach mCallback.onConfigureMTU(BluetoothGatt.this, mtu, status); 606580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } catch (Exception ex) { 607580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach Log.w(TAG, "Unhandled exception in callback", ex); 608580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 609f305589f22f3fa1d73f2e29009d382c9a4f5c293Wei Wang } 6109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta }; 6119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 612b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta /*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device, 613b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta int transport) { 6149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mContext = context; 615ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService = iGatt; 616ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mDevice = device; 617b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta mTransport = transport; 6189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mServices = new ArrayList<BluetoothGattService>(); 6199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 620ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 6219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 62433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Close this Bluetooth GATT client. 625b30f91e38c19f6728d836293446d4b9c76705e7fMatthew Xie * 626b30f91e38c19f6728d836293446d4b9c76705e7fMatthew Xie * Application should call this method as early as possible after it is done with 627b30f91e38c19f6728d836293446d4b9c76705e7fMatthew Xie * this GATT client. 6289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 62933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public void close() { 6309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "close()"); 6319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta unregisterApp(); 63333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mConnState = CONN_STATE_CLOSED; 6349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 6379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a service by UUID, instance and type. 6389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 6399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 6409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /*package*/ BluetoothGattService getService(BluetoothDevice device, UUID uuid, 6419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta int instanceId, int type) { 6429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for(BluetoothGattService svc : mServices) { 6439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (svc.getDevice().equals(device) && 6449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta svc.getType() == type && 6459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta svc.getInstanceId() == instanceId && 6469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta svc.getUuid().equals(uuid)) { 6479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return svc; 6489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return null; 6519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 655ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Register an application callback to start using GATT. 6569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 657ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered} 658ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * is used to notify success or failure if the function returns true. 6599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 6609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 6619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 662ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @param callback GATT callback handler that will receive asynchronous callbacks. 663ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @return If true, the callback will be called to notify success or failure, 664ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * false on immediate error 6659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 666ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private boolean registerApp(BluetoothGattCallback callback) { 6679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "registerApp()"); 6689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null) return false; 6699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mCallback = callback; 6719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta UUID uuid = UUID.randomUUID(); 6729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid); 6739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 6759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback); 6769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 6779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 6789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 6799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 6829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 6859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Unregister the current application and callbacks. 6869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 687ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie private void unregisterApp() { 6889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf); 6899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 6909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 6919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 6929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mCallback = null; 6939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.unregisterClient(mClientIf); 6949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mClientIf = 0; 6959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 6969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 6979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 6999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 701ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Initiate a connection to a Bluetooth GATT capable device. 7029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>The connection may not be established right away, but will be 7049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * completed when the remote device is available. A 7059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onConnectionStateChange} callback will be 7069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked when the connection state changes as a result of this function. 7079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>The autoConnect paramter determines whether to actively connect to 7099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * the remote device, or rather passively scan and finalize the connection 7109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * when the remote device is in range/available. Generally, the first ever 7119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * connection to a device should be direct (autoConnect set to false) and 7129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * subsequent connections to known devices should be invoked with the 713ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * autoConnect parameter set to true. 7149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param device Remote device to connect to 7189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param autoConnect Whether to directly connect to the remote device (false) 7199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * or to automatically connect as soon as the remote 7209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * device becomes available (true). 7219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the connection attempt was initiated successfully 7229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 723ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) { 724ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect); 725ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 726ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (mConnState != CONN_STATE_IDLE) { 727ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new IllegalStateException("Not idle"); 728ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 729ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_CONNECTING; 730ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 731ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (!registerApp(callback)) { 732ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie synchronized(mStateLock) { 733ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mConnState = CONN_STATE_IDLE; 734ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie } 735ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie Log.e(TAG, "Failed to register callback"); 7369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 7379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 739ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie // the connection will continue after successful callback registration 740ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mAutoConnect = autoConnect; 7419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 7429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Disconnects an established connection, or cancels a connection attempt 7469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * currently in progress. 7479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 7499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 750ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public void disconnect() { 751ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress()); 7529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 7539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 755ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.clientDisconnect(mClientIf, mDevice.getAddress()); 7569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 7579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 7589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 75933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 76033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie 76133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie /** 76233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Connect back to remote device. 76333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 76433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * <p>This method is used to re-connect to a remote device after the 76533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * connection has been dropped. If the device is not in range, the 76633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * re-connection will be triggered once the device is back in range. 76733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 76833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * @return true, if the connection attempt was initiated successfully 76933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie */ 77033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public boolean connect() { 77133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie try { 77233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie mService.clientConnect(mClientIf, mDevice.getAddress(), 773b88fa824ab6337684de9aa8437c4952df4f1a75eGanesh Ganapathi Batta false, mTransport); // autoConnect is inverse of "isDirect" 77433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return true; 77533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } catch (RemoteException e) { 77633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie Log.e(TAG,"",e); 77733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return false; 77833ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 77933ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie } 78033ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie 78133ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie /** 78233ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * Return the remote bluetooth device this GATT client targets to 78333ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * 78433ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie * @return remote bluetooth device 78533ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie */ 78633ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie public BluetoothDevice getDevice() { 78733ec9840c70ddc7cd008ecf2660c441defc5f302Matthew Xie return mDevice; 7889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 7899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 7909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 7919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Discovers services offered by a remote device as well as their 7929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * characteristics and descriptors. 7939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This is an asynchronous operation. Once service discovery is completed, 7959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * the {@link BluetoothGattCallback#onServicesDiscovered} callback is 7969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered. If the discovery was successful, the remote services can be 7979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * retrieved using the {@link #getServices} function. 7989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 7999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 8009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the remote service discovery has been started 8029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 803ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean discoverServices() { 804ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress()); 8059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 8069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mServices.clear(); 8089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 810ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.discoverServices(mClientIf, mDevice.getAddress()); 8119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 8129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 8139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 8149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 8179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 8209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a list of GATT services offered by the remote device. 8219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function requires that service discovery has been completed 8239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for the given device. 8249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 8269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return List of services on the remote device. Returns an empty list 8289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * if service discovery has not yet been performed. 8299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 830ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public List<BluetoothGattService> getServices() { 8319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta List<BluetoothGattService> result = 8329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ArrayList<BluetoothGattService>(); 8339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for (BluetoothGattService service : mServices) { 835ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (service.getDevice().equals(mDevice)) { 8369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta result.add(service); 8379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return result; 8419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 8449908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Returns a {@link BluetoothGattService}, if the requested UUID is 8459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * supported by the remote device. 8469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function requires that service discovery has been completed 8489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for the given device. 8499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>If multiple instances of the same service (as identified by UUID) 8519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * exist, the first instance of the service is returned. 8529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 8549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param uuid UUID of the requested service 8569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return BluetoothGattService if supported, or null if the requested 8579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * service is not offered by the remote device. 8589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 859ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public BluetoothGattService getService(UUID uuid) { 8609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta for (BluetoothGattService service : mServices) { 861ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (service.getDevice().equals(mDevice) && 8629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service.getUuid().equals(uuid)) { 8639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return service; 8649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return null; 8689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 8699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 8719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Reads the requested characteristic from the associated remote device. 8729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This is an asynchronous operation. The result of the read operation 8749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * is reported by the {@link BluetoothGattCallback#onCharacteristicRead} 8759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * callback. 8769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 8789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 8799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic Characteristic to read from the remote device 8809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the read operation was initiated successfully 8819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 8829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) { 8839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((characteristic.getProperties() & 8849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false; 8859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid()); 8879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 8889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 8909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 8919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 8929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 8939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 8949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 895cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 896cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 897cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 898cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 899cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 9009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 9019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.readCharacteristic(mClientIf, device.getAddress(), 9029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service.getType(), service.getInstanceId(), 9039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ParcelUuid(service.getUuid()), characteristic.getInstanceId(), 9049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ParcelUuid(characteristic.getUuid()), AUTHENTICATION_NONE); 9059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 907cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 9089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 9099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 9129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 915ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Writes a given characteristic and its values to the associated remote device. 9169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once the write operation has been completed, the 9189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked, 9199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * reporting the result of the operation. 9209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 9229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic Characteristic to write on the remote device 9249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the write operation was initiated successfully 9259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 9269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) { 9279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 9289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta && (characteristic.getProperties() & 9299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false; 9309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9319908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid()); 9329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 9339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 9359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 9369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 9389908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 9399908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 940cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 941cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 942cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 943cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 944cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 9459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 9469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.writeCharacteristic(mClientIf, device.getAddress(), 9479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service.getType(), service.getInstanceId(), 9489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ParcelUuid(service.getUuid()), characteristic.getInstanceId(), 9499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ParcelUuid(characteristic.getUuid()), 9509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.getWriteType(), AUTHENTICATION_NONE, 9519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.getValue()); 9529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 954cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 9559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 9569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 9599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 9609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 9629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Reads the value for a given descriptor from the associated remote device. 9639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once the read operation has been completed, the 9659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onDescriptorRead} callback is 9669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered, signaling the result of the operation. 9679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 9699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 9709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param descriptor Descriptor value to read from the remote device 9719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the read operation was initiated successfully 9729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 9739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean readDescriptor(BluetoothGattDescriptor descriptor) { 9749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid()); 9759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 9769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); 9789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return false; 9799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 9819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 9829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 9839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 9849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 9859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 986cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 987cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 988cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 989cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 990cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 9919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 99225b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach mService.readDescriptor(mClientIf, device.getAddress(), service.getType(), 99325b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach service.getInstanceId(), new ParcelUuid(service.getUuid()), 99425b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach characteristic.getInstanceId(), new ParcelUuid(characteristic.getUuid()), 99525b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach descriptor.getInstanceId(), new ParcelUuid(descriptor.getUuid()), 99625b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach AUTHENTICATION_NONE); 9979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 9989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 999cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 10009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 10019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 10049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 10079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Write the value of a given descriptor to the associated remote device. 10089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is 10109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered to report the result of the write operation. 10119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param descriptor Descriptor to write to the associated remote device 10159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the write operation was initiated successfully 10169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 10179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean writeDescriptor(BluetoothGattDescriptor descriptor) { 10189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid()); 10199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 10209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); 10229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (characteristic == null) return false; 10239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 10259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 10269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 10289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 10299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1030cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 1031cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 1032cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 1033cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1034cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 10359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 103625b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach mService.writeDescriptor(mClientIf, device.getAddress(), service.getType(), 103725b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach service.getInstanceId(), new ParcelUuid(service.getUuid()), 103825b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach characteristic.getInstanceId(), new ParcelUuid(characteristic.getUuid()), 103925b9cf953bd3e97f726f8c27d7a752b27c9a2373Andre Eisenbach descriptor.getInstanceId(), new ParcelUuid(descriptor.getUuid()), 10409908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta characteristic.getWriteType(), AUTHENTICATION_NONE, 10419908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta descriptor.getValue()); 10429908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10439908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 1044cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 10459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 10469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 10499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 10529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Initiates a reliable write transaction for a given remote device. 10539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once a reliable write transaction has been initiated, all calls 10559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * to {@link #writeCharacteristic} are sent to the remote device for 10569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * verification and queued up for atomic execution. The application will 10579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * receive an {@link BluetoothGattCallback#onCharacteristicWrite} callback 10589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * in response to every {@link #writeCharacteristic} call and is responsible 10599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * for verifying if the value has been transmitted accurately. 10609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>After all characteristics have been queued up and verified, 10629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link #executeReliableWrite} will execute all writes. If a characteristic 10639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * was not written correctly, calling {@link #abortReliableWrite} will 10649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * cancel the current transaction without commiting any values on the 10659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * remote device. 10669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the reliable write transaction has been initiated 10709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1071ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean beginReliableWrite() { 1072ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress()); 10739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 10749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1076ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.beginReliableWrite(mClientIf, mDevice.getAddress()); 10779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 10789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 10799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 10809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 10839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 10849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 10859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 10869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Executes a reliable write transaction for a given remote device. 10879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>This function will commit all queued up characteristic write 10899908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * operations for a given remote device. 10909908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>A {@link BluetoothGattCallback#onReliableWriteCompleted} callback is 10929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked to indicate whether the transaction has been executed correctly. 10939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10949908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 10959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 10969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the request to execute the transaction has been sent 10979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1098ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean executeReliableWrite() { 1099ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress()); 11009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 11019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 1102cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach synchronized(mDeviceBusy) { 1103cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach if (mDeviceBusy) return false; 1104cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = true; 1105cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach } 1106cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach 11079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1108ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.endReliableWrite(mClientIf, mDevice.getAddress(), true); 11099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 11109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 1111cc68cc962d1c90aaa0cdf2fffa68810998717517Andre Eisenbach mDeviceBusy = false; 11129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 11139908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11149908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 11169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11189908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 11199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Cancels a reliable write transaction for a given device. 11209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Calling this function will discard all queued characteristic write 11229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * operations for a given remote device. 11239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 11259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 112648f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du public void abortReliableWrite() { 1127ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress()); 11289908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return; 11299908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11309908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1131ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.endReliableWrite(mClientIf, mDevice.getAddress(), false); 11329908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 11339908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 11349908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11359908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11369908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11379908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1138b7b7d7a05c164a56dd4155de4e84fc25ba706728John Du * @deprecated Use {@link #abortReliableWrite()} 113948f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du */ 114048f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du public void abortReliableWrite(BluetoothDevice mDevice) { 114148f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du abortReliableWrite(); 114248f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du } 114348f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du 114448f8b5dbf6d387002abee1ec0da73446d2aab0dfJohn Du /** 11459908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Enable or disable notifications/indications for a given characteristic. 11469908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11479908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Once notifications are enabled for a characteristic, a 11489908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * {@link BluetoothGattCallback#onCharacteristicChanged} callback will be 11499908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * triggered if the remote device indicates that the given characteristic 11509908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * has changed. 11519908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11529908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 11539908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 11549908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param characteristic The characteristic for which to enable notifications 11559908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @param enable Set to true to enable notifications/indications 11569908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the requested notification status was set successfully 11579908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 11589908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic, 11599908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta boolean enable) { 11609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (DBG) Log.d(TAG, "setCharacteristicNotification() - uuid: " + characteristic.getUuid() 11619908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta + " enable: " + enable); 11629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 11639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothGattService service = characteristic.getService(); 11659908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (service == null) return false; 11669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta BluetoothDevice device = service.getDevice(); 11689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (device == null) return false; 11699908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11709908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 11719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta mService.registerForNotification(mClientIf, device.getAddress(), 11729908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta service.getType(), service.getInstanceId(), 11739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ParcelUuid(service.getUuid()), characteristic.getInstanceId(), 11749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta new ParcelUuid(characteristic.getUuid()), 11759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta enable); 11769908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 11779908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 11789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 11799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11819908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 11829908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11839908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 11859908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Clears the internal cache and forces a refresh of the services from the 11869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * remote device. 11879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @hide 11889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1189ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean refresh() { 1190ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress()); 11919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 11929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 11939908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1194ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.refreshDevice(mClientIf, mDevice.getAddress()); 11959908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 11969908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 11979908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 11989908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 11999908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12009908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 12019908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12029908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12039908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 12049908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * Read the RSSI for a connected remote device. 12059908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12069908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>The {@link BluetoothGattCallback#onReadRemoteRssi} callback will be 12079908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * invoked when the RSSI value has been read. 12089908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12099908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 12109908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 12119908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * @return true, if the RSSI value has been requested successfully 12129908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 1213ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie public boolean readRemoteRssi() { 1214ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress()); 12159908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta if (mService == null || mClientIf == 0) return false; 12169908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12179908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta try { 1218ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie mService.readRemoteRssi(mClientIf, mDevice.getAddress()); 12199908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } catch (RemoteException e) { 12209908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta Log.e(TAG,"",e); 12219908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return false; 12229908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12239908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12249908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta return true; 12259908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12269908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12279908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1228580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * Configure the MTU used for a given connection. 1229580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1230580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * <p>When performing a write request operation (write without response), 1231580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * the data sent is truncated to the MTU size. This function may be used 1232580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * to request a larget MTU size to be able to send more data at once. 1233580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1234580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * <p>A {@link BluetoothGattCallback#onConfigureMTU} callback will indicate 1235580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * whether this operation was successful. 1236580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1237580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 1238580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * 1239580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * @return true, if the new MTU value has been requested successfully 1240580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach * @hide 1241580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach */ 1242580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach public boolean configureMTU(int mtu) { 1243580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (DBG) Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress() 1244580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach + " mtu: " + mtu); 1245580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach if (mService == null || mClientIf == 0) return false; 1246580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1247580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach try { 1248580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach mService.configureMTU(mClientIf, mDevice.getAddress(), mtu); 1249580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } catch (RemoteException e) { 1250580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach Log.e(TAG,"",e); 1251580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return false; 1252580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 1253580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1254580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach return true; 1255580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach } 1256580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach 1257580b0a13028ed2187964735a5515d87900d241ceAndre Eisenbach /** 1258ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} 1259ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as argument 12609908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1261ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 12629908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 12639908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 12649908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public int getConnectionState(BluetoothDevice device) { 1265ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead."); 12669908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12679908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12689908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1269ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} 1270ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as argument 12719908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1272ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 12739908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 12749908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 12759908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public List<BluetoothDevice> getConnectedDevices() { 1276ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException 1277ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie ("Use BluetoothManager#getConnectedDevices instead."); 12789908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12799908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta 12809908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta /** 1281ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * Not supported - please use 1282ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])} 1283ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * with {@link BluetoothProfile#GATT} as first argument 12849908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta * 1285ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie * @throws UnsupportedOperationException 12869908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta */ 12879908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta @Override 12889908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 1289ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie throw new UnsupportedOperationException 1290ddf7e4756c31d0ed90802f98abeaa79df6d16b2aMatthew Xie ("Use BluetoothManager#getDevicesMatchingConnectionStates instead."); 12919908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta } 12929908112fd085d8b0d91e0562d32eebd1884f09a5Ganesh Ganapathi Batta} 1293