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