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