blob: f9ce6eacacea10d66461867190d9100c3431cdea [file] [log] [blame]
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001/*
2 * Copyright (C) 2013 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 android.bluetooth;
18
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080019import android.bluetooth.BluetoothDevice;
20import android.bluetooth.BluetoothProfile;
21import android.bluetooth.BluetoothProfile.ServiceListener;
22import android.bluetooth.IBluetoothManager;
23import android.bluetooth.IBluetoothStateChangeCallback;
24
25import android.content.ComponentName;
26import android.content.Context;
27import android.content.Intent;
28import android.content.ServiceConnection;
29import android.os.IBinder;
30import android.os.ParcelUuid;
31import android.os.RemoteException;
32import android.os.ServiceManager;
33import android.util.Log;
34
35import java.util.ArrayList;
36import java.util.List;
37import java.util.UUID;
38
39/**
Matthew Xieddf7e472013-03-01 18:41:02 -080040 * Public API for the Bluetooth GATT Profile.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080041 *
Matthew Xieddf7e472013-03-01 18:41:02 -080042 * <p>This class provides Bluetooth GATT functionality to enable communication
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080043 * with Bluetooth Smart or Smart Ready devices.
44 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080045 * <p>To connect to a remote peripheral device, create a {@link BluetoothGattCallback}
Matthew Xieddf7e472013-03-01 18:41:02 -080046 * and call {@link BluetoothDevice#connectGattServer} to get a instance of this class.
47 * GATT capable devices can be discovered using the Bluetooth device discovery or BLE
48 * scan process.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080049 */
50public final class BluetoothGatt implements BluetoothProfile {
51 private static final String TAG = "BluetoothGatt";
52 private static final boolean DBG = true;
Matthew Xieddf7e472013-03-01 18:41:02 -080053 private static final boolean VDBG = true;
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080054
Matthew Xieddf7e472013-03-01 18:41:02 -080055 private final Context mContext;
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080056 private IBluetoothGatt mService;
57 private BluetoothGattCallback mCallback;
58 private int mClientIf;
59 private boolean mAuthRetry = false;
Matthew Xieddf7e472013-03-01 18:41:02 -080060 private BluetoothDevice mDevice;
61 private boolean mAutoConnect;
62 private int mConnState;
63 private final Object mStateLock = new Object();
64
65 private static final int CONN_STATE_IDLE = 0;
66 private static final int CONN_STATE_CONNECTING = 1;
67 private static final int CONN_STATE_CONNECTED = 2;
68 private static final int CONN_STATE_DISCONNECTING = 3;
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080069
70 private List<BluetoothGattService> mServices;
71
Matthew Xieddf7e472013-03-01 18:41:02 -080072 /** A GATT operation failed */
73 public static final int GATT_FAILURE = 0;
74
75 /** A GATT operation completed successfully */
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080076 public static final int GATT_SUCCESS = 0;
77
Matthew Xieddf7e472013-03-01 18:41:02 -080078 /** GATT read operation is not permitted */
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080079 public static final int GATT_READ_NOT_PERMITTED = 0x2;
80
Matthew Xieddf7e472013-03-01 18:41:02 -080081 /** GATT write operation is not permitted */
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080082 public static final int GATT_WRITE_NOT_PERMITTED = 0x3;
83
84 /** Insufficient authentication for a given operation */
85 public static final int GATT_INSUFFICIENT_AUTHENTICATION = 0x5;
86
87 /** The given request is not supported */
88 public static final int GATT_REQUEST_NOT_SUPPORTED = 0x6;
89
90 /** Insufficient encryption for a given operation */
91 public static final int GATT_INSUFFICIENT_ENCRYPTION = 0xf;
92
93 /** A read or write operation was requested with an invalid offset */
94 public static final int GATT_INVALID_OFFSET = 0x7;
95
96 /** A write operation exceeds the maximum length of the attribute */
97 public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 0xd;
98
99 /**
100 * No authentication required.
101 * @hide
102 */
103 /*package*/ static final int AUTHENTICATION_NONE = 0;
104
105 /**
106 * Authentication requested; no man-in-the-middle protection required.
107 * @hide
108 */
109 /*package*/ static final int AUTHENTICATION_NO_MITM = 1;
110
111 /**
112 * Authentication with man-in-the-middle protection requested.
113 * @hide
114 */
115 /*package*/ static final int AUTHENTICATION_MITM = 2;
116
117 /**
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800118 * Bluetooth GATT interface callbacks
119 */
120 private final IBluetoothGattCallback mBluetoothGattCallback =
121 new IBluetoothGattCallback.Stub() {
122 /**
123 * Application interface registered - app is ready to go
124 * @hide
125 */
126 public void onClientRegistered(int status, int clientIf) {
127 if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status
128 + " clientIf=" + clientIf);
Matthew Xieddf7e472013-03-01 18:41:02 -0800129 if (VDBG) {
130 synchronized(mStateLock) {
131 if (mConnState != CONN_STATE_CONNECTING) {
132 Log.e(TAG, "Bad connection state: " + mConnState);
133 }
134 }
135 }
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800136 mClientIf = clientIf;
Matthew Xieddf7e472013-03-01 18:41:02 -0800137 if (status != GATT_SUCCESS) {
138 mCallback.onConnectionStateChange(mDevice, GATT_FAILURE,
139 BluetoothProfile.STATE_DISCONNECTED);
140 synchronized(mStateLock) {
141 mConnState = CONN_STATE_IDLE;
142 }
143 return;
144 }
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800145 try {
Matthew Xieddf7e472013-03-01 18:41:02 -0800146 mService.clientConnect(mClientIf, mDevice.getAddress(),
147 !mAutoConnect); // autoConnect is inverse of "isDirect"
148 } catch (RemoteException e) {
149 Log.e(TAG,"",e);
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800150 }
151 }
152
153 /**
154 * Client connection state changed
155 * @hide
156 */
157 public void onClientConnectionState(int status, int clientIf,
158 boolean connected, String address) {
159 if (DBG) Log.d(TAG, "onClientConnectionState() - status=" + status
160 + " clientIf=" + clientIf + " device=" + address);
Matthew Xieddf7e472013-03-01 18:41:02 -0800161 if (!address.equals(mDevice.getAddress())) {
162 return;
163 }
164 int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
165 BluetoothProfile.STATE_DISCONNECTED;
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800166 try {
Matthew Xieddf7e472013-03-01 18:41:02 -0800167 mCallback.onConnectionStateChange(mDevice, status, profileState);
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800168 } catch (Exception ex) {
169 Log.w(TAG, "Unhandled exception: " + ex);
170 }
Matthew Xieddf7e472013-03-01 18:41:02 -0800171
172 synchronized(mStateLock) {
173 if (connected) {
174 mConnState = CONN_STATE_CONNECTED;
175 } else {
176 mConnState = CONN_STATE_IDLE;
177 }
178 }
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800179 }
180
181 /**
182 * Callback reporting an LE scan result.
183 * @hide
184 */
185 public void onScanResult(String address, int rssi, byte[] advData) {
Matthew Xieddf7e472013-03-01 18:41:02 -0800186 // no op
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800187 }
188
189 /**
190 * A new GATT service has been discovered.
191 * The service is added to the internal list and the search
192 * continues.
193 * @hide
194 */
195 public void onGetService(String address, int srvcType,
196 int srvcInstId, ParcelUuid srvcUuid) {
197 if (DBG) Log.d(TAG, "onGetService() - Device=" + address + " UUID=" + srvcUuid);
Matthew Xieddf7e472013-03-01 18:41:02 -0800198 if (!address.equals(mDevice.getAddress())) {
199 return;
200 }
201 mServices.add(new BluetoothGattService(mDevice, srvcUuid.getUuid(),
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800202 srvcInstId, srvcType));
203 }
204
205 /**
206 * An included service has been found durig GATT discovery.
207 * The included service is added to the respective parent.
208 * @hide
209 */
210 public void onGetIncludedService(String address, int srvcType,
211 int srvcInstId, ParcelUuid srvcUuid,
212 int inclSrvcType, int inclSrvcInstId,
213 ParcelUuid inclSrvcUuid) {
214 if (DBG) Log.d(TAG, "onGetIncludedService() - Device=" + address
215 + " UUID=" + srvcUuid + " Included=" + inclSrvcUuid);
216
Matthew Xieddf7e472013-03-01 18:41:02 -0800217 if (!address.equals(mDevice.getAddress())) {
218 return;
219 }
220 BluetoothGattService service = getService(mDevice,
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800221 srvcUuid.getUuid(), srvcInstId, srvcType);
Matthew Xieddf7e472013-03-01 18:41:02 -0800222 BluetoothGattService includedService = getService(mDevice,
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800223 inclSrvcUuid.getUuid(), inclSrvcInstId, inclSrvcType);
224
225 if (service != null && includedService != null) {
226 service.addIncludedService(includedService);
227 }
228 }
229
230 /**
231 * A new GATT characteristic has been discovered.
232 * Add the new characteristic to the relevant service and continue
233 * the remote device inspection.
234 * @hide
235 */
236 public void onGetCharacteristic(String address, int srvcType,
237 int srvcInstId, ParcelUuid srvcUuid,
238 int charInstId, ParcelUuid charUuid,
239 int charProps) {
240 if (DBG) Log.d(TAG, "onGetCharacteristic() - Device=" + address + " UUID=" +
241 charUuid);
242
Matthew Xieddf7e472013-03-01 18:41:02 -0800243 if (!address.equals(mDevice.getAddress())) {
244 return;
245 }
246 BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800247 srvcInstId, srvcType);
248 if (service != null) {
249 service.addCharacteristic(new BluetoothGattCharacteristic(
250 service, charUuid.getUuid(), charInstId, charProps, 0));
251 }
252 }
253
254 /**
255 * A new GATT descriptor has been discovered.
256 * Finally, add the descriptor to the related characteristic.
257 * This should conclude the remote device update.
258 * @hide
259 */
260 public void onGetDescriptor(String address, int srvcType,
261 int srvcInstId, ParcelUuid srvcUuid,
262 int charInstId, ParcelUuid charUuid,
263 ParcelUuid descUuid) {
264 if (DBG) Log.d(TAG, "onGetDescriptor() - Device=" + address + " UUID=" + descUuid);
265
Matthew Xieddf7e472013-03-01 18:41:02 -0800266 if (!address.equals(mDevice.getAddress())) {
267 return;
268 }
269 BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800270 srvcInstId, srvcType);
271 if (service == null) return;
272
273 BluetoothGattCharacteristic characteristic = service.getCharacteristic(
274 charUuid.getUuid());
275 if (characteristic == null) return;
276
277 characteristic.addDescriptor(new BluetoothGattDescriptor(
278 characteristic, descUuid.getUuid(), 0));
279 }
280
281 /**
282 * Remote search has been completed.
283 * The internal object structure should now reflect the state
284 * of the remote device database. Let the application know that
285 * we are done at this point.
286 * @hide
287 */
288 public void onSearchComplete(String address, int status) {
289 if (DBG) Log.d(TAG, "onSearchComplete() = Device=" + address + " Status=" + status);
Matthew Xieddf7e472013-03-01 18:41:02 -0800290 if (!address.equals(mDevice.getAddress())) {
291 return;
292 }
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800293 try {
Matthew Xieddf7e472013-03-01 18:41:02 -0800294 mCallback.onServicesDiscovered(mDevice, status);
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800295 } catch (Exception ex) {
296 Log.w(TAG, "Unhandled exception: " + ex);
297 }
298 }
299
300 /**
301 * Remote characteristic has been read.
302 * Updates the internal value.
303 * @hide
304 */
305 public void onCharacteristicRead(String address, int status, int srvcType,
306 int srvcInstId, ParcelUuid srvcUuid,
307 int charInstId, ParcelUuid charUuid, byte[] value) {
308 if (DBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address
309 + " UUID=" + charUuid + " Status=" + status);
310
Matthew Xieddf7e472013-03-01 18:41:02 -0800311 if (!address.equals(mDevice.getAddress())) {
312 return;
313 }
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800314 if ((status == GATT_INSUFFICIENT_AUTHENTICATION
315 || status == GATT_INSUFFICIENT_ENCRYPTION)
316 && mAuthRetry == false) {
317 try {
318 mAuthRetry = true;
319 mService.readCharacteristic(mClientIf, address,
320 srvcType, srvcInstId, srvcUuid,
321 charInstId, charUuid, AUTHENTICATION_MITM);
322 return;
323 } catch (RemoteException e) {
324 Log.e(TAG,"",e);
325 }
326 }
327
328 mAuthRetry = false;
329
Matthew Xieddf7e472013-03-01 18:41:02 -0800330 BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800331 srvcInstId, srvcType);
332 if (service == null) return;
333
334 BluetoothGattCharacteristic characteristic = service.getCharacteristic(
335 charUuid.getUuid(), charInstId);
336 if (characteristic == null) return;
337
338 if (status == 0) characteristic.setValue(value);
339
340 try {
341 mCallback.onCharacteristicRead(characteristic, status);
342 } catch (Exception ex) {
343 Log.w(TAG, "Unhandled exception: " + ex);
344 }
345 }
346
347 /**
348 * Characteristic has been written to the remote device.
349 * Let the app know how we did...
350 * @hide
351 */
352 public void onCharacteristicWrite(String address, int status, int srvcType,
353 int srvcInstId, ParcelUuid srvcUuid,
354 int charInstId, ParcelUuid charUuid) {
355 if (DBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address
356 + " UUID=" + charUuid + " Status=" + status);
357
Matthew Xieddf7e472013-03-01 18:41:02 -0800358 if (!address.equals(mDevice.getAddress())) {
359 return;
360 }
361 BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800362 srvcInstId, srvcType);
363 if (service == null) return;
364
365 BluetoothGattCharacteristic characteristic = service.getCharacteristic(
366 charUuid.getUuid(), charInstId);
367 if (characteristic == null) return;
368
369 if ((status == GATT_INSUFFICIENT_AUTHENTICATION
370 || status == GATT_INSUFFICIENT_ENCRYPTION)
371 && mAuthRetry == false) {
372 try {
373 mAuthRetry = true;
374 mService.writeCharacteristic(mClientIf, address,
375 srvcType, srvcInstId, srvcUuid, charInstId, charUuid,
376 characteristic.getWriteType(), AUTHENTICATION_MITM,
377 characteristic.getValue());
378 return;
379 } catch (RemoteException e) {
380 Log.e(TAG,"",e);
381 }
382 }
383
384 mAuthRetry = false;
385
386 try {
387 mCallback.onCharacteristicWrite(characteristic, status);
388 } catch (Exception ex) {
389 Log.w(TAG, "Unhandled exception: " + ex);
390 }
391 }
392
393 /**
394 * Remote characteristic has been updated.
395 * Updates the internal value.
396 * @hide
397 */
398 public void onNotify(String address, int srvcType,
399 int srvcInstId, ParcelUuid srvcUuid,
400 int charInstId, ParcelUuid charUuid,
401 byte[] value) {
402 if (DBG) Log.d(TAG, "onNotify() - Device=" + address + " UUID=" + charUuid);
403
Matthew Xieddf7e472013-03-01 18:41:02 -0800404 if (!address.equals(mDevice.getAddress())) {
405 return;
406 }
407 BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800408 srvcInstId, srvcType);
409 if (service == null) return;
410
411 BluetoothGattCharacteristic characteristic = service.getCharacteristic(
412 charUuid.getUuid(), charInstId);
413 if (characteristic == null) return;
414
415 characteristic.setValue(value);
416
417 try {
418 mCallback.onCharacteristicChanged(characteristic);
419 } catch (Exception ex) {
420 Log.w(TAG, "Unhandled exception: " + ex);
421 }
422 }
423
424 /**
425 * Descriptor has been read.
426 * @hide
427 */
428 public void onDescriptorRead(String address, int status, int srvcType,
429 int srvcInstId, ParcelUuid srvcUuid,
430 int charInstId, ParcelUuid charUuid,
431 ParcelUuid descrUuid, byte[] value) {
432 if (DBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " UUID=" + charUuid);
433
Matthew Xieddf7e472013-03-01 18:41:02 -0800434 if (!address.equals(mDevice.getAddress())) {
435 return;
436 }
437 BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800438 srvcInstId, srvcType);
439 if (service == null) return;
440
441 BluetoothGattCharacteristic characteristic = service.getCharacteristic(
442 charUuid.getUuid(), charInstId);
443 if (characteristic == null) return;
444
445 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
446 descrUuid.getUuid());
447 if (descriptor == null) return;
448
449 if (status == 0) descriptor.setValue(value);
450
451 if ((status == GATT_INSUFFICIENT_AUTHENTICATION
452 || status == GATT_INSUFFICIENT_ENCRYPTION)
453 && mAuthRetry == false) {
454 try {
455 mAuthRetry = true;
456 mService.readDescriptor(mClientIf, address,
457 srvcType, srvcInstId, srvcUuid, charInstId, charUuid,
458 descrUuid, AUTHENTICATION_MITM);
459 } catch (RemoteException e) {
460 Log.e(TAG,"",e);
461 }
462 }
463
464 mAuthRetry = true;
465
466 try {
467 mCallback.onDescriptorRead(descriptor, status);
468 } catch (Exception ex) {
469 Log.w(TAG, "Unhandled exception: " + ex);
470 }
471 }
472
473 /**
474 * Descriptor write operation complete.
475 * @hide
476 */
477 public void onDescriptorWrite(String address, int status, int srvcType,
478 int srvcInstId, ParcelUuid srvcUuid,
479 int charInstId, ParcelUuid charUuid,
480 ParcelUuid descrUuid) {
481 if (DBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " UUID=" + charUuid);
482
Matthew Xieddf7e472013-03-01 18:41:02 -0800483 if (!address.equals(mDevice.getAddress())) {
484 return;
485 }
486 BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800487 srvcInstId, srvcType);
488 if (service == null) return;
489
490 BluetoothGattCharacteristic characteristic = service.getCharacteristic(
491 charUuid.getUuid(), charInstId);
492 if (characteristic == null) return;
493
494 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
495 descrUuid.getUuid());
496 if (descriptor == null) return;
497
498 if ((status == GATT_INSUFFICIENT_AUTHENTICATION
499 || status == GATT_INSUFFICIENT_ENCRYPTION)
500 && mAuthRetry == false) {
501 try {
502 mAuthRetry = true;
503 mService.writeDescriptor(mClientIf, address,
504 srvcType, srvcInstId, srvcUuid, charInstId, charUuid,
505 descrUuid, characteristic.getWriteType(),
506 AUTHENTICATION_MITM, descriptor.getValue());
507 } catch (RemoteException e) {
508 Log.e(TAG,"",e);
509 }
510 }
511
512 mAuthRetry = false;
513
514 try {
515 mCallback.onDescriptorWrite(descriptor, status);
516 } catch (Exception ex) {
517 Log.w(TAG, "Unhandled exception: " + ex);
518 }
519 }
520
521 /**
522 * Prepared write transaction completed (or aborted)
523 * @hide
524 */
525 public void onExecuteWrite(String address, int status) {
526 if (DBG) Log.d(TAG, "onExecuteWrite() - Device=" + address
527 + " status=" + status);
Matthew Xieddf7e472013-03-01 18:41:02 -0800528 if (!address.equals(mDevice.getAddress())) {
529 return;
530 }
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800531 try {
Matthew Xieddf7e472013-03-01 18:41:02 -0800532 mCallback.onReliableWriteCompleted(mDevice, status);
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800533 } catch (Exception ex) {
534 Log.w(TAG, "Unhandled exception: " + ex);
535 }
536 }
537
538 /**
539 * Remote device RSSI has been read
540 * @hide
541 */
542 public void onReadRemoteRssi(String address, int rssi, int status) {
543 if (DBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address +
544 " rssi=" + rssi + " status=" + status);
Matthew Xieddf7e472013-03-01 18:41:02 -0800545 if (!address.equals(mDevice.getAddress())) {
546 return;
547 }
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800548 try {
Matthew Xieddf7e472013-03-01 18:41:02 -0800549 mCallback.onReadRemoteRssi(mDevice, rssi, status);
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800550 } catch (Exception ex) {
551 Log.w(TAG, "Unhandled exception: " + ex);
552 }
553 }
554 };
555
Matthew Xieddf7e472013-03-01 18:41:02 -0800556 /*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device) {
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800557 mContext = context;
Matthew Xieddf7e472013-03-01 18:41:02 -0800558 mService = iGatt;
559 mDevice = device;
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800560 mServices = new ArrayList<BluetoothGattService>();
561
Matthew Xieddf7e472013-03-01 18:41:02 -0800562 mConnState = CONN_STATE_IDLE;
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800563 }
564
565 /**
566 * Close the connection to the gatt service.
567 */
568 /*package*/ void close() {
569 if (DBG) Log.d(TAG, "close()");
570
571 unregisterApp();
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800572 }
573
574 /**
575 * Returns a service by UUID, instance and type.
576 * @hide
577 */
578 /*package*/ BluetoothGattService getService(BluetoothDevice device, UUID uuid,
579 int instanceId, int type) {
580 for(BluetoothGattService svc : mServices) {
581 if (svc.getDevice().equals(device) &&
582 svc.getType() == type &&
583 svc.getInstanceId() == instanceId &&
584 svc.getUuid().equals(uuid)) {
585 return svc;
586 }
587 }
588 return null;
589 }
590
591
592 /**
Matthew Xieddf7e472013-03-01 18:41:02 -0800593 * Register an application callback to start using GATT.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800594 *
Matthew Xieddf7e472013-03-01 18:41:02 -0800595 * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
596 * is used to notify success or failure if the function returns true.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800597 *
598 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
599 *
Matthew Xieddf7e472013-03-01 18:41:02 -0800600 * @param callback GATT callback handler that will receive asynchronous callbacks.
601 * @return If true, the callback will be called to notify success or failure,
602 * false on immediate error
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800603 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800604 private boolean registerApp(BluetoothGattCallback callback) {
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800605 if (DBG) Log.d(TAG, "registerApp()");
606 if (mService == null) return false;
607
608 mCallback = callback;
609 UUID uuid = UUID.randomUUID();
610 if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);
611
612 try {
613 mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
614 } catch (RemoteException e) {
615 Log.e(TAG,"",e);
616 return false;
617 }
618
619 return true;
620 }
621
622 /**
623 * Unregister the current application and callbacks.
624 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800625 private void unregisterApp() {
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800626 if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf);
627 if (mService == null || mClientIf == 0) return;
628
629 try {
630 mCallback = null;
631 mService.unregisterClient(mClientIf);
632 mClientIf = 0;
633 } catch (RemoteException e) {
634 Log.e(TAG,"",e);
635 }
636 }
637
638 /**
Matthew Xieddf7e472013-03-01 18:41:02 -0800639 * Initiate a connection to a Bluetooth GATT capable device.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800640 *
641 * <p>The connection may not be established right away, but will be
642 * completed when the remote device is available. A
643 * {@link BluetoothGattCallback#onConnectionStateChange} callback will be
644 * invoked when the connection state changes as a result of this function.
645 *
646 * <p>The autoConnect paramter determines whether to actively connect to
647 * the remote device, or rather passively scan and finalize the connection
648 * when the remote device is in range/available. Generally, the first ever
649 * connection to a device should be direct (autoConnect set to false) and
650 * subsequent connections to known devices should be invoked with the
Matthew Xieddf7e472013-03-01 18:41:02 -0800651 * autoConnect parameter set to true.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800652 *
653 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
654 *
655 * @param device Remote device to connect to
656 * @param autoConnect Whether to directly connect to the remote device (false)
657 * or to automatically connect as soon as the remote
658 * device becomes available (true).
659 * @return true, if the connection attempt was initiated successfully
660 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800661 /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) {
662 if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
663 synchronized(mStateLock) {
664 if (mConnState != CONN_STATE_IDLE) {
665 throw new IllegalStateException("Not idle");
666 }
667 mConnState = CONN_STATE_CONNECTING;
668 }
669 if (!registerApp(callback)) {
670 synchronized(mStateLock) {
671 mConnState = CONN_STATE_IDLE;
672 }
673 Log.e(TAG, "Failed to register callback");
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800674 return false;
675 }
676
Matthew Xieddf7e472013-03-01 18:41:02 -0800677 // the connection will continue after successful callback registration
678 mAutoConnect = autoConnect;
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800679 return true;
680 }
681
682 /**
683 * Disconnects an established connection, or cancels a connection attempt
684 * currently in progress.
685 *
686 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800687 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800688 public void disconnect() {
689 if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800690 if (mService == null || mClientIf == 0) return;
691
692 try {
Matthew Xieddf7e472013-03-01 18:41:02 -0800693 mService.clientDisconnect(mClientIf, mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800694 } catch (RemoteException e) {
695 Log.e(TAG,"",e);
696 }
Matthew Xieddf7e472013-03-01 18:41:02 -0800697 // TBD deregister after conneciton is torn down
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800698 }
699
700 /**
701 * Discovers services offered by a remote device as well as their
702 * characteristics and descriptors.
703 *
704 * <p>This is an asynchronous operation. Once service discovery is completed,
705 * the {@link BluetoothGattCallback#onServicesDiscovered} callback is
706 * triggered. If the discovery was successful, the remote services can be
707 * retrieved using the {@link #getServices} function.
708 *
709 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
710 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800711 * @return true, if the remote service discovery has been started
712 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800713 public boolean discoverServices() {
714 if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800715 if (mService == null || mClientIf == 0) return false;
716
717 mServices.clear();
718
719 try {
Matthew Xieddf7e472013-03-01 18:41:02 -0800720 mService.discoverServices(mClientIf, mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800721 } catch (RemoteException e) {
722 Log.e(TAG,"",e);
723 return false;
724 }
725
726 return true;
727 }
728
729 /**
730 * Returns a list of GATT services offered by the remote device.
731 *
732 * <p>This function requires that service discovery has been completed
733 * for the given device.
734 *
735 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
736 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800737 * @return List of services on the remote device. Returns an empty list
738 * if service discovery has not yet been performed.
739 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800740 public List<BluetoothGattService> getServices() {
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800741 List<BluetoothGattService> result =
742 new ArrayList<BluetoothGattService>();
743
744 for (BluetoothGattService service : mServices) {
Matthew Xieddf7e472013-03-01 18:41:02 -0800745 if (service.getDevice().equals(mDevice)) {
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800746 result.add(service);
747 }
748 }
749
750 return result;
751 }
752
753 /**
754 * Returns a {@link BluetoothGattService}, if the requested UUID is
755 * supported by the remote device.
756 *
757 * <p>This function requires that service discovery has been completed
758 * for the given device.
759 *
760 * <p>If multiple instances of the same service (as identified by UUID)
761 * exist, the first instance of the service is returned.
762 *
763 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
764 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800765 * @param uuid UUID of the requested service
766 * @return BluetoothGattService if supported, or null if the requested
767 * service is not offered by the remote device.
768 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800769 public BluetoothGattService getService(UUID uuid) {
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800770 for (BluetoothGattService service : mServices) {
Matthew Xieddf7e472013-03-01 18:41:02 -0800771 if (service.getDevice().equals(mDevice) &&
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800772 service.getUuid().equals(uuid)) {
773 return service;
774 }
775 }
776
777 return null;
778 }
779
780 /**
781 * Reads the requested characteristic from the associated remote device.
782 *
783 * <p>This is an asynchronous operation. The result of the read operation
784 * is reported by the {@link BluetoothGattCallback#onCharacteristicRead}
785 * callback.
786 *
787 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
788 *
789 * @param characteristic Characteristic to read from the remote device
790 * @return true, if the read operation was initiated successfully
791 */
792 public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
793 if ((characteristic.getProperties() &
794 BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false;
795
796 if (DBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid());
797 if (mService == null || mClientIf == 0) return false;
798
799 BluetoothGattService service = characteristic.getService();
800 if (service == null) return false;
801
802 BluetoothDevice device = service.getDevice();
803 if (device == null) return false;
804
805 try {
806 mService.readCharacteristic(mClientIf, device.getAddress(),
807 service.getType(), service.getInstanceId(),
808 new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
809 new ParcelUuid(characteristic.getUuid()), AUTHENTICATION_NONE);
810 } catch (RemoteException e) {
811 Log.e(TAG,"",e);
812 return false;
813 }
814
815 return true;
816 }
817
818 /**
Matthew Xieddf7e472013-03-01 18:41:02 -0800819 * Writes a given characteristic and its values to the associated remote device.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800820 *
821 * <p>Once the write operation has been completed, the
822 * {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked,
823 * reporting the result of the operation.
824 *
825 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
826 *
827 * @param characteristic Characteristic to write on the remote device
828 * @return true, if the write operation was initiated successfully
829 */
830 public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
831 if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
832 && (characteristic.getProperties() &
833 BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;
834
835 if (DBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
836 if (mService == null || mClientIf == 0) return false;
837
838 BluetoothGattService service = characteristic.getService();
839 if (service == null) return false;
840
841 BluetoothDevice device = service.getDevice();
842 if (device == null) return false;
843
844 try {
845 mService.writeCharacteristic(mClientIf, device.getAddress(),
846 service.getType(), service.getInstanceId(),
847 new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
848 new ParcelUuid(characteristic.getUuid()),
849 characteristic.getWriteType(), AUTHENTICATION_NONE,
850 characteristic.getValue());
851 } catch (RemoteException e) {
852 Log.e(TAG,"",e);
853 return false;
854 }
855
856 return true;
857 }
858
859 /**
860 * Reads the value for a given descriptor from the associated remote device.
861 *
862 * <p>Once the read operation has been completed, the
863 * {@link BluetoothGattCallback#onDescriptorRead} callback is
864 * triggered, signaling the result of the operation.
865 *
866 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
867 *
868 * @param descriptor Descriptor value to read from the remote device
869 * @return true, if the read operation was initiated successfully
870 */
871 public boolean readDescriptor(BluetoothGattDescriptor descriptor) {
872 if (DBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid());
873 if (mService == null || mClientIf == 0) return false;
874
875 BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
876 if (characteristic == null) return false;
877
878 BluetoothGattService service = characteristic.getService();
879 if (service == null) return false;
880
881 BluetoothDevice device = service.getDevice();
882 if (device == null) return false;
883
884 try {
885 mService.readDescriptor(mClientIf, device.getAddress(),
886 service.getType(), service.getInstanceId(),
887 new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
888 new ParcelUuid(characteristic.getUuid()),
889 new ParcelUuid(descriptor.getUuid()), AUTHENTICATION_NONE);
890 } catch (RemoteException e) {
891 Log.e(TAG,"",e);
892 return false;
893 }
894
895 return true;
896 }
897
898 /**
899 * Write the value of a given descriptor to the associated remote device.
900 *
901 * <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is
902 * triggered to report the result of the write operation.
903 *
904 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
905 *
906 * @param descriptor Descriptor to write to the associated remote device
907 * @return true, if the write operation was initiated successfully
908 */
909 public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
910 if (DBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid());
911 if (mService == null || mClientIf == 0) return false;
912
913 BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
914 if (characteristic == null) return false;
915
916 BluetoothGattService service = characteristic.getService();
917 if (service == null) return false;
918
919 BluetoothDevice device = service.getDevice();
920 if (device == null) return false;
921
922 try {
923 mService.writeDescriptor(mClientIf, device.getAddress(),
924 service.getType(), service.getInstanceId(),
925 new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
926 new ParcelUuid(characteristic.getUuid()),
927 new ParcelUuid(descriptor.getUuid()),
928 characteristic.getWriteType(), AUTHENTICATION_NONE,
929 descriptor.getValue());
930 } catch (RemoteException e) {
931 Log.e(TAG,"",e);
932 return false;
933 }
934
935 return true;
936 }
937
938 /**
939 * Initiates a reliable write transaction for a given remote device.
940 *
941 * <p>Once a reliable write transaction has been initiated, all calls
942 * to {@link #writeCharacteristic} are sent to the remote device for
943 * verification and queued up for atomic execution. The application will
944 * receive an {@link BluetoothGattCallback#onCharacteristicWrite} callback
945 * in response to every {@link #writeCharacteristic} call and is responsible
946 * for verifying if the value has been transmitted accurately.
947 *
948 * <p>After all characteristics have been queued up and verified,
949 * {@link #executeReliableWrite} will execute all writes. If a characteristic
950 * was not written correctly, calling {@link #abortReliableWrite} will
951 * cancel the current transaction without commiting any values on the
952 * remote device.
953 *
954 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
955 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800956 * @return true, if the reliable write transaction has been initiated
957 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800958 public boolean beginReliableWrite() {
959 if (DBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800960 if (mService == null || mClientIf == 0) return false;
961
962 try {
Matthew Xieddf7e472013-03-01 18:41:02 -0800963 mService.beginReliableWrite(mClientIf, mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800964 } catch (RemoteException e) {
965 Log.e(TAG,"",e);
966 return false;
967 }
968
969 return true;
970 }
971
972 /**
973 * Executes a reliable write transaction for a given remote device.
974 *
975 * <p>This function will commit all queued up characteristic write
976 * operations for a given remote device.
977 *
978 * <p>A {@link BluetoothGattCallback#onReliableWriteCompleted} callback is
979 * invoked to indicate whether the transaction has been executed correctly.
980 *
981 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
982 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800983 * @return true, if the request to execute the transaction has been sent
984 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800985 public boolean executeReliableWrite() {
986 if (DBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800987 if (mService == null || mClientIf == 0) return false;
988
989 try {
Matthew Xieddf7e472013-03-01 18:41:02 -0800990 mService.endReliableWrite(mClientIf, mDevice.getAddress(), true);
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800991 } catch (RemoteException e) {
992 Log.e(TAG,"",e);
993 return false;
994 }
995
996 return true;
997 }
998
999 /**
1000 * Cancels a reliable write transaction for a given device.
1001 *
1002 * <p>Calling this function will discard all queued characteristic write
1003 * operations for a given remote device.
1004 *
1005 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001006 */
Matthew Xieddf7e472013-03-01 18:41:02 -08001007 public void abortReliableWrite(BluetoothDevice mDevice) {
1008 if (DBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001009 if (mService == null || mClientIf == 0) return;
1010
1011 try {
Matthew Xieddf7e472013-03-01 18:41:02 -08001012 mService.endReliableWrite(mClientIf, mDevice.getAddress(), false);
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001013 } catch (RemoteException e) {
1014 Log.e(TAG,"",e);
1015 }
1016 }
1017
1018 /**
1019 * Enable or disable notifications/indications for a given characteristic.
1020 *
1021 * <p>Once notifications are enabled for a characteristic, a
1022 * {@link BluetoothGattCallback#onCharacteristicChanged} callback will be
1023 * triggered if the remote device indicates that the given characteristic
1024 * has changed.
1025 *
1026 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
1027 *
1028 * @param characteristic The characteristic for which to enable notifications
1029 * @param enable Set to true to enable notifications/indications
1030 * @return true, if the requested notification status was set successfully
1031 */
1032 public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
1033 boolean enable) {
1034 if (DBG) Log.d(TAG, "setCharacteristicNotification() - uuid: " + characteristic.getUuid()
1035 + " enable: " + enable);
1036 if (mService == null || mClientIf == 0) return false;
1037
1038 BluetoothGattService service = characteristic.getService();
1039 if (service == null) return false;
1040
1041 BluetoothDevice device = service.getDevice();
1042 if (device == null) return false;
1043
1044 try {
1045 mService.registerForNotification(mClientIf, device.getAddress(),
1046 service.getType(), service.getInstanceId(),
1047 new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
1048 new ParcelUuid(characteristic.getUuid()),
1049 enable);
1050 } catch (RemoteException e) {
1051 Log.e(TAG,"",e);
1052 return false;
1053 }
1054
1055 return true;
1056 }
1057
1058 /**
1059 * Clears the internal cache and forces a refresh of the services from the
1060 * remote device.
1061 * @hide
1062 */
Matthew Xieddf7e472013-03-01 18:41:02 -08001063 public boolean refresh() {
1064 if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001065 if (mService == null || mClientIf == 0) return false;
1066
1067 try {
Matthew Xieddf7e472013-03-01 18:41:02 -08001068 mService.refreshDevice(mClientIf, mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001069 } catch (RemoteException e) {
1070 Log.e(TAG,"",e);
1071 return false;
1072 }
1073
1074 return true;
1075 }
1076
1077 /**
1078 * Read the RSSI for a connected remote device.
1079 *
1080 * <p>The {@link BluetoothGattCallback#onReadRemoteRssi} callback will be
1081 * invoked when the RSSI value has been read.
1082 *
1083 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
1084 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001085 * @return true, if the RSSI value has been requested successfully
1086 */
Matthew Xieddf7e472013-03-01 18:41:02 -08001087 public boolean readRemoteRssi() {
1088 if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001089 if (mService == null || mClientIf == 0) return false;
1090
1091 try {
Matthew Xieddf7e472013-03-01 18:41:02 -08001092 mService.readRemoteRssi(mClientIf, mDevice.getAddress());
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001093 } catch (RemoteException e) {
1094 Log.e(TAG,"",e);
1095 return false;
1096 }
1097
1098 return true;
1099 }
1100
1101 /**
Matthew Xieddf7e472013-03-01 18:41:02 -08001102 * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
1103 * with {@link BluetoothProfile#GATT} as argument
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001104 *
Matthew Xieddf7e472013-03-01 18:41:02 -08001105 * @throws UnsupportedOperationException
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001106 */
1107 @Override
1108 public int getConnectionState(BluetoothDevice device) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001109 throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001110 }
1111
1112 /**
Matthew Xieddf7e472013-03-01 18:41:02 -08001113 * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
1114 * with {@link BluetoothProfile#GATT} as argument
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001115 *
Matthew Xieddf7e472013-03-01 18:41:02 -08001116 * @throws UnsupportedOperationException
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001117 */
1118 @Override
1119 public List<BluetoothDevice> getConnectedDevices() {
Matthew Xieddf7e472013-03-01 18:41:02 -08001120 throw new UnsupportedOperationException
1121 ("Use BluetoothManager#getConnectedDevices instead.");
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001122 }
1123
1124 /**
Matthew Xieddf7e472013-03-01 18:41:02 -08001125 * Not supported - please use
1126 * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])}
1127 * with {@link BluetoothProfile#GATT} as first argument
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001128 *
Matthew Xieddf7e472013-03-01 18:41:02 -08001129 * @throws UnsupportedOperationException
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001130 */
1131 @Override
1132 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001133 throw new UnsupportedOperationException
1134 ("Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001135 }
1136}