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