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