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