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