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