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