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