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