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