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