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