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