1 /* 2 * Copyright (C) 2012 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 #define LOG_TAG "BluetoothServiceJni" 18 #include "android_runtime/AndroidRuntime.h" 19 #include "android_runtime/Log.h" 20 #include "com_android_bluetooth.h" 21 #include "cutils/properties.h" 22 #include "hardware/bt_sock.h" 23 #include "utils/Log.h" 24 #include "utils/misc.h" 25 26 #include <pthread.h> 27 #include <string.h> 28 29 #include <fcntl.h> 30 #include <sys/prctl.h> 31 #include <sys/stat.h> 32 33 namespace android { 34 // OOB_LE_BD_ADDR_SIZE is 6 bytes addres + 1 byte address type 35 #define OOB_LE_BD_ADDR_SIZE 7 36 #define OOB_TK_SIZE 16 37 #define OOB_LE_SC_C_SIZE 16 38 #define OOB_LE_SC_R_SIZE 16 39 40 static jmethodID method_stateChangeCallback; 41 static jmethodID method_adapterPropertyChangedCallback; 42 static jmethodID method_devicePropertyChangedCallback; 43 static jmethodID method_deviceFoundCallback; 44 static jmethodID method_pinRequestCallback; 45 static jmethodID method_sspRequestCallback; 46 static jmethodID method_bondStateChangeCallback; 47 static jmethodID method_aclStateChangeCallback; 48 static jmethodID method_discoveryStateChangeCallback; 49 static jmethodID method_setWakeAlarm; 50 static jmethodID method_acquireWakeLock; 51 static jmethodID method_releaseWakeLock; 52 static jmethodID method_energyInfo; 53 54 static struct { 55 jclass clazz; 56 jmethodID constructor; 57 } android_bluetooth_UidTraffic; 58 59 static const bt_interface_t* sBluetoothInterface = NULL; 60 static const btsock_interface_t* sBluetoothSocketInterface = NULL; 61 static JNIEnv* callbackEnv = NULL; 62 63 static jobject sJniAdapterServiceObj; 64 static jobject sJniCallbacksObj; 65 static jfieldID sJniCallbacksField; 66 67 const bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; } 68 69 JNIEnv* getCallbackEnv() { return callbackEnv; } 70 71 static void adapter_state_change_callback(bt_state_t status) { 72 CallbackEnv sCallbackEnv(__func__); 73 if (!sCallbackEnv.valid()) return; 74 ALOGV("%s: Status is: %d", __func__, status); 75 76 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, 77 (jint)status); 78 } 79 80 static int get_properties(int num_properties, bt_property_t* properties, 81 jintArray* types, jobjectArray* props) { 82 for (int i = 0; i < num_properties; i++) { 83 ScopedLocalRef<jbyteArray> propVal( 84 callbackEnv, callbackEnv->NewByteArray(properties[i].len)); 85 if (!propVal.get()) { 86 ALOGE("Error while allocation of array in %s", __func__); 87 return -1; 88 } 89 90 callbackEnv->SetByteArrayRegion(propVal.get(), 0, properties[i].len, 91 (jbyte*)properties[i].val); 92 callbackEnv->SetObjectArrayElement(*props, i, propVal.get()); 93 callbackEnv->SetIntArrayRegion(*types, i, 1, (jint*)&properties[i].type); 94 } 95 return 0; 96 } 97 98 static void adapter_properties_callback(bt_status_t status, int num_properties, 99 bt_property_t* properties) { 100 CallbackEnv sCallbackEnv(__func__); 101 if (!sCallbackEnv.valid()) return; 102 103 ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties); 104 105 if (status != BT_STATUS_SUCCESS) { 106 ALOGE("%s: Status %d is incorrect", __func__, status); 107 return; 108 } 109 110 ScopedLocalRef<jbyteArray> val( 111 sCallbackEnv.get(), 112 (jbyteArray)sCallbackEnv->NewByteArray(num_properties)); 113 if (!val.get()) { 114 ALOGE("%s: Error allocating byteArray", __func__); 115 return; 116 } 117 118 ScopedLocalRef<jclass> mclass(sCallbackEnv.get(), 119 sCallbackEnv->GetObjectClass(val.get())); 120 121 /* (BT) Initialize the jobjectArray and jintArray here itself and send the 122 initialized array pointers alone to get_properties */ 123 124 ScopedLocalRef<jobjectArray> props( 125 sCallbackEnv.get(), 126 sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL)); 127 if (!props.get()) { 128 ALOGE("%s: Error allocating object Array for properties", __func__); 129 return; 130 } 131 132 ScopedLocalRef<jintArray> types( 133 sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties)); 134 if (!types.get()) { 135 ALOGE("%s: Error allocating int Array for values", __func__); 136 return; 137 } 138 139 jintArray typesPtr = types.get(); 140 jobjectArray propsPtr = props.get(); 141 if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) { 142 return; 143 } 144 145 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, 146 method_adapterPropertyChangedCallback, 147 types.get(), props.get()); 148 } 149 150 static void remote_device_properties_callback(bt_status_t status, 151 bt_bdaddr_t* bd_addr, 152 int num_properties, 153 bt_property_t* properties) { 154 CallbackEnv sCallbackEnv(__func__); 155 if (!sCallbackEnv.valid()) return; 156 157 ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties); 158 159 if (status != BT_STATUS_SUCCESS) { 160 ALOGE("%s: Status %d is incorrect", __func__, status); 161 return; 162 } 163 164 ScopedLocalRef<jbyteArray> val( 165 sCallbackEnv.get(), 166 (jbyteArray)sCallbackEnv->NewByteArray(num_properties)); 167 if (!val.get()) { 168 ALOGE("%s: Error allocating byteArray", __func__); 169 return; 170 } 171 172 ScopedLocalRef<jclass> mclass(sCallbackEnv.get(), 173 sCallbackEnv->GetObjectClass(val.get())); 174 175 /* Initialize the jobjectArray and jintArray here itself and send the 176 initialized array pointers alone to get_properties */ 177 178 ScopedLocalRef<jobjectArray> props( 179 sCallbackEnv.get(), 180 sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL)); 181 if (!props.get()) { 182 ALOGE("%s: Error allocating object Array for properties", __func__); 183 return; 184 } 185 186 ScopedLocalRef<jintArray> types( 187 sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties)); 188 if (!types.get()) { 189 ALOGE("%s: Error allocating int Array for values", __func__); 190 return; 191 } 192 193 ScopedLocalRef<jbyteArray> addr( 194 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t))); 195 if (!addr.get()) { 196 ALOGE("Error while allocation byte array in %s", __func__); 197 return; 198 } 199 200 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t), 201 (jbyte*)bd_addr); 202 203 jintArray typesPtr = types.get(); 204 jobjectArray propsPtr = props.get(); 205 if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) { 206 return; 207 } 208 209 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, 210 method_devicePropertyChangedCallback, addr.get(), 211 types.get(), props.get()); 212 } 213 214 static void device_found_callback(int num_properties, 215 bt_property_t* properties) { 216 CallbackEnv sCallbackEnv(__func__); 217 if (!sCallbackEnv.valid()) return; 218 219 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), NULL); 220 int addr_index; 221 for (int i = 0; i < num_properties; i++) { 222 if (properties[i].type == BT_PROPERTY_BDADDR) { 223 addr.reset(sCallbackEnv->NewByteArray(properties[i].len)); 224 if (!addr.get()) { 225 ALOGE("Address is NULL (unable to allocate) in %s", __func__); 226 return; 227 } 228 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, properties[i].len, 229 (jbyte*)properties[i].val); 230 addr_index = i; 231 } 232 } 233 if (!addr.get()) { 234 ALOGE("Address is NULL in %s", __func__); 235 return; 236 } 237 238 ALOGV("%s: Properties: %d, Address: %s", __func__, num_properties, 239 (const char*)properties[addr_index].val); 240 241 remote_device_properties_callback(BT_STATUS_SUCCESS, 242 (bt_bdaddr_t*)properties[addr_index].val, 243 num_properties, properties); 244 245 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, 246 addr.get()); 247 } 248 249 static void bond_state_changed_callback(bt_status_t status, 250 bt_bdaddr_t* bd_addr, 251 bt_bond_state_t state) { 252 CallbackEnv sCallbackEnv(__func__); 253 if (!sCallbackEnv.valid()) return; 254 255 if (!bd_addr) { 256 ALOGE("Address is null in %s", __func__); 257 return; 258 } 259 260 ScopedLocalRef<jbyteArray> addr( 261 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t))); 262 if (!addr.get()) { 263 ALOGE("Address allocation failed in %s", __func__); 264 return; 265 } 266 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t), 267 (jbyte*)bd_addr); 268 269 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, 270 (jint)status, addr.get(), (jint)state); 271 } 272 273 static void acl_state_changed_callback(bt_status_t status, bt_bdaddr_t* bd_addr, 274 bt_acl_state_t state) { 275 if (!bd_addr) { 276 ALOGE("Address is null in %s", __func__); 277 return; 278 } 279 280 CallbackEnv sCallbackEnv(__func__); 281 if (!sCallbackEnv.valid()) return; 282 283 ScopedLocalRef<jbyteArray> addr( 284 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t))); 285 if (!addr.get()) { 286 ALOGE("Address allocation failed in %s", __func__); 287 return; 288 } 289 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t), 290 (jbyte*)bd_addr); 291 292 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, 293 (jint)status, addr.get(), (jint)state); 294 } 295 296 static void discovery_state_changed_callback(bt_discovery_state_t state) { 297 CallbackEnv sCallbackEnv(__func__); 298 if (!sCallbackEnv.valid()) return; 299 300 ALOGV("%s: DiscoveryState:%d ", __func__, state); 301 302 sCallbackEnv->CallVoidMethod( 303 sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state); 304 } 305 306 static void pin_request_callback(bt_bdaddr_t* bd_addr, bt_bdname_t* bdname, 307 uint32_t cod, bool min_16_digits) { 308 if (!bd_addr) { 309 ALOGE("Address is null in %s", __func__); 310 return; 311 } 312 313 CallbackEnv sCallbackEnv(__func__); 314 if (!sCallbackEnv.valid()) return; 315 316 ScopedLocalRef<jbyteArray> addr( 317 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t))); 318 if (!addr.get()) { 319 ALOGE("Error while allocating in: %s", __func__); 320 return; 321 } 322 323 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t), 324 (jbyte*)bd_addr); 325 326 ScopedLocalRef<jbyteArray> devname( 327 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t))); 328 if (!devname.get()) { 329 ALOGE("Error while allocating in: %s", __func__); 330 return; 331 } 332 333 sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t), 334 (jbyte*)bdname); 335 336 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, 337 addr.get(), devname.get(), cod, min_16_digits); 338 } 339 340 static void ssp_request_callback(bt_bdaddr_t* bd_addr, bt_bdname_t* bdname, 341 uint32_t cod, bt_ssp_variant_t pairing_variant, 342 uint32_t pass_key) { 343 if (!bd_addr) { 344 ALOGE("Address is null in %s", __func__); 345 return; 346 } 347 CallbackEnv sCallbackEnv(__func__); 348 if (!sCallbackEnv.valid()) return; 349 350 ScopedLocalRef<jbyteArray> addr( 351 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t))); 352 if (!addr.get()) { 353 ALOGE("Error while allocating in: %s", __func__); 354 return; 355 } 356 357 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t), 358 (jbyte*)bd_addr); 359 360 ScopedLocalRef<jbyteArray> devname( 361 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t))); 362 if (!devname.get()) { 363 ALOGE("Error while allocating in: %s", __func__); 364 return; 365 } 366 367 sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t), 368 (jbyte*)bdname); 369 370 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, 371 addr.get(), devname.get(), cod, 372 (jint)pairing_variant, pass_key); 373 } 374 375 static void callback_thread_event(bt_cb_thread_evt event) { 376 JavaVM* vm = AndroidRuntime::getJavaVM(); 377 if (event == ASSOCIATE_JVM) { 378 JavaVMAttachArgs args; 379 char name[] = "BT Service Callback Thread"; 380 args.version = JNI_VERSION_1_6; 381 args.name = name; 382 args.group = NULL; 383 vm->AttachCurrentThread(&callbackEnv, &args); 384 ALOGV("Callback thread attached: %p", callbackEnv); 385 } else if (event == DISASSOCIATE_JVM) { 386 if (callbackEnv != AndroidRuntime::getJNIEnv()) { 387 ALOGE("Callback: '%s' is not called on the correct thread", __func__); 388 return; 389 } 390 vm->DetachCurrentThread(); 391 } 392 } 393 394 static void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) { 395 396 } 397 398 static void le_test_mode_recv_callback(bt_status_t status, 399 uint16_t packet_count) { 400 ALOGV("%s: status:%d packet_count:%d ", __func__, status, packet_count); 401 } 402 403 static void energy_info_recv_callback(bt_activity_energy_info* p_energy_info, 404 bt_uid_traffic_t* uid_data) { 405 CallbackEnv sCallbackEnv(__func__); 406 if (!sCallbackEnv.valid()) return; 407 408 jsize len = 0; 409 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) { 410 len++; 411 } 412 413 ScopedLocalRef<jobjectArray> array( 414 sCallbackEnv.get(), sCallbackEnv->NewObjectArray( 415 len, android_bluetooth_UidTraffic.clazz, NULL)); 416 jsize i = 0; 417 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) { 418 ScopedLocalRef<jobject> uidObj( 419 sCallbackEnv.get(), 420 sCallbackEnv->NewObject(android_bluetooth_UidTraffic.clazz, 421 android_bluetooth_UidTraffic.constructor, 422 (jint)data->app_uid, (jlong)data->rx_bytes, 423 (jlong)data->tx_bytes)); 424 sCallbackEnv->SetObjectArrayElement(array.get(), i++, uidObj.get()); 425 } 426 427 sCallbackEnv->CallVoidMethod( 428 sJniAdapterServiceObj, method_energyInfo, p_energy_info->status, 429 p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time, 430 p_energy_info->idle_time, p_energy_info->energy_used, array.get()); 431 } 432 433 static bt_callbacks_t sBluetoothCallbacks = { 434 sizeof(sBluetoothCallbacks), adapter_state_change_callback, 435 adapter_properties_callback, remote_device_properties_callback, 436 device_found_callback, discovery_state_changed_callback, 437 pin_request_callback, ssp_request_callback, 438 bond_state_changed_callback, acl_state_changed_callback, 439 callback_thread_event, dut_mode_recv_callback, 440 le_test_mode_recv_callback, energy_info_recv_callback}; 441 442 // The callback to call when the wake alarm fires. 443 static alarm_cb sAlarmCallback; 444 445 // The data to pass to the wake alarm callback. 446 static void* sAlarmCallbackData; 447 448 class JNIThreadAttacher { 449 public: 450 JNIThreadAttacher() : vm_(nullptr), env_(nullptr) { 451 vm_ = AndroidRuntime::getJavaVM(); 452 status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6); 453 454 if (status_ != JNI_OK && status_ != JNI_EDETACHED) { 455 ALOGE( 456 "JNIThreadAttacher: unable to get environment for JNI CALL, " 457 "status: %d", 458 status_); 459 env_ = nullptr; 460 return; 461 } 462 463 if (status_ == JNI_EDETACHED) { 464 char name[17] = {0}; 465 if (prctl(PR_GET_NAME, (unsigned long)name) != 0) { 466 ALOGE( 467 "JNIThreadAttacher: unable to grab previous thread name, error: %s", 468 strerror(errno)); 469 env_ = nullptr; 470 return; 471 } 472 473 JavaVMAttachArgs args = { 474 .version = JNI_VERSION_1_6, .name = name, .group = nullptr}; 475 if (vm_->AttachCurrentThread(&env_, &args) != 0) { 476 ALOGE("JNIThreadAttacher: unable to attach thread to VM"); 477 env_ = nullptr; 478 return; 479 } 480 } 481 } 482 483 ~JNIThreadAttacher() { 484 if (status_ == JNI_EDETACHED) vm_->DetachCurrentThread(); 485 } 486 487 JNIEnv* getEnv() { return env_; } 488 489 private: 490 JavaVM* vm_; 491 JNIEnv* env_; 492 jint status_; 493 }; 494 495 static bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake, 496 alarm_cb cb, void* data) { 497 JNIThreadAttacher attacher; 498 JNIEnv* env = attacher.getEnv(); 499 500 if (env == nullptr) { 501 ALOGE("%s: Unable to get JNI Env", __func__); 502 return false; 503 } 504 505 sAlarmCallback = cb; 506 sAlarmCallbackData = data; 507 508 jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE; 509 jboolean ret = 510 env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm, 511 (jlong)delay_millis, jshould_wake); 512 if (!ret) { 513 sAlarmCallback = NULL; 514 sAlarmCallbackData = NULL; 515 } 516 517 return (ret == JNI_TRUE); 518 } 519 520 static int acquire_wake_lock_callout(const char* lock_name) { 521 JNIThreadAttacher attacher; 522 JNIEnv* env = attacher.getEnv(); 523 524 if (env == nullptr) { 525 ALOGE("%s: Unable to get JNI Env", __func__); 526 return BT_STATUS_JNI_THREAD_ATTACH_ERROR; 527 } 528 529 jint ret = BT_STATUS_SUCCESS; 530 { 531 ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name)); 532 if (lock_name_jni.get()) { 533 bool acquired = env->CallBooleanMethod( 534 sJniAdapterServiceObj, method_acquireWakeLock, lock_name_jni.get()); 535 if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR; 536 } else { 537 ALOGE("%s unable to allocate string: %s", __func__, lock_name); 538 ret = BT_STATUS_NOMEM; 539 } 540 } 541 542 return ret; 543 } 544 545 static int release_wake_lock_callout(const char* lock_name) { 546 JNIThreadAttacher attacher; 547 JNIEnv* env = attacher.getEnv(); 548 549 if (env == nullptr) { 550 ALOGE("%s: Unable to get JNI Env", __func__); 551 return BT_STATUS_JNI_THREAD_ATTACH_ERROR; 552 } 553 554 jint ret = BT_STATUS_SUCCESS; 555 { 556 ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name)); 557 if (lock_name_jni.get()) { 558 bool released = env->CallBooleanMethod( 559 sJniAdapterServiceObj, method_releaseWakeLock, lock_name_jni.get()); 560 if (!released) ret = BT_STATUS_WAKELOCK_ERROR; 561 } else { 562 ALOGE("%s unable to allocate string: %s", __func__, lock_name); 563 ret = BT_STATUS_NOMEM; 564 } 565 } 566 567 return ret; 568 } 569 570 // Called by Java code when alarm is fired. A wake lock is held by the caller 571 // over the duration of this callback. 572 static void alarmFiredNative(JNIEnv* env, jobject obj) { 573 if (sAlarmCallback) { 574 sAlarmCallback(sAlarmCallbackData); 575 } else { 576 ALOGE("%s() - Alarm fired with callback not set!", __func__); 577 } 578 } 579 580 static bt_os_callouts_t sBluetoothOsCallouts = { 581 sizeof(sBluetoothOsCallouts), set_wake_alarm_callout, 582 acquire_wake_lock_callout, release_wake_lock_callout, 583 }; 584 585 static void classInitNative(JNIEnv* env, jclass clazz) { 586 jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic"); 587 android_bluetooth_UidTraffic.constructor = 588 env->GetMethodID(jniUidTrafficClass, "<init>", "(IJJ)V"); 589 590 jclass jniCallbackClass = 591 env->FindClass("com/android/bluetooth/btservice/JniCallbacks"); 592 sJniCallbacksField = env->GetFieldID( 593 clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;"); 594 595 method_stateChangeCallback = 596 env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V"); 597 598 method_adapterPropertyChangedCallback = env->GetMethodID( 599 jniCallbackClass, "adapterPropertyChangedCallback", "([I[[B)V"); 600 method_discoveryStateChangeCallback = env->GetMethodID( 601 jniCallbackClass, "discoveryStateChangeCallback", "(I)V"); 602 603 method_devicePropertyChangedCallback = env->GetMethodID( 604 jniCallbackClass, "devicePropertyChangedCallback", "([B[I[[B)V"); 605 method_deviceFoundCallback = 606 env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V"); 607 method_pinRequestCallback = 608 env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V"); 609 method_sspRequestCallback = 610 env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V"); 611 612 method_bondStateChangeCallback = 613 env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V"); 614 615 method_aclStateChangeCallback = 616 env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BI)V"); 617 618 method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z"); 619 method_acquireWakeLock = 620 env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z"); 621 method_releaseWakeLock = 622 env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z"); 623 method_energyInfo = env->GetMethodID( 624 clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V"); 625 626 char value[PROPERTY_VALUE_MAX]; 627 property_get("bluetooth.mock_stack", value, ""); 628 629 const char* id = 630 (strcmp(value, "1") ? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID); 631 632 hw_module_t* module; 633 int err = hw_get_module(id, (hw_module_t const**)&module); 634 635 if (err == 0) { 636 hw_device_t* abstraction; 637 err = module->methods->open(module, id, &abstraction); 638 if (err == 0) { 639 bluetooth_module_t* btStack = (bluetooth_module_t*)abstraction; 640 sBluetoothInterface = btStack->get_bluetooth_interface(); 641 } else { 642 ALOGE("Error while opening Bluetooth library"); 643 } 644 } else { 645 ALOGE("No Bluetooth Library found"); 646 } 647 } 648 649 static bool initNative(JNIEnv* env, jobject obj) { 650 ALOGV("%s", __func__); 651 652 android_bluetooth_UidTraffic.clazz = 653 (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic")); 654 655 sJniAdapterServiceObj = env->NewGlobalRef(obj); 656 sJniCallbacksObj = 657 env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField)); 658 659 if (!sBluetoothInterface) { 660 return JNI_FALSE; 661 } 662 663 int ret = sBluetoothInterface->init(&sBluetoothCallbacks); 664 if (ret != BT_STATUS_SUCCESS) { 665 ALOGE("Error while setting the callbacks: %d\n", ret); 666 sBluetoothInterface = NULL; 667 return JNI_FALSE; 668 } 669 ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts); 670 if (ret != BT_STATUS_SUCCESS) { 671 ALOGE("Error while setting Bluetooth callouts: %d\n", ret); 672 sBluetoothInterface->cleanup(); 673 sBluetoothInterface = NULL; 674 return JNI_FALSE; 675 } 676 677 sBluetoothSocketInterface = 678 (btsock_interface_t*)sBluetoothInterface->get_profile_interface( 679 BT_PROFILE_SOCKETS_ID); 680 if (sBluetoothSocketInterface == NULL) { 681 ALOGE("Error getting socket interface"); 682 } 683 684 return JNI_TRUE; 685 } 686 687 static bool cleanupNative(JNIEnv* env, jobject obj) { 688 ALOGV("%s", __func__); 689 690 if (!sBluetoothInterface) return JNI_FALSE; 691 692 sBluetoothInterface->cleanup(); 693 ALOGI("%s: return from cleanup", __func__); 694 695 env->DeleteGlobalRef(sJniCallbacksObj); 696 env->DeleteGlobalRef(sJniAdapterServiceObj); 697 env->DeleteGlobalRef(android_bluetooth_UidTraffic.clazz); 698 android_bluetooth_UidTraffic.clazz = NULL; 699 return JNI_TRUE; 700 } 701 702 static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) { 703 ALOGV("%s", __func__); 704 705 if (!sBluetoothInterface) return JNI_FALSE; 706 int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0); 707 return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE 708 : JNI_FALSE; 709 } 710 711 static jboolean disableNative(JNIEnv* env, jobject obj) { 712 ALOGV("%s", __func__); 713 714 if (!sBluetoothInterface) return JNI_FALSE; 715 716 int ret = sBluetoothInterface->disable(); 717 /* Retrun JNI_FALSE only when BTIF explicitly reports 718 BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY 719 case which indicates that stack had not been enabled. 720 */ 721 return (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE; 722 } 723 724 static jboolean startDiscoveryNative(JNIEnv* env, jobject obj) { 725 ALOGV("%s", __func__); 726 727 if (!sBluetoothInterface) return JNI_FALSE; 728 729 int ret = sBluetoothInterface->start_discovery(); 730 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 731 } 732 733 static jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) { 734 ALOGV("%s", __func__); 735 736 if (!sBluetoothInterface) return JNI_FALSE; 737 738 int ret = sBluetoothInterface->cancel_discovery(); 739 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 740 } 741 742 static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, 743 jint transport) { 744 ALOGV("%s", __func__); 745 746 if (!sBluetoothInterface) return JNI_FALSE; 747 748 jbyte* addr = env->GetByteArrayElements(address, NULL); 749 if (addr == NULL) { 750 jniThrowIOException(env, EINVAL); 751 return JNI_FALSE; 752 } 753 754 int ret = sBluetoothInterface->create_bond((bt_bdaddr_t*)addr, transport); 755 env->ReleaseByteArrayElements(address, addr, 0); 756 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 757 } 758 759 static jbyteArray callByteArrayGetter(JNIEnv* env, jobject object, 760 const char* className, 761 const char* methodName) { 762 jclass myClass = env->FindClass(className); 763 jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B"); 764 return (jbyteArray)env->CallObjectMethod(object, myMethod); 765 } 766 767 static jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj, 768 jbyteArray address, jint transport, 769 jobject oobData) { 770 bt_out_of_band_data_t oob_data; 771 772 memset(&oob_data, 0, sizeof(oob_data)); 773 774 if (!sBluetoothInterface) return JNI_FALSE; 775 776 jbyte* addr = env->GetByteArrayElements(address, NULL); 777 if (addr == NULL) { 778 jniThrowIOException(env, EINVAL); 779 return JNI_FALSE; 780 } 781 782 jbyte* leBtDeviceAddressBytes = NULL; 783 jbyte* smTKBytes = NULL; 784 jbyte* leScCBytes = NULL; 785 jbyte* leScRBytes = NULL; 786 jbyteArray leBtDeviceAddress = NULL; 787 jbyteArray smTK = NULL; 788 jbyteArray leScC = NULL; 789 jbyteArray leScR = NULL; 790 int status = BT_STATUS_FAIL; 791 792 leBtDeviceAddress = callByteArrayGetter( 793 env, oobData, "android/bluetooth/OobData", "getLeBluetoothDeviceAddress"); 794 if (leBtDeviceAddress != NULL) { 795 leBtDeviceAddressBytes = env->GetByteArrayElements(leBtDeviceAddress, NULL); 796 int len = env->GetArrayLength(leBtDeviceAddress); 797 if (len != OOB_LE_BD_ADDR_SIZE) { 798 ALOGI( 799 "%s: wrong length of leBtDeviceAddress, should be empty or %d bytes.", 800 __func__, OOB_LE_BD_ADDR_SIZE); 801 jniThrowIOException(env, EINVAL); 802 goto done; 803 } 804 memcpy(oob_data.le_bt_dev_addr, leBtDeviceAddressBytes, len); 805 } 806 807 smTK = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", 808 "getSecurityManagerTk"); 809 if (smTK != NULL) { 810 smTKBytes = env->GetByteArrayElements(smTK, NULL); 811 int len = env->GetArrayLength(smTK); 812 if (len != OOB_TK_SIZE) { 813 ALOGI("%s: wrong length of smTK, should be empty or %d bytes.", __func__, 814 OOB_TK_SIZE); 815 jniThrowIOException(env, EINVAL); 816 goto done; 817 } 818 memcpy(oob_data.sm_tk, smTKBytes, len); 819 } 820 821 leScC = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", 822 "getLeSecureConnectionsConfirmation"); 823 if (leScC != NULL) { 824 leScCBytes = env->GetByteArrayElements(leScC, NULL); 825 int len = env->GetArrayLength(leScC); 826 if (len != OOB_LE_SC_C_SIZE) { 827 ALOGI( 828 "%s: wrong length of LE SC Confirmation, should be empty or %d " 829 "bytes.", 830 __func__, OOB_LE_SC_C_SIZE); 831 jniThrowIOException(env, EINVAL); 832 goto done; 833 } 834 memcpy(oob_data.le_sc_c, leScCBytes, len); 835 } 836 837 leScR = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", 838 "getLeSecureConnectionsRandom"); 839 if (leScR != NULL) { 840 leScRBytes = env->GetByteArrayElements(leScR, NULL); 841 int len = env->GetArrayLength(leScR); 842 if (len != OOB_LE_SC_R_SIZE) { 843 ALOGI("%s: wrong length of LE SC Random, should be empty or %d bytes.", 844 __func__, OOB_LE_SC_R_SIZE); 845 jniThrowIOException(env, EINVAL); 846 goto done; 847 } 848 memcpy(oob_data.le_sc_r, leScRBytes, len); 849 } 850 851 status = sBluetoothInterface->create_bond_out_of_band((bt_bdaddr_t*)addr, 852 transport, &oob_data); 853 854 done: 855 env->ReleaseByteArrayElements(address, addr, 0); 856 857 if (leBtDeviceAddress != NULL) 858 env->ReleaseByteArrayElements(leBtDeviceAddress, leBtDeviceAddressBytes, 0); 859 860 if (smTK != NULL) env->ReleaseByteArrayElements(smTK, smTKBytes, 0); 861 862 if (leScC != NULL) env->ReleaseByteArrayElements(leScC, leScCBytes, 0); 863 864 if (leScR != NULL) env->ReleaseByteArrayElements(leScR, leScRBytes, 0); 865 866 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 867 } 868 869 static jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 870 ALOGV("%s", __func__); 871 872 if (!sBluetoothInterface) return JNI_FALSE; 873 874 jbyte* addr = env->GetByteArrayElements(address, NULL); 875 if (addr == NULL) { 876 jniThrowIOException(env, EINVAL); 877 return JNI_FALSE; 878 } 879 880 int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t*)addr); 881 env->ReleaseByteArrayElements(address, addr, 0); 882 883 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 884 } 885 886 static jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 887 ALOGV("%s", __func__); 888 889 if (!sBluetoothInterface) return JNI_FALSE; 890 891 jbyte* addr = env->GetByteArrayElements(address, NULL); 892 if (addr == NULL) { 893 jniThrowIOException(env, EINVAL); 894 return JNI_FALSE; 895 } 896 897 int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t*)addr); 898 env->ReleaseByteArrayElements(address, addr, 0); 899 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 900 } 901 902 static int getConnectionStateNative(JNIEnv* env, jobject obj, 903 jbyteArray address) { 904 ALOGV("%s", __func__); 905 if (!sBluetoothInterface) return JNI_FALSE; 906 907 jbyte* addr = env->GetByteArrayElements(address, NULL); 908 if (addr == NULL) { 909 jniThrowIOException(env, EINVAL); 910 return JNI_FALSE; 911 } 912 913 int ret = sBluetoothInterface->get_connection_state((bt_bdaddr_t*)addr); 914 env->ReleaseByteArrayElements(address, addr, 0); 915 916 return ret; 917 } 918 919 static jboolean pinReplyNative(JNIEnv* env, jobject obj, jbyteArray address, 920 jboolean accept, jint len, jbyteArray pinArray) { 921 ALOGV("%s", __func__); 922 923 if (!sBluetoothInterface) return JNI_FALSE; 924 925 jbyte* addr = env->GetByteArrayElements(address, NULL); 926 if (addr == NULL) { 927 jniThrowIOException(env, EINVAL); 928 return JNI_FALSE; 929 } 930 931 jbyte* pinPtr = NULL; 932 if (accept) { 933 pinPtr = env->GetByteArrayElements(pinArray, NULL); 934 if (pinPtr == NULL) { 935 jniThrowIOException(env, EINVAL); 936 env->ReleaseByteArrayElements(address, addr, 0); 937 return JNI_FALSE; 938 } 939 } 940 941 int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len, 942 (bt_pin_code_t*)pinPtr); 943 env->ReleaseByteArrayElements(address, addr, 0); 944 env->ReleaseByteArrayElements(pinArray, pinPtr, 0); 945 946 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 947 } 948 949 static jboolean sspReplyNative(JNIEnv* env, jobject obj, jbyteArray address, 950 jint type, jboolean accept, jint passkey) { 951 ALOGV("%s", __func__); 952 953 if (!sBluetoothInterface) return JNI_FALSE; 954 955 jbyte* addr = env->GetByteArrayElements(address, NULL); 956 if (addr == NULL) { 957 jniThrowIOException(env, EINVAL); 958 return JNI_FALSE; 959 } 960 961 int ret = sBluetoothInterface->ssp_reply( 962 (bt_bdaddr_t*)addr, (bt_ssp_variant_t)type, accept, passkey); 963 env->ReleaseByteArrayElements(address, addr, 0); 964 965 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 966 } 967 968 static jboolean setAdapterPropertyNative(JNIEnv* env, jobject obj, jint type, 969 jbyteArray value) { 970 ALOGV("%s", __func__); 971 972 if (!sBluetoothInterface) return JNI_FALSE; 973 974 jbyte* val = env->GetByteArrayElements(value, NULL); 975 bt_property_t prop; 976 prop.type = (bt_property_type_t)type; 977 prop.len = env->GetArrayLength(value); 978 prop.val = val; 979 980 int ret = sBluetoothInterface->set_adapter_property(&prop); 981 env->ReleaseByteArrayElements(value, val, 0); 982 983 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 984 } 985 986 static jboolean getAdapterPropertiesNative(JNIEnv* env, jobject obj) { 987 ALOGV("%s", __func__); 988 989 if (!sBluetoothInterface) return JNI_FALSE; 990 991 int ret = sBluetoothInterface->get_adapter_properties(); 992 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 993 } 994 995 static jboolean getAdapterPropertyNative(JNIEnv* env, jobject obj, jint type) { 996 ALOGV("%s", __func__); 997 998 if (!sBluetoothInterface) return JNI_FALSE; 999 1000 int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t)type); 1001 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1002 } 1003 1004 static jboolean getDevicePropertyNative(JNIEnv* env, jobject obj, 1005 jbyteArray address, jint type) { 1006 ALOGV("%s", __func__); 1007 1008 if (!sBluetoothInterface) return JNI_FALSE; 1009 1010 jbyte* addr = env->GetByteArrayElements(address, NULL); 1011 if (addr == NULL) { 1012 jniThrowIOException(env, EINVAL); 1013 return JNI_FALSE; 1014 } 1015 1016 int ret = sBluetoothInterface->get_remote_device_property( 1017 (bt_bdaddr_t*)addr, (bt_property_type_t)type); 1018 env->ReleaseByteArrayElements(address, addr, 0); 1019 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1020 } 1021 1022 static jboolean setDevicePropertyNative(JNIEnv* env, jobject obj, 1023 jbyteArray address, jint type, 1024 jbyteArray value) { 1025 ALOGV("%s", __func__); 1026 1027 if (!sBluetoothInterface) return JNI_FALSE; 1028 1029 jbyte* val = env->GetByteArrayElements(value, NULL); 1030 if (val == NULL) { 1031 jniThrowIOException(env, EINVAL); 1032 return JNI_FALSE; 1033 } 1034 1035 jbyte* addr = env->GetByteArrayElements(address, NULL); 1036 if (addr == NULL) { 1037 env->ReleaseByteArrayElements(value, val, 0); 1038 jniThrowIOException(env, EINVAL); 1039 return JNI_FALSE; 1040 } 1041 1042 bt_property_t prop; 1043 prop.type = (bt_property_type_t)type; 1044 prop.len = env->GetArrayLength(value); 1045 prop.val = val; 1046 1047 int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t*)addr, 1048 &prop); 1049 env->ReleaseByteArrayElements(value, val, 0); 1050 env->ReleaseByteArrayElements(address, addr, 0); 1051 1052 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1053 } 1054 1055 static jboolean getRemoteServicesNative(JNIEnv* env, jobject obj, 1056 jbyteArray address) { 1057 ALOGV("%s", __func__); 1058 1059 if (!sBluetoothInterface) return JNI_FALSE; 1060 1061 jbyte* addr = addr = env->GetByteArrayElements(address, NULL); 1062 if (addr == NULL) { 1063 jniThrowIOException(env, EINVAL); 1064 return JNI_FALSE; 1065 } 1066 1067 int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t*)addr); 1068 env->ReleaseByteArrayElements(address, addr, 0); 1069 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1070 } 1071 1072 static int connectSocketNative(JNIEnv* env, jobject object, jbyteArray address, 1073 jint type, jbyteArray uuidObj, jint channel, 1074 jint flag, jint callingUid) { 1075 if (!sBluetoothSocketInterface) return -1; 1076 1077 jbyte* addr = env->GetByteArrayElements(address, NULL); 1078 if (!addr) { 1079 ALOGE("failed to get Bluetooth device address"); 1080 return -1; 1081 } 1082 1083 jbyte* uuid = NULL; 1084 if (uuidObj != NULL) { 1085 uuid = env->GetByteArrayElements(uuidObj, NULL); 1086 if (!uuid) { 1087 ALOGE("failed to get uuid"); 1088 env->ReleaseByteArrayElements(address, addr, 0); 1089 return -1; 1090 } 1091 } 1092 1093 int socket_fd = -1; 1094 bt_status_t status = sBluetoothSocketInterface->connect( 1095 (bt_bdaddr_t*)addr, (btsock_type_t)type, (const uint8_t*)uuid, channel, 1096 &socket_fd, flag, callingUid); 1097 if (status != BT_STATUS_SUCCESS) { 1098 ALOGE("Socket connection failed: %d", status); 1099 socket_fd = -1; 1100 } else if (socket_fd < 0) { 1101 ALOGE("Fail to create file descriptor on socket fd"); 1102 } 1103 1104 env->ReleaseByteArrayElements(address, addr, 0); 1105 env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1106 return socket_fd; 1107 } 1108 1109 static int createSocketChannelNative(JNIEnv* env, jobject object, jint type, 1110 jstring name_str, jbyteArray uuidObj, 1111 jint channel, jint flag, jint callingUid) { 1112 if (!sBluetoothSocketInterface) return -1; 1113 1114 ALOGV("%s: SOCK FLAG = %x", __func__, flag); 1115 1116 const char* service_name = NULL; 1117 if (name_str != NULL) { 1118 service_name = env->GetStringUTFChars(name_str, NULL); 1119 } 1120 1121 jbyte* uuid = NULL; 1122 if (uuidObj != NULL) { 1123 uuid = env->GetByteArrayElements(uuidObj, NULL); 1124 if (!uuid) { 1125 ALOGE("failed to get uuid"); 1126 if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 1127 return -1; 1128 } 1129 } 1130 1131 int socket_fd = -1; 1132 bt_status_t status = sBluetoothSocketInterface->listen( 1133 (btsock_type_t)type, service_name, (const uint8_t*)uuid, channel, 1134 &socket_fd, flag, callingUid); 1135 if (status != BT_STATUS_SUCCESS) { 1136 ALOGE("Socket listen failed: %d", status); 1137 socket_fd = -1; 1138 } else if (socket_fd < 0) { 1139 ALOGE("Fail to creat file descriptor on socket fd"); 1140 } 1141 1142 if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 1143 if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1144 return socket_fd; 1145 } 1146 1147 static int readEnergyInfo() { 1148 ALOGV("%s", __func__); 1149 1150 if (!sBluetoothInterface) return JNI_FALSE; 1151 int ret = sBluetoothInterface->read_energy_info(); 1152 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1153 } 1154 1155 static void dumpNative(JNIEnv* env, jobject obj, jobject fdObj, 1156 jobjectArray argArray) { 1157 ALOGV("%s", __func__); 1158 if (!sBluetoothInterface) return; 1159 1160 int fd = jniGetFDFromFileDescriptor(env, fdObj); 1161 if (fd < 0) return; 1162 1163 int numArgs = env->GetArrayLength(argArray); 1164 1165 jstring* argObjs = new jstring[numArgs]; 1166 const char** args = nullptr; 1167 if (numArgs > 0) args = new const char*[numArgs]; 1168 1169 for (int i = 0; i < numArgs; i++) { 1170 argObjs[i] = (jstring)env->GetObjectArrayElement(argArray, i); 1171 args[i] = env->GetStringUTFChars(argObjs[i], NULL); 1172 } 1173 1174 sBluetoothInterface->dump(fd, args); 1175 1176 for (int i = 0; i < numArgs; i++) { 1177 env->ReleaseStringUTFChars(argObjs[i], args[i]); 1178 } 1179 1180 delete[] args; 1181 delete[] argObjs; 1182 } 1183 1184 static jboolean factoryResetNative(JNIEnv* env, jobject obj) { 1185 ALOGV("%s", __func__); 1186 if (!sBluetoothInterface) return JNI_FALSE; 1187 int ret = sBluetoothInterface->config_clear(); 1188 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1189 } 1190 1191 static void interopDatabaseClearNative(JNIEnv* env, jobject obj) { 1192 ALOGV("%s", __func__); 1193 if (!sBluetoothInterface) return; 1194 sBluetoothInterface->interop_database_clear(); 1195 } 1196 1197 static void interopDatabaseAddNative(JNIEnv* env, jobject obj, int feature, 1198 jbyteArray address, int length) { 1199 ALOGV("%s", __func__); 1200 if (!sBluetoothInterface) return; 1201 1202 jbyte* addr = env->GetByteArrayElements(address, NULL); 1203 if (addr == NULL) { 1204 jniThrowIOException(env, EINVAL); 1205 return; 1206 } 1207 1208 sBluetoothInterface->interop_database_add(feature, (bt_bdaddr_t*)addr, 1209 length); 1210 env->ReleaseByteArrayElements(address, addr, 0); 1211 } 1212 1213 static JNINativeMethod sMethods[] = { 1214 /* name, signature, funcPtr */ 1215 {"classInitNative", "()V", (void*)classInitNative}, 1216 {"initNative", "()Z", (void*)initNative}, 1217 {"cleanupNative", "()V", (void*)cleanupNative}, 1218 {"enableNative", "(Z)Z", (void*)enableNative}, 1219 {"disableNative", "()Z", (void*)disableNative}, 1220 {"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative}, 1221 {"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative}, 1222 {"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative}, 1223 {"getDevicePropertyNative", "([BI)Z", (void*)getDevicePropertyNative}, 1224 {"setDevicePropertyNative", "([BI[B)Z", (void*)setDevicePropertyNative}, 1225 {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative}, 1226 {"cancelDiscoveryNative", "()Z", (void*)cancelDiscoveryNative}, 1227 {"createBondNative", "([BI)Z", (void*)createBondNative}, 1228 {"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z", 1229 (void*)createBondOutOfBandNative}, 1230 {"removeBondNative", "([B)Z", (void*)removeBondNative}, 1231 {"cancelBondNative", "([B)Z", (void*)cancelBondNative}, 1232 {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative}, 1233 {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative}, 1234 {"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative}, 1235 {"getRemoteServicesNative", "([B)Z", (void*)getRemoteServicesNative}, 1236 {"connectSocketNative", "([BI[BIII)I", (void*)connectSocketNative}, 1237 {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I", 1238 (void*)createSocketChannelNative}, 1239 {"alarmFiredNative", "()V", (void*)alarmFiredNative}, 1240 {"readEnergyInfo", "()I", (void*)readEnergyInfo}, 1241 {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V", 1242 (void*)dumpNative}, 1243 {"factoryResetNative", "()Z", (void*)factoryResetNative}, 1244 {"interopDatabaseClearNative", "()V", (void*)interopDatabaseClearNative}, 1245 {"interopDatabaseAddNative", "(I[BI)V", (void*)interopDatabaseAddNative}}; 1246 1247 int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) { 1248 return jniRegisterNativeMethods( 1249 env, "com/android/bluetooth/btservice/AdapterService", sMethods, 1250 NELEM(sMethods)); 1251 } 1252 1253 } /* namespace android */ 1254 1255 /* 1256 * JNI Initialization 1257 */ 1258 jint JNI_OnLoad(JavaVM* jvm, void* reserved) { 1259 JNIEnv* e; 1260 int status; 1261 1262 ALOGV("Bluetooth Adapter Service : loading JNI\n"); 1263 1264 // Check JNI version 1265 if (jvm->GetEnv((void**)&e, JNI_VERSION_1_6)) { 1266 ALOGE("JNI version mismatch error"); 1267 return JNI_ERR; 1268 } 1269 1270 status = android::register_com_android_bluetooth_btservice_AdapterService(e); 1271 if (status < 0) { 1272 ALOGE("jni adapter service registration failure, status: %d", status); 1273 return JNI_ERR; 1274 } 1275 1276 status = android::register_com_android_bluetooth_hfp(e); 1277 if (status < 0) { 1278 ALOGE("jni hfp registration failure, status: %d", status); 1279 return JNI_ERR; 1280 } 1281 1282 status = android::register_com_android_bluetooth_hfpclient(e); 1283 if (status < 0) { 1284 ALOGE("jni hfp client registration failure, status: %d", status); 1285 return JNI_ERR; 1286 } 1287 1288 status = android::register_com_android_bluetooth_a2dp(e); 1289 if (status < 0) { 1290 ALOGE("jni a2dp source registration failure: %d", status); 1291 return JNI_ERR; 1292 } 1293 1294 status = android::register_com_android_bluetooth_a2dp_sink(e); 1295 if (status < 0) { 1296 ALOGE("jni a2dp sink registration failure: %d", status); 1297 return JNI_ERR; 1298 } 1299 1300 status = android::register_com_android_bluetooth_avrcp(e); 1301 if (status < 0) { 1302 ALOGE("jni avrcp target registration failure: %d", status); 1303 return JNI_ERR; 1304 } 1305 1306 status = android::register_com_android_bluetooth_avrcp_controller(e); 1307 if (status < 0) { 1308 ALOGE("jni avrcp controller registration failure: %d", status); 1309 return JNI_ERR; 1310 } 1311 1312 status = android::register_com_android_bluetooth_hid(e); 1313 if (status < 0) { 1314 ALOGE("jni hid registration failure: %d", status); 1315 return JNI_ERR; 1316 } 1317 1318 status = android::register_com_android_bluetooth_hidd(e); 1319 if (status < 0) { 1320 ALOGE("jni hidd registration failure: %d", status); 1321 return JNI_ERR; 1322 } 1323 1324 status = android::register_com_android_bluetooth_hdp(e); 1325 if (status < 0) { 1326 ALOGE("jni hdp registration failure: %d", status); 1327 return JNI_ERR; 1328 } 1329 1330 status = android::register_com_android_bluetooth_pan(e); 1331 if (status < 0) { 1332 ALOGE("jni pan registration failure: %d", status); 1333 return JNI_ERR; 1334 } 1335 1336 status = android::register_com_android_bluetooth_gatt(e); 1337 if (status < 0) { 1338 ALOGE("jni gatt registration failure: %d", status); 1339 return JNI_ERR; 1340 } 1341 1342 status = android::register_com_android_bluetooth_sdp(e); 1343 if (status < 0) { 1344 ALOGE("jni sdp registration failure: %d", status); 1345 return JNI_ERR; 1346 } 1347 1348 return JNI_VERSION_1_6; 1349 } 1350