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