1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.googlecode.android_scripting.facade.bluetooth;
18
19import android.app.Service;
20import android.bluetooth.BluetoothAdapter;
21import android.bluetooth.BluetoothDevice;
22import android.bluetooth.BluetoothGatt;
23import android.bluetooth.BluetoothGattCallback;
24import android.bluetooth.BluetoothGattCharacteristic;
25import android.bluetooth.BluetoothGattDescriptor;
26import android.bluetooth.BluetoothGattService;
27import android.bluetooth.BluetoothManager;
28import android.bluetooth.BluetoothProfile;
29import android.content.Context;
30import android.os.Bundle;
31
32import com.googlecode.android_scripting.Log;
33import com.googlecode.android_scripting.MainThread;
34import com.googlecode.android_scripting.facade.EventFacade;
35import com.googlecode.android_scripting.facade.FacadeManager;
36import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
37import com.googlecode.android_scripting.rpc.Rpc;
38import com.googlecode.android_scripting.rpc.RpcParameter;
39import com.googlecode.android_scripting.rpc.RpcStopEvent;
40
41import java.util.ArrayList;
42import java.util.HashMap;
43import java.util.List;
44import java.util.UUID;
45import java.util.concurrent.Callable;
46
47public class GattClientFacade extends RpcReceiver {
48    private final EventFacade mEventFacade;
49    private BluetoothAdapter mBluetoothAdapter;
50    private BluetoothManager mBluetoothManager;
51    private final Service mService;
52    private final Context mContext;
53    private final HashMap<Integer, myBluetoothGattCallback> mGattCallbackList;
54    private final HashMap<Integer, BluetoothGatt> mBluetoothGattList;
55    private final HashMap<Integer, BluetoothGattCharacteristic> mCharacteristicList;
56    private final HashMap<Integer, BluetoothGattDescriptor> mDescriptorList;
57    private final HashMap<Integer, BluetoothGattService> mGattServiceList;
58    private final HashMap<Integer, List<BluetoothGattService>> mBluetoothGattDiscoveredServicesList;
59    private final HashMap<Integer, List<BluetoothDevice>> mGattServerDiscoveredDevicesList;
60    private static int GattCallbackCount;
61    private static int BluetoothGattDiscoveredServicesCount;
62    private static int BluetoothGattCount;
63    private static int CharacteristicCount;
64    private static int DescriptorCount;
65    private static int GattServerCallbackCount;
66    private static int GattServerCount;
67    private static int GattServiceCount;
68
69    public GattClientFacade(FacadeManager manager) {
70        super(manager);
71        mService = manager.getService();
72        mContext = mService.getApplicationContext();
73        mBluetoothAdapter =
74                MainThread.run(
75                        mService,
76                        new Callable<BluetoothAdapter>() {
77                            @Override
78                            public BluetoothAdapter call() throws Exception {
79                                return BluetoothAdapter.getDefaultAdapter();
80                            }
81                        });
82        mBluetoothManager = (BluetoothManager) mContext.getSystemService(Service.BLUETOOTH_SERVICE);
83        mEventFacade = manager.getReceiver(EventFacade.class);
84        mGattCallbackList = new HashMap<Integer, myBluetoothGattCallback>();
85        mCharacteristicList = new HashMap<Integer, BluetoothGattCharacteristic>();
86        mBluetoothGattList = new HashMap<Integer, BluetoothGatt>();
87        mDescriptorList = new HashMap<Integer, BluetoothGattDescriptor>();
88        mGattServiceList = new HashMap<Integer, BluetoothGattService>();
89        mBluetoothGattDiscoveredServicesList = new HashMap<Integer, List<BluetoothGattService>>();
90        mGattServerDiscoveredDevicesList = new HashMap<Integer, List<BluetoothDevice>>();
91    }
92
93    /**
94     * Create a BluetoothGatt connection
95     *
96     * @param index of the callback to start a connection on
97     * @param macAddress the mac address of the ble device
98     * @param autoConnect Whether to directly connect to the remote device (false) or to
99     *       automatically connect as soon as the remote device becomes available (true)
100     * @param opportunistic Whether this GATT client is opportunistic. An opportunistic GATT client
101     *                      does not hold a GATT connection. It automatically disconnects when no
102     *                      other GATT connections are active for the remote device.
103     * @param transport preferred transport for GATT connections to remote dual-mode devices
104     *       TRANSPORT_AUTO or TRANSPORT_BREDR or TRANSPORT_LE
105     * @return the index of the BluetoothGatt object
106     * @throws Exception
107     */
108    @Rpc(description = "Create a gatt connection")
109    public int gattClientConnectGatt(
110            @RpcParameter(name = "index") Integer index,
111            @RpcParameter(name = "macAddress") String macAddress,
112            @RpcParameter(name = "autoConnect") Boolean autoConnect,
113            @RpcParameter(name = "transport") Integer transport,
114            @RpcParameter(name = "opportunistic") Boolean opportunistic,
115            @RpcParameter(name = "phy") Integer phy)
116            throws Exception {
117        if (mGattCallbackList.get(index) != null) {
118            BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
119            if (phy == null) phy = BluetoothDevice.PHY_LE_1M;
120
121            BluetoothGatt mBluetoothGatt = device.connectGatt(mService.getApplicationContext(),
122                    autoConnect, mGattCallbackList.get(index), transport, opportunistic, phy, null);
123            BluetoothGattCount += 1;
124            mBluetoothGattList.put(BluetoothGattCount, mBluetoothGatt);
125            return BluetoothGattCount;
126        } else {
127            throw new Exception("Invalid index input:" + Integer.toString(index));
128        }
129    }
130
131    /**
132     * Trigger discovering of services on the BluetoothGatt object
133     *
134     * @param index The BluetoothGatt object index
135     * @return true, if the remote service discovery has been started
136     * @throws Exception
137     */
138    @Rpc(description = "Trigger discovering of services on the BluetoothGatt object")
139    public boolean gattClientDiscoverServices(@RpcParameter(name = "index") Integer index)
140            throws Exception {
141        if (mBluetoothGattList.get(index) != null) {
142            return mBluetoothGattList.get(index).discoverServices();
143        } else {
144            throw new Exception("Invalid index input:" + Integer.toString(index));
145        }
146    }
147
148    /**
149     * Trigger discovering of services by UUID on the BluetoothGatt object
150     *
151     * @param index The BluetoothGatt object index
152     * @param uuid service UUID
153     * @return true, if the remote service discovery has been started
154     * @throws Exception
155     */
156    @Rpc(description = "Trigger discovering of services on the BluetoothGatt object")
157    public boolean gattClientDiscoverServiceByUuid(@RpcParameter(name = "index") Integer index,
158            @RpcParameter(name = "uuid") String uuid) throws Exception {
159        BluetoothGatt gatt = mBluetoothGattList.get(index);
160        if (gatt != null) {
161            Object ret = gatt.getClass().getMethod("discoverServiceByUuid", UUID.class)
162                            .invoke(gatt, UUID.fromString(uuid));
163            return (Boolean) ret;
164        } else {
165            throw new Exception("Invalid index input:" + Integer.toString(index));
166        }
167    }
168
169
170    /**
171     * Get the services from the BluetoothGatt object
172     *
173     * @param index The BluetoothGatt object index
174     * @return a list of BluetoothGattServices
175     * @throws Exception
176     */
177    @Rpc(description = "Get the services from the BluetoothGatt object")
178    public List<BluetoothGattService> gattClientGetServices(
179            @RpcParameter(name = "index") Integer index) throws Exception {
180        if (mBluetoothGattList.get(index) != null) {
181            return mBluetoothGattList.get(index).getServices();
182        } else {
183            throw new Exception("Invalid index input:" + Integer.toString(index));
184        }
185    }
186
187    /**
188     * Abort reliable write of a bluetooth gatt
189     *
190     * @param index the bluetooth gatt index
191     * @throws Exception
192     */
193    @Rpc(description = "Abort reliable write of a bluetooth gatt")
194    public void gattClientAbortReliableWrite(@RpcParameter(name = "index") Integer index)
195            throws Exception {
196        if (mBluetoothGattList.get(index) != null) {
197            mBluetoothGattList.get(index).abortReliableWrite();
198        } else {
199            throw new Exception("Invalid index input:" + index);
200        }
201    }
202
203    /**
204     * Begin reliable write of a bluetooth gatt
205     *
206     * @param index the bluetooth gatt index
207     * @return
208     * @throws Exception
209     */
210    @Rpc(description = "Begin reliable write of a bluetooth gatt")
211    public boolean gattClientBeginReliableWrite(@RpcParameter(name = "index") Integer index)
212            throws Exception {
213        if (mBluetoothGattList.get(index) != null) {
214            return mBluetoothGattList.get(index).beginReliableWrite();
215        } else {
216            throw new Exception("Invalid index input:" + index);
217        }
218    }
219
220    /**
221     * Configure a bluetooth gatt's MTU
222     *
223     * @param index the bluetooth gatt index
224     * @param mtu the MTU to set
225     * @return
226     * @throws Exception
227     */
228    @Rpc(description = "true, if the new MTU value has been requested successfully")
229    public boolean gattClientRequestMtu(
230            @RpcParameter(name = "index") Integer index, @RpcParameter(name = "mtu") Integer mtu)
231            throws Exception {
232        if (mBluetoothGattList.get(index) != null) {
233            return mBluetoothGattList.get(index).requestMtu(mtu);
234        } else {
235            throw new Exception("Invalid index input:" + index);
236        }
237    }
238
239    /**
240     * Read the current transmitter PHY and receiver PHY of the connection.
241     *
242     * @param index the bluetooth gatt index
243     * @throws Exception
244     */
245    @Rpc(description = "Read PHY")
246    public void gattClientReadPhy(@RpcParameter(name = "index") Integer index) throws Exception {
247        if (mBluetoothGattList.get(index) != null) {
248            mBluetoothGattList.get(index).readPhy();
249        } else {
250            throw new Exception("Invalid index input:" + index);
251        }
252    }
253
254    /**
255     * Set the preferred connection PHY.
256     *
257     * @param index the bluetooth gatt index
258     * @throws Exception
259     */
260    @Rpc(description = "Set the preferred connection PHY")
261    public void gattClientSetPreferredPhy(@RpcParameter(name = "index") Integer index,
262            @RpcParameter(name = "txPhy") Integer txPhy,
263            @RpcParameter(name = "rxPhy") Integer rxPhy,
264            @RpcParameter(name = "txPhy") Integer phyOptions) throws Exception {
265        if (mBluetoothGattList.get(index) != null) {
266            mBluetoothGattList.get(index).setPreferredPhy(txPhy, rxPhy, phyOptions);
267        } else {
268            throw new Exception("Invalid index input:" + index);
269        }
270    }
271
272    /**
273     * Disconnect a bluetooth gatt
274     *
275     * @param index the bluetooth gatt index
276     * @throws Exception
277     */
278    @Rpc(description = "Disconnect a bluetooth gatt")
279    @RpcStopEvent("GattConnect")
280    public void gattClientDisconnect(@RpcParameter(name = "index") Integer index) throws Exception {
281        if (mBluetoothGattList.get(index) != null) {
282            mBluetoothGattList.get(index).disconnect();
283        } else {
284            throw new Exception("Invalid index input: " + index);
285        }
286    }
287
288    /**
289     * Close a bluetooth gatt object
290     *
291     * @param index the bluetooth gatt index
292     * @throws Exception
293     */
294    @Rpc(description = "Close a Bluetooth GATT object")
295    public void gattClientClose(@RpcParameter(name = "index") Integer index) throws Exception {
296        if (mBluetoothGattList.get(index) != null) {
297            mBluetoothGattList.get(index).close();
298        } else {
299            throw new Exception("Invalid index input: " + index);
300        }
301    }
302
303    /**
304     * Execute reliable write on a bluetooth gatt
305     *
306     * @param index the bluetooth gatt index
307     * @return true, if the request to execute the transaction has been sent
308     * @throws Exception
309     */
310    @Rpc(description = "Execute reliable write on a bluetooth gatt")
311    public boolean gattExecuteReliableWrite(@RpcParameter(name = "index") Integer index)
312            throws Exception {
313        if (mBluetoothGattList.get(index) != null) {
314            return mBluetoothGattList.get(index).executeReliableWrite();
315        } else {
316            throw new Exception("Invalid index input:" + index);
317        }
318    }
319
320    /**
321     * Get a list of Bluetooth Devices connnected to the bluetooth gatt
322     *
323     * @param index the bluetooth gatt index
324     * @return List of BluetoothDevice Objects
325     * @throws Exception
326     */
327    @Rpc(description = "Get a list of Bluetooth Devices connnected to the bluetooth gatt")
328    public List<BluetoothDevice> gattClientGetConnectedDevices(
329            @RpcParameter(name = "index") Integer index) throws Exception {
330        if (mBluetoothGattList.get(index) != null) {
331            return mBluetoothGattList.get(index).getConnectedDevices();
332        } else {
333            throw new Exception("Invalid index input:" + index);
334        }
335    }
336
337    /**
338     * Get the remote bluetooth device this GATT client targets to
339     *
340     * @param index the bluetooth gatt index
341     * @return the remote bluetooth device this gatt client targets to
342     * @throws Exception
343     */
344    @Rpc(description = "Get the remote bluetooth device this GATT client targets to")
345    public BluetoothDevice gattGetDevice(@RpcParameter(name = "index") Integer index)
346            throws Exception {
347        if (mBluetoothGattList.get(index) != null) {
348            return mBluetoothGattList.get(index).getDevice();
349        } else {
350            throw new Exception("Invalid index input:" + index);
351        }
352    }
353
354    /**
355     * Get the bluetooth devices matching input connection states
356     *
357     * @param index the bluetooth gatt index
358     * @param states the list of states to match
359     * @return The list of BluetoothDevice objects that match the states
360     * @throws Exception
361     */
362    @Rpc(description = "Get the bluetooth devices matching input connection states")
363    public List<BluetoothDevice> gattClientGetDevicesMatchingConnectionStates(
364            @RpcParameter(name = "index") Integer index, @RpcParameter(
365                name = "states") int[] states)
366            throws Exception {
367        if (mBluetoothGattList.get(index) != null) {
368            return mBluetoothGattList.get(index).getDevicesMatchingConnectionStates(states);
369        } else {
370            throw new Exception("Invalid index input:" + index);
371        }
372    }
373
374    /**
375     * Get the service from an input UUID
376     *
377     * @param index the bluetooth gatt index
378     * @return BluetoothGattService related to the bluetooth gatt
379     * @throws Exception
380     */
381    @Rpc(description = "Get the service from an input UUID")
382    public ArrayList<String> gattClientGetServiceUuidList(
383            @RpcParameter(name = "index") Integer index)
384            throws Exception {
385        if (mBluetoothGattList.get(index) != null) {
386            ArrayList<String> serviceUuidList = new ArrayList<String>();
387            for (BluetoothGattService service : mBluetoothGattList.get(index).getServices()) {
388                serviceUuidList.add(service.getUuid().toString());
389            }
390            return serviceUuidList;
391        } else {
392            throw new Exception("Invalid index input:" + index);
393        }
394    }
395
396    /**
397     * Reads the requested characteristic from the associated remote device.
398     *
399     * @deprecated Use {@link #gattClientReadCharacteristicByIndex(gattIndex,
400     *     discoveredServiceListIndex, serviceIndex, characteristicIndex)} instead.
401     * @param gattIndex the BluetoothGatt server accociated with the device
402     * @param discoveredServiceListIndex the index returned from the discovered services callback
403     * @param serviceIndex the service index of the discovered services
404     * @param characteristicUuid the characteristic uuid to read
405     * @return true, if the read operation was initiated successfully
406     * @throws Exception
407     */
408    @Rpc(description = "Reads the requested characteristic from the associated remote device.")
409    @Deprecated
410    public boolean gattClientReadCharacteristic(
411            @RpcParameter(name = "gattIndex") Integer gattIndex,
412            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
413            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
414            @RpcParameter(name = "characteristicUuid") String characteristicUuid) throws Exception {
415        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
416        if (bluetoothGatt == null) {
417            throw new Exception("Invalid gattIndex " + gattIndex);
418        }
419        List<BluetoothGattService> gattServiceList =
420                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
421        if (gattServiceList == null) {
422            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
423        }
424        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
425        if (gattService == null) {
426            throw new Exception("Invalid serviceIndex " + serviceIndex);
427        }
428        UUID cUuid = UUID.fromString(characteristicUuid);
429        BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
430        if (gattCharacteristic == null) {
431            throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
432        }
433        return bluetoothGatt.readCharacteristic(gattCharacteristic);
434    }
435
436    /**
437     * Reads the characteristic from the associated remote device.
438     *
439     * @param gattIndex the BluetoothGatt server accociated with the device
440     * @param uuid the characteristic uuid to read
441     * @return true, if the read operation was initiated successfully
442     * @throws Exception
443     */
444    @Rpc(description = "Reads the characteristic from the associated remote device.")
445    public boolean gattClientReadUsingCharacteristicUuid(
446            @RpcParameter(name = "gattIndex") Integer gattIndex,
447            @RpcParameter(name = "uuid") String uuid,
448            @RpcParameter(name = "startHandle") Integer startHandle,
449            @RpcParameter(name = "endHandle") Integer endHandle) throws Exception {
450        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
451        if (bluetoothGatt == null) {
452            throw new Exception("Invalid gattIndex " + gattIndex);
453        }
454        UUID cUuid = UUID.fromString(uuid);
455        return bluetoothGatt.readUsingCharacteristicUuid(cUuid, startHandle, endHandle);
456    }
457
458    /**
459     * Reads the requested characteristic from the associated remote device.
460     *
461     * @param gattIndex the BluetoothGatt server accociated with the device
462     * @param discoveredServiceListIndex the index returned from the discovered services callback
463     * @param serviceIndex the service index of the discovered services
464     * @param characteristicIndex the characteristic index
465     * @return true, if the read operation was initiated successfully
466     * @throws Exception
467     */
468    @Rpc(description = "Reads the requested characteristic from the associated remote device.")
469    public boolean gattClientReadCharacteristicByIndex(
470            @RpcParameter(name = "gattIndex") Integer gattIndex,
471            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
472            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
473            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex)
474            throws Exception {
475        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
476        if (bluetoothGatt == null) {
477            throw new Exception("Invalid gattIndex " + gattIndex);
478        }
479        List<BluetoothGattService> gattServiceList =
480                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
481        if (gattServiceList == null) {
482            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
483        }
484        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
485        if (gattService == null) {
486            throw new Exception("Invalid serviceIndex " + serviceIndex);
487        }
488        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
489        if (charList.get(characteristicIndex) == null) {
490            throw new Exception("Invalid characteristicIndex " + characteristicIndex);
491        }
492        return bluetoothGatt.readCharacteristic(charList.get(characteristicIndex));
493    }
494
495    /**
496     * Reads the requested characteristic from the associated remote device by instance id.
497     *
498     * @param gattIndex the BluetoothGatt server accociated with the device
499     * @param discoveredServiceListIndex the index returned from the discovered services callback
500     * @return true, if the read operation was initiated successfully
501     * @throws Exception
502     */
503    @Rpc(description = "Reads the requested characteristic from the associated remote "
504            + "device by instance id.")
505    public boolean gattClientReadCharacteristicByInstanceId(
506            @RpcParameter(name = "gattIndex") Integer gattIndex,
507            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
508            @RpcParameter(name = "characteristicInstanceId") Integer characteristicInstanceId)
509            throws Exception {
510        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
511        if (bluetoothGatt == null) {
512            throw new Exception("Invalid gattIndex " + gattIndex);
513        }
514        List<BluetoothGattService> gattServiceList =
515                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
516        if (gattServiceList == null) {
517            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
518        }
519        for (BluetoothGattService mGattService : gattServiceList) {
520            List<BluetoothGattCharacteristic> charList = mGattService.getCharacteristics();
521            for (BluetoothGattCharacteristic mGattChar : charList) {
522                if (mGattChar.getInstanceId() == characteristicInstanceId) {
523                    Log.i("Found Characteristic to read. instanceId: "
524                        + Integer.toString(characteristicInstanceId)
525                        + " UUID: " + mGattChar.getUuid().toString());
526                    return bluetoothGatt.readCharacteristic(mGattChar);
527                }
528            }
529        }
530        Log.e("Failed to find Characteristic with instanceId: " + Integer.toString(
531            characteristicInstanceId));
532        return false;
533    }
534
535    /**
536     * Writes the requested characteristic from the associated remote device by instance id.
537     *
538     * @param gattIndex the BluetoothGatt server accociated with the device
539     * @param discoveredServiceListIndex the index returned from the discovered services callback
540     * @param characteristicInstanceId the integer instance id of the Characteristic to write to
541     * @param value the value to write to the characteristic
542     * @return true, if the read operation was initiated successfully
543     * @throws Exception
544     */
545    @Rpc(description = "Writes the requested characteristic from the associated remote "
546            + "device by instance id.")
547    public boolean gattClientWriteDescriptorByInstanceId(
548            @RpcParameter(name = "gattIndex") Integer gattIndex,
549            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
550            @RpcParameter(name = "descriptorInstanceId") Integer descriptorInstanceId,
551            @RpcParameter(name = "value") byte[] value)
552            throws Exception {
553        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
554        if (bluetoothGatt == null) {
555            throw new Exception("Invalid gattIndex " + gattIndex);
556        }
557        List<BluetoothGattService> gattServiceList =
558                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
559        if (gattServiceList == null) {
560            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
561        }
562        for (BluetoothGattService mGattService : gattServiceList) {
563            List<BluetoothGattCharacteristic> charList = mGattService.getCharacteristics();
564            for (BluetoothGattCharacteristic mGattChar : charList) {
565                List<BluetoothGattDescriptor> descList = mGattChar.getDescriptors();
566                for (BluetoothGattDescriptor mGattDesc : descList) {
567                    if (mGattDesc.getInstanceId() == descriptorInstanceId) {
568                        mGattDesc.setValue(value);
569                        Log.i("Found Descriptor to write. instanceId: "
570                            + Integer.toString(descriptorInstanceId)
571                            + " UUID: " + mGattDesc.getUuid().toString());
572                        return bluetoothGatt.writeDescriptor(mGattDesc);
573                    }
574                }
575            }
576        }
577        Log.e("Failed to find Descriptor with instanceId: " + Integer.toString(
578            descriptorInstanceId));
579        return false;
580    }
581
582    /**
583     * Writes the requested characteristic from the associated remote device by instance id.
584     *
585     * @param gattIndex the BluetoothGatt server accociated with the device
586     * @param discoveredServiceListIndex the index returned from the discovered services callback
587     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
588     * @param value the value to write to the characteristic
589     * @return true, if the read operation was initiated successfully
590     * @throws Exception
591     */
592    @Rpc(description = "Writes the requested characteristic from the associated remote "
593            + "device by instance id.")
594    public boolean gattClientWriteCharacteristicByInstanceId(
595            @RpcParameter(name = "gattIndex") Integer gattIndex,
596            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
597            @RpcParameter(name = "characteristicInstanceId") Integer characteristicInstanceId,
598            @RpcParameter(name = "value") byte[] value)
599            throws Exception {
600        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
601        if (bluetoothGatt == null) {
602            throw new Exception("Invalid gattIndex " + gattIndex);
603        }
604        List<BluetoothGattService> gattServiceList =
605                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
606        if (gattServiceList == null) {
607            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
608        }
609        for (BluetoothGattService mGattService : gattServiceList) {
610            List<BluetoothGattCharacteristic> charList = mGattService.getCharacteristics();
611            for (BluetoothGattCharacteristic mGattChar : charList) {
612                if (mGattChar.getInstanceId() == characteristicInstanceId) {
613                    mGattChar.setValue(value);
614                    Log.i("Found Characteristic to write. instanceId: "
615                        + Integer.toString(characteristicInstanceId)
616                        + " UUID: " + mGattChar.getUuid().toString());
617                    return bluetoothGatt.writeCharacteristic(mGattChar);
618                }
619            }
620        }
621        Log.e("Failed to find Characteristic with instanceId: " + Integer.toString(
622            characteristicInstanceId));
623        return false;
624    }
625
626    /**
627     * Writes the requested characteristic in which write is not permitted. For conformance tests
628     * only.
629     *
630     * @param gattIndex the BluetoothGatt server accociated with the device
631     * @param discoveredServiceListIndex the index returned from the discovered services callback
632     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
633     * @param value the value to write to the characteristic
634     * @return true, if the read operation was initiated successfully
635     * @throws Exception
636     */
637    @Rpc(description = "Writes the requested characteristic from the associated remote "
638            + "device by instance id.")
639    public boolean gattClientModifyAccessAndWriteCharacteristicByInstanceId(
640            @RpcParameter(name = "gattIndex") Integer gattIndex,
641            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
642            @RpcParameter(name = "characteristicInstanceId") Integer characteristicInstanceId,
643            @RpcParameter(name = "value") byte[] value)
644            throws Exception {
645        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
646        if (bluetoothGatt == null) {
647            throw new Exception("Invalid gattIndex " + gattIndex);
648        }
649        List<BluetoothGattService> gattServiceList =
650                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
651        if (gattServiceList == null) {
652            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
653        }
654        for (BluetoothGattService mGattService : gattServiceList) {
655            List<BluetoothGattCharacteristic> charList = mGattService.getCharacteristics();
656            for (BluetoothGattCharacteristic mGattChar : charList) {
657                if (mGattChar.getInstanceId() == characteristicInstanceId) {
658                    Log.i("Found Characteristic to write. instanceId: "
659                        + Integer.toString(characteristicInstanceId)
660                        + " UUID: " + mGattChar.getUuid().toString());
661                    BluetoothGattCharacteristic modChar = new BluetoothGattCharacteristic(
662                        mGattChar.getUuid(), 0x08, 0x10);
663                    modChar.setInstanceId(mGattChar.getInstanceId());
664                    mGattService.addCharacteristic(modChar);
665                    modChar.setValue(value);
666                    return bluetoothGatt.writeCharacteristic(modChar);
667                }
668            }
669        }
670        Log.e("Failed to find Characteristic with instanceId: " + Integer.toString(
671            characteristicInstanceId));
672        return false;
673    }
674
675    /**
676     * Writes the requested descriptor in which write is not permitted. For conformance tests only.
677     *
678     * @param gattIndex the BluetoothGatt server accociated with the device
679     * @param discoveredServiceListIndex the index returned from the discovered services callback
680     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
681     * @param value the value to write to the characteristic
682     * @return true, if the read operation was initiated successfully
683     * @throws Exception
684     */
685    @Rpc(description = "Writes a Characteristic with an invalid instanceId to each service.")
686    public boolean gattClientWriteInvalidCharacteristicByInstanceId(
687            @RpcParameter(name = "gattIndex") Integer gattIndex,
688            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
689            @RpcParameter(name = "instanceId") Integer instanceId,
690            @RpcParameter(name = "value") byte[] value)
691            throws Exception {
692        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
693        if (bluetoothGatt == null) {
694            throw new Exception("Invalid gattIndex " + gattIndex);
695        }
696        List<BluetoothGattService> gattServiceList =
697                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
698        if (gattServiceList == null) {
699            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
700        }
701        for (BluetoothGattService mGattService : gattServiceList) {
702            BluetoothGattCharacteristic invalidHandleChar = new BluetoothGattCharacteristic(
703                UUID.fromString("aa7edd5a-4d1d-4f0e-883a-d145616a1630"), 0x08, 0x10);
704            invalidHandleChar.setInstanceId(instanceId);
705            mGattService.addCharacteristic(invalidHandleChar);
706            invalidHandleChar.setValue(value);
707            //todo: this used to be return bluetoothGatt. Retest with and without return
708            bluetoothGatt.writeCharacteristic(invalidHandleChar);
709        }
710        return true;
711    }
712
713    /**
714     * Writes the requested characteristic in which write is not permitted. For conformance tests
715     * only.
716     *
717     * @param gattIndex the BluetoothGatt server accociated with the device
718     * @param discoveredServiceListIndex the index returned from the discovered services callback
719     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
720     * @param value the value to write to the characteristic
721     * @return true, if the read operation was initiated successfully
722     * @throws Exception
723     */
724    @Rpc(description = "Read the requested characteristic from the associated remote "
725            + "device by instance id.")
726    public boolean gattClientModifyAccessAndReadCharacteristicByInstanceId(
727            @RpcParameter(name = "gattIndex") Integer gattIndex,
728            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
729            @RpcParameter(name = "characteristicInstanceId") Integer characteristicInstanceId)
730            throws Exception {
731        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
732        if (bluetoothGatt == null) {
733            throw new Exception("Invalid gattIndex " + gattIndex);
734        }
735        List<BluetoothGattService> gattServiceList =
736                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
737        if (gattServiceList == null) {
738            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
739        }
740        for (BluetoothGattService mGattService : gattServiceList) {
741            List<BluetoothGattCharacteristic> charList = mGattService.getCharacteristics();
742            for (BluetoothGattCharacteristic mGattChar : charList) {
743                if (mGattChar.getInstanceId() == characteristicInstanceId) {
744                    Log.i("Found Characteristic to read. instanceId: "
745                        + Integer.toString(characteristicInstanceId)
746                        + " UUID: " + mGattChar.getUuid().toString());
747                    BluetoothGattCharacteristic modChar = new BluetoothGattCharacteristic(
748                        mGattChar.getUuid(), 0x02, 0x01);
749                    modChar.setInstanceId(mGattChar.getInstanceId());
750                    mGattService.addCharacteristic(modChar);
751                    return bluetoothGatt.readCharacteristic(modChar);
752                }
753            }
754        }
755        Log.e("Failed to find Characteristic with instanceId: " + Integer.toString(
756            characteristicInstanceId));
757        return false;
758    }
759
760    /**
761     * Writes the requested descriptor in which write is not permitted. For conformance tests only.
762     *
763     * @param gattIndex the BluetoothGatt server accociated with the device
764     * @param discoveredServiceListIndex the index returned from the discovered services callback
765     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
766     * @param value the value to write to the characteristic
767     * @return true, if the read operation was initiated successfully
768     * @throws Exception
769     */
770    @Rpc(description = "Read a Characteristic with an invalid instanceId to each service.")
771    public boolean gattClientReadInvalidCharacteristicByInstanceId(
772            @RpcParameter(name = "gattIndex") Integer gattIndex,
773            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
774            @RpcParameter(name = "characteristicInstanceId") Integer characteristicInstanceId)
775            throws Exception {
776        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
777        if (bluetoothGatt == null) {
778            throw new Exception("Invalid gattIndex " + gattIndex);
779        }
780        List<BluetoothGattService> gattServiceList =
781                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
782        if (gattServiceList == null) {
783            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
784        }
785        for (BluetoothGattService mGattService : gattServiceList) {
786            BluetoothGattCharacteristic invalidHandleChar = new BluetoothGattCharacteristic(
787                UUID.fromString("aa7edd5a-4d1d-4f0e-883a-d145616a1630"), 0x02, 0x01);
788            invalidHandleChar.setInstanceId(characteristicInstanceId);
789            mGattService.addCharacteristic(invalidHandleChar);
790            bluetoothGatt.readCharacteristic(invalidHandleChar);
791        }
792        return true;
793    }
794
795    /**
796     * Writes the requested descriptor in which write is not permitted. For conformance tests
797     * only.
798     *
799     * @param gattIndex the BluetoothGatt server accociated with the device
800     * @param discoveredServiceListIndex the index returned from the discovered services callback
801     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
802     * @param value the value to write to the characteristic
803     * @return true, if the read operation was initiated successfully
804     * @throws Exception
805     */
806    @Rpc(description = "Writes the requested descriptor from the associated remote "
807            + "device by instance id.")
808    public boolean gattClientModifyAccessAndWriteDescriptorByInstanceId(
809            @RpcParameter(name = "gattIndex") Integer gattIndex,
810            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
811            @RpcParameter(name = "descriptorInstanceId") Integer descriptorInstanceId,
812            @RpcParameter(name = "value") byte[] value)
813            throws Exception {
814        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
815        if (bluetoothGatt == null) {
816            throw new Exception("Invalid gattIndex " + gattIndex);
817        }
818        List<BluetoothGattService> gattServiceList =
819                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
820        if (gattServiceList == null) {
821            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
822        }
823        for (BluetoothGattService mGattService : gattServiceList) {
824            List<BluetoothGattCharacteristic> charList = mGattService.getCharacteristics();
825            for (BluetoothGattCharacteristic mGattChar : charList) {
826                for (BluetoothGattDescriptor mGattDesc : mGattChar.getDescriptors()) {
827                    if (mGattDesc.getInstanceId() == descriptorInstanceId) {
828                        Log.i("Found Descriptor to write. instanceId: "
829                            + Integer.toString(descriptorInstanceId)
830                            + " UUID: " + mGattChar.getUuid().toString());
831                        BluetoothGattDescriptor modDesc = new BluetoothGattDescriptor(
832                            mGattDesc.getUuid(), 0x10);
833                        modDesc.setInstanceId(descriptorInstanceId);
834                        mGattChar.addDescriptor(modDesc);
835                        modDesc.setValue(value);
836                        return bluetoothGatt.writeDescriptor(modDesc);
837                    }
838                }
839            }
840        }
841        Log.e("Failed to find Descriptor with instanceId: " + Integer.toString(
842            descriptorInstanceId));
843        return false;
844    }
845
846    /**
847     * Writes the requested descriptor in which write is not permitted. For conformance tests only.
848     *
849     * @param gattIndex the BluetoothGatt server accociated with the device
850     * @param discoveredServiceListIndex the index returned from the discovered services callback
851     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
852     * @param value the value to write to the characteristic
853     * @return true, if the read operation was initiated successfully
854     * @throws Exception
855     */
856    @Rpc(description = "Writes a Characteristic with an invalid instanceId to each service.")
857    public boolean gattClientWriteInvalidDescriptorByInstanceId(
858            @RpcParameter(name = "gattIndex") Integer gattIndex,
859            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
860            @RpcParameter(name = "instanceId") Integer instanceId,
861            @RpcParameter(name = "value") byte[] value)
862            throws Exception {
863        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
864        if (bluetoothGatt == null) {
865            throw new Exception("Invalid gattIndex " + gattIndex);
866        }
867        List<BluetoothGattService> gattServiceList =
868                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
869        if (gattServiceList == null) {
870            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
871        }
872        for (BluetoothGattService mGattService : gattServiceList) {
873            for (BluetoothGattCharacteristic mGattChar : mGattService.getCharacteristics()) {
874                BluetoothGattDescriptor invalidHandleDesc = new BluetoothGattDescriptor(
875                    UUID.fromString("aa7edd5a-4d1d-4f0e-883a-d145616a1630"), 0x10);
876                invalidHandleDesc.setInstanceId(instanceId);
877                mGattChar.addDescriptor(invalidHandleDesc);
878                invalidHandleDesc.setValue(value);
879                bluetoothGatt.writeDescriptor(invalidHandleDesc);
880            }
881        }
882        return true;
883    }
884
885    /**
886     * Writes the requested descriptor in which write is not permitted. For conformance tests
887     * only.
888     *
889     * @param gattIndex the BluetoothGatt server accociated with the device
890     * @param discoveredServiceListIndex the index returned from the discovered services callback
891     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
892     * @param value the value to write to the characteristic
893     * @return true, if the read operation was initiated successfully
894     * @throws Exception
895     */
896    @Rpc(description = "Read the requested descriptor from the associated remote "
897            + "device by instance id.")
898    public boolean gattClientModifyAccessAndReadDescriptorByInstanceId(
899            @RpcParameter(name = "gattIndex") Integer gattIndex,
900            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
901            @RpcParameter(name = "descriptorInstanceId") Integer descriptorInstanceId)
902            throws Exception {
903        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
904        if (bluetoothGatt == null) {
905            throw new Exception("Invalid gattIndex " + gattIndex);
906        }
907        List<BluetoothGattService> gattServiceList =
908                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
909        if (gattServiceList == null) {
910            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
911        }
912        for (BluetoothGattService mGattService : gattServiceList) {
913            List<BluetoothGattCharacteristic> charList = mGattService.getCharacteristics();
914            for (BluetoothGattCharacteristic mGattChar : charList) {
915                for (BluetoothGattDescriptor mGattDesc : mGattChar.getDescriptors()) {
916                    if (mGattDesc.getInstanceId() == descriptorInstanceId) {
917                        Log.i("Found Descriptor to read. instanceId: "
918                            + Integer.toString(descriptorInstanceId)
919                            + " UUID: " + mGattDesc.getUuid().toString());
920                        BluetoothGattDescriptor modDesc = new BluetoothGattDescriptor(
921                            mGattDesc.getUuid(), 0x01);
922                        modDesc.setInstanceId(descriptorInstanceId);
923                        mGattChar.addDescriptor(modDesc);
924                        return bluetoothGatt.readDescriptor(modDesc);
925                    }
926                }
927            }
928        }
929        Log.e("Failed to find Descriptor with instanceId: " + Integer.toString(
930            descriptorInstanceId));
931        return false;
932    }
933
934    /**
935     * Writes the requested descriptor in which write is not permitted. For conformance tests only.
936     *
937     * @param gattIndex the BluetoothGatt server accociated with the device
938     * @param discoveredServiceListIndex the index returned from the discovered services callback
939     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
940     * @param value the value to write to the characteristic
941     * @return true, if the read operation was initiated successfully
942     * @throws Exception
943     */
944    @Rpc(description = "Read a Characteristic with an invalid instanceId to each service.")
945    public boolean gattClientReadInvalidDescriptorByInstanceId(
946            @RpcParameter(name = "gattIndex") Integer gattIndex,
947            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
948            @RpcParameter(name = "descriptorInstanceId") Integer descriptorInstanceId)
949            throws Exception {
950        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
951        if (bluetoothGatt == null) {
952            throw new Exception("Invalid gattIndex " + gattIndex);
953        }
954        List<BluetoothGattService> gattServiceList =
955                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
956        if (gattServiceList == null) {
957            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
958        }
959        for (BluetoothGattService mGattService : gattServiceList) {
960            for (BluetoothGattCharacteristic mGattChar : mGattService.getCharacteristics()) {
961                BluetoothGattDescriptor invalidHandleDesc = new BluetoothGattDescriptor(
962                    UUID.fromString("aa7edd5a-4d1d-4f0e-883a-d145616a1630"), 0x01);
963                invalidHandleDesc.setInstanceId(descriptorInstanceId);
964                mGattChar.addDescriptor(invalidHandleDesc);
965                bluetoothGatt.readDescriptor(invalidHandleDesc);
966            }
967        }
968        return true;
969    }
970
971    /**
972     * Writes the requested characteristic in which write is not permitted. For conformance tests
973     * only.
974     *
975     * @param gattIndex the BluetoothGatt server accociated with the device
976     * @param discoveredServiceListIndex the index returned from the discovered services callback
977     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
978     * @param value the value to write to the characteristic
979     * @return true, if the read operation was initiated successfully
980     * @throws Exception
981     */
982    @Rpc(description = "Read the requested characteristic from the associated remote "
983            + "device by uuid.")
984    public boolean gattClientModifyAccessAndReadCharacteristicByUuidAndInstanceId(
985            @RpcParameter(name = "gattIndex") Integer gattIndex,
986            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
987            @RpcParameter(name = "characteristicInstanceId") Integer characteristicInstanceId,
988            @RpcParameter(name = "characteristicUuid") String characteristicUuid)
989            throws Exception {
990        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
991        if (bluetoothGatt == null) {
992            throw new Exception("Invalid gattIndex " + gattIndex);
993        }
994        List<BluetoothGattService> gattServiceList =
995                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
996        if (gattServiceList == null) {
997            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
998        }
999        for (BluetoothGattService mGattService : gattServiceList) {
1000            List<BluetoothGattCharacteristic> charList = mGattService.getCharacteristics();
1001            for (BluetoothGattCharacteristic mGattChar : charList) {
1002                if (mGattChar.getUuid().toString().equalsIgnoreCase(characteristicUuid) &&
1003                        mGattChar.getInstanceId() == characteristicInstanceId) {
1004                    Log.i("Found Characteristic to read. UUID: " + mGattChar.getUuid().toString());
1005                    BluetoothGattCharacteristic modChar = new BluetoothGattCharacteristic(
1006                        mGattChar.getUuid(), 0x02, 0x01);
1007                    modChar.setInstanceId(characteristicInstanceId);
1008                    mGattService.addCharacteristic(modChar);
1009                    bluetoothGatt.readCharacteristic(modChar);
1010                }
1011            }
1012        }
1013        return true;
1014    }
1015
1016    /**
1017     * Writes the requested descriptor in which write is not permitted. For conformance tests only.
1018     *
1019     * @param gattIndex the BluetoothGatt server accociated with the device
1020     * @param discoveredServiceListIndex the index returned from the discovered services callback
1021     * @param descriptorInstanceId the integer instance id of the Characteristic to write to
1022     * @param value the value to write to the characteristic
1023     * @return true, if the read operation was initiated successfully
1024     * @throws Exception
1025     */
1026    @Rpc(description = "Read a Characteristic with an invalid Uuid to each service.")
1027    public boolean gattClientReadInvalidCharacteristicByUuidAndInstanceId(
1028            @RpcParameter(name = "gattIndex") Integer gattIndex,
1029            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1030            @RpcParameter(name = "characteristicUuid") String characteristicUuid)
1031            throws Exception {
1032        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1033        if (bluetoothGatt == null) {
1034            throw new Exception("Invalid gattIndex " + gattIndex);
1035        }
1036        List<BluetoothGattService> gattServiceList =
1037                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1038        if (gattServiceList == null) {
1039            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1040        }
1041        for (BluetoothGattService mGattService : gattServiceList) {
1042            BluetoothGattCharacteristic invalidHandleChar = new BluetoothGattCharacteristic(
1043                UUID.fromString(characteristicUuid), 0x02, 0x01);
1044            mGattService.addCharacteristic(invalidHandleChar);
1045            bluetoothGatt.readCharacteristic(invalidHandleChar);
1046        }
1047        return true;
1048    }
1049
1050    /**
1051     * /** Reads the value for a given descriptor from the associated remote device
1052     *
1053     * @deprecated Use {@link #gattClientReadDescriptorByIndex(
1054     * gattIndex, discoveredServiceListIndex, serviceIndex, characteristicIndex, descriptorIndex)}
1055     * instead.
1056     * @param gattIndex - the gatt index to use
1057     * @param discoveredServiceListIndex - the discvered serivice list index
1058     * @param serviceIndex - the servce index of the discoveredServiceListIndex
1059     * @param characteristicUuid - the characteristic uuid in which the descriptor is
1060     * @param descriptorUuid - the descriptor uuid to read
1061     * @return
1062     * @throws Exception
1063     */
1064    @Deprecated
1065    @Rpc(description = "Reads the value for a given descriptor from the associated remote device")
1066    public boolean gattClientReadDescriptor(
1067            @RpcParameter(name = "gattIndex") Integer gattIndex,
1068            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1069            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1070            @RpcParameter(name = "characteristicUuid") String characteristicUuid,
1071            @RpcParameter(name = "descriptorUuid") String descriptorUuid) throws Exception {
1072        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1073        if (bluetoothGatt == null) {
1074            throw new Exception("Invalid gattIndex " + gattIndex);
1075        }
1076        List<BluetoothGattService> gattServiceList = mBluetoothGattDiscoveredServicesList.get(
1077                      discoveredServiceListIndex);
1078        if (gattServiceList == null) {
1079            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1080        }
1081        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
1082        if (gattService == null) {
1083            throw new Exception("Invalid serviceIndex " + serviceIndex);
1084        }
1085        UUID cUuid = UUID.fromString(characteristicUuid);
1086        BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
1087        if (gattCharacteristic == null) {
1088            throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
1089        }
1090        UUID dUuid = UUID.fromString(descriptorUuid);
1091        BluetoothGattDescriptor gattDescriptor = gattCharacteristic.getDescriptor(dUuid);
1092        if (gattDescriptor == null) {
1093            throw new Exception("Invalid descriptor uuid: " + descriptorUuid);
1094        }
1095        return bluetoothGatt.readDescriptor(gattDescriptor);
1096    }
1097
1098
1099    /**
1100     * /** Reads the value for a given descriptor from the associated remote device
1101     *
1102     * @param gattIndex - the gatt index to use
1103     * @param discoveredServiceListIndex - the discvered serivice list index
1104     * @param serviceIndex - the servce index of the discoveredServiceListIndex
1105     * @param characteristicIndex - the characteristic index
1106     * @param descriptorIndex - the descriptor index to read
1107     * @return
1108     * @throws Exception
1109     */
1110    @Rpc(description = "Reads the value for a given descriptor from the associated remote device")
1111    public boolean gattClientReadDescriptorByIndex(
1112            @RpcParameter(name = "gattIndex") Integer gattIndex,
1113            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1114            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1115            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex,
1116            @RpcParameter(name = "descriptorIndex") Integer descriptorIndex)
1117            throws Exception {
1118        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1119        if (bluetoothGatt == null) {
1120            throw new Exception("Invalid gattIndex " + gattIndex);
1121        }
1122        List<BluetoothGattService> gattServiceList =
1123                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1124        if (gattServiceList == null) {
1125            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1126        }
1127        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
1128        if (gattService == null) {
1129            throw new Exception("Invalid serviceIndex " + serviceIndex);
1130        }
1131        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
1132        if (charList.get(characteristicIndex) == null) {
1133            throw new Exception("Invalid characteristicIndex " + characteristicIndex);
1134        }
1135        BluetoothGattCharacteristic gattCharacteristic = charList.get(characteristicIndex);
1136        List<BluetoothGattDescriptor> descList = gattCharacteristic.getDescriptors();
1137        if (descList.get(descriptorIndex) == null) {
1138            throw new Exception("Invalid descriptorIndex " + descriptorIndex);
1139        }
1140        return bluetoothGatt.readDescriptor(descList.get(descriptorIndex));
1141    }
1142
1143    /**
1144     * Write the value of a given descriptor to the associated remote device
1145     *
1146     * @deprecated Use {@link #gattClientWriteDescriptorByIndex(
1147     * gattIndex, discoveredServiceListIndex, serviceIndex, characteristicIndex, descriptorIndex)}
1148     * instead.
1149     * @param index the bluetooth gatt index
1150     * @param serviceIndex the service index to write to
1151     * @param characteristicUuid the uuid where the descriptor lives
1152     * @param descriptorIndex the descriptor index
1153     * @return true, if the write operation was initiated successfully
1154     * @throws Exception
1155     */
1156    @Deprecated
1157    @Rpc(description = "Write the value of a given descriptor to the associated remote device")
1158    public boolean gattClientWriteDescriptor(
1159            @RpcParameter(name = "gattIndex") Integer gattIndex,
1160            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1161            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1162            @RpcParameter(name = "characteristicUuid") String characteristicUuid,
1163            @RpcParameter(name = "descriptorUuid") String descriptorUuid) throws Exception {
1164        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1165        if (bluetoothGatt == null) {
1166            throw new Exception("Invalid gattIndex " + gattIndex);
1167        }
1168        List<BluetoothGattService> discoveredServiceList =
1169                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1170        if (discoveredServiceList == null) {
1171            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1172        }
1173        BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
1174        if (gattService == null) {
1175            throw new Exception("Invalid serviceIndex " + serviceIndex);
1176        }
1177        UUID cUuid = UUID.fromString(characteristicUuid);
1178        BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
1179        if (gattCharacteristic == null) {
1180            throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
1181        }
1182        UUID dUuid = UUID.fromString(descriptorUuid);
1183        BluetoothGattDescriptor gattDescriptor = gattCharacteristic.getDescriptor(dUuid);
1184        if (gattDescriptor == null) {
1185            throw new Exception("Invalid descriptor uuid: " + descriptorUuid);
1186        }
1187        return bluetoothGatt.writeDescriptor(gattDescriptor);
1188    }
1189
1190    /**
1191     * Write the value of a given descriptor to the associated remote device
1192     *
1193     * @param index the bluetooth gatt index
1194     * @param serviceIndex the service index to write to
1195     * @param characteristicIndex the characteristic index to write to
1196     * @param descriptorIndex the descriptor index to write to
1197     * @return true, if the write operation was initiated successfully
1198     * @throws Exception
1199     */
1200    @Rpc(description = "Write the value of a given descriptor to the associated remote device")
1201    public boolean gattClientWriteDescriptorByIndex(
1202            @RpcParameter(name = "gattIndex") Integer gattIndex,
1203            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1204            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1205            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex,
1206            @RpcParameter(name = "descriptorIndex") Integer descriptorIndex)
1207            throws Exception {
1208        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1209        if (bluetoothGatt == null) {
1210            throw new Exception("Invalid gattIndex " + gattIndex);
1211        }
1212        List<BluetoothGattService> gattServiceList =
1213                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1214        if (gattServiceList == null) {
1215            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1216        }
1217        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
1218        if (gattService == null) {
1219            throw new Exception("Invalid serviceIndex " + serviceIndex);
1220        }
1221        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
1222        if (charList.get(characteristicIndex) == null) {
1223            throw new Exception("Invalid characteristicIndex " + characteristicIndex);
1224        }
1225        BluetoothGattCharacteristic gattCharacteristic = charList.get(characteristicIndex);
1226        List<BluetoothGattDescriptor> descList = gattCharacteristic.getDescriptors();
1227        if (descList.get(descriptorIndex) == null) {
1228            throw new Exception("Invalid descriptorIndex " + descriptorIndex);
1229        }
1230        return bluetoothGatt.writeDescriptor(descList.get(descriptorIndex));
1231    }
1232
1233    /**
1234     * Write the value to a discovered descriptor.
1235     *
1236     * @deprecated Use {@link #gattClientDescriptorSetValueByIndex(
1237     *  gattIndex, discoveredServiceListIndex, serviceIndex, characteristicIndex, descriptorIndex,
1238     *  value)} instead.
1239     * @param gattIndex - the gatt index to use
1240     * @param discoveredServiceListIndex - the discovered service list index
1241     * @param serviceIndex - the service index of the discoveredServiceListIndex
1242     * @param characteristicUuid - the characteristic uuid in which the descriptor is
1243     * @param descriptorUuid - the descriptor uuid to read
1244     * @param value - the value to set the descriptor to
1245     * @return true is the value was set to the descriptor
1246     * @throws Exception
1247     */
1248    @Deprecated
1249    @Rpc(description = "Write the value of a given descriptor to the associated remote device")
1250    public boolean gattClientDescriptorSetValue(
1251            @RpcParameter(name = "gattIndex") Integer gattIndex,
1252            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1253            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1254            @RpcParameter(name = "characteristicUuid") String characteristicUuid,
1255            @RpcParameter(name = "descriptorUuid") String descriptorUuid,
1256            @RpcParameter(name = "value") byte[] value) throws Exception {
1257        if (mBluetoothGattList.get(gattIndex) == null) {
1258            throw new Exception("Invalid gattIndex " + gattIndex);
1259        }
1260        List<BluetoothGattService> discoveredServiceList =
1261                  mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1262        if (discoveredServiceList == null) {
1263            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1264        }
1265        BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
1266        if (gattService == null) {
1267            throw new Exception("Invalid serviceIndex " + serviceIndex);
1268        }
1269        UUID cUuid = UUID.fromString(characteristicUuid);
1270        BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
1271        if (gattCharacteristic == null) {
1272            throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
1273        }
1274        UUID dUuid = UUID.fromString(descriptorUuid);
1275        BluetoothGattDescriptor gattDescriptor = gattCharacteristic.getDescriptor(dUuid);
1276        if (gattDescriptor == null) {
1277            throw new Exception("Invalid descriptor uuid: " + descriptorUuid);
1278        }
1279        return gattDescriptor.setValue(value);
1280    }
1281
1282    /**
1283     * Write the value to a discovered descriptor.
1284     *
1285     * @param gattIndex - the gatt index to use
1286     * @param discoveredServiceListIndex - the discovered service list index
1287     * @param serviceIndex - the service index of the discoveredServiceListIndex
1288     * @param characteristicIndex - the characteristic index
1289     * @param descriptorIndex - the descriptor index to set
1290     * @param value - the value to set the descriptor to
1291     * @return true is the value was set to the descriptor
1292     * @throws Exception
1293     */
1294    @Rpc(description = "Write the value of a given descriptor to the associated remote device")
1295    public boolean gattClientDescriptorSetValueByIndex(
1296            @RpcParameter(name = "gattIndex") Integer gattIndex,
1297            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1298            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1299            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex,
1300            @RpcParameter(name = "descriptorIndex") Integer descriptorIndex,
1301            @RpcParameter(name = "value") byte[] value)
1302            throws Exception {
1303        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1304        if (bluetoothGatt == null) {
1305            throw new Exception("Invalid gattIndex " + gattIndex);
1306        }
1307        List<BluetoothGattService> gattServiceList =
1308                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1309        if (gattServiceList == null) {
1310            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1311        }
1312        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
1313        if (gattService == null) {
1314            throw new Exception("Invalid serviceIndex " + serviceIndex);
1315        }
1316        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
1317        if (charList.get(characteristicIndex) == null) {
1318            throw new Exception("Invalid characteristicIndex " + characteristicIndex);
1319        }
1320        BluetoothGattCharacteristic gattCharacteristic = charList.get(characteristicIndex);
1321        List<BluetoothGattDescriptor> descList = gattCharacteristic.getDescriptors();
1322        if (descList.get(descriptorIndex) == null) {
1323            throw new Exception("Invalid descriptorIndex " + descriptorIndex);
1324        }
1325        return descList.get(descriptorIndex).setValue(value);
1326    }
1327
1328
1329    /**
1330     * Write the value of a given characteristic to the associated remote device
1331     *
1332     * @deprecated Use {@link #gattClientWriteCharacteristicByIndex(
1333     *  gattIndex, discoveredServiceListIndex, serviceIndex, characteristicIndex)} instead.
1334     * @param index the bluetooth gatt index
1335     * @param serviceIndex the service where the characteristic lives
1336     * @param characteristicUuid the characteristic uuid to write to
1337     * @return true, if the write operation was successful
1338     * @throws Exception
1339     */
1340    @Deprecated
1341    @Rpc(description = "Write the value of a given characteristic to the associated remote device")
1342    public boolean gattClientWriteCharacteristic(
1343            @RpcParameter(name = "gattIndex") Integer gattIndex,
1344            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1345            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1346            @RpcParameter(name = "characteristicUuid") String characteristicUuid) throws Exception {
1347        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1348        if (bluetoothGatt == null) {
1349            throw new Exception("Invalid gattIndex " + gattIndex);
1350        }
1351        List<BluetoothGattService> discoveredServiceList =
1352                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1353        if (discoveredServiceList == null) {
1354            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1355        }
1356        BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
1357        if (gattService == null) {
1358            throw new Exception("Invalid serviceIndex " + serviceIndex);
1359        }
1360        UUID cUuid = UUID.fromString(characteristicUuid);
1361        BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
1362        if (gattCharacteristic == null) {
1363            throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
1364        }
1365        return bluetoothGatt.writeCharacteristic(gattCharacteristic);
1366    }
1367
1368    /**
1369     * Write the value of a given characteristic to the associated remote device
1370     *
1371     * @param index the bluetooth gatt index
1372     * @param serviceIndex the service where the characteristic lives
1373     * @param characteristicIndex the characteristic index
1374     * @return true, if the write operation was successful
1375     * @throws Exception
1376     */
1377    @Rpc(description = "Write the value of a given characteristic to the associated remote device")
1378    public boolean gattClientWriteCharacteristicByIndex(
1379            @RpcParameter(name = "gattIndex") Integer gattIndex,
1380            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1381            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1382            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex)
1383            throws Exception {
1384        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1385        if (bluetoothGatt == null) {
1386            throw new Exception("Invalid gattIndex " + gattIndex);
1387        }
1388        List<BluetoothGattService> gattServiceList =
1389                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1390        if (gattServiceList == null) {
1391            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1392        }
1393        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
1394        if (gattService == null) {
1395            throw new Exception("Invalid serviceIndex " + serviceIndex);
1396        }
1397        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
1398        if (charList.get(characteristicIndex) == null) {
1399            throw new Exception("Invalid characteristicIndex " + characteristicIndex);
1400        }
1401        return bluetoothGatt.writeCharacteristic(charList.get(characteristicIndex));
1402    }
1403
1404    /**
1405     * PTS HELPER... Write the value of a given characteristic to the associated remote device
1406     *
1407     * @param index the bluetooth gatt index
1408     * @param serviceIndex the service where the characteristic lives
1409     * @param characteristicIndex the characteristic index
1410     * @return true, if the write operation was successful
1411     * @throws Exception
1412     */
1413    @Rpc(description = "Write the value of a given characteristic to the associated remote device")
1414    public boolean gattClientReadInvalidCharacteristicInstanceId(
1415            @RpcParameter(name = "gattIndex") Integer gattIndex,
1416            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1417            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1418            @RpcParameter(name = "instanceId") Integer instanceId)
1419            throws Exception {
1420        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1421        if (bluetoothGatt == null) {
1422            throw new Exception("Invalid gattIndex " + gattIndex);
1423        }
1424        List<BluetoothGattService> gattServiceList =
1425                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1426        if (gattServiceList == null) {
1427            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1428        }
1429        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
1430        if (gattService == null) {
1431            throw new Exception("Invalid serviceIndex " + serviceIndex);
1432        }
1433        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
1434        charList.get(0).setInstanceId(instanceId);
1435        return bluetoothGatt.readCharacteristic(charList.get(0));
1436    }
1437
1438    /**
1439     * Get the input Characteristic's instance ID.
1440     *
1441     * @param index the bluetooth gatt index
1442     * @param serviceIndex the service where the characteristic lives
1443     * @param characteristicIndex the characteristic index
1444     * @return true, if the write operation was successful
1445     * @throws Exception
1446     */
1447    @Rpc(description = "Write the value of a given characteristic to the associated remote device")
1448    public Integer gattClientGetCharacteristicInstanceId(
1449            @RpcParameter(name = "gattIndex") Integer gattIndex,
1450            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1451            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1452            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex)
1453            throws Exception {
1454        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1455        if (bluetoothGatt == null) {
1456            throw new Exception("Invalid gattIndex " + gattIndex);
1457        }
1458        List<BluetoothGattService> gattServiceList =
1459                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1460        if (gattServiceList == null) {
1461            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1462        }
1463        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
1464        if (gattService == null) {
1465            throw new Exception("Invalid serviceIndex " + serviceIndex);
1466        }
1467        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
1468        if (charList.get(characteristicIndex) == null) {
1469            throw new Exception("Invalid characteristicIndex " + characteristicIndex);
1470        }
1471        return charList.get(characteristicIndex).getInstanceId();
1472    }
1473
1474    /**
1475     * Get the input Descriptor's instance ID.
1476     *
1477     * @param index the bluetooth gatt index
1478     * @param serviceIndex the service where the characteristic lives
1479     * @param characteristicIndex the characteristic index
1480     * @param descriptorIndex the descriptor index
1481     * @return true, if the write operation was successful
1482     * @throws Exception
1483     */
1484    @Rpc(description = "Write the value of a given characteristic to the associated remote device")
1485    public Integer gattClientGetDescriptorInstanceId(
1486            @RpcParameter(name = "gattIndex") Integer gattIndex,
1487            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1488            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1489            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex,
1490            @RpcParameter(name = "descriptorIndex") Integer descriptorIndex)
1491            throws Exception {
1492        BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
1493        if (bluetoothGatt == null) {
1494            throw new Exception("Invalid gattIndex " + gattIndex);
1495        }
1496        List<BluetoothGattService> gattServiceList =
1497                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1498        if (gattServiceList == null) {
1499            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1500        }
1501        BluetoothGattService gattService = gattServiceList.get(serviceIndex);
1502        if (gattService == null) {
1503            throw new Exception("Invalid serviceIndex " + serviceIndex);
1504        }
1505        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
1506        if (charList.get(characteristicIndex) == null) {
1507            throw new Exception("Invalid characteristicIndex " + characteristicIndex);
1508        }
1509        BluetoothGattCharacteristic gattCharacteristic = charList.get(characteristicIndex);
1510        if (gattCharacteristic == null) {
1511            throw new Exception("Invalid characteristicIndex " + serviceIndex);
1512        }
1513        List<BluetoothGattDescriptor> descList = gattCharacteristic.getDescriptors();
1514        if (descList.get(descriptorIndex) == null) {
1515            throw new Exception("Invalid descriptorIndex " + descriptorIndex);
1516        }
1517        return descList.get(descriptorIndex).getInstanceId();
1518    }
1519
1520    /**
1521     * Write the value to a discovered characteristic.
1522     *
1523     * @deprecated Use {@link #gattClientCharacteristicSetValueByIndex(
1524     *  gattIndex, discoveredServiceListIndex, serviceIndex, characteristicIndex, value)} instead.
1525     * @param gattIndex - the gatt index to use
1526     * @param discoveredServiceListIndex - the discovered service list index
1527     * @param serviceIndex - the service index of the discoveredServiceListIndex
1528     * @param characteristicUuid - the characteristic uuid in which the descriptor is
1529     * @param value - the value to set the characteristic to
1530     * @return true, if the value was set to the characteristic
1531     * @throws Exception
1532     */
1533    @Deprecated
1534    @Rpc(description = "Write the value of a given characteristic to the associated remote device")
1535    public boolean gattClientCharacteristicSetValue(
1536            @RpcParameter(name = "gattIndex") Integer gattIndex,
1537            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1538            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1539            @RpcParameter(name = "characteristicUuid") String characteristicUuid,
1540            @RpcParameter(name = "value") byte[] value) throws Exception {
1541        if (mBluetoothGattList.get(gattIndex) == null) {
1542            throw new Exception("Invalid gattIndex " + gattIndex);
1543        }
1544        List<BluetoothGattService> discoveredServiceList =
1545                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1546        if (discoveredServiceList == null) {
1547            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1548        }
1549        BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
1550        if (gattService == null) {
1551            throw new Exception("Invalid serviceIndex " + serviceIndex);
1552        }
1553        UUID cUuid = UUID.fromString(characteristicUuid);
1554        BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
1555        if (gattCharacteristic == null) {
1556            throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
1557        }
1558        return gattCharacteristic.setValue(value);
1559    }
1560
1561    /**
1562     * Write the value to a discovered characteristic.
1563     *
1564     * @param gattIndex - the gatt index to use
1565     * @param discoveredServiceListIndex - the discovered service list index
1566     * @param serviceIndex - the service index of the discoveredServiceListIndex
1567     * @param characteristicIndex - the characteristic index
1568     * @param value - the value to set the characteristic to
1569     * @return true, if the value was set to the characteristic
1570     * @throws Exception
1571     */
1572    @Rpc(description = "Write the value of a given characteristic to the associated remote device")
1573    public boolean gattClientCharacteristicSetValueByIndex(
1574            @RpcParameter(name = "gattIndex") Integer gattIndex,
1575            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1576            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1577            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex,
1578            @RpcParameter(name = "value") byte[] value)
1579            throws Exception {
1580        if (mBluetoothGattList.get(gattIndex) == null) {
1581            throw new Exception("Invalid gattIndex " + gattIndex);
1582        }
1583        List<BluetoothGattService> discoveredServiceList =
1584                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1585        if (discoveredServiceList == null) {
1586            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1587        }
1588        BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
1589        if (gattService == null) {
1590            throw new Exception("Invalid serviceIndex " + serviceIndex);
1591        }
1592        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
1593        if (charList.get(characteristicIndex) == null) {
1594            throw new Exception("Invalid characteristicIndex: " + characteristicIndex);
1595        }
1596        return charList.get(characteristicIndex).setValue(value);
1597    }
1598
1599    /**
1600     * Set write type to a discovered characteristic.
1601     *
1602     * @deprecated Use {@link #gattClientCharacteristicSetWriteTypeByIndex(
1603     *  gattIndex, discoveredServiceListIndex, serviceIndex, ccharacteristicUuid, writeType)}
1604     * instead.
1605     * @param gattIndex - the gatt index to use
1606     * @param discoveredServiceListIndex - the discovered service list index
1607     * @param serviceIndex - the service index of the discoveredServiceListIndex
1608     * @param characteristicUuid - the characteristic uuid in which the descriptor is
1609     * @param writeType - the write type for characteristic
1610     * @return true, if the value was set to the characteristic
1611     * @throws Exception
1612     */
1613    @Deprecated
1614    @Rpc(description = "Set write type of a given characteristic to the associated remote device")
1615    public boolean gattClientCharacteristicSetWriteType(
1616            @RpcParameter(name = "gattIndex") Integer gattIndex,
1617            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1618            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1619            @RpcParameter(name = "characteristicUuid") String characteristicUuid,
1620            @RpcParameter(name = "writeType") Integer writeType) throws Exception {
1621        if (mBluetoothGattList.get(gattIndex) == null) {
1622            throw new Exception("Invalid gattIndex " + gattIndex);
1623        }
1624        List<BluetoothGattService> discoveredServiceList =
1625                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1626        if (discoveredServiceList == null) {
1627            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1628        }
1629        BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
1630        if (gattService == null) {
1631            throw new Exception("Invalid serviceIndex " + serviceIndex);
1632        }
1633        UUID cUuid = UUID.fromString(characteristicUuid);
1634        BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
1635        if (gattCharacteristic == null) {
1636            throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
1637        }
1638        gattCharacteristic.setWriteType(writeType);
1639        return true;
1640    }
1641
1642    /**
1643     * Set write type to a discovered characteristic.
1644     *
1645     * @param gattIndex - the gatt index to use
1646     * @param discoveredServiceListIndex - the discovered service list index
1647     * @param serviceIndex - the service index of the discoveredServiceListIndex
1648     * @param characteristicIndex - the characteristic index
1649     * @param writeType - the write type for characteristic
1650     * @return true, if the value was set to the characteristic
1651     * @throws Exception
1652     */
1653    @Rpc(description = "Set write type of a given characteristic to the associated remote device")
1654    public void gattClientCharacteristicSetWriteTypeByIndex(
1655            @RpcParameter(name = "gattIndex") Integer gattIndex,
1656            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1657            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1658            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex,
1659            @RpcParameter(name = "writeType") Integer writeType)
1660            throws Exception {
1661        if (mBluetoothGattList.get(gattIndex) == null) {
1662            throw new Exception("Invalid gattIndex " + gattIndex);
1663        }
1664        List<BluetoothGattService> discoveredServiceList =
1665                mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1666        if (discoveredServiceList == null) {
1667            throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
1668        }
1669        BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
1670        if (gattService == null) {
1671            throw new Exception("Invalid serviceIndex " + serviceIndex);
1672        }
1673        List<BluetoothGattCharacteristic> charList = gattService.getCharacteristics();
1674        if (charList.get(characteristicIndex) == null) {
1675            throw new Exception("Invalid characteristicIndex: " + characteristicIndex);
1676        }
1677        charList.get(characteristicIndex).setWriteType(writeType);
1678    }
1679
1680    /**
1681     * Read the RSSI for a connected remote device
1682     *
1683     * @param index the bluetooth gatt index
1684     * @return true, if the RSSI value has been requested successfully
1685     * @throws Exception
1686     */
1687    @Rpc(description = "Read the RSSI for a connected remote device")
1688    public boolean gattClientReadRSSI(
1689            @RpcParameter(name = "index") Integer index) throws Exception {
1690        if (mBluetoothGattList.get(index) != null) {
1691            return mBluetoothGattList.get(index).readRemoteRssi();
1692        } else {
1693            throw new Exception("Invalid index input:" + index);
1694        }
1695    }
1696
1697    /**
1698     * Clears the internal cache and forces a refresh of the services from the remote device
1699     *
1700     * @param index the bluetooth gatt index
1701     * @return Clears the internal cache and forces a refresh of the services from the remote
1702     *         device.
1703     * @throws Exception
1704     */
1705    @Rpc(description = "Clears the internal cache and forces a refresh of the services from the "
1706            + "remote device")
1707    public boolean gattClientRefresh(@RpcParameter(name = "index") Integer index) throws Exception {
1708        if (mBluetoothGattList.get(index) != null) {
1709            return mBluetoothGattList.get(index).refresh();
1710        } else {
1711            throw new Exception("Invalid index input:" + index);
1712        }
1713    }
1714
1715    /**
1716     * Request a connection parameter update.
1717     *
1718     * @param index the bluetooth gatt index
1719     * @param connectionPriority connection priority
1720     * @return boolean True if successful False otherwise.
1721     * @throws Exception
1722     */
1723    @Rpc(description = "Request a connection parameter update. from the Bluetooth Gatt")
1724    public boolean gattClientRequestConnectionPriority(
1725            @RpcParameter(name = "index") Integer index,
1726            @RpcParameter(name = "connectionPriority") Integer connectionPriority)
1727            throws Exception {
1728        boolean result = false;
1729        if (mBluetoothGattList.get(index) != null) {
1730            result = mBluetoothGattList.get(index).requestConnectionPriority(connectionPriority);
1731        } else {
1732            throw new Exception("Invalid index input:" + index);
1733        }
1734        return result;
1735    }
1736
1737    /**
1738     * Request a connection parameter update for Connection Interval.
1739     *
1740     * @param index the bluetooth gatt index
1741     * @param minConnectionInterval minimum connection interval
1742     * @param maxConnectionInterval maximum connection interval
1743     * @param slaveLatency maximum slave latency
1744     * @param supervisionTimeout supervision timeout
1745     * @return boolean True if successful False otherwise.
1746     * @throws Exception
1747     */
1748    @Rpc(description = "Request an LE connection parameters update.")
1749    public boolean gattClientRequestLeConnectionParameters(
1750            @RpcParameter(name = "index") Integer index,
1751            @RpcParameter(name = "minConnectionInterval") Integer minConnectionInterval,
1752            @RpcParameter(name = "maxConnectionInterval") Integer maxConnectionInterval,
1753            @RpcParameter(name = "slaveLatency") Integer slaveLatency,
1754            @RpcParameter(name = "supervisionTimeout") Integer supervisionTimeout,
1755            @RpcParameter(name = "minConnectionEventLen") Integer minConnectionEventLen,
1756            @RpcParameter(name = "maxConnectionEventLen") Integer maxConnectionEventLen)
1757            throws Exception {
1758        boolean result = false;
1759        if (mBluetoothGattList.get(index) != null) {
1760            result = mBluetoothGattList.get(index).requestLeConnectionUpdate(
1761                minConnectionInterval, maxConnectionInterval, slaveLatency, supervisionTimeout,
1762                minConnectionEventLen, maxConnectionEventLen);
1763        } else {
1764            throw new Exception("Invalid index input:" + index);
1765        }
1766        return result;
1767    }
1768
1769    /**
1770     * Sets the characteristic notification of a bluetooth gatt
1771     *
1772     * @deprecated Use {@link #gattClientSetCharacteristicNotificationByIndex(
1773     *  gattIndex, discoveredServiceListIndex, serviceIndex, characteristicIndex, enable)} instead.
1774     * @param index the bluetooth gatt index
1775     * @param characteristicIndex the characteristic index
1776     * @param enable Enable or disable notifications/indications for a given characteristic
1777     * @return true, if the requested notification status was set successfully
1778     * @throws Exception
1779     */
1780    @Deprecated
1781    @Rpc(description = "Sets the characteristic notification of a bluetooth gatt")
1782    public boolean gattClientSetCharacteristicNotification(
1783            @RpcParameter(name = "gattIndex")
1784            Integer gattIndex,
1785            @RpcParameter(name = "discoveredServiceListIndex")
1786            Integer discoveredServiceListIndex,
1787            @RpcParameter(name = "serviceIndex")
1788            Integer serviceIndex,
1789            @RpcParameter(name = "characteristicUuid")
1790            String characteristicUuid,
1791            @RpcParameter(name = "enable")
1792            Boolean enable
1793            ) throws Exception {
1794        if (mBluetoothGattList.get(gattIndex) != null) {
1795            if(mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex) != null) {
1796                List<BluetoothGattService> discoveredServiceList =
1797                    mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1798                if (discoveredServiceList.get(serviceIndex) != null) {
1799                    UUID cUuid = UUID.fromString(characteristicUuid);
1800                    if (discoveredServiceList.get(serviceIndex).getCharacteristic(cUuid) != null) {
1801                        return mBluetoothGattList.get(gattIndex).setCharacteristicNotification(
1802                                discoveredServiceList.get(serviceIndex).getCharacteristic(cUuid), enable);
1803                    } else {
1804                        throw new Exception ("Invalid characteristic uuid: " + characteristicUuid);
1805                    }
1806                } else {
1807                    throw new Exception ("Invalid serviceIndex " + serviceIndex);
1808                }
1809            } else {
1810                throw new Exception("Invalid discoveredServiceListIndex: " + discoveredServiceListIndex);
1811            }
1812        } else {
1813            throw new Exception("Invalid gattIndex input: " + gattIndex);
1814        }
1815    }
1816
1817    /**
1818     * Sets the characteristic notification of a bluetooth gatt
1819     *
1820     * @param gattIndex the bluetooth gatt index
1821     * @param characteristicIndex the characteristic index
1822     * @param enable Enable or disable notifications/indications for a given characteristic
1823     * @return true, if the requested notification status was set successfully
1824     * @throws Exception
1825     */
1826    @Rpc(description = "Sets the characteristic notification of a bluetooth gatt")
1827    public boolean gattClientSetCharacteristicNotificationByIndex(
1828            @RpcParameter(name = "gattIndex") Integer gattIndex,
1829            @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
1830            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
1831            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex,
1832            @RpcParameter(name = "enable") Boolean enable)
1833            throws Exception {
1834        if (mBluetoothGattList.get(gattIndex) != null) {
1835            if (mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex) != null) {
1836                List<BluetoothGattService> discoveredServiceList =
1837                        mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
1838                if (discoveredServiceList.get(serviceIndex) != null) {
1839                    List<BluetoothGattCharacteristic> charList =
1840                            discoveredServiceList.get(serviceIndex).getCharacteristics();
1841                    if (charList.get(characteristicIndex) != null) {
1842                        return mBluetoothGattList
1843                                .get(gattIndex)
1844                                .setCharacteristicNotification(charList.get(characteristicIndex),
1845                                    enable);
1846                    } else {
1847                        throw new Exception("Invalid characteristicIndex: " + characteristicIndex);
1848                    }
1849                } else {
1850                    throw new Exception("Invalid serviceIndex " + serviceIndex);
1851                }
1852            } else {
1853                throw new Exception(
1854                    "Invalid discoveredServiceListIndex: " + discoveredServiceListIndex);
1855            }
1856        } else {
1857            throw new Exception("Invalid gattIndex input: " + gattIndex);
1858        }
1859    }
1860
1861    /**
1862     * Create a new GattCallback object
1863     *
1864     * @return the index of the callback object
1865     */
1866    @Rpc(description = "Create a new GattCallback object")
1867    public Integer gattCreateGattCallback() {
1868        GattCallbackCount += 1;
1869        int index = GattCallbackCount;
1870        mGattCallbackList.put(index, new myBluetoothGattCallback(index));
1871        return index;
1872    }
1873
1874    /**
1875     * Returns the list of discovered Bluetooth Gatt Services.
1876     *
1877     * @throws Exception
1878     */
1879    @Rpc(description = "Get Bluetooth Gatt Services")
1880    public int gattClientGetDiscoveredServicesCount(@RpcParameter(name = "index") Integer index)
1881            throws Exception {
1882        if (mBluetoothGattDiscoveredServicesList.get(index) != null) {
1883            return mBluetoothGattDiscoveredServicesList.get(index).size();
1884        } else {
1885            throw new Exception("Invalid index input:" + index);
1886        }
1887    }
1888
1889    /**
1890     * Returns the discovered Bluetooth Gatt Service Uuid.
1891     *
1892     * @throws Exception
1893     */
1894    @Rpc(description = "Get Bluetooth Gatt Service Uuid")
1895    public String gattClientGetDiscoveredServiceUuid(
1896            @RpcParameter(name = "index") Integer index,
1897            @RpcParameter(name = "serviceIndex") Integer serviceIndex)
1898            throws Exception {
1899        List<BluetoothGattService> mBluetoothServiceList =
1900                mBluetoothGattDiscoveredServicesList.get(index);
1901        if (mBluetoothServiceList != null) {
1902            return mBluetoothServiceList.get(serviceIndex).getUuid().toString();
1903        } else {
1904            throw new Exception("Invalid index input:" + index);
1905        }
1906    }
1907
1908    /**
1909     * Get discovered characteristic uuids from the pheripheral device.
1910     *
1911     * @param index the index of the bluetooth gatt discovered services list
1912     * @param serviceIndex the service to get
1913     * @return the list of characteristic uuids
1914     * @throws Exception
1915     */
1916    @Rpc(description = "Get Bluetooth Gatt Services")
1917    public ArrayList<String> gattClientGetDiscoveredCharacteristicUuids(
1918            @RpcParameter(name = "index") Integer index,
1919            @RpcParameter(name = "serviceIndex") Integer serviceIndex)
1920            throws Exception {
1921        if (mBluetoothGattDiscoveredServicesList.get(index) != null) {
1922            if (mBluetoothGattDiscoveredServicesList.get(index).get(serviceIndex) != null) {
1923                ArrayList<String> uuidList = new ArrayList<String>();
1924                List<BluetoothGattCharacteristic> charList =
1925                        mBluetoothGattDiscoveredServicesList.get(index).get(
1926                            serviceIndex).getCharacteristics();
1927                for (BluetoothGattCharacteristic mChar : charList) {
1928                    uuidList.add(mChar.getUuid().toString());
1929                }
1930                return uuidList;
1931            } else {
1932                throw new Exception("Invalid serviceIndex input:" + index);
1933            }
1934        } else {
1935            throw new Exception("Invalid index input:" + index);
1936        }
1937    }
1938
1939    /**
1940     * Get discovered descriptor uuids from the pheripheral device.
1941     *
1942     * @deprecated Use {@link #gattClientGetDiscoveredDescriptorUuidsByIndex(
1943     *  index, serviceIndex, characteristicIndex)} instead.
1944     * @param index the discovered services list index
1945     * @param serviceIndex the service index of the discovered services list
1946     * @param characteristicUuid the characteristicUuid to select from the
1947     * discovered service which contains the list of descriptors.
1948     * @return the list of descriptor uuids
1949     * @throws Exception
1950     */
1951    @Deprecated
1952    @Rpc(description = "Get Bluetooth Gatt Services")
1953    public ArrayList<String> gattClientGetDiscoveredDescriptorUuids (
1954            @RpcParameter(name = "index")
1955            Integer index,
1956            @RpcParameter(name = "serviceIndex")
1957            Integer serviceIndex,
1958            @RpcParameter(name = "characteristicUuid")
1959            String characteristicUuid
1960            ) throws Exception {
1961        if (mBluetoothGattDiscoveredServicesList.get(index) != null) {
1962            if (mBluetoothGattDiscoveredServicesList.get(index).get(serviceIndex) != null) {
1963                BluetoothGattService service = mBluetoothGattDiscoveredServicesList.get(
1964                        index).get(serviceIndex);
1965                UUID cUuid = UUID.fromString(characteristicUuid);
1966                if (service.getCharacteristic(cUuid) != null) {
1967                    ArrayList<String> uuidList = new ArrayList<String>();
1968                    for (BluetoothGattDescriptor mDesc : service.getCharacteristic(
1969                            cUuid).getDescriptors()) {
1970                        uuidList.add(mDesc.getUuid().toString());
1971                    }
1972                    return uuidList;
1973                } else {
1974                    throw new Exception("Invalid characeristicUuid : "
1975                            + characteristicUuid);
1976                }
1977            } else {
1978                throw new Exception("Invalid serviceIndex input:"
1979                        + index);
1980            }
1981        } else {
1982            throw new Exception("Invalid index input:"
1983                    + index);
1984        }
1985    }
1986
1987    /**
1988     * Get discovered descriptor uuids from the pheripheral device.
1989     *
1990     * @param index the discovered services list index
1991     * @param serviceIndex the service index of the discovered services list
1992     * @param characteristicIndex the characteristicIndex to select from the discovered service
1993     *       which contains the list of descriptors.
1994     * @return the list of descriptor uuids
1995     * @throws Exception
1996     */
1997    @Rpc(description = "Get Bluetooth Gatt Services")
1998    public ArrayList<String> gattClientGetDiscoveredDescriptorUuidsByIndex(
1999            @RpcParameter(name = "index") Integer index,
2000            @RpcParameter(name = "serviceIndex") Integer serviceIndex,
2001            @RpcParameter(name = "characteristicIndex") Integer characteristicIndex)
2002            throws Exception {
2003        if (mBluetoothGattDiscoveredServicesList.get(index) == null) {
2004            throw new Exception("Invalid index: " + index);
2005        }
2006        if (mBluetoothGattDiscoveredServicesList.get(index).get(serviceIndex) == null) {
2007            throw new Exception("Invalid serviceIndex: " + serviceIndex);
2008        }
2009        List<BluetoothGattCharacteristic> charList =
2010                mBluetoothGattDiscoveredServicesList.get(index).get(
2011                    serviceIndex).getCharacteristics();
2012        if (charList.get(characteristicIndex) == null) {
2013            throw new Exception("Invalid characteristicIndex: " + characteristicIndex);
2014        }
2015        List<BluetoothGattDescriptor> descList = charList.get(characteristicIndex).getDescriptors();
2016        ArrayList<String> uuidList = new ArrayList<String>();
2017        for (BluetoothGattDescriptor mDesc : descList) {
2018            uuidList.add(mDesc.getUuid().toString());
2019        }
2020        return uuidList;
2021    }
2022
2023    private class myBluetoothGattCallback extends BluetoothGattCallback {
2024        private final Bundle mResults;
2025        private final int index;
2026        private final String mEventType;
2027
2028        public myBluetoothGattCallback(int idx) {
2029            mResults = new Bundle();
2030            mEventType = "GattConnect";
2031            index = idx;
2032        }
2033
2034        @Override
2035        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
2036            Log.d("gatt_connect change onConnectionStateChange " + mEventType + " " + index);
2037            if (newState == BluetoothProfile.STATE_CONNECTED) {
2038                Log.d(
2039                        "State Connected to mac address "
2040                                + gatt.getDevice().getAddress()
2041                                + " status "
2042                                + status);
2043            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
2044                Log.d(
2045                        "State Disconnected from mac address "
2046                                + gatt.getDevice().getAddress()
2047                                + " status "
2048                                + status);
2049            } else if (newState == BluetoothProfile.STATE_CONNECTING) {
2050                Log.d(
2051                        "State Connecting to mac address "
2052                                + gatt.getDevice().getAddress()
2053                                + " status "
2054                                + status);
2055            } else if (newState == BluetoothProfile.STATE_DISCONNECTING) {
2056                Log.d(
2057                        "State Disconnecting from mac address "
2058                                + gatt.getDevice().getAddress()
2059                                + " status "
2060                                + status);
2061            }
2062            mResults.putInt("Status", status);
2063            mResults.putInt("State", newState);
2064            mEventFacade.postEvent(
2065                    mEventType + index + "onConnectionStateChange", mResults.clone());
2066            mResults.clear();
2067        }
2068
2069        @Override
2070        public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
2071            Log.d("gatt_connect change onPhyRead " + mEventType + " " + index);
2072            mResults.putInt("TxPhy", txPhy);
2073            mResults.putInt("RxPhy", rxPhy);
2074            mResults.putInt("Status", status);
2075            mEventFacade.postEvent(mEventType + index + "onPhyRead", mResults.clone());
2076            mResults.clear();
2077        }
2078
2079        @Override
2080        public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
2081            Log.d("gatt_connect change onPhyUpdate " + mEventType + " " + index);
2082            mResults.putInt("TxPhy", txPhy);
2083            mResults.putInt("RxPhy", rxPhy);
2084            mResults.putInt("Status", status);
2085            mEventFacade.postEvent(mEventType + index + "onPhyUpdate", mResults.clone());
2086            mResults.clear();
2087        }
2088
2089        @Override
2090        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
2091            Log.d("gatt_connect change onServicesDiscovered " + mEventType + " " + index);
2092            int idx = BluetoothGattDiscoveredServicesCount++;
2093            mBluetoothGattDiscoveredServicesList.put(idx, gatt.getServices());
2094            mResults.putInt("ServicesIndex", idx);
2095            mResults.putInt("Status", status);
2096            mEventFacade.postEvent(mEventType + index + "onServicesDiscovered", mResults.clone());
2097            mResults.clear();
2098        }
2099
2100        @Override
2101        public void onCharacteristicRead(
2102                BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
2103            Log.d("gatt_connect change onCharacteristicRead " + mEventType + " " + index);
2104            mResults.putInt("Status", status);
2105            mResults.putString("CharacteristicUuid", characteristic.getUuid().toString());
2106            mResults.putByteArray("CharacteristicValue", characteristic.getValue());
2107            mEventFacade.postEvent(mEventType + index + "onCharacteristicRead", mResults.clone());
2108            mResults.clear();
2109        }
2110
2111        @Override
2112        public void onCharacteristicWrite(
2113                BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
2114            Log.d("gatt_connect change onCharacteristicWrite " + mEventType + " " + index);
2115            mResults.putInt("Status", status);
2116            mResults.putString("CharacteristicUuid", characteristic.getUuid().toString());
2117            mResults.putByteArray("CharacteristicValue", characteristic.getValue());
2118            mEventFacade.postEvent(mEventType + index + "onCharacteristicWrite", mResults.clone());
2119            mResults.clear();
2120        }
2121
2122        @Override
2123        public void onCharacteristicChanged(
2124                BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
2125            Log.d("gatt_connect change onCharacteristicChanged " + mEventType + " " + index);
2126            mResults.putInt("ID", index);
2127            mResults.putString("CharacteristicUuid", characteristic.getUuid().toString());
2128            mResults.putByteArray("CharacteristicValue", characteristic.getValue());
2129            mEventFacade.postEvent(
2130                    mEventType + index + "onCharacteristicChanged", mResults.clone());
2131            mResults.clear();
2132        }
2133
2134        @Override
2135        public void onDescriptorRead(
2136                BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
2137            Log.d("gatt_connect change onServicesDiscovered " + mEventType + " " + index);
2138            mResults.putInt("Status", status);
2139            mResults.putString("DescriptorUuid", descriptor.getUuid().toString());
2140            mEventFacade.postEvent(mEventType + index + "onDescriptorRead", mResults.clone());
2141            mResults.clear();
2142        }
2143
2144        @Override
2145        public void onDescriptorWrite(
2146                BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
2147            Log.d("gatt_connect change onDescriptorWrite " + mEventType + " " + index);
2148            mResults.putInt("ID", index);
2149            mResults.putInt("Status", status);
2150            mResults.putString("DescriptorUuid", descriptor.getUuid().toString());
2151            mEventFacade.postEvent(mEventType + index + "onDescriptorWrite", mResults.clone());
2152            mResults.clear();
2153        }
2154
2155        @Override
2156        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
2157            Log.d("gatt_connect change onReliableWriteCompleted " + mEventType + " " + index);
2158            mResults.putInt("Status", status);
2159            mEventFacade.postEvent(
2160                    mEventType + index + "onReliableWriteCompleted", mResults.clone());
2161            mResults.clear();
2162        }
2163
2164        @Override
2165        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
2166            Log.d("gatt_connect change onReadRemoteRssi " + mEventType + " " + index);
2167            mResults.putInt("Status", status);
2168            mResults.putInt("Rssi", rssi);
2169            mEventFacade.postEvent(mEventType + index + "onReadRemoteRssi", mResults.clone());
2170            mResults.clear();
2171        }
2172
2173        @Override
2174        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
2175            Log.d("gatt_connect change onMtuChanged " + mEventType + " " + index);
2176            mResults.putInt("Status", status);
2177            mResults.putInt("MTU", mtu);
2178            mEventFacade.postEvent(mEventType + index + "onMtuChanged", mResults.clone());
2179            mResults.clear();
2180        }
2181
2182        public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency,
2183                                            int timeout, int status) {
2184            Log.d("gatt_connect change onConnectionUpdated " + mEventType + " " + index
2185                    + ", interval: " + interval + ", latency: " + latency
2186                    + ", timeout: " + timeout + ", status: " + status);
2187
2188            mResults.putInt("Status", status);
2189            mResults.putInt("Interval", interval);
2190            mResults.putInt("Latency", latency);
2191            mResults.putInt("Timeout", timeout);
2192            mEventFacade.postEvent(mEventType + index + "onConnectionUpdated", mResults.clone());
2193            mResults.clear();
2194        }
2195    }
2196
2197    @Override
2198    public void shutdown() {
2199        if (!mBluetoothGattList.isEmpty()) {
2200            if (mBluetoothGattList.values() != null) {
2201                for (BluetoothGatt mBluetoothGatt : mBluetoothGattList.values()) {
2202                    mBluetoothGatt.close();
2203                }
2204            }
2205        }
2206        mGattCallbackList.clear();
2207    }
2208}
2209