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