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