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