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