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