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