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