1 /* 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 17 package com.android.cts.verifier.bluetooth; 18 19 import android.app.Service; 20 import android.bluetooth.BluetoothDevice; 21 import android.bluetooth.BluetoothGatt; 22 import android.bluetooth.BluetoothGattCharacteristic; 23 import android.bluetooth.BluetoothGattDescriptor; 24 import android.bluetooth.BluetoothGattServer; 25 import android.bluetooth.BluetoothGattServerCallback; 26 import android.bluetooth.BluetoothGattService; 27 import android.bluetooth.BluetoothManager; 28 import android.bluetooth.BluetoothProfile; 29 import android.bluetooth.le.AdvertiseCallback; 30 import android.bluetooth.le.AdvertiseData; 31 import android.bluetooth.le.AdvertiseSettings; 32 import android.bluetooth.le.BluetoothLeAdvertiser; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.os.Build; 36 import android.os.Handler; 37 import android.os.IBinder; 38 import android.os.ParcelUuid; 39 import android.util.Log; 40 import android.widget.Toast; 41 42 import com.android.cts.verifier.R; 43 44 import java.util.Arrays; 45 import java.util.Set; 46 import java.util.Timer; 47 import java.util.UUID; 48 49 public class BleServerService extends Service { 50 51 public static final boolean DEBUG = true; 52 public static final String TAG = "BleServerService"; 53 54 public static final int COMMAND_ADD_SERVICE = 0; 55 public static final int COMMAND_WRITE_CHARACTERISTIC = 1; 56 public static final int COMMAND_WRITE_DESCRIPTOR = 2; 57 58 public static final String BLE_BLUETOOTH_MISMATCH_SECURE = 59 "com.android.cts.verifier.bluetooth.BLE_BLUETOOTH_MISMATCH_SECURE"; 60 public static final String BLE_BLUETOOTH_MISMATCH_INSECURE = 61 "com.android.cts.verifier.bluetooth.BLE_BLUETOOTH_MISMATCH_INSECURE"; 62 public static final String BLE_BLUETOOTH_DISABLED = 63 "com.android.cts.verifier.bluetooth.BLE_BLUETOOTH_DISABLED"; 64 public static final String BLE_ACTION_SERVER_SECURE = 65 "com.android.cts.verifier.bluetooth.BLE_ACTION_SERVER_SECURE"; 66 public static final String BLE_ACTION_SERVER_NON_SECURE = 67 "com.android.cts.verifier.bluetooth.BLE_ACTION_SERVER_NON_SECURE"; 68 69 70 public static final String BLE_SERVER_CONNECTED = 71 "com.android.cts.verifier.bluetooth.BLE_SERVER_CONNECTED"; 72 public static final String BLE_SERVER_DISCONNECTED = 73 "com.android.cts.verifier.bluetooth.BLE_SERVER_DISCONNECTED"; 74 public static final String BLE_SERVICE_ADDED = 75 "com.android.cts.verifier.bluetooth.BLE_SERVICE_ADDED"; 76 public static final String BLE_MTU_REQUEST_23BYTES = 77 "com.android.cts.verifier.bluetooth.BLE_MTU_REQUEST_23BYTES"; 78 public static final String BLE_MTU_REQUEST_512BYTES = 79 "com.android.cts.verifier.bluetooth.BLE_MTU_REQUEST_512BYTES"; 80 /* This is sent when Client perform MTU Exchange more than once */ 81 public static final String BLE_MTU_BAD_REQUEST = 82 "com.android.cts.verifier.bluetooth.BLE_MTU_BAD_REQUEST"; 83 public static final String BLE_CHARACTERISTIC_READ_REQUEST = 84 "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_READ_REQUEST"; 85 public static final String BLE_CHARACTERISTIC_WRITE_REQUEST = 86 "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_WRITE_REQUEST"; 87 public static final String BLE_CHARACTERISTIC_READ_REQUEST_WITHOUT_PERMISSION = 88 "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_READ_REQUEST_WITHOUT_PERMISSION"; 89 public static final String BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION = 90 "com.android.cts.verifier.bluetooth" 91 + ".BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION"; 92 public static final String BLE_CHARACTERISTIC_READ_REQUEST_NEED_ENCRYPTED = 93 "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_READ_REQUEST_NEED_ENCRYPTED"; 94 public static final String BLE_CHARACTERISTIC_WRITE_REQUEST_NEED_ENCRYPTED = 95 "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_WRITE_REQUEST_NEED_ENCRYPTED"; 96 public static final String BLE_CHARACTERISTIC_NOTIFICATION_REQUEST = 97 "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_NOTIFICATION_REQUEST"; 98 public static final String BLE_CHARACTERISTIC_INDICATE_REQUEST = 99 "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_INDICATE_REQUEST"; 100 public static final String BLE_DESCRIPTOR_READ_REQUEST = 101 "com.android.cts.verifier.bluetooth.BLE_DESCRIPTOR_READ_REQUEST"; 102 public static final String BLE_DESCRIPTOR_WRITE_REQUEST = 103 "com.android.cts.verifier.bluetooth.BLE_DESCRIPTOR_WRITE_REQUEST"; 104 public static final String BLE_DESCRIPTOR_READ_REQUEST_WITHOUT_PERMISSION = 105 "com.android.cts.verifier.bluetooth.BLE_DESCRIPTOR_READ_REQUEST_WITHOUT_PERMISSION"; 106 public static final String BLE_DESCRIPTOR_WRITE_REQUEST_WITHOUT_PERMISSION = 107 "com.android.cts.verifier.bluetooth.BLE_DESCRIPTOR_WRITE_REQUEST_WITHOUT_PERMISSION"; 108 public static final String BLE_DESCRIPTOR_READ_REQUEST_NEED_ENCRYPTED = 109 "com.android.cts.verifier.bluetooth.BLE_DESCRIPTOR_READ_REQUEST_NEED_ENCRYPTED"; 110 public static final String BLE_DESCRIPTOR_WRITE_REQUEST_NEED_ENCRYPTED = 111 "com.android.cts.verifier.bluetooth.BLE_DESCRIPTOR_WRITE_REQUEST_NEED_ENCRYPTED"; 112 public static final String BLE_EXECUTE_WRITE = 113 "com.android.cts.verifier.bluetooth.BLE_EXECUTE_WRITE"; 114 public static final String BLE_OPEN_FAIL = 115 "com.android.cts.verifier.bluetooth.BLE_OPEN_FAIL"; 116 public static final String BLE_RELIABLE_WRITE_BAD_RESP = 117 "com.android.cts.verifier.bluetooth.BLE_RELIABLE_WRITE_BAD_RESP"; 118 public static final String BLE_ADVERTISE_UNSUPPORTED = 119 "com.android.cts.verifier.bluetooth.BLE_ADVERTISE_UNSUPPORTED"; 120 public static final String BLE_ADD_SERVICE_FAIL = 121 "com.android.cts.verifier.bluetooth.BLE_ADD_SERVICE_FAIL"; 122 public static final String BLE_SERVICE_CHANGED_INDICATION = 123 "com.android.cts.verifier.bluetooth.BLE_SERVICE_CHANGED_INDICATION"; 124 125 private static final UUID SERVICE_UUID = 126 UUID.fromString("00009999-0000-1000-8000-00805f9b34fb"); 127 private static final UUID CHARACTERISTIC_UUID = 128 UUID.fromString("00009998-0000-1000-8000-00805f9b34fb"); 129 private static final UUID CHARACTERISTIC_RESULT_UUID = 130 UUID.fromString("00009974-0000-1000-8000-00805f9b34fb"); 131 private static final UUID UPDATE_CHARACTERISTIC_UUID = 132 UUID.fromString("00009997-0000-1000-8000-00805f9b34fb"); 133 private static final UUID DESCRIPTOR_UUID = 134 UUID.fromString("00009996-0000-1000-8000-00805f9b34fb"); 135 public static final UUID ADV_SERVICE_UUID = 136 UUID.fromString("00003333-0000-1000-8000-00805f9b34fb"); 137 138 private static final UUID SERVICE_UUID_ADDITIONAL = 139 UUID.fromString("00009995-0000-1000-8000-00805f9b34fb"); 140 private static final UUID SERVICE_UUID_INCLUDED = 141 UUID.fromString("00009994-0000-1000-8000-00805f9b34fb"); 142 private static final UUID SERVICE_UUID_SERVICE_CHANGED = 143 UUID.fromString("00009993-0000-1000-8000-00805f9b34fb"); 144 145 // Variable for registration permission of Characteristic 146 private static final UUID CHARACTERISTIC_NO_READ_UUID = 147 UUID.fromString("00009984-0000-1000-8000-00805f9b34fb"); 148 private static final UUID CHARACTERISTIC_NO_WRITE_UUID = 149 UUID.fromString("00009983-0000-1000-8000-00805f9b34fb"); 150 private static final UUID CHARACTERISTIC_NEED_ENCRYPTED_READ_UUID = 151 UUID.fromString("00009982-0000-1000-8000-00805f9b34fb"); 152 private static final UUID CHARACTERISTIC_NEED_ENCRYPTED_WRITE_UUID = 153 UUID.fromString("00009981-0000-1000-8000-00805f9b34fb"); 154 155 // Variable for registration permission of Descriptor 156 private static final UUID DESCRIPTOR_NO_READ_UUID = 157 UUID.fromString("00009973-0000-1000-8000-00805f9b34fb"); 158 private static final UUID DESCRIPTOR_NO_WRITE_UUID = 159 UUID.fromString("00009972-0000-1000-8000-00805f9b34fb"); 160 private static final UUID DESCRIPTOR_NEED_ENCRYPTED_READ_UUID = 161 UUID.fromString("00009969-0000-1000-8000-00805f9b34fb"); 162 private static final UUID DESCRIPTOR_NEED_ENCRYPTED_WRITE_UUID = 163 UUID.fromString("00009968-0000-1000-8000-00805f9b34fb"); 164 165 // Variable for registration upper limit confirmation of Characteristic 166 private static final UUID UPDATE_CHARACTERISTIC_UUID_1 = 167 UUID.fromString("00009989-0000-1000-8000-00805f9b34fb"); 168 private static final UUID UPDATE_CHARACTERISTIC_UUID_2 = 169 UUID.fromString("00009988-0000-1000-8000-00805f9b34fb"); 170 private static final UUID UPDATE_CHARACTERISTIC_UUID_3 = 171 UUID.fromString("00009987-0000-1000-8000-00805f9b34fb"); 172 private static final UUID UPDATE_CHARACTERISTIC_UUID_4 = 173 UUID.fromString("00009986-0000-1000-8000-00805f9b34fb"); 174 private static final UUID UPDATE_CHARACTERISTIC_UUID_5 = 175 UUID.fromString("00009985-0000-1000-8000-00805f9b34fb"); 176 private static final UUID UPDATE_CHARACTERISTIC_UUID_6 = 177 UUID.fromString("00009979-0000-1000-8000-00805f9b34fb"); 178 private static final UUID UPDATE_CHARACTERISTIC_UUID_7 = 179 UUID.fromString("00009978-0000-1000-8000-00805f9b34fb"); 180 private static final UUID UPDATE_CHARACTERISTIC_UUID_8 = 181 UUID.fromString("00009977-0000-1000-8000-00805f9b34fb"); 182 private static final UUID UPDATE_CHARACTERISTIC_UUID_9 = 183 UUID.fromString("00009976-0000-1000-8000-00805f9b34fb"); 184 private static final UUID UPDATE_CHARACTERISTIC_UUID_10 = 185 UUID.fromString("00009975-0000-1000-8000-00805f9b34fb"); 186 private static final UUID UPDATE_CHARACTERISTIC_UUID_11 = 187 UUID.fromString("00009959-0000-1000-8000-00805f9b34fb"); 188 private static final UUID UPDATE_CHARACTERISTIC_UUID_12 = 189 UUID.fromString("00009958-0000-1000-8000-00805f9b34fb"); 190 private static final UUID UPDATE_CHARACTERISTIC_UUID_13 = 191 UUID.fromString("00009957-0000-1000-8000-00805f9b34fb"); 192 private static final UUID UPDATE_CHARACTERISTIC_UUID_14 = 193 UUID.fromString("00009956-0000-1000-8000-00805f9b34fb"); 194 private static final UUID UPDATE_CHARACTERISTIC_UUID_15 = 195 UUID.fromString("00009955-0000-1000-8000-00805f9b34fb"); 196 197 // Variable for registration characteristic of service changed service 198 private static final UUID SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID = 199 UUID.fromString("00009949-0000-1000-8000-00805f9b34fb"); 200 private static final UUID SERVICE_CHANGED_CHARACTERISTIC_UUID = 201 UUID.fromString("00009948-0000-1000-8000-00805f9b34fb"); 202 203 private static final UUID UPDATE_DESCRIPTOR_UUID = 204 UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); 205 206 private static final UUID INDICATE_CHARACTERISTIC_UUID = 207 UUID.fromString("00009971-0000-1000-8000-00805f9b34fb"); 208 209 private static final int CONN_INTERVAL = 150; // connection interval 150ms 210 211 // Delay of notification when secure test failed to start. 212 private static final long NOTIFICATION_DELAY_OF_SECURE_TEST_FAILURE = 5 * 1000; 213 214 public static final String WRITE_VALUE = "SERVER_TEST"; 215 public static final String NOTIFY_VALUE = "NOTIFY_TEST"; 216 public static final String INDICATE_VALUE = "INDICATE_TEST"; 217 public static final String READ_NO_PERMISSION = "READ_NO_CHAR"; 218 public static final String WRITE_NO_PERMISSION = "WRITE_NO_CHAR"; 219 public static final String DESCRIPTOR_READ_NO_PERMISSION = "READ_NO_DESC"; 220 public static final String DESCRIPTOR_WRITE_NO_PERMISSION = "WRITE_NO_DESC"; 221 222 private BluetoothManager mBluetoothManager; 223 private BluetoothGattServer mGattServer; 224 private BluetoothGattService mService; 225 private BluetoothDevice mDevice; 226 private Timer mNotificationTimer; 227 private Handler mHandler; 228 private String mReliableWriteValue; 229 private BluetoothLeAdvertiser mAdvertiser; 230 private boolean mIndicated; 231 private int mNotifyCount; 232 private boolean mSecure; 233 private int mExpectWritesDuringMtuChangeCount; 234 private int mMtuSize = -1; 235 private String mMtuTestReceivedData = ""; 236 private Runnable mResetValuesTask; 237 private BluetoothGattService mAdditionalNotificationService; 238 private BluetoothGattService mServiceChangedService; 239 240 // Task to notify failure of starting secure test. 241 // Secure test calls BluetoothDevice#createBond() when devices were not paired. 242 // createBond() causes onConnectionStateChange() twice, and it works as strange sequence. 243 // At the first onConnectionStateChange(), target device is not paired(bond state is 244 // BluetoothDevice.BOND_NONE). 245 // At the second onConnectionStateChange(), target devices is paired(bond state is 246 // BluetoothDevice.BOND_BONDED). 247 // CTS Verifier will perform lazy check of bond state.Verifier checks bond state 248 // after NOTIFICATION_DELAY_OF_SECURE_TEST_FAILURE from the first onConnectionStateChange(). 249 private Runnable mNotificationTaskOfSecureTestStartFailure; 250 251 @Override onCreate()252 public void onCreate() { 253 super.onCreate(); 254 255 mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 256 mAdvertiser = mBluetoothManager.getAdapter().getBluetoothLeAdvertiser(); 257 mGattServer = mBluetoothManager.openGattServer(this, mCallbacks); 258 259 mService = createService(); 260 mAdditionalNotificationService = createAdditionalNotificationService(); 261 mServiceChangedService = createServiceChangedService(); 262 263 mDevice = null; 264 mReliableWriteValue = ""; 265 266 mHandler = new Handler(); 267 if (!mBluetoothManager.getAdapter().isEnabled()) { 268 notifyBluetoothDisabled(); 269 } else if (mGattServer == null) { 270 notifyOpenFail(); 271 } else if (mAdvertiser == null) { 272 notifyAdvertiseUnsupported(); 273 } else { 274 // start adding services 275 mNotifyCount = 11; 276 mSecure = false; 277 mExpectWritesDuringMtuChangeCount = 0; 278 if (!mGattServer.addService(mService)) { 279 notifyAddServiceFail(); 280 } 281 } 282 } 283 notifyBluetoothDisabled()284 private void notifyBluetoothDisabled() { 285 Intent intent = new Intent(BLE_BLUETOOTH_DISABLED); 286 sendBroadcast(intent); 287 } 288 notifyMismatchSecure()289 private void notifyMismatchSecure() { 290 Intent intent = new Intent(BLE_BLUETOOTH_MISMATCH_SECURE); 291 sendBroadcast(intent); 292 } 293 notifyMismatchInsecure()294 private void notifyMismatchInsecure() { 295 /* 296 Intent intent = new Intent(BLE_BLUETOOTH_MISMATCH_INSECURE); 297 sendBroadcast(intent); 298 */ 299 } 300 301 @Override onStartCommand(Intent intent, int flags, int startId)302 public int onStartCommand(Intent intent, int flags, int startId) { 303 String action = intent.getAction(); 304 if (action != null) { 305 switch (action) { 306 case BLE_ACTION_SERVER_SECURE: 307 mSecure = true; 308 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) { 309 showMessage("Skip MTU test."); 310 notifyMtuRequest(BLE_MTU_REQUEST_23BYTES); 311 notifyMtuRequest(BLE_MTU_REQUEST_512BYTES); 312 } 313 break; 314 case BLE_ACTION_SERVER_NON_SECURE: 315 mSecure = false; 316 break; 317 } 318 } 319 320 if (mBluetoothManager.getAdapter().isEnabled() && (mAdvertiser != null)) { 321 startAdvertise(); 322 } 323 return START_NOT_STICKY; 324 } 325 326 @Override onBind(Intent intent)327 public IBinder onBind(Intent intent) { 328 return null; 329 } 330 331 @Override onDestroy()332 public void onDestroy() { 333 super.onDestroy(); 334 cancelNotificationTaskOfSecureTestStartFailure(); 335 stopAdvertise(); 336 if (mGattServer == null) { 337 return; 338 } 339 if (mDevice != null) { 340 mGattServer.cancelConnection(mDevice); 341 } 342 mGattServer.clearServices(); 343 mGattServer.close(); 344 } 345 346 /** 347 * Sets default value to characteristic and descriptor. 348 * 349 * Set operation will be done after connection interval. 350 * (If set values immediately, multiple read/write operations may fail.) 351 */ resetValues()352 private synchronized void resetValues() { 353 // cancel pending task 354 if (mResetValuesTask != null) { 355 mHandler.removeCallbacks(mResetValuesTask); 356 mResetValuesTask = null; 357 } 358 359 // reserve task 360 mResetValuesTask = new Runnable() { 361 @Override 362 public void run() { 363 getCharacteristic(CHARACTERISTIC_UUID).setValue(WRITE_VALUE.getBytes()); 364 getDescriptor().setValue(WRITE_VALUE.getBytes()); 365 } 366 }; 367 mHandler.postDelayed(mResetValuesTask, CONN_INTERVAL); 368 } 369 notifyOpenFail()370 private void notifyOpenFail() { 371 if (DEBUG) { 372 Log.d(TAG, "notifyOpenFail"); 373 } 374 Intent intent = new Intent(BLE_OPEN_FAIL); 375 sendBroadcast(intent); 376 } 377 notifyAddServiceFail()378 private void notifyAddServiceFail() { 379 if (DEBUG) { 380 Log.d(TAG, "notifyAddServiceFail"); 381 } 382 Intent intent = new Intent(BLE_ADD_SERVICE_FAIL); 383 sendBroadcast(intent); 384 } 385 notifyAdvertiseUnsupported()386 private void notifyAdvertiseUnsupported() { 387 if (DEBUG) { 388 Log.d(TAG, "notifyAdvertiseUnsupported"); 389 } 390 Intent intent = new Intent(BLE_ADVERTISE_UNSUPPORTED); 391 sendBroadcast(intent); 392 } 393 notifyConnected()394 private void notifyConnected() { 395 if (DEBUG) { 396 Log.d(TAG, "notifyConnected"); 397 } 398 399 Intent intent = new Intent(BLE_SERVER_CONNECTED); 400 sendBroadcast(intent); 401 resetValues(); 402 } 403 notifyDisconnected()404 private void notifyDisconnected() { 405 if (DEBUG) { 406 Log.d(TAG, "notifyDisconnected"); 407 } 408 Intent intent = new Intent(BLE_SERVER_DISCONNECTED); 409 sendBroadcast(intent); 410 } 411 notifyServiceAdded()412 private void notifyServiceAdded() { 413 if (DEBUG) { 414 Log.d(TAG, "notifyServiceAdded"); 415 } 416 Intent intent = new Intent(BLE_SERVICE_ADDED); 417 sendBroadcast(intent); 418 } 419 notifyMtuRequest(String action)420 private void notifyMtuRequest(String action) { 421 if (DEBUG) { 422 Log.d(TAG, "notifyMtuRequest : " + action); 423 } 424 Intent intent = new Intent(action); 425 426 sendBroadcast(intent); 427 } 428 notifyCharacteristicReadRequest(boolean resetValues)429 private void notifyCharacteristicReadRequest(boolean resetValues) { 430 if (DEBUG) { 431 Log.d(TAG, "notifyCharacteristicReadRequest"); 432 } 433 Intent intent = new Intent(BLE_CHARACTERISTIC_READ_REQUEST); 434 sendBroadcast(intent); 435 436 if (resetValues) { 437 resetValues(); 438 } 439 } 440 notifyCharacteristicWriteRequest()441 private void notifyCharacteristicWriteRequest() { 442 if (DEBUG) { 443 Log.d(TAG, "notifyCharacteristicWriteRequest"); 444 } 445 Intent intent = new Intent(BLE_CHARACTERISTIC_WRITE_REQUEST); 446 sendBroadcast(intent); 447 448 resetValues(); 449 } 450 notifyCharacteristicReadRequestWithoutPermission()451 private void notifyCharacteristicReadRequestWithoutPermission() { 452 if (DEBUG) { 453 Log.d(TAG, "notifyCharacteristicReadRequestWithoutPermission"); 454 } 455 Intent intent = new Intent(BLE_CHARACTERISTIC_READ_REQUEST_WITHOUT_PERMISSION); 456 sendBroadcast(intent); 457 458 resetValues(); 459 } 460 notifyCharacteristicWriteRequestWithoutPermission()461 private void notifyCharacteristicWriteRequestWithoutPermission() { 462 if (DEBUG) { 463 Log.d(TAG, "notifyCharacteristicWriteRequestWithoutPermission"); 464 } 465 Intent intent = new Intent(BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION); 466 sendBroadcast(intent); 467 468 resetValues(); 469 } 470 notifyCharacteristicReadRequestNeedEncrypted()471 private void notifyCharacteristicReadRequestNeedEncrypted() { 472 if (DEBUG) { 473 Log.d(TAG, "notifyCharacteristicReadRequestNeedEncrypted"); 474 } 475 Intent intent = new Intent(BLE_CHARACTERISTIC_READ_REQUEST_NEED_ENCRYPTED); 476 sendBroadcast(intent); 477 478 resetValues(); 479 } 480 notifyCharacteristicWriteRequestNeedEncrypted()481 private void notifyCharacteristicWriteRequestNeedEncrypted() { 482 if (DEBUG) { 483 Log.d(TAG, "notifyCharacteristicWriteRequestNeedEncrypted"); 484 } 485 Intent intent = new Intent(BLE_CHARACTERISTIC_WRITE_REQUEST_NEED_ENCRYPTED); 486 sendBroadcast(intent); 487 488 resetValues(); 489 } 490 notifyCharacteristicNotificationRequest()491 private void notifyCharacteristicNotificationRequest() { 492 if (DEBUG) { 493 Log.d(TAG, "notifyCharacteristicNotificationRequest"); 494 } 495 mNotifyCount = 11; 496 Intent intent = new Intent(BLE_CHARACTERISTIC_NOTIFICATION_REQUEST); 497 sendBroadcast(intent); 498 499 resetValues(); 500 } 501 notifyCharacteristicIndicationRequest()502 private void notifyCharacteristicIndicationRequest() { 503 if (DEBUG) { 504 Log.d(TAG, "notifyCharacteristicIndicationRequest"); 505 } 506 Intent intent = new Intent(BLE_CHARACTERISTIC_INDICATE_REQUEST); 507 sendBroadcast(intent); 508 509 resetValues(); 510 } 511 notifyDescriptorReadRequest()512 private void notifyDescriptorReadRequest() { 513 if (DEBUG) { 514 Log.d(TAG, "notifyDescriptorReadRequest"); 515 } 516 Intent intent = new Intent(BLE_DESCRIPTOR_READ_REQUEST); 517 sendBroadcast(intent); 518 519 resetValues(); 520 } 521 notifyDescriptorWriteRequest()522 private void notifyDescriptorWriteRequest() { 523 if (DEBUG) { 524 Log.d(TAG, "notifyDescriptorWriteRequest"); 525 } 526 Intent intent = new Intent(BLE_DESCRIPTOR_WRITE_REQUEST); 527 sendBroadcast(intent); 528 529 resetValues(); 530 } 531 notifyDescriptorReadRequestWithoutPermission()532 private void notifyDescriptorReadRequestWithoutPermission() { 533 if (DEBUG) { 534 Log.d(TAG, "notifyDescriptorReadRequestWithoutPermission"); 535 } 536 Intent intent = new Intent(BLE_DESCRIPTOR_READ_REQUEST_WITHOUT_PERMISSION); 537 sendBroadcast(intent); 538 539 resetValues(); 540 } 541 notifyDescriptorWriteRequestWithoutPermission()542 private void notifyDescriptorWriteRequestWithoutPermission() { 543 if (DEBUG) { 544 Log.d(TAG, "notifyDescriptorWriteRequestWithoutPermission"); 545 } 546 Intent intent = new Intent(BLE_DESCRIPTOR_WRITE_REQUEST_WITHOUT_PERMISSION); 547 sendBroadcast(intent); 548 549 resetValues(); 550 } 551 notifyDescriptorReadRequestNeedEncrypted()552 private void notifyDescriptorReadRequestNeedEncrypted() { 553 if (DEBUG) { 554 Log.d(TAG, "notifyDescriptorReadRequestNeedEncrypted"); 555 } 556 Intent intent = new Intent(BLE_DESCRIPTOR_READ_REQUEST_NEED_ENCRYPTED); 557 sendBroadcast(intent); 558 559 resetValues(); 560 } 561 notifyDescriptorWriteRequestNeedEncrypted()562 private void notifyDescriptorWriteRequestNeedEncrypted() { 563 if (DEBUG) { 564 Log.d(TAG, "notifyDescriptorWriteRequestNeedEncrypted"); 565 } 566 Intent intent = new Intent(BLE_DESCRIPTOR_WRITE_REQUEST_NEED_ENCRYPTED); 567 sendBroadcast(intent); 568 569 resetValues(); 570 } 571 notifyExecuteWrite()572 private void notifyExecuteWrite() { 573 if (DEBUG) { 574 Log.d(TAG, "notifyExecuteWrite"); 575 } 576 Intent intent = new Intent(BLE_EXECUTE_WRITE); 577 sendBroadcast(intent); 578 579 resetValues(); 580 } 581 notifyReliableWriteBadResp()582 private void notifyReliableWriteBadResp() { 583 if (DEBUG) { 584 Log.d(TAG, "notifyReliableWriteBadResp"); 585 } 586 Intent intent = new Intent(BLE_RELIABLE_WRITE_BAD_RESP); 587 sendBroadcast(intent); 588 589 resetValues(); 590 } 591 notifyServiceChangedIndication()592 private void notifyServiceChangedIndication() { 593 if (DEBUG) { 594 Log.d(TAG, "notifyServiceChangedIndication"); 595 } 596 Intent intent = new Intent(BLE_SERVICE_CHANGED_INDICATION); 597 sendBroadcast(intent); 598 599 resetValues(); 600 } 601 getCharacteristic(UUID uuid)602 private BluetoothGattCharacteristic getCharacteristic(UUID uuid) { 603 BluetoothGattCharacteristic characteristic = mService.getCharacteristic(uuid); 604 if (characteristic == null) { 605 showMessage("Characteristic not found"); 606 } 607 return characteristic; 608 } 609 getDescriptor()610 private BluetoothGattDescriptor getDescriptor() { 611 BluetoothGattDescriptor descriptor = null; 612 613 BluetoothGattCharacteristic characteristic = getCharacteristic(CHARACTERISTIC_UUID); 614 if (characteristic != null) { 615 descriptor = characteristic.getDescriptor(DESCRIPTOR_UUID); 616 if (descriptor == null) { 617 showMessage("Descriptor not found"); 618 } 619 } 620 return descriptor; 621 } 622 createServiceChangedService()623 private BluetoothGattService createServiceChangedService() { 624 BluetoothGattService service = 625 new BluetoothGattService(SERVICE_UUID_SERVICE_CHANGED, 626 BluetoothGattService.SERVICE_TYPE_PRIMARY); 627 628 BluetoothGattCharacteristic dummyCharacteristic = 629 new BluetoothGattCharacteristic(SERVICE_CHANGED_CHARACTERISTIC_UUID, 0x02, 0x02); 630 631 service.addCharacteristic(dummyCharacteristic); 632 return service; 633 } 634 635 /** 636 * Create service for notification test 637 */ createAdditionalNotificationService()638 private BluetoothGattService createAdditionalNotificationService() { 639 BluetoothGattService service = 640 new BluetoothGattService(SERVICE_UUID_ADDITIONAL, 641 BluetoothGattService.SERVICE_TYPE_PRIMARY); 642 643 BluetoothGattCharacteristic notiCharacteristic = 644 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_1, 0x12, 0x1); 645 BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 646 0x11); 647 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 648 notiCharacteristic.addDescriptor(descriptor); 649 notiCharacteristic.setValue(NOTIFY_VALUE); 650 service.addCharacteristic(notiCharacteristic); 651 652 notiCharacteristic = 653 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_2, 0x14, 0x11); 654 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 655 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 656 notiCharacteristic.addDescriptor(descriptor); 657 notiCharacteristic.setValue(NOTIFY_VALUE); 658 service.addCharacteristic(notiCharacteristic); 659 660 notiCharacteristic = 661 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_3, 0x16, 0x11); 662 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 663 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 664 notiCharacteristic.addDescriptor(descriptor); 665 notiCharacteristic.setValue(NOTIFY_VALUE); 666 service.addCharacteristic(notiCharacteristic); 667 668 notiCharacteristic = 669 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_4, 0x18, 0x10); 670 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 671 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 672 notiCharacteristic.addDescriptor(descriptor); 673 notiCharacteristic.setValue(NOTIFY_VALUE); 674 service.addCharacteristic(notiCharacteristic); 675 676 notiCharacteristic = 677 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_5, 0x1C, 0x11); 678 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 679 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 680 notiCharacteristic.addDescriptor(descriptor); 681 notiCharacteristic.setValue(NOTIFY_VALUE); 682 service.addCharacteristic(notiCharacteristic); 683 684 notiCharacteristic = 685 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_11, 0x3A, 0x11); 686 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 687 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 688 notiCharacteristic.addDescriptor(descriptor); 689 notiCharacteristic.setValue(NOTIFY_VALUE); 690 service.addCharacteristic(notiCharacteristic); 691 692 notiCharacteristic = 693 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_12, 0x3C, 0x11); 694 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 695 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 696 notiCharacteristic.addDescriptor(descriptor); 697 notiCharacteristic.setValue(NOTIFY_VALUE); 698 service.addCharacteristic(notiCharacteristic); 699 700 notiCharacteristic = 701 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_13, 0x3E, 0x11); 702 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 703 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 704 notiCharacteristic.addDescriptor(descriptor); 705 notiCharacteristic.setValue(NOTIFY_VALUE); 706 service.addCharacteristic(notiCharacteristic); 707 708 notiCharacteristic = 709 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_14, 0x10, 0x0); 710 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 711 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 712 notiCharacteristic.addDescriptor(descriptor); 713 notiCharacteristic.setValue(NOTIFY_VALUE); 714 service.addCharacteristic(notiCharacteristic); 715 716 notiCharacteristic = 717 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_15, 0x30, 0x0); 718 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 719 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 720 notiCharacteristic.addDescriptor(descriptor); 721 notiCharacteristic.setValue(NOTIFY_VALUE); 722 service.addCharacteristic(notiCharacteristic); 723 724 return service; 725 } 726 createService()727 private BluetoothGattService createService() { 728 BluetoothGattService service = 729 new BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY); 730 BluetoothGattCharacteristic characteristic = 731 new BluetoothGattCharacteristic(CHARACTERISTIC_UUID, 0x0A, 0x11); 732 characteristic.setValue(WRITE_VALUE.getBytes()); 733 734 BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(DESCRIPTOR_UUID, 0x11); 735 descriptor.setValue(WRITE_VALUE.getBytes()); 736 characteristic.addDescriptor(descriptor); 737 738 BluetoothGattDescriptor descriptor_permission = new BluetoothGattDescriptor( 739 DESCRIPTOR_NO_READ_UUID, 0x10); 740 characteristic.addDescriptor(descriptor_permission); 741 742 descriptor_permission = new BluetoothGattDescriptor(DESCRIPTOR_NO_WRITE_UUID, 0x01); 743 characteristic.addDescriptor(descriptor_permission); 744 745 service.addCharacteristic(characteristic); 746 747 characteristic = 748 new BluetoothGattCharacteristic(CHARACTERISTIC_RESULT_UUID, 0x0A, 0x11); 749 750 BluetoothGattDescriptor descriptor_encrypted = new BluetoothGattDescriptor( 751 DESCRIPTOR_NEED_ENCRYPTED_READ_UUID, 0x02); 752 characteristic.addDescriptor(descriptor_encrypted); 753 754 descriptor_encrypted = new BluetoothGattDescriptor(DESCRIPTOR_NEED_ENCRYPTED_WRITE_UUID, 755 0x20); 756 characteristic.addDescriptor(descriptor_encrypted); 757 758 service.addCharacteristic(characteristic); 759 760 // Add new Characteristics 761 // Registered the characteristic of read permission for operation confirmation. 762 characteristic = 763 new BluetoothGattCharacteristic(CHARACTERISTIC_NO_READ_UUID, 0x0A, 0x10); 764 service.addCharacteristic(characteristic); 765 766 // Registered the characteristic of write permission for operation confirmation. 767 characteristic = 768 new BluetoothGattCharacteristic(CHARACTERISTIC_NO_WRITE_UUID, 0x0A, 0x01); 769 service.addCharacteristic(characteristic); 770 771 // Registered the characteristic of authenticate (Encrypted) for operation confirmation. 772 characteristic = 773 new BluetoothGattCharacteristic(CHARACTERISTIC_NEED_ENCRYPTED_READ_UUID, 0x0A, 774 0x02); 775 service.addCharacteristic(characteristic); 776 777 characteristic = 778 new BluetoothGattCharacteristic(CHARACTERISTIC_NEED_ENCRYPTED_WRITE_UUID, 0x0A, 779 0x20); 780 service.addCharacteristic(characteristic); 781 782 // Add new Characteristics(Indicate) 783 BluetoothGattCharacteristic indicateCharacteristic = 784 new BluetoothGattCharacteristic(INDICATE_CHARACTERISTIC_UUID, 0x2A, 0x11); 785 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 786 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 787 indicateCharacteristic.addDescriptor(descriptor); 788 indicateCharacteristic.setValue(INDICATE_VALUE); 789 service.addCharacteristic(indicateCharacteristic); 790 791 // Add new Characteristics(Notify) 792 BluetoothGattCharacteristic notiCharacteristic = 793 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID, 0x1A, 0x11); 794 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 795 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 796 notiCharacteristic.addDescriptor(descriptor); 797 notiCharacteristic.setValue(NOTIFY_VALUE); 798 service.addCharacteristic(notiCharacteristic); 799 800 notiCharacteristic = 801 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_6, 0x1E, 0x11); 802 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 803 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 804 notiCharacteristic.addDescriptor(descriptor); 805 notiCharacteristic.setValue(NOTIFY_VALUE); 806 service.addCharacteristic(notiCharacteristic); 807 808 notiCharacteristic = 809 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_7, 0x32, 0x1); 810 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 811 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 812 notiCharacteristic.addDescriptor(descriptor); 813 notiCharacteristic.setValue(NOTIFY_VALUE); 814 service.addCharacteristic(notiCharacteristic); 815 816 notiCharacteristic = 817 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_8, 0x34, 0x11); 818 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 819 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 820 notiCharacteristic.addDescriptor(descriptor); 821 notiCharacteristic.setValue(NOTIFY_VALUE); 822 service.addCharacteristic(notiCharacteristic); 823 824 notiCharacteristic = 825 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_9, 0x36, 0x11); 826 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 827 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 828 notiCharacteristic.addDescriptor(descriptor); 829 notiCharacteristic.setValue(NOTIFY_VALUE); 830 service.addCharacteristic(notiCharacteristic); 831 832 notiCharacteristic = 833 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_10, 0x38, 0x10); 834 descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11); 835 descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); 836 notiCharacteristic.addDescriptor(descriptor); 837 notiCharacteristic.setValue(NOTIFY_VALUE); 838 service.addCharacteristic(notiCharacteristic); 839 840 // Add new Characteristics (Service change control) 841 BluetoothGattCharacteristic controlCharacteristic = 842 new BluetoothGattCharacteristic(SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID, 0x08, 843 0x10); 844 service.addCharacteristic(controlCharacteristic); 845 846 return service; 847 } 848 showMessage(final String msg)849 private void showMessage(final String msg) { 850 mHandler.post(new Runnable() { 851 public void run() { 852 Toast.makeText(BleServerService.this, msg, Toast.LENGTH_SHORT).show(); 853 } 854 }); 855 } 856 onMtuTestDataReceive()857 private void onMtuTestDataReceive() { 858 859 Log.d(TAG, "onMtuTestDataReceive(" + mExpectWritesDuringMtuChangeCount + "):" 860 + mMtuTestReceivedData); 861 862 // verify 863 if (mMtuTestReceivedData.equals(BleClientService.WRITE_VALUE_512BYTES_FOR_MTU)) { 864 865 // write back data 866 // MTU test verifies whether the write/read operations go well. 867 BluetoothGattCharacteristic characteristic = getCharacteristic(CHARACTERISTIC_UUID); 868 characteristic.setValue(mMtuTestReceivedData.getBytes()); 869 870 if (mExpectWritesDuringMtuChangeCount == 1) { 871 notifyMtuRequest(BLE_MTU_REQUEST_512BYTES); 872 mExpectWritesDuringMtuChangeCount = 0; 873 } else if (mExpectWritesDuringMtuChangeCount == 0) { 874 notifyMtuRequest(BLE_MTU_REQUEST_23BYTES); 875 } else { 876 notifyMtuRequest(BLE_MTU_BAD_REQUEST); 877 } 878 mMtuTestReceivedData = ""; 879 return; 880 } 881 882 showMessage(getString(R.string.ble_mtu_fail_message)); 883 notifyMtuRequest(BLE_MTU_BAD_REQUEST); 884 mMtuTestReceivedData = ""; 885 mExpectWritesDuringMtuChangeCount = 0; 886 } 887 cancelNotificationTaskOfSecureTestStartFailure()888 private synchronized void cancelNotificationTaskOfSecureTestStartFailure() { 889 if (mNotificationTaskOfSecureTestStartFailure != null) { 890 mHandler.removeCallbacks(mNotificationTaskOfSecureTestStartFailure); 891 mNotificationTaskOfSecureTestStartFailure = null; 892 } 893 } 894 895 private final BluetoothGattServerCallback mCallbacks = new BluetoothGattServerCallback() { 896 @Override 897 public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { 898 if (DEBUG) { 899 Log.d(TAG, "onConnectionStateChange: newState=" + newState); 900 } 901 902 if (status == BluetoothGatt.GATT_SUCCESS) { 903 if (newState == BluetoothProfile.STATE_CONNECTED) { 904 mDevice = device; 905 boolean bonded = false; 906 Set<BluetoothDevice> pairedDevices = 907 mBluetoothManager.getAdapter().getBondedDevices(); 908 if (pairedDevices.size() > 0) { 909 for (BluetoothDevice target : pairedDevices) { 910 if (target.getAddress().equals(device.getAddress())) { 911 bonded = true; 912 break; 913 } 914 } 915 } 916 917 if (mSecure && ((device.getBondState() == BluetoothDevice.BOND_NONE) 918 || !bonded)) { 919 // not pairing and execute Secure Test 920 cancelNotificationTaskOfSecureTestStartFailure(); 921 /* 922 mNotificationTaskOfSecureTestStartFailure = new Runnable() { 923 @Override 924 public void run() { 925 mNotificationTaskOfSecureTestStartFailure = null; 926 if (mSecure && (mDevice.getBondState() != BluetoothDevice 927 .BOND_BONDED)) { 928 notifyMismatchSecure(); 929 } 930 } 931 }; 932 mHandler.postDelayed(mNotificationTaskOfSecureTestStartFailure, 933 NOTIFICATION_DELAY_OF_SECURE_TEST_FAILURE); 934 */ 935 } else if (!mSecure && ((device.getBondState() != BluetoothDevice.BOND_NONE) 936 || bonded)) { 937 // already pairing nad execute Insecure Test 938 /* 939 notifyMismatchInsecure(); 940 */ 941 } else { 942 cancelNotificationTaskOfSecureTestStartFailure(); 943 notifyConnected(); 944 } 945 } else if (status == BluetoothProfile.STATE_DISCONNECTED) { 946 notifyDisconnected(); 947 mDevice = null; 948 } 949 } 950 } 951 952 @Override 953 public void onServiceAdded(int status, BluetoothGattService service) { 954 if (DEBUG) { 955 Log.d(TAG, "onServiceAdded(): " + service.getUuid()); 956 dumpService(service, 0); 957 } 958 if (status == BluetoothGatt.GATT_SUCCESS) { 959 UUID uuid = service.getUuid(); 960 961 if (uuid.equals(mService.getUuid())) { 962 // create and add nested service 963 BluetoothGattService includedService = 964 new BluetoothGattService(SERVICE_UUID_INCLUDED, 965 BluetoothGattService.SERVICE_TYPE_SECONDARY); 966 BluetoothGattCharacteristic characteristic = 967 new BluetoothGattCharacteristic(CHARACTERISTIC_UUID, 0x0A, 0x11); 968 characteristic.setValue(WRITE_VALUE.getBytes()); 969 BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor( 970 DESCRIPTOR_UUID, 0x11); 971 descriptor.setValue(WRITE_VALUE.getBytes()); 972 characteristic.addDescriptor(descriptor); 973 includedService.addCharacteristic(characteristic); 974 mGattServer.addService(includedService); 975 } else if (uuid.equals(SERVICE_UUID_INCLUDED)) { 976 mService.addService(service); 977 mGattServer.addService(mAdditionalNotificationService); 978 } else if (uuid.equals(mAdditionalNotificationService.getUuid())) { 979 mGattServer.addService(mServiceChangedService); 980 } else if (uuid.equals(mServiceChangedService.getUuid())) { 981 // all services added 982 notifyServiceAdded(); 983 } else { 984 notifyAddServiceFail(); 985 } 986 } else { 987 notifyAddServiceFail(); 988 } 989 } 990 991 @Override 992 public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, 993 BluetoothGattCharacteristic characteristic) { 994 if (mGattServer == null) { 995 if (DEBUG) { 996 Log.d(TAG, "GattServer is null, return"); 997 } 998 return; 999 } 1000 if (DEBUG) { 1001 Log.d(TAG, "onCharacteristicReadRequest()"); 1002 } 1003 1004 boolean finished = false; 1005 byte[] value = null; 1006 if (mMtuSize > 0) { 1007 byte[] buf = characteristic.getValue(); 1008 if (buf != null) { 1009 int len = Math.min((buf.length - offset), mMtuSize); 1010 if (len > 0) { 1011 value = Arrays.copyOfRange(buf, offset, (offset + len)); 1012 } 1013 finished = ((offset + len) >= buf.length); 1014 if (finished) { 1015 Log.d(TAG, "sent whole data: " + (new String(characteristic.getValue()))); 1016 } 1017 } 1018 } else { 1019 value = characteristic.getValue(); 1020 finished = true; 1021 } 1022 1023 mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value); 1024 1025 UUID uid = characteristic.getUuid(); 1026 if (uid.equals(CHARACTERISTIC_NEED_ENCRYPTED_READ_UUID)) { 1027 notifyCharacteristicReadRequestNeedEncrypted(); 1028 } else { 1029 notifyCharacteristicReadRequest(finished); 1030 } 1031 } 1032 1033 @Override 1034 public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, 1035 BluetoothGattCharacteristic characteristic, 1036 boolean preparedWrite, boolean responseNeeded, 1037 int offset, byte[] value) { 1038 if (mGattServer == null) { 1039 if (DEBUG) { 1040 Log.d(TAG, "GattServer is null, return"); 1041 } 1042 return; 1043 } 1044 if (DEBUG) { 1045 Log.d(TAG, "onCharacteristicWriteRequest: preparedWrite=" + preparedWrite 1046 + ", responseNeeded= " + responseNeeded); 1047 } 1048 1049 if (characteristic.getUuid().equals(CHARACTERISTIC_RESULT_UUID)) { 1050 String resValue = new String(value); 1051 Log.d(TAG, "CHARACTERISTIC_RESULT_UUID: resValue=" + resValue); 1052 switch (resValue) { 1053 case WRITE_NO_PERMISSION: 1054 notifyCharacteristicWriteRequestWithoutPermission(); 1055 break; 1056 case READ_NO_PERMISSION: 1057 notifyCharacteristicReadRequestWithoutPermission(); 1058 break; 1059 case DESCRIPTOR_WRITE_NO_PERMISSION: 1060 notifyDescriptorWriteRequestWithoutPermission(); 1061 break; 1062 case DESCRIPTOR_READ_NO_PERMISSION: 1063 notifyDescriptorReadRequestWithoutPermission(); 1064 break; 1065 case BleClientService.SERVICE_CHANGED_VALUE: 1066 notifyServiceChangedIndication(); 1067 break; 1068 } 1069 if (responseNeeded) { 1070 mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, 1071 value); 1072 } 1073 return; 1074 } 1075 1076 if (characteristic.getUuid().equals(SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID)) { 1077 if (responseNeeded) { 1078 mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, 1079 value); 1080 } 1081 mGattServer.removeService(mServiceChangedService); 1082 return; 1083 } 1084 1085 String valueStr = new String(value); 1086 1087 // MTU test flow 1088 String mtuPrefix = "REQUEST_MTU"; 1089 if (valueStr.startsWith(mtuPrefix) 1090 || mExpectWritesDuringMtuChangeCount > 0 1091 || mMtuTestReceivedData.length() > 10) { 1092 if (preparedWrite) { 1093 mMtuTestReceivedData += new String(value); 1094 } else { 1095 String strValue = new String(value); 1096 mMtuTestReceivedData = strValue; 1097 onMtuTestDataReceive(); 1098 } 1099 if (responseNeeded) { 1100 mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, 1101 value); 1102 } 1103 1104 return; 1105 } 1106 1107 // Reliable write with bad response test flow 1108 if (BleClientService.WRITE_VALUE_BAD_RESP.equals(valueStr)) { 1109 mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null); 1110 notifyReliableWriteBadResp(); 1111 return; 1112 } 1113 1114 if (preparedWrite) { 1115 mReliableWriteValue += (new String(value)); 1116 } else { 1117 characteristic.setValue(value); 1118 // verify 1119 if (Arrays.equals(BleClientService.WRITE_VALUE.getBytes(), 1120 characteristic.getValue())) { 1121 UUID uid = characteristic.getUuid(); 1122 if (uid.equals(CHARACTERISTIC_NEED_ENCRYPTED_WRITE_UUID)) { 1123 notifyCharacteristicWriteRequestNeedEncrypted(); 1124 } else { 1125 notifyCharacteristicWriteRequest(); 1126 } 1127 } else { 1128 showMessage("Written data is not correct"); 1129 } 1130 } 1131 1132 if (responseNeeded) { 1133 mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, 1134 value); 1135 } 1136 } 1137 1138 @Override 1139 public void onDescriptorReadRequest(BluetoothDevice device, int requestId, 1140 int offset, BluetoothGattDescriptor descriptor) { 1141 if (mGattServer == null) { 1142 if (DEBUG) { 1143 Log.d(TAG, "GattServer is null, return"); 1144 } 1145 return; 1146 } 1147 if (DEBUG) { 1148 Log.d(TAG, "onDescriptorReadRequest(): (descriptor == getDescriptor())=" 1149 + (descriptor == getDescriptor())); 1150 } 1151 1152 UUID uid = descriptor.getUuid(); 1153 if (uid.equals(DESCRIPTOR_NEED_ENCRYPTED_READ_UUID)) { 1154 notifyDescriptorReadRequestNeedEncrypted(); 1155 } else { 1156 notifyDescriptorReadRequest(); 1157 } 1158 1159 byte[] value = descriptor.getValue(); 1160 if (value == null) { 1161 throw new RuntimeException("descriptor data read is null"); 1162 } 1163 1164 mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value); 1165 } 1166 1167 @Override 1168 public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, 1169 BluetoothGattDescriptor descriptor, 1170 boolean preparedWrite, boolean responseNeeded, 1171 int offset, byte[] value) { 1172 if (mGattServer == null) { 1173 if (DEBUG) { 1174 Log.d(TAG, "GattServer is null, return"); 1175 } 1176 return; 1177 } 1178 BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); 1179 UUID uid = characteristic.getUuid(); 1180 if (DEBUG) { 1181 Log.d(TAG, "onDescriptorWriteRequest: preparedWrite=" + preparedWrite 1182 + ", responseNeeded= " + responseNeeded); 1183 Log.d(TAG, " characteristic uuid = " + uid); 1184 } 1185 1186 UUID duid = descriptor.getUuid(); 1187 // If there is a written request to the CCCD for Notify. 1188 if (duid.equals(UPDATE_DESCRIPTOR_UUID)) { 1189 if (Arrays.equals(value, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) { 1190 mGattServer.notifyCharacteristicChanged( 1191 mDevice, descriptor.getCharacteristic(), false, 1192 characteristic.getValue()); 1193 1194 mIndicated = false; 1195 } else if (Arrays.equals(value, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE)) { 1196 mGattServer.notifyCharacteristicChanged( 1197 mDevice, descriptor.getCharacteristic(), true, 1198 characteristic.getValue()); 1199 mIndicated = true; 1200 } 1201 } else if (duid.equals(DESCRIPTOR_NEED_ENCRYPTED_WRITE_UUID)) { 1202 // verify 1203 if (Arrays.equals(BleClientService.WRITE_VALUE.getBytes(), value)) { 1204 notifyDescriptorWriteRequestNeedEncrypted(); 1205 } else { 1206 showMessage("Written data is not correct"); 1207 } 1208 } else { 1209 // verify 1210 if (Arrays.equals(BleClientService.WRITE_VALUE.getBytes(), value)) { 1211 notifyDescriptorWriteRequest(); 1212 } else { 1213 showMessage("Written data is not correct"); 1214 } 1215 } 1216 if (responseNeeded) { 1217 mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, 1218 value); 1219 } 1220 } 1221 1222 @Override 1223 public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) { 1224 if (mGattServer == null) { 1225 if (DEBUG) { 1226 Log.d(TAG, "GattServer is null, return"); 1227 } 1228 return; 1229 } 1230 if (DEBUG) { 1231 Log.d(TAG, "onExecuteWrite"); 1232 } 1233 1234 if (execute) { 1235 if (mMtuTestReceivedData.length() > 10 1236 && mMtuTestReceivedData.startsWith("REQUEST_MTU")) { 1237 onMtuTestDataReceive(); 1238 } else { 1239 // verify 1240 String str = BleClientService.WRITE_VALUE_507BYTES_FOR_RELIABLE_WRITE 1241 + BleClientService.WRITE_VALUE_507BYTES_FOR_RELIABLE_WRITE; 1242 if (str.equals(mReliableWriteValue)) { 1243 notifyExecuteWrite(); 1244 } else { 1245 showMessage("Failed to receive data"); 1246 Log.d(TAG, "Failed to receive data:" + mReliableWriteValue); 1247 } 1248 } 1249 mReliableWriteValue = ""; 1250 } 1251 mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null); 1252 } 1253 1254 @Override 1255 public void onNotificationSent(BluetoothDevice device, int status) { 1256 if (mGattServer == null) { 1257 if (DEBUG) { 1258 Log.d(TAG, "GattServer is null, return"); 1259 } 1260 return; 1261 } 1262 if (DEBUG) { 1263 Log.d(TAG, "onNotificationSent"); 1264 } 1265 1266 if (status == BluetoothGatt.GATT_SUCCESS) { 1267 if (mIndicated) { 1268 notifyCharacteristicIndicationRequest(); 1269 } else { 1270 mNotifyCount--; 1271 if (mNotifyCount == 0) { 1272 notifyCharacteristicNotificationRequest(); 1273 } 1274 } 1275 } 1276 } 1277 1278 @Override 1279 public void onMtuChanged(BluetoothDevice device, int mtu) { 1280 if (mGattServer == null) { 1281 if (DEBUG) { 1282 Log.d(TAG, "GattServer is null, return"); 1283 } 1284 return; 1285 } 1286 if (DEBUG) { 1287 Log.d(TAG, "onMtuChanged mExpectWritesDuringMtuChangeCount " 1288 + mExpectWritesDuringMtuChangeCount); 1289 } 1290 1291 mMtuSize = mtu; 1292 if (mExpectWritesDuringMtuChangeCount == 0) { 1293 if (mtu != 517) { 1294 String msg = String.format(getString(R.string.ble_mtu_mismatch_message), 1295 517, mtu); 1296 showMessage(msg); 1297 } 1298 } else { 1299 String msg = String.format(getString(R.string.ble_mtu_unexpected_message)); 1300 showMessage(msg); 1301 } 1302 1303 mMtuTestReceivedData = ""; 1304 ++mExpectWritesDuringMtuChangeCount; 1305 } 1306 }; 1307 startAdvertise()1308 private void startAdvertise() { 1309 if (DEBUG) { 1310 Log.d(TAG, "startAdvertise"); 1311 } 1312 AdvertiseData data = new AdvertiseData.Builder() 1313 .addServiceData(new ParcelUuid(ADV_SERVICE_UUID), new byte[]{1, 2, 3}) 1314 .addServiceUuid(new ParcelUuid(ADV_SERVICE_UUID)) 1315 .build(); 1316 AdvertiseSettings setting = new AdvertiseSettings.Builder() 1317 .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY) 1318 .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM) 1319 .setConnectable(true) 1320 .build(); 1321 mAdvertiser.startAdvertising(setting, data, mAdvertiseCallback); 1322 } 1323 stopAdvertise()1324 private void stopAdvertise() { 1325 if (DEBUG) { 1326 Log.d(TAG, "stopAdvertise"); 1327 } 1328 if (mAdvertiser != null) { 1329 mAdvertiser.stopAdvertising(mAdvertiseCallback); 1330 } 1331 } 1332 1333 private final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() { 1334 @Override 1335 public void onStartFailure(int errorCode) { 1336 // Implementation for API Test. 1337 super.onStartFailure(errorCode); 1338 if (DEBUG) { 1339 Log.d(TAG, "onStartFailure"); 1340 } 1341 1342 if (errorCode == ADVERTISE_FAILED_FEATURE_UNSUPPORTED) { 1343 notifyAdvertiseUnsupported(); 1344 } else { 1345 notifyOpenFail(); 1346 } 1347 } 1348 1349 @Override 1350 public void onStartSuccess(AdvertiseSettings settingsInEffect) { 1351 // Implementation for API Test. 1352 super.onStartSuccess(settingsInEffect); 1353 if (DEBUG) { 1354 Log.d(TAG, "onStartSuccess"); 1355 } 1356 } 1357 }; 1358 1359 /*protected*/ dumpService(BluetoothGattService service, int level)1360 static void dumpService(BluetoothGattService service, int level) { 1361 String indent = ""; 1362 for (int i = 0; i < level; ++i) { 1363 indent += " "; 1364 } 1365 1366 Log.d(TAG, indent + "[service]"); 1367 Log.d(TAG, indent + "UUID: " + service.getUuid()); 1368 Log.d(TAG, indent + " [characteristics]"); 1369 for (BluetoothGattCharacteristic ch : service.getCharacteristics()) { 1370 Log.d(TAG, indent + " UUID: " + ch.getUuid()); 1371 Log.d(TAG, indent + " properties: " + String.format("0x%02X", ch.getProperties())); 1372 Log.d(TAG, 1373 indent + " permissions: " + String.format("0x%02X", ch.getPermissions())); 1374 Log.d(TAG, indent + " [descriptors]"); 1375 for (BluetoothGattDescriptor d : ch.getDescriptors()) { 1376 Log.d(TAG, indent + " UUID: " + d.getUuid()); 1377 Log.d(TAG, indent + " permissions: " + String.format("0x%02X", 1378 d.getPermissions())); 1379 } 1380 } 1381 1382 if (service.getIncludedServices() != null) { 1383 Log.d(TAG, indent + " [included services]"); 1384 for (BluetoothGattService s : service.getIncludedServices()) { 1385 dumpService(s, level + 1); 1386 } 1387 } 1388 } 1389 1390 } 1391 1392