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
23 #include <dlfcn.h>
24 #include <errno.h>
25 #include <pthread.h>
26 #include <string.h>
27
28 #include <fcntl.h>
29 #include <sys/prctl.h>
30 #include <sys/stat.h>
31
32 #include <hardware/bluetooth.h>
33 #include <nativehelper/JNIPlatformHelp.h>
34 #include <mutex>
35
36 #include <pthread.h>
37
38 using bluetooth::Uuid;
39 #ifndef DYNAMIC_LOAD_BLUETOOTH
40 extern bt_interface_t bluetoothInterface;
41 #endif
42
43 namespace android {
44 // Both
45 // OOB_ADDRESS_SIZE is 6 bytes address + 1 byte address type
46 #define OOB_ADDRESS_SIZE 7
47 #define OOB_C_SIZE 16
48 #define OOB_R_SIZE 16
49 #define OOB_NAME_MAX_SIZE 256
50 // Classic
51 #define OOB_DATA_LEN_SIZE 2
52 #define OOB_COD_SIZE 3
53 // LE
54 #define OOB_TK_SIZE 16
55 #define OOB_LE_FLAG_SIZE 1
56 #define OOB_LE_ROLE_SIZE 1
57 #define OOB_LE_APPEARANCE_SIZE 2
58
59 #define TRANSPORT_AUTO 0
60 #define TRANSPORT_BREDR 1
61 #define TRANSPORT_LE 2
62
63 const jint INVALID_FD = -1;
64
65 static jmethodID method_oobDataReceivedCallback;
66 static jmethodID method_stateChangeCallback;
67 static jmethodID method_adapterPropertyChangedCallback;
68 static jmethodID method_devicePropertyChangedCallback;
69 static jmethodID method_deviceFoundCallback;
70 static jmethodID method_pinRequestCallback;
71 static jmethodID method_sspRequestCallback;
72 static jmethodID method_bondStateChangeCallback;
73 static jmethodID method_addressConsolidateCallback;
74 static jmethodID method_leAddressAssociateCallback;
75 static jmethodID method_aclStateChangeCallback;
76 static jmethodID method_discoveryStateChangeCallback;
77 static jmethodID method_linkQualityReportCallback;
78 static jmethodID method_switchBufferSizeCallback;
79 static jmethodID method_switchCodecCallback;
80 static jmethodID method_setWakeAlarm;
81 static jmethodID method_acquireWakeLock;
82 static jmethodID method_releaseWakeLock;
83 static jmethodID method_energyInfo;
84
85 static struct {
86 jclass clazz;
87 jmethodID constructor;
88 } android_bluetooth_UidTraffic;
89
90 static const bt_interface_t* sBluetoothInterface = NULL;
91 static const btsock_interface_t* sBluetoothSocketInterface = NULL;
92 static JavaVM* vm = NULL;
93 static JNIEnv* callbackEnv = NULL;
94 static pthread_t sCallbackThread;
95 static bool sHaveCallbackThread;
96
97 static jobject sJniAdapterServiceObj;
98 static jobject sJniCallbacksObj;
99 static jfieldID sJniCallbacksField;
100
getBluetoothInterface()101 const bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; }
102
getCallbackEnv()103 JNIEnv* getCallbackEnv() { return callbackEnv; }
104
isCallbackThread()105 bool isCallbackThread() {
106 return sHaveCallbackThread && pthread_equal(sCallbackThread, pthread_self());
107 }
108
adapter_state_change_callback(bt_state_t status)109 static void adapter_state_change_callback(bt_state_t status) {
110 CallbackEnv sCallbackEnv(__func__);
111 if (!sCallbackEnv.valid()) return;
112 ALOGV("%s: Status is: %d", __func__, status);
113
114 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback,
115 (jint)status);
116 }
117
get_properties(int num_properties,bt_property_t * properties,jintArray * types,jobjectArray * props)118 static int get_properties(int num_properties, bt_property_t* properties,
119 jintArray* types, jobjectArray* props) {
120 for (int i = 0; i < num_properties; i++) {
121 ScopedLocalRef<jbyteArray> propVal(
122 callbackEnv, callbackEnv->NewByteArray(properties[i].len));
123 if (!propVal.get()) {
124 ALOGE("Error while allocation of array in %s", __func__);
125 return -1;
126 }
127
128 callbackEnv->SetByteArrayRegion(propVal.get(), 0, properties[i].len,
129 (jbyte*)properties[i].val);
130 callbackEnv->SetObjectArrayElement(*props, i, propVal.get());
131 callbackEnv->SetIntArrayRegion(*types, i, 1, (jint*)&properties[i].type);
132 }
133 return 0;
134 }
135
adapter_properties_callback(bt_status_t status,int num_properties,bt_property_t * properties)136 static void adapter_properties_callback(bt_status_t status, int num_properties,
137 bt_property_t* properties) {
138 CallbackEnv sCallbackEnv(__func__);
139 if (!sCallbackEnv.valid()) return;
140
141 ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties);
142
143 if (status != BT_STATUS_SUCCESS) {
144 ALOGE("%s: Status %d is incorrect", __func__, status);
145 return;
146 }
147
148 ScopedLocalRef<jbyteArray> val(
149 sCallbackEnv.get(),
150 (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
151 if (!val.get()) {
152 ALOGE("%s: Error allocating byteArray", __func__);
153 return;
154 }
155
156 ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
157 sCallbackEnv->GetObjectClass(val.get()));
158
159 /* (BT) Initialize the jobjectArray and jintArray here itself and send the
160 initialized array pointers alone to get_properties */
161
162 ScopedLocalRef<jobjectArray> props(
163 sCallbackEnv.get(),
164 sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
165 if (!props.get()) {
166 ALOGE("%s: Error allocating object Array for properties", __func__);
167 return;
168 }
169
170 ScopedLocalRef<jintArray> types(
171 sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
172 if (!types.get()) {
173 ALOGE("%s: Error allocating int Array for values", __func__);
174 return;
175 }
176
177 jintArray typesPtr = types.get();
178 jobjectArray propsPtr = props.get();
179 if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
180 return;
181 }
182
183 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
184 method_adapterPropertyChangedCallback,
185 types.get(), props.get());
186 }
187
remote_device_properties_callback(bt_status_t status,RawAddress * bd_addr,int num_properties,bt_property_t * properties)188 static void remote_device_properties_callback(bt_status_t status,
189 RawAddress* bd_addr,
190 int num_properties,
191 bt_property_t* properties) {
192 CallbackEnv sCallbackEnv(__func__);
193 if (!sCallbackEnv.valid()) return;
194
195 ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties);
196
197 if (status != BT_STATUS_SUCCESS) {
198 ALOGE("%s: Status %d is incorrect", __func__, status);
199 return;
200 }
201
202 ScopedLocalRef<jbyteArray> val(
203 sCallbackEnv.get(),
204 (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
205 if (!val.get()) {
206 ALOGE("%s: Error allocating byteArray", __func__);
207 return;
208 }
209
210 ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
211 sCallbackEnv->GetObjectClass(val.get()));
212
213 /* Initialize the jobjectArray and jintArray here itself and send the
214 initialized array pointers alone to get_properties */
215
216 ScopedLocalRef<jobjectArray> props(
217 sCallbackEnv.get(),
218 sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
219 if (!props.get()) {
220 ALOGE("%s: Error allocating object Array for properties", __func__);
221 return;
222 }
223
224 ScopedLocalRef<jintArray> types(
225 sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
226 if (!types.get()) {
227 ALOGE("%s: Error allocating int Array for values", __func__);
228 return;
229 }
230
231 ScopedLocalRef<jbyteArray> addr(
232 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
233 if (!addr.get()) {
234 ALOGE("Error while allocation byte array in %s", __func__);
235 return;
236 }
237
238 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
239 (jbyte*)bd_addr);
240
241 jintArray typesPtr = types.get();
242 jobjectArray propsPtr = props.get();
243 if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
244 return;
245 }
246
247 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
248 method_devicePropertyChangedCallback, addr.get(),
249 types.get(), props.get());
250 }
251
device_found_callback(int num_properties,bt_property_t * properties)252 static void device_found_callback(int num_properties,
253 bt_property_t* properties) {
254 CallbackEnv sCallbackEnv(__func__);
255 if (!sCallbackEnv.valid()) return;
256
257 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), NULL);
258 int addr_index;
259 for (int i = 0; i < num_properties; i++) {
260 if (properties[i].type == BT_PROPERTY_BDADDR) {
261 addr.reset(sCallbackEnv->NewByteArray(properties[i].len));
262 if (!addr.get()) {
263 ALOGE("Address is NULL (unable to allocate) in %s", __func__);
264 return;
265 }
266 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, properties[i].len,
267 (jbyte*)properties[i].val);
268 addr_index = i;
269 }
270 }
271 if (!addr.get()) {
272 ALOGE("Address is NULL in %s", __func__);
273 return;
274 }
275
276 ALOGV("%s: Properties: %d, Address: %s", __func__, num_properties,
277 (const char*)properties[addr_index].val);
278
279 remote_device_properties_callback(BT_STATUS_SUCCESS,
280 (RawAddress*)properties[addr_index].val,
281 num_properties, properties);
282
283 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback,
284 addr.get());
285 }
286
bond_state_changed_callback(bt_status_t status,RawAddress * bd_addr,bt_bond_state_t state,int fail_reason)287 static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
288 bt_bond_state_t state,
289 int fail_reason) {
290 CallbackEnv sCallbackEnv(__func__);
291 if (!sCallbackEnv.valid()) return;
292
293 if (!bd_addr) {
294 ALOGE("Address is null in %s", __func__);
295 return;
296 }
297
298 ScopedLocalRef<jbyteArray> addr(
299 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
300 if (!addr.get()) {
301 ALOGE("Address allocation failed in %s", __func__);
302 return;
303 }
304 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
305 (jbyte*)bd_addr);
306
307 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback,
308 (jint)status, addr.get(), (jint)state,
309 (jint)fail_reason);
310 }
311
address_consolidate_callback(RawAddress * main_bd_addr,RawAddress * secondary_bd_addr)312 static void address_consolidate_callback(RawAddress* main_bd_addr,
313 RawAddress* secondary_bd_addr) {
314 CallbackEnv sCallbackEnv(__func__);
315
316 ScopedLocalRef<jbyteArray> main_addr(
317 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
318 if (!main_addr.get()) {
319 ALOGE("Address allocation failed in %s", __func__);
320 return;
321 }
322 sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress),
323 (jbyte*)main_bd_addr);
324
325 ScopedLocalRef<jbyteArray> secondary_addr(
326 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
327 if (!secondary_addr.get()) {
328 ALOGE("Address allocation failed in %s", __func__);
329 return;
330 }
331
332 sCallbackEnv->SetByteArrayRegion(secondary_addr.get(), 0, sizeof(RawAddress),
333 (jbyte*)secondary_bd_addr);
334
335 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
336 method_addressConsolidateCallback,
337 main_addr.get(), secondary_addr.get());
338 }
339
le_address_associate_callback(RawAddress * main_bd_addr,RawAddress * secondary_bd_addr)340 static void le_address_associate_callback(RawAddress* main_bd_addr,
341 RawAddress* secondary_bd_addr) {
342 CallbackEnv sCallbackEnv(__func__);
343
344 ScopedLocalRef<jbyteArray> main_addr(
345 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
346 if (!main_addr.get()) {
347 ALOGE("Address allocation failed in %s", __func__);
348 return;
349 }
350 sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress),
351 (jbyte*)main_bd_addr);
352
353 ScopedLocalRef<jbyteArray> secondary_addr(
354 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
355 if (!secondary_addr.get()) {
356 ALOGE("Address allocation failed in %s", __func__);
357 return;
358 }
359
360 sCallbackEnv->SetByteArrayRegion(secondary_addr.get(), 0, sizeof(RawAddress),
361 (jbyte*)secondary_bd_addr);
362
363 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
364 method_leAddressAssociateCallback,
365 main_addr.get(), secondary_addr.get());
366 }
367
acl_state_changed_callback(bt_status_t status,RawAddress * bd_addr,bt_acl_state_t state,int transport_link_type,bt_hci_error_code_t hci_reason)368 static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
369 bt_acl_state_t state,
370 int transport_link_type,
371 bt_hci_error_code_t hci_reason) {
372 if (!bd_addr) {
373 ALOGE("Address is null in %s", __func__);
374 return;
375 }
376
377 CallbackEnv sCallbackEnv(__func__);
378 if (!sCallbackEnv.valid()) return;
379
380 ScopedLocalRef<jbyteArray> addr(
381 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
382 if (!addr.get()) {
383 ALOGE("Address allocation failed in %s", __func__);
384 return;
385 }
386 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
387 (jbyte*)bd_addr);
388
389 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback,
390 (jint)status, addr.get(), (jint)state,
391 (jint)transport_link_type, (jint)hci_reason);
392 }
393
discovery_state_changed_callback(bt_discovery_state_t state)394 static void discovery_state_changed_callback(bt_discovery_state_t state) {
395 CallbackEnv sCallbackEnv(__func__);
396 if (!sCallbackEnv.valid()) return;
397
398 ALOGV("%s: DiscoveryState:%d ", __func__, state);
399
400 sCallbackEnv->CallVoidMethod(
401 sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state);
402 }
403
pin_request_callback(RawAddress * bd_addr,bt_bdname_t * bdname,uint32_t cod,bool min_16_digits)404 static void pin_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
405 uint32_t cod, bool min_16_digits) {
406 if (!bd_addr) {
407 ALOGE("Address is null in %s", __func__);
408 return;
409 }
410
411 CallbackEnv sCallbackEnv(__func__);
412 if (!sCallbackEnv.valid()) return;
413
414 ScopedLocalRef<jbyteArray> addr(
415 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
416 if (!addr.get()) {
417 ALOGE("Error while allocating in: %s", __func__);
418 return;
419 }
420
421 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
422 (jbyte*)bd_addr);
423
424 ScopedLocalRef<jbyteArray> devname(
425 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)));
426 if (!devname.get()) {
427 ALOGE("Error while allocating in: %s", __func__);
428 return;
429 }
430
431 sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t),
432 (jbyte*)bdname);
433
434 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback,
435 addr.get(), devname.get(), cod, min_16_digits);
436 }
437
ssp_request_callback(RawAddress * bd_addr,bt_bdname_t * bdname,uint32_t cod,bt_ssp_variant_t pairing_variant,uint32_t pass_key)438 static void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
439 uint32_t cod, bt_ssp_variant_t pairing_variant,
440 uint32_t pass_key) {
441 if (!bd_addr) {
442 ALOGE("Address is null in %s", __func__);
443 return;
444 }
445 CallbackEnv sCallbackEnv(__func__);
446 if (!sCallbackEnv.valid()) return;
447
448 ScopedLocalRef<jbyteArray> addr(
449 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
450 if (!addr.get()) {
451 ALOGE("Error while allocating in: %s", __func__);
452 return;
453 }
454
455 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
456 (jbyte*)bd_addr);
457
458 ScopedLocalRef<jbyteArray> devname(
459 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)));
460 if (!devname.get()) {
461 ALOGE("Error while allocating in: %s", __func__);
462 return;
463 }
464
465 sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t),
466 (jbyte*)bdname);
467
468 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback,
469 addr.get(), devname.get(), cod,
470 (jint)pairing_variant, pass_key);
471 }
472
createClassicOobDataObject(JNIEnv * env,bt_oob_data_t oob_data)473 static jobject createClassicOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) {
474 ALOGV("%s", __func__);
475 jclass classicBuilderClass =
476 env->FindClass("android/bluetooth/OobData$ClassicBuilder");
477
478 jbyteArray confirmationHash = env->NewByteArray(OOB_C_SIZE);
479 env->SetByteArrayRegion(confirmationHash, 0, OOB_C_SIZE,
480 reinterpret_cast<jbyte*>(oob_data.c));
481
482 jbyteArray oobDataLength = env->NewByteArray(OOB_DATA_LEN_SIZE);
483 env->SetByteArrayRegion(oobDataLength, 0, OOB_DATA_LEN_SIZE,
484 reinterpret_cast<jbyte*>(oob_data.oob_data_length));
485
486 jbyteArray address = env->NewByteArray(OOB_ADDRESS_SIZE);
487 env->SetByteArrayRegion(address, 0, OOB_ADDRESS_SIZE,
488 reinterpret_cast<jbyte*>(oob_data.address));
489
490 jmethodID classicBuilderConstructor =
491 env->GetMethodID(classicBuilderClass, "<init>", "([B[B[B)V");
492
493 jobject oobDataClassicBuilder =
494 env->NewObject(classicBuilderClass, classicBuilderConstructor,
495 confirmationHash, oobDataLength, address);
496
497 jmethodID setRMethod =
498 env->GetMethodID(classicBuilderClass, "setRandomizerHash",
499 "([B)Landroid/bluetooth/OobData$ClassicBuilder;");
500 jbyteArray randomizerHash = env->NewByteArray(OOB_R_SIZE);
501 env->SetByteArrayRegion(randomizerHash, 0, OOB_R_SIZE,
502 reinterpret_cast<jbyte*>(oob_data.r));
503
504 oobDataClassicBuilder =
505 env->CallObjectMethod(oobDataClassicBuilder, setRMethod, randomizerHash);
506
507 jmethodID setNameMethod =
508 env->GetMethodID(classicBuilderClass, "setDeviceName",
509 "([B)Landroid/bluetooth/OobData$ClassicBuilder;");
510
511 int name_char_count = 0;
512 for (int i = 0; i < OOB_NAME_MAX_SIZE; i++) {
513 if (oob_data.device_name[i] == 0) {
514 name_char_count = i;
515 break;
516 }
517 }
518
519 jbyteArray deviceName = env->NewByteArray(name_char_count);
520 env->SetByteArrayRegion(deviceName, 0, name_char_count,
521 reinterpret_cast<jbyte*>(oob_data.device_name));
522
523 oobDataClassicBuilder =
524 env->CallObjectMethod(oobDataClassicBuilder, setNameMethod, deviceName);
525
526 jmethodID buildMethod = env->GetMethodID(classicBuilderClass, "build",
527 "()Landroid/bluetooth/OobData;");
528
529 return env->CallObjectMethod(oobDataClassicBuilder, buildMethod);
530 }
531
createLeOobDataObject(JNIEnv * env,bt_oob_data_t oob_data)532 static jobject createLeOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) {
533 ALOGV("%s", __func__);
534
535 jclass leBuilderClass = env->FindClass("android/bluetooth/OobData$LeBuilder");
536
537 jbyteArray confirmationHash = env->NewByteArray(OOB_C_SIZE);
538 env->SetByteArrayRegion(confirmationHash, 0, OOB_C_SIZE,
539 reinterpret_cast<jbyte*>(oob_data.c));
540
541 jbyteArray address = env->NewByteArray(OOB_ADDRESS_SIZE);
542 env->SetByteArrayRegion(address, 0, OOB_ADDRESS_SIZE,
543 reinterpret_cast<jbyte*>(oob_data.address));
544
545 jint le_role = (jint)oob_data.le_device_role;
546
547 jmethodID leBuilderConstructor =
548 env->GetMethodID(leBuilderClass, "<init>", "([B[BI)V");
549
550 jobject oobDataLeBuilder = env->NewObject(
551 leBuilderClass, leBuilderConstructor, confirmationHash, address, le_role);
552
553 jmethodID setRMethod =
554 env->GetMethodID(leBuilderClass, "setRandomizerHash",
555 "([B)Landroid/bluetooth/OobData$LeBuilder;");
556 jbyteArray randomizerHash = env->NewByteArray(OOB_R_SIZE);
557 env->SetByteArrayRegion(randomizerHash, 0, OOB_R_SIZE,
558 reinterpret_cast<jbyte*>(oob_data.r));
559
560 oobDataLeBuilder =
561 env->CallObjectMethod(oobDataLeBuilder, setRMethod, randomizerHash);
562
563 jmethodID setNameMethod =
564 env->GetMethodID(leBuilderClass, "setDeviceName",
565 "([B)Landroid/bluetooth/OobData$LeBuilder;");
566
567 int name_char_count = 0;
568 for (int i = 0; i < OOB_NAME_MAX_SIZE; i++) {
569 if (oob_data.device_name[i] == 0) {
570 name_char_count = i;
571 break;
572 }
573 }
574
575 jbyteArray deviceName = env->NewByteArray(name_char_count);
576 env->SetByteArrayRegion(deviceName, 0, name_char_count,
577 reinterpret_cast<jbyte*>(oob_data.device_name));
578
579 oobDataLeBuilder =
580 env->CallObjectMethod(oobDataLeBuilder, setNameMethod, deviceName);
581
582 jmethodID buildMethod = env->GetMethodID(leBuilderClass, "build",
583 "()Landroid/bluetooth/OobData;");
584
585 return env->CallObjectMethod(oobDataLeBuilder, buildMethod);
586 }
587
generate_local_oob_data_callback(tBT_TRANSPORT transport,bt_oob_data_t oob_data)588 static void generate_local_oob_data_callback(tBT_TRANSPORT transport,
589 bt_oob_data_t oob_data) {
590 ALOGV("%s", __func__);
591 CallbackEnv sCallbackEnv(__func__);
592 if (!sCallbackEnv.valid()) return;
593
594 if (transport == TRANSPORT_BREDR) {
595 sCallbackEnv->CallVoidMethod(
596 sJniCallbacksObj, method_oobDataReceivedCallback, (jint)transport,
597 ((oob_data.is_valid)
598 ? createClassicOobDataObject(sCallbackEnv.get(), oob_data)
599 : nullptr));
600 } else if (transport == TRANSPORT_LE) {
601 sCallbackEnv->CallVoidMethod(
602 sJniCallbacksObj, method_oobDataReceivedCallback, (jint)transport,
603 ((oob_data.is_valid)
604 ? createLeOobDataObject(sCallbackEnv.get(), oob_data)
605 : nullptr));
606 } else {
607 // TRANSPORT_AUTO is a concept, however, the host stack doesn't fully
608 // implement it So passing it from the java layer is currently useless until
609 // the implementation and concept of TRANSPORT_AUTO is fleshed out.
610 ALOGE("TRANSPORT: %d not implemented", transport);
611 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
612 method_oobDataReceivedCallback,
613 (jint)transport, nullptr);
614 }
615 }
616
link_quality_report_callback(uint64_t timestamp,int report_id,int rssi,int snr,int retransmission_count,int packets_not_receive_count,int negative_acknowledgement_count)617 static void link_quality_report_callback(
618 uint64_t timestamp, int report_id, int rssi, int snr,
619 int retransmission_count, int packets_not_receive_count,
620 int negative_acknowledgement_count) {
621 CallbackEnv sCallbackEnv(__func__);
622 if (!sCallbackEnv.valid()) return;
623
624 ALOGV("%s: LinkQualityReportCallback: %d %d %d %d %d %d", __func__,
625 report_id, rssi, snr, retransmission_count, packets_not_receive_count,
626 negative_acknowledgement_count);
627
628 sCallbackEnv->CallVoidMethod(
629 sJniCallbacksObj, method_linkQualityReportCallback,
630 (jlong)timestamp, (jint)report_id, (jint)rssi, (jint)snr,
631 (jint)retransmission_count, (jint)packets_not_receive_count,
632 (jint)negative_acknowledgement_count);
633 }
634
switch_buffer_size_callback(bool is_low_latency_buffer_size)635 static void switch_buffer_size_callback(bool is_low_latency_buffer_size) {
636 CallbackEnv sCallbackEnv(__func__);
637 if (!sCallbackEnv.valid()) return;
638
639 ALOGV("%s: SwitchBufferSizeCallback: %s", __func__,
640 is_low_latency_buffer_size ? "true" : "false");
641
642 sCallbackEnv->CallVoidMethod(
643 sJniCallbacksObj, method_switchBufferSizeCallback,
644 (jboolean)is_low_latency_buffer_size);
645 }
646
switch_codec_callback(bool is_low_latency_buffer_size)647 static void switch_codec_callback(bool is_low_latency_buffer_size) {
648 CallbackEnv sCallbackEnv(__func__);
649 if (!sCallbackEnv.valid()) return;
650
651 ALOGV("%s: SwitchCodecCallback: %s", __func__,
652 is_low_latency_buffer_size ? "true" : "false");
653
654 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_switchCodecCallback,
655 (jboolean)is_low_latency_buffer_size);
656 }
657
callback_thread_event(bt_cb_thread_evt event)658 static void callback_thread_event(bt_cb_thread_evt event) {
659 if (event == ASSOCIATE_JVM) {
660 JavaVMAttachArgs args;
661 char name[] = "BT Service Callback Thread";
662 args.version = JNI_VERSION_1_6;
663 args.name = name;
664 args.group = NULL;
665 vm->AttachCurrentThread(&callbackEnv, &args);
666 sHaveCallbackThread = true;
667 sCallbackThread = pthread_self();
668 ALOGV("Callback thread attached: %p", callbackEnv);
669 } else if (event == DISASSOCIATE_JVM) {
670 if (!isCallbackThread()) {
671 ALOGE("Callback: '%s' is not called on the correct thread", __func__);
672 return;
673 }
674 vm->DetachCurrentThread();
675 sHaveCallbackThread = false;
676 }
677 }
678
dut_mode_recv_callback(uint16_t opcode,uint8_t * buf,uint8_t len)679 static void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) {
680
681 }
682
le_test_mode_recv_callback(bt_status_t status,uint16_t packet_count)683 static void le_test_mode_recv_callback(bt_status_t status,
684 uint16_t packet_count) {
685 ALOGV("%s: status:%d packet_count:%d ", __func__, status, packet_count);
686 }
687
energy_info_recv_callback(bt_activity_energy_info * p_energy_info,bt_uid_traffic_t * uid_data)688 static void energy_info_recv_callback(bt_activity_energy_info* p_energy_info,
689 bt_uid_traffic_t* uid_data) {
690 CallbackEnv sCallbackEnv(__func__);
691 if (!sCallbackEnv.valid()) return;
692
693 jsize len = 0;
694 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
695 len++;
696 }
697
698 ScopedLocalRef<jobjectArray> array(
699 sCallbackEnv.get(), sCallbackEnv->NewObjectArray(
700 len, android_bluetooth_UidTraffic.clazz, NULL));
701 jsize i = 0;
702 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
703 ScopedLocalRef<jobject> uidObj(
704 sCallbackEnv.get(),
705 sCallbackEnv->NewObject(android_bluetooth_UidTraffic.clazz,
706 android_bluetooth_UidTraffic.constructor,
707 (jint)data->app_uid, (jlong)data->rx_bytes,
708 (jlong)data->tx_bytes));
709 sCallbackEnv->SetObjectArrayElement(array.get(), i++, uidObj.get());
710 }
711
712 sCallbackEnv->CallVoidMethod(
713 sJniAdapterServiceObj, method_energyInfo, p_energy_info->status,
714 p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time,
715 p_energy_info->idle_time, p_energy_info->energy_used, array.get());
716 }
717
718 static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks),
719 adapter_state_change_callback,
720 adapter_properties_callback,
721 remote_device_properties_callback,
722 device_found_callback,
723 discovery_state_changed_callback,
724 pin_request_callback,
725 ssp_request_callback,
726 bond_state_changed_callback,
727 address_consolidate_callback,
728 le_address_associate_callback,
729 acl_state_changed_callback,
730 callback_thread_event,
731 dut_mode_recv_callback,
732 le_test_mode_recv_callback,
733 energy_info_recv_callback,
734 link_quality_report_callback,
735 generate_local_oob_data_callback,
736 switch_buffer_size_callback,
737 switch_codec_callback};
738
739 // The callback to call when the wake alarm fires.
740 static alarm_cb sAlarmCallback;
741
742 // The data to pass to the wake alarm callback.
743 static void* sAlarmCallbackData;
744
745 class JNIThreadAttacher {
746 public:
JNIThreadAttacher(JavaVM * vm)747 JNIThreadAttacher(JavaVM* vm) : vm_(vm), env_(nullptr) {
748 status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6);
749
750 if (status_ != JNI_OK && status_ != JNI_EDETACHED) {
751 ALOGE(
752 "JNIThreadAttacher: unable to get environment for JNI CALL, "
753 "status: %d",
754 status_);
755 env_ = nullptr;
756 return;
757 }
758
759 if (status_ == JNI_EDETACHED) {
760 char name[17] = {0};
761 if (prctl(PR_GET_NAME, (unsigned long)name) != 0) {
762 ALOGE(
763 "JNIThreadAttacher: unable to grab previous thread name, error: %s",
764 strerror(errno));
765 env_ = nullptr;
766 return;
767 }
768
769 JavaVMAttachArgs args = {
770 .version = JNI_VERSION_1_6, .name = name, .group = nullptr};
771 if (vm_->AttachCurrentThread(&env_, &args) != 0) {
772 ALOGE("JNIThreadAttacher: unable to attach thread to VM");
773 env_ = nullptr;
774 return;
775 }
776 }
777 }
778
~JNIThreadAttacher()779 ~JNIThreadAttacher() {
780 if (status_ == JNI_EDETACHED) vm_->DetachCurrentThread();
781 }
782
getEnv()783 JNIEnv* getEnv() { return env_; }
784
785 private:
786 JavaVM* vm_;
787 JNIEnv* env_;
788 jint status_;
789 };
790
set_wake_alarm_callout(uint64_t delay_millis,bool should_wake,alarm_cb cb,void * data)791 static bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake,
792 alarm_cb cb, void* data) {
793 JNIThreadAttacher attacher(vm);
794 JNIEnv* env = attacher.getEnv();
795
796 if (env == nullptr) {
797 ALOGE("%s: Unable to get JNI Env", __func__);
798 return false;
799 }
800
801 sAlarmCallback = cb;
802 sAlarmCallbackData = data;
803
804 jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE;
805 jboolean ret =
806 env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm,
807 (jlong)delay_millis, jshould_wake);
808 if (!ret) {
809 sAlarmCallback = NULL;
810 sAlarmCallbackData = NULL;
811 }
812
813 return (ret == JNI_TRUE);
814 }
815
acquire_wake_lock_callout(const char * lock_name)816 static int acquire_wake_lock_callout(const char* lock_name) {
817 JNIThreadAttacher attacher(vm);
818 JNIEnv* env = attacher.getEnv();
819
820 if (env == nullptr) {
821 ALOGE("%s: Unable to get JNI Env", __func__);
822 return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
823 }
824
825 jint ret = BT_STATUS_SUCCESS;
826 {
827 ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
828 if (lock_name_jni.get()) {
829 bool acquired = env->CallBooleanMethod(
830 sJniAdapterServiceObj, method_acquireWakeLock, lock_name_jni.get());
831 if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR;
832 } else {
833 ALOGE("%s unable to allocate string: %s", __func__, lock_name);
834 ret = BT_STATUS_NOMEM;
835 }
836 }
837
838 return ret;
839 }
840
release_wake_lock_callout(const char * lock_name)841 static int release_wake_lock_callout(const char* lock_name) {
842 JNIThreadAttacher attacher(vm);
843 JNIEnv* env = attacher.getEnv();
844
845 if (env == nullptr) {
846 ALOGE("%s: Unable to get JNI Env", __func__);
847 return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
848 }
849
850 jint ret = BT_STATUS_SUCCESS;
851 {
852 ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
853 if (lock_name_jni.get()) {
854 bool released = env->CallBooleanMethod(
855 sJniAdapterServiceObj, method_releaseWakeLock, lock_name_jni.get());
856 if (!released) ret = BT_STATUS_WAKELOCK_ERROR;
857 } else {
858 ALOGE("%s unable to allocate string: %s", __func__, lock_name);
859 ret = BT_STATUS_NOMEM;
860 }
861 }
862
863 return ret;
864 }
865
866 // Called by Java code when alarm is fired. A wake lock is held by the caller
867 // over the duration of this callback.
alarmFiredNative(JNIEnv * env,jobject obj)868 static void alarmFiredNative(JNIEnv* env, jobject obj) {
869 if (sAlarmCallback) {
870 sAlarmCallback(sAlarmCallbackData);
871 } else {
872 ALOGE("%s() - Alarm fired with callback not set!", __func__);
873 }
874 }
875
876 static bt_os_callouts_t sBluetoothOsCallouts = {
877 sizeof(sBluetoothOsCallouts), set_wake_alarm_callout,
878 acquire_wake_lock_callout, release_wake_lock_callout,
879 };
880
hal_util_load_bt_library(const bt_interface_t ** interface)881 int hal_util_load_bt_library(const bt_interface_t** interface) {
882 #ifndef DYNAMIC_LOAD_BLUETOOTH
883 *interface = &bluetoothInterface;
884 return 0;
885 #else
886 const char* sym = BLUETOOTH_INTERFACE_STRING;
887 bt_interface_t* itf = nullptr;
888
889 // The library name is not set by default, so the preset library name is used.
890 void* handle = dlopen("libbluetooth.so", RTLD_NOW);
891 if (!handle) {
892 const char* err_str = dlerror();
893 ALOGE("%s: failed to load Bluetooth library, error=%s", __func__,
894 err_str ? err_str : "error unknown");
895 goto error;
896 }
897
898 // Get the address of the bt_interface_t.
899 itf = (bt_interface_t*)dlsym(handle, sym);
900 if (!itf) {
901 ALOGE("%s: failed to load symbol from Bluetooth library %s", __func__, sym);
902 goto error;
903 }
904
905 // Success.
906 ALOGI("%s: loaded Bluetooth library successfully", __func__);
907 *interface = itf;
908 return 0;
909
910 error:
911 *interface = NULL;
912 if (handle) dlclose(handle);
913
914 return -EINVAL;
915 #endif
916 }
917
classInitNative(JNIEnv * env,jclass clazz)918 static void classInitNative(JNIEnv* env, jclass clazz) {
919 jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic");
920 android_bluetooth_UidTraffic.constructor =
921 env->GetMethodID(jniUidTrafficClass, "<init>", "(IJJ)V");
922
923 jclass jniCallbackClass =
924 env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
925 sJniCallbacksField = env->GetFieldID(
926 clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;");
927
928 method_oobDataReceivedCallback =
929 env->GetMethodID(jniCallbackClass, "oobDataReceivedCallback",
930 "(ILandroid/bluetooth/OobData;)V");
931
932 method_stateChangeCallback =
933 env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
934
935 method_adapterPropertyChangedCallback = env->GetMethodID(
936 jniCallbackClass, "adapterPropertyChangedCallback", "([I[[B)V");
937 method_discoveryStateChangeCallback = env->GetMethodID(
938 jniCallbackClass, "discoveryStateChangeCallback", "(I)V");
939
940 method_devicePropertyChangedCallback = env->GetMethodID(
941 jniCallbackClass, "devicePropertyChangedCallback", "([B[I[[B)V");
942 method_deviceFoundCallback =
943 env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
944 method_pinRequestCallback =
945 env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V");
946 method_sspRequestCallback =
947 env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V");
948
949 method_bondStateChangeCallback =
950 env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BII)V");
951
952 method_addressConsolidateCallback = env->GetMethodID(
953 jniCallbackClass, "addressConsolidateCallback", "([B[B)V");
954
955 method_leAddressAssociateCallback = env->GetMethodID(
956 jniCallbackClass, "leAddressAssociateCallback", "([B[B)V");
957
958 method_aclStateChangeCallback =
959 env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BIII)V");
960
961 method_linkQualityReportCallback = env->GetMethodID(
962 jniCallbackClass, "linkQualityReportCallback", "(JIIIIII)V");
963
964 method_switchBufferSizeCallback =
965 env->GetMethodID(jniCallbackClass, "switchBufferSizeCallback", "(Z)V");
966
967 method_switchCodecCallback =
968 env->GetMethodID(jniCallbackClass, "switchCodecCallback", "(Z)V");
969
970 method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
971 method_acquireWakeLock =
972 env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
973 method_releaseWakeLock =
974 env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");
975 method_energyInfo = env->GetMethodID(
976 clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V");
977
978 if (env->GetJavaVM(&vm) != JNI_OK) {
979 ALOGE("Could not get JavaVM");
980 }
981
982 if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) {
983 ALOGE("No Bluetooth Library found");
984 }
985 }
986
initNative(JNIEnv * env,jobject obj,jboolean isGuest,jboolean isCommonCriteriaMode,int configCompareResult,jobjectArray initFlags,jboolean isAtvDevice,jstring userDataDirectory)987 static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest,
988 jboolean isCommonCriteriaMode, int configCompareResult,
989 jobjectArray initFlags, jboolean isAtvDevice,
990 jstring userDataDirectory) {
991 ALOGV("%s", __func__);
992
993 android_bluetooth_UidTraffic.clazz =
994 (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic"));
995
996 sJniAdapterServiceObj = env->NewGlobalRef(obj);
997 sJniCallbacksObj =
998 env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
999
1000 if (!sBluetoothInterface) {
1001 return JNI_FALSE;
1002 }
1003
1004 int flagCount = env->GetArrayLength(initFlags);
1005 jstring* flagObjs = new jstring[flagCount];
1006 const char** flags = nullptr;
1007 if (flagCount > 0) {
1008 flags = new const char*[flagCount + 1];
1009 flags[flagCount] = nullptr;
1010 }
1011
1012 for (int i = 0; i < flagCount; i++) {
1013 flagObjs[i] = (jstring)env->GetObjectArrayElement(initFlags, i);
1014 flags[i] = env->GetStringUTFChars(flagObjs[i], NULL);
1015 }
1016
1017 const char* user_data_directory =
1018 env->GetStringUTFChars(userDataDirectory, NULL);
1019
1020 int ret = sBluetoothInterface->init(
1021 &sBluetoothCallbacks, isGuest == JNI_TRUE ? 1 : 0,
1022 isCommonCriteriaMode == JNI_TRUE ? 1 : 0, configCompareResult, flags,
1023 isAtvDevice == JNI_TRUE ? 1 : 0, user_data_directory);
1024
1025 env->ReleaseStringUTFChars(userDataDirectory, user_data_directory);
1026
1027 for (int i = 0; i < flagCount; i++) {
1028 env->ReleaseStringUTFChars(flagObjs[i], flags[i]);
1029 }
1030
1031 delete[] flags;
1032 delete[] flagObjs;
1033
1034 if (ret != BT_STATUS_SUCCESS) {
1035 ALOGE("Error while setting the callbacks: %d\n", ret);
1036 sBluetoothInterface = NULL;
1037 return JNI_FALSE;
1038 }
1039 ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
1040 if (ret != BT_STATUS_SUCCESS) {
1041 ALOGE("Error while setting Bluetooth callouts: %d\n", ret);
1042 sBluetoothInterface->cleanup();
1043 sBluetoothInterface = NULL;
1044 return JNI_FALSE;
1045 }
1046
1047 sBluetoothSocketInterface =
1048 (btsock_interface_t*)sBluetoothInterface->get_profile_interface(
1049 BT_PROFILE_SOCKETS_ID);
1050 if (sBluetoothSocketInterface == NULL) {
1051 ALOGE("Error getting socket interface");
1052 }
1053
1054 return JNI_TRUE;
1055 }
1056
cleanupNative(JNIEnv * env,jobject obj)1057 static bool cleanupNative(JNIEnv* env, jobject obj) {
1058 ALOGV("%s", __func__);
1059
1060 if (!sBluetoothInterface) return JNI_FALSE;
1061
1062 sBluetoothInterface->cleanup();
1063 ALOGI("%s: return from cleanup", __func__);
1064
1065 if (sJniCallbacksObj) {
1066 env->DeleteGlobalRef(sJniCallbacksObj);
1067 sJniCallbacksObj = NULL;
1068 }
1069
1070 if (sJniAdapterServiceObj) {
1071 env->DeleteGlobalRef(sJniAdapterServiceObj);
1072 sJniAdapterServiceObj = NULL;
1073 }
1074
1075 if (android_bluetooth_UidTraffic.clazz) {
1076 env->DeleteGlobalRef(android_bluetooth_UidTraffic.clazz);
1077 android_bluetooth_UidTraffic.clazz = NULL;
1078 }
1079 return JNI_TRUE;
1080 }
1081
enableNative(JNIEnv * env,jobject obj)1082 static jboolean enableNative(JNIEnv* env, jobject obj) {
1083 ALOGV("%s", __func__);
1084
1085 if (!sBluetoothInterface) return JNI_FALSE;
1086 int ret = sBluetoothInterface->enable();
1087 return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE
1088 : JNI_FALSE;
1089 }
1090
disableNative(JNIEnv * env,jobject obj)1091 static jboolean disableNative(JNIEnv* env, jobject obj) {
1092 ALOGV("%s", __func__);
1093
1094 if (!sBluetoothInterface) return JNI_FALSE;
1095
1096 int ret = sBluetoothInterface->disable();
1097 /* Retrun JNI_FALSE only when BTIF explicitly reports
1098 BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY
1099 case which indicates that stack had not been enabled.
1100 */
1101 return (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE;
1102 }
1103
startDiscoveryNative(JNIEnv * env,jobject obj)1104 static jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
1105 ALOGV("%s", __func__);
1106
1107 if (!sBluetoothInterface) return JNI_FALSE;
1108
1109 int ret = sBluetoothInterface->start_discovery();
1110 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1111 }
1112
cancelDiscoveryNative(JNIEnv * env,jobject obj)1113 static jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) {
1114 ALOGV("%s", __func__);
1115
1116 if (!sBluetoothInterface) return JNI_FALSE;
1117
1118 int ret = sBluetoothInterface->cancel_discovery();
1119 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1120 }
1121
createBondNative(JNIEnv * env,jobject obj,jbyteArray address,jint transport)1122 static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address,
1123 jint transport) {
1124 ALOGV("%s", __func__);
1125
1126 if (!sBluetoothInterface) return JNI_FALSE;
1127
1128 jbyte* addr = env->GetByteArrayElements(address, NULL);
1129 if (addr == NULL) {
1130 jniThrowIOException(env, EINVAL);
1131 return JNI_FALSE;
1132 }
1133
1134 int ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport);
1135 env->ReleaseByteArrayElements(address, addr, 0);
1136 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1137 }
1138
callByteArrayGetter(JNIEnv * env,jobject object,const char * className,const char * methodName)1139 static jbyteArray callByteArrayGetter(JNIEnv* env, jobject object,
1140 const char* className,
1141 const char* methodName) {
1142 jclass myClass = env->FindClass(className);
1143 jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B");
1144 return (jbyteArray)env->CallObjectMethod(object, myMethod);
1145 }
1146
callIntGetter(JNIEnv * env,jobject object,const char * className,const char * methodName)1147 static jint callIntGetter(JNIEnv* env, jobject object, const char* className,
1148 const char* methodName) {
1149 jclass myClass = env->FindClass(className);
1150 jmethodID myMethod = env->GetMethodID(myClass, methodName, "()I");
1151 return env->CallIntMethod(object, myMethod);
1152 }
1153
set_data(JNIEnv * env,bt_oob_data_t & oob_data,jobject oobData,jint transport)1154 static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData,
1155 jint transport) {
1156 // Need both arguments to be non NULL
1157 if (oobData == NULL) {
1158 ALOGE("%s: oobData is null! Nothing to do.", __func__);
1159 return JNI_FALSE;
1160 }
1161
1162 memset(&oob_data, 0, sizeof(oob_data));
1163
1164 jbyteArray address = callByteArrayGetter(
1165 env, oobData, "android/bluetooth/OobData", "getDeviceAddressWithType");
1166
1167 // Check the data
1168 int len = env->GetArrayLength(address);
1169 if (len != OOB_ADDRESS_SIZE) {
1170 ALOGE("%s: addressBytes must be 7 bytes in length (address plus type) 6+1!",
1171 __func__);
1172 jniThrowIOException(env, EINVAL);
1173 return JNI_FALSE;
1174 }
1175
1176 // Convert the address from byte[]
1177 jbyte* addressBytes = env->GetByteArrayElements(address, NULL);
1178 if (addressBytes == NULL) {
1179 ALOGE("%s: addressBytes cannot be null!", __func__);
1180 jniThrowIOException(env, EINVAL);
1181 return JNI_FALSE;
1182 }
1183 memcpy(oob_data.address, addressBytes, len);
1184
1185 // Get the device name byte[] java object
1186 jbyteArray deviceName = callByteArrayGetter(
1187 env, oobData, "android/bluetooth/OobData", "getDeviceName");
1188
1189 // Optional
1190 // Convert it to a jbyte* and copy it to the struct
1191 jbyte* deviceNameBytes = NULL;
1192 if (deviceName != NULL) {
1193 deviceNameBytes = env->GetByteArrayElements(deviceName, NULL);
1194 int len = env->GetArrayLength(deviceName);
1195 if (len > OOB_NAME_MAX_SIZE) {
1196 ALOGI(
1197 "%s: wrong length of deviceName, should be empty or less than or "
1198 "equal to %d bytes.",
1199 __func__, OOB_NAME_MAX_SIZE);
1200 jniThrowIOException(env, EINVAL);
1201 env->ReleaseByteArrayElements(deviceName, deviceNameBytes, 0);
1202 return JNI_FALSE;
1203 }
1204 memcpy(oob_data.device_name, deviceNameBytes, len);
1205 env->ReleaseByteArrayElements(deviceName, deviceNameBytes, 0);
1206 }
1207 // Used by both classic and LE
1208 jbyteArray confirmation = callByteArrayGetter(
1209 env, oobData, "android/bluetooth/OobData", "getConfirmationHash");
1210 if (confirmation == NULL) {
1211 ALOGE("%s: confirmation cannot be null!", __func__);
1212 jniThrowIOException(env, EINVAL);
1213 return JNI_FALSE;
1214 }
1215
1216 // Confirmation is mandatory
1217 jbyte* confirmationBytes = NULL;
1218 confirmationBytes = env->GetByteArrayElements(confirmation, NULL);
1219 len = env->GetArrayLength(confirmation);
1220 if (confirmationBytes == NULL || len != OOB_C_SIZE) {
1221 ALOGI(
1222 "%s: wrong length of Confirmation, should be empty or %d "
1223 "bytes.",
1224 __func__, OOB_C_SIZE);
1225 jniThrowIOException(env, EINVAL);
1226 env->ReleaseByteArrayElements(confirmation, confirmationBytes, 0);
1227 return JNI_FALSE;
1228 }
1229 memcpy(oob_data.c, confirmationBytes, len);
1230 env->ReleaseByteArrayElements(confirmation, confirmationBytes, 0);
1231
1232 // Random is supposedly optional according to the specification
1233 jbyteArray randomizer = callByteArrayGetter(
1234 env, oobData, "android/bluetooth/OobData", "getRandomizerHash");
1235 jbyte* randomizerBytes = NULL;
1236 if (randomizer != NULL) {
1237 randomizerBytes = env->GetByteArrayElements(randomizer, NULL);
1238 int len = env->GetArrayLength(randomizer);
1239 if (randomizerBytes == NULL || len != OOB_R_SIZE) {
1240 ALOGI("%s: wrong length of Random, should be empty or %d bytes.",
1241 __func__, OOB_R_SIZE);
1242 jniThrowIOException(env, EINVAL);
1243 env->ReleaseByteArrayElements(randomizer, randomizerBytes, 0);
1244 return JNI_FALSE;
1245 }
1246 memcpy(oob_data.r, randomizerBytes, len);
1247 env->ReleaseByteArrayElements(randomizer, randomizerBytes, 0);
1248 }
1249
1250 // Transport specific data fetching/setting
1251 if (transport == TRANSPORT_BREDR) {
1252 // Classic
1253 // Not optional
1254 jbyteArray oobDataLength = callByteArrayGetter(
1255 env, oobData, "android/bluetooth/OobData", "getClassicLength");
1256 jbyte* oobDataLengthBytes = NULL;
1257 if (oobDataLength == NULL ||
1258 env->GetArrayLength(oobDataLength) != OOB_DATA_LEN_SIZE) {
1259 ALOGI("%s: wrong length of oobDataLength, should be empty or %d bytes.",
1260 __func__, OOB_DATA_LEN_SIZE);
1261 jniThrowIOException(env, EINVAL);
1262 env->ReleaseByteArrayElements(oobDataLength, oobDataLengthBytes, 0);
1263 return JNI_FALSE;
1264 }
1265
1266 oobDataLengthBytes = env->GetByteArrayElements(oobDataLength, NULL);
1267 memcpy(oob_data.oob_data_length, oobDataLengthBytes, len);
1268 env->ReleaseByteArrayElements(oobDataLength, oobDataLengthBytes, 0);
1269
1270 // Optional
1271 jbyteArray classOfDevice = callByteArrayGetter(
1272 env, oobData, "android/bluetooth/OobData", "getClassOfDevice");
1273 jbyte* classOfDeviceBytes = NULL;
1274 if (classOfDevice != NULL) {
1275 classOfDeviceBytes = env->GetByteArrayElements(classOfDevice, NULL);
1276 int len = env->GetArrayLength(classOfDevice);
1277 if (len != OOB_COD_SIZE) {
1278 ALOGI("%s: wrong length of classOfDevice, should be empty or %d bytes.",
1279 __func__, OOB_COD_SIZE);
1280 jniThrowIOException(env, EINVAL);
1281 env->ReleaseByteArrayElements(classOfDevice, classOfDeviceBytes, 0);
1282 return JNI_FALSE;
1283 }
1284 memcpy(oob_data.class_of_device, classOfDeviceBytes, len);
1285 env->ReleaseByteArrayElements(classOfDevice, classOfDeviceBytes, 0);
1286 }
1287 } else if (transport == TRANSPORT_LE) {
1288 // LE
1289 jbyteArray temporaryKey = callByteArrayGetter(
1290 env, oobData, "android/bluetooth/OobData", "getLeTemporaryKey");
1291 jbyte* temporaryKeyBytes = NULL;
1292 if (temporaryKey != NULL) {
1293 temporaryKeyBytes = env->GetByteArrayElements(temporaryKey, NULL);
1294 int len = env->GetArrayLength(temporaryKey);
1295 if (len != OOB_TK_SIZE) {
1296 ALOGI("%s: wrong length of temporaryKey, should be empty or %d bytes.",
1297 __func__, OOB_TK_SIZE);
1298 jniThrowIOException(env, EINVAL);
1299 env->ReleaseByteArrayElements(temporaryKey, temporaryKeyBytes, 0);
1300 return JNI_FALSE;
1301 }
1302 memcpy(oob_data.sm_tk, temporaryKeyBytes, len);
1303 env->ReleaseByteArrayElements(temporaryKey, temporaryKeyBytes, 0);
1304 }
1305
1306 jbyteArray leAppearance = callByteArrayGetter(
1307 env, oobData, "android/bluetooth/OobData", "getLeAppearance");
1308 jbyte* leAppearanceBytes = NULL;
1309 if (leAppearance != NULL) {
1310 leAppearanceBytes = env->GetByteArrayElements(leAppearance, NULL);
1311 int len = env->GetArrayLength(leAppearance);
1312 if (len != OOB_LE_APPEARANCE_SIZE) {
1313 ALOGI("%s: wrong length of leAppearance, should be empty or %d bytes.",
1314 __func__, OOB_LE_APPEARANCE_SIZE);
1315 jniThrowIOException(env, EINVAL);
1316 env->ReleaseByteArrayElements(leAppearance, leAppearanceBytes, 0);
1317 return JNI_FALSE;
1318 }
1319 memcpy(oob_data.le_appearance, leAppearanceBytes, len);
1320 env->ReleaseByteArrayElements(leAppearance, leAppearanceBytes, 0);
1321 }
1322
1323 jint leRole = callIntGetter(env, oobData, "android/bluetooth/OobData",
1324 "getLeDeviceRole");
1325 oob_data.le_device_role = leRole;
1326
1327 jint leFlag =
1328 callIntGetter(env, oobData, "android/bluetooth/OobData", "getLeFlags");
1329 oob_data.le_flags = leFlag;
1330 }
1331 return JNI_TRUE;
1332 }
1333
generateLocalOobDataNative(JNIEnv * env,jobject obj,jint transport)1334 static void generateLocalOobDataNative(JNIEnv* env, jobject obj,
1335 jint transport) {
1336 // No BT interface? Can't do anything.
1337 if (!sBluetoothInterface) return;
1338
1339 if (sBluetoothInterface->generate_local_oob_data(transport) !=
1340 BT_STATUS_SUCCESS) {
1341 ALOGE("%s: Call to generate_local_oob_data failed!", __func__);
1342 bt_oob_data_t oob_data;
1343 oob_data.is_valid = false;
1344 generate_local_oob_data_callback(transport, oob_data);
1345 }
1346 }
1347
createBondOutOfBandNative(JNIEnv * env,jobject obj,jbyteArray address,jint transport,jobject p192Data,jobject p256Data)1348 static jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj,
1349 jbyteArray address, jint transport,
1350 jobject p192Data, jobject p256Data) {
1351 // No BT interface? Can't do anything.
1352 if (!sBluetoothInterface) return JNI_FALSE;
1353
1354 // No data? Can't do anything
1355 if (p192Data == NULL && p256Data == NULL) {
1356 ALOGE("%s: All OOB Data are null! Nothing to do.", __func__);
1357 jniThrowIOException(env, EINVAL);
1358 return JNI_FALSE;
1359 }
1360
1361 // This address is already reversed which is why its being passed...
1362 // In the future we want to remove this and just reverse the address
1363 // for the oobdata in the host stack.
1364 if (address == NULL) {
1365 ALOGE("%s: Address cannot be null! Nothing to do.", __func__);
1366 jniThrowIOException(env, EINVAL);
1367 return JNI_FALSE;
1368 }
1369
1370 // Check the data
1371 int len = env->GetArrayLength(address);
1372 if (len != 6) {
1373 ALOGE("%s: addressBytes must be 6 bytes in length (address plus type) 6+1!",
1374 __func__);
1375 jniThrowIOException(env, EINVAL);
1376 return JNI_FALSE;
1377 }
1378
1379 jbyte* addr = env->GetByteArrayElements(address, NULL);
1380 if (addr == NULL) {
1381 jniThrowIOException(env, EINVAL);
1382 return JNI_FALSE;
1383 }
1384
1385 // Convert P192 data from Java POJO to C Struct
1386 bt_oob_data_t p192_data;
1387 if (p192Data != NULL) {
1388 if (set_data(env, p192_data, p192Data, transport) == JNI_FALSE) {
1389 jniThrowIOException(env, EINVAL);
1390 return JNI_FALSE;
1391 }
1392 }
1393
1394 // Convert P256 data from Java POJO to C Struct
1395 bt_oob_data_t p256_data;
1396 if (p256Data != NULL) {
1397 if (set_data(env, p256_data, p256Data, transport) == JNI_FALSE) {
1398 jniThrowIOException(env, EINVAL);
1399 return JNI_FALSE;
1400 }
1401 }
1402
1403 return ((sBluetoothInterface->create_bond_out_of_band(
1404 (RawAddress*)addr, transport, &p192_data, &p256_data)) ==
1405 BT_STATUS_SUCCESS)
1406 ? JNI_TRUE
1407 : JNI_FALSE;
1408 }
1409
removeBondNative(JNIEnv * env,jobject obj,jbyteArray address)1410 static jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
1411 ALOGV("%s", __func__);
1412
1413 if (!sBluetoothInterface) return JNI_FALSE;
1414
1415 jbyte* addr = env->GetByteArrayElements(address, NULL);
1416 if (addr == NULL) {
1417 jniThrowIOException(env, EINVAL);
1418 return JNI_FALSE;
1419 }
1420
1421 int ret = sBluetoothInterface->remove_bond((RawAddress*)addr);
1422 env->ReleaseByteArrayElements(address, addr, 0);
1423
1424 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1425 }
1426
cancelBondNative(JNIEnv * env,jobject obj,jbyteArray address)1427 static jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
1428 ALOGV("%s", __func__);
1429
1430 if (!sBluetoothInterface) return JNI_FALSE;
1431
1432 jbyte* addr = env->GetByteArrayElements(address, NULL);
1433 if (addr == NULL) {
1434 jniThrowIOException(env, EINVAL);
1435 return JNI_FALSE;
1436 }
1437
1438 int ret = sBluetoothInterface->cancel_bond((RawAddress*)addr);
1439 env->ReleaseByteArrayElements(address, addr, 0);
1440 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1441 }
1442
getConnectionStateNative(JNIEnv * env,jobject obj,jbyteArray address)1443 static int getConnectionStateNative(JNIEnv* env, jobject obj,
1444 jbyteArray address) {
1445 ALOGV("%s", __func__);
1446 if (!sBluetoothInterface) return JNI_FALSE;
1447
1448 jbyte* addr = env->GetByteArrayElements(address, NULL);
1449 if (addr == NULL) {
1450 jniThrowIOException(env, EINVAL);
1451 return JNI_FALSE;
1452 }
1453
1454 int ret = sBluetoothInterface->get_connection_state((RawAddress*)addr);
1455 env->ReleaseByteArrayElements(address, addr, 0);
1456
1457 return ret;
1458 }
1459
pinReplyNative(JNIEnv * env,jobject obj,jbyteArray address,jboolean accept,jint len,jbyteArray pinArray)1460 static jboolean pinReplyNative(JNIEnv* env, jobject obj, jbyteArray address,
1461 jboolean accept, jint len, jbyteArray pinArray) {
1462 ALOGV("%s", __func__);
1463
1464 if (!sBluetoothInterface) return JNI_FALSE;
1465
1466 jbyte* addr = env->GetByteArrayElements(address, NULL);
1467 if (addr == NULL) {
1468 jniThrowIOException(env, EINVAL);
1469 return JNI_FALSE;
1470 }
1471
1472 jbyte* pinPtr = NULL;
1473 if (accept) {
1474 pinPtr = env->GetByteArrayElements(pinArray, NULL);
1475 if (pinPtr == NULL) {
1476 jniThrowIOException(env, EINVAL);
1477 env->ReleaseByteArrayElements(address, addr, 0);
1478 return JNI_FALSE;
1479 }
1480 }
1481
1482 int ret = sBluetoothInterface->pin_reply((RawAddress*)addr, accept, len,
1483 (bt_pin_code_t*)pinPtr);
1484 env->ReleaseByteArrayElements(address, addr, 0);
1485 env->ReleaseByteArrayElements(pinArray, pinPtr, 0);
1486
1487 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1488 }
1489
sspReplyNative(JNIEnv * env,jobject obj,jbyteArray address,jint type,jboolean accept,jint passkey)1490 static jboolean sspReplyNative(JNIEnv* env, jobject obj, jbyteArray address,
1491 jint type, jboolean accept, jint passkey) {
1492 ALOGV("%s", __func__);
1493
1494 if (!sBluetoothInterface) return JNI_FALSE;
1495
1496 jbyte* addr = env->GetByteArrayElements(address, NULL);
1497 if (addr == NULL) {
1498 jniThrowIOException(env, EINVAL);
1499 return JNI_FALSE;
1500 }
1501
1502 int ret = sBluetoothInterface->ssp_reply(
1503 (RawAddress*)addr, (bt_ssp_variant_t)type, accept, passkey);
1504 env->ReleaseByteArrayElements(address, addr, 0);
1505
1506 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1507 }
1508
setAdapterPropertyNative(JNIEnv * env,jobject obj,jint type,jbyteArray value)1509 static jboolean setAdapterPropertyNative(JNIEnv* env, jobject obj, jint type,
1510 jbyteArray value) {
1511 ALOGV("%s", __func__);
1512
1513 if (!sBluetoothInterface) return JNI_FALSE;
1514
1515 jbyte* val = env->GetByteArrayElements(value, NULL);
1516 bt_property_t prop;
1517 prop.type = (bt_property_type_t)type;
1518 prop.len = env->GetArrayLength(value);
1519 prop.val = val;
1520
1521 int ret = sBluetoothInterface->set_adapter_property(&prop);
1522 env->ReleaseByteArrayElements(value, val, 0);
1523
1524 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1525 }
1526
getAdapterPropertiesNative(JNIEnv * env,jobject obj)1527 static jboolean getAdapterPropertiesNative(JNIEnv* env, jobject obj) {
1528 ALOGV("%s", __func__);
1529
1530 if (!sBluetoothInterface) return JNI_FALSE;
1531
1532 int ret = sBluetoothInterface->get_adapter_properties();
1533 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1534 }
1535
getAdapterPropertyNative(JNIEnv * env,jobject obj,jint type)1536 static jboolean getAdapterPropertyNative(JNIEnv* env, jobject obj, jint type) {
1537 ALOGV("%s", __func__);
1538
1539 if (!sBluetoothInterface) return JNI_FALSE;
1540
1541 int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t)type);
1542 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1543 }
1544
getDevicePropertyNative(JNIEnv * env,jobject obj,jbyteArray address,jint type)1545 static jboolean getDevicePropertyNative(JNIEnv* env, jobject obj,
1546 jbyteArray address, jint type) {
1547 ALOGV("%s", __func__);
1548
1549 if (!sBluetoothInterface) return JNI_FALSE;
1550
1551 jbyte* addr = env->GetByteArrayElements(address, NULL);
1552 if (addr == NULL) {
1553 jniThrowIOException(env, EINVAL);
1554 return JNI_FALSE;
1555 }
1556
1557 int ret = sBluetoothInterface->get_remote_device_property(
1558 (RawAddress*)addr, (bt_property_type_t)type);
1559 env->ReleaseByteArrayElements(address, addr, 0);
1560 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1561 }
1562
setDevicePropertyNative(JNIEnv * env,jobject obj,jbyteArray address,jint type,jbyteArray value)1563 static jboolean setDevicePropertyNative(JNIEnv* env, jobject obj,
1564 jbyteArray address, jint type,
1565 jbyteArray value) {
1566 ALOGV("%s", __func__);
1567
1568 if (!sBluetoothInterface) return JNI_FALSE;
1569
1570 jbyte* val = env->GetByteArrayElements(value, NULL);
1571 if (val == NULL) {
1572 jniThrowIOException(env, EINVAL);
1573 return JNI_FALSE;
1574 }
1575
1576 jbyte* addr = env->GetByteArrayElements(address, NULL);
1577 if (addr == NULL) {
1578 env->ReleaseByteArrayElements(value, val, 0);
1579 jniThrowIOException(env, EINVAL);
1580 return JNI_FALSE;
1581 }
1582
1583 bt_property_t prop;
1584 prop.type = (bt_property_type_t)type;
1585 prop.len = env->GetArrayLength(value);
1586 prop.val = val;
1587
1588 int ret =
1589 sBluetoothInterface->set_remote_device_property((RawAddress*)addr, &prop);
1590 env->ReleaseByteArrayElements(value, val, 0);
1591 env->ReleaseByteArrayElements(address, addr, 0);
1592
1593 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1594 }
1595
getRemoteServicesNative(JNIEnv * env,jobject obj,jbyteArray address,jint transport)1596 static jboolean getRemoteServicesNative(JNIEnv* env, jobject obj,
1597 jbyteArray address, jint transport) {
1598 ALOGV("%s", __func__);
1599
1600 if (!sBluetoothInterface) return JNI_FALSE;
1601
1602 jbyte* addr = addr = env->GetByteArrayElements(address, NULL);
1603 if (addr == NULL) {
1604 jniThrowIOException(env, EINVAL);
1605 return JNI_FALSE;
1606 }
1607
1608 int ret =
1609 sBluetoothInterface->get_remote_services((RawAddress*)addr, transport);
1610 env->ReleaseByteArrayElements(address, addr, 0);
1611 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1612 }
1613
readEnergyInfo()1614 static int readEnergyInfo() {
1615 ALOGV("%s", __func__);
1616
1617 if (!sBluetoothInterface) return JNI_FALSE;
1618 int ret = sBluetoothInterface->read_energy_info();
1619 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1620 }
1621
dumpNative(JNIEnv * env,jobject obj,jobject fdObj,jobjectArray argArray)1622 static void dumpNative(JNIEnv* env, jobject obj, jobject fdObj,
1623 jobjectArray argArray) {
1624 ALOGV("%s", __func__);
1625 if (!sBluetoothInterface) return;
1626
1627 int fd = jniGetFDFromFileDescriptor(env, fdObj);
1628 if (fd < 0) return;
1629
1630 int numArgs = env->GetArrayLength(argArray);
1631
1632 jstring* argObjs = new jstring[numArgs];
1633 const char** args = nullptr;
1634 if (numArgs > 0) {
1635 args = new const char*[numArgs + 1];
1636 args[numArgs] = nullptr;
1637 }
1638
1639 for (int i = 0; i < numArgs; i++) {
1640 argObjs[i] = (jstring)env->GetObjectArrayElement(argArray, i);
1641 args[i] = env->GetStringUTFChars(argObjs[i], NULL);
1642 }
1643
1644 sBluetoothInterface->dump(fd, args);
1645
1646 for (int i = 0; i < numArgs; i++) {
1647 env->ReleaseStringUTFChars(argObjs[i], args[i]);
1648 }
1649
1650 delete[] args;
1651 delete[] argObjs;
1652 }
1653
dumpMetricsNative(JNIEnv * env,jobject obj)1654 static jbyteArray dumpMetricsNative(JNIEnv* env, jobject obj) {
1655 ALOGI("%s", __func__);
1656 if (!sBluetoothInterface) return env->NewByteArray(0);
1657
1658 std::string output;
1659 sBluetoothInterface->dumpMetrics(&output);
1660 jsize output_size = output.size() * sizeof(char);
1661 jbyteArray output_bytes = env->NewByteArray(output_size);
1662 env->SetByteArrayRegion(output_bytes, 0, output_size,
1663 (const jbyte*)output.data());
1664 return output_bytes;
1665 }
1666
factoryResetNative(JNIEnv * env,jobject obj)1667 static jboolean factoryResetNative(JNIEnv* env, jobject obj) {
1668 ALOGV("%s", __func__);
1669 if (!sBluetoothInterface) return JNI_FALSE;
1670 int ret = sBluetoothInterface->config_clear();
1671 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1672 }
1673
obfuscateAddressNative(JNIEnv * env,jobject obj,jbyteArray address)1674 static jbyteArray obfuscateAddressNative(JNIEnv* env, jobject obj,
1675 jbyteArray address) {
1676 ALOGV("%s", __func__);
1677 if (!sBluetoothInterface) return env->NewByteArray(0);
1678 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1679 if (addr == nullptr) {
1680 jniThrowIOException(env, EINVAL);
1681 return env->NewByteArray(0);
1682 }
1683 RawAddress addr_obj = {};
1684 addr_obj.FromOctets((uint8_t*)addr);
1685 std::string output = sBluetoothInterface->obfuscate_address(addr_obj);
1686 jsize output_size = output.size() * sizeof(char);
1687 jbyteArray output_bytes = env->NewByteArray(output_size);
1688 env->SetByteArrayRegion(output_bytes, 0, output_size,
1689 (const jbyte*)output.data());
1690 return output_bytes;
1691 }
1692
setBufferLengthMillisNative(JNIEnv * env,jobject obj,jint codec,jint size)1693 static jboolean setBufferLengthMillisNative(JNIEnv* env, jobject obj,
1694 jint codec, jint size) {
1695 ALOGV("%s", __func__);
1696
1697 if (!sBluetoothInterface) return JNI_FALSE;
1698
1699 int ret = sBluetoothInterface->set_dynamic_audio_buffer_size(codec, size);
1700 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1701 }
1702
connectSocketNative(JNIEnv * env,jobject obj,jbyteArray address,jint type,jbyteArray uuid,jint port,jint flag,jint callingUid)1703 static jint connectSocketNative(JNIEnv* env, jobject obj, jbyteArray address,
1704 jint type, jbyteArray uuid, jint port,
1705 jint flag, jint callingUid) {
1706 int socket_fd = INVALID_FD;
1707 jbyte* addr = nullptr;
1708 jbyte* uuidBytes = nullptr;
1709 Uuid btUuid;
1710
1711 if (!sBluetoothSocketInterface) {
1712 goto done;
1713 }
1714 addr = env->GetByteArrayElements(address, nullptr);
1715 uuidBytes = env->GetByteArrayElements(uuid, nullptr);
1716 if (addr == nullptr || uuidBytes == nullptr) {
1717 jniThrowIOException(env, EINVAL);
1718 goto done;
1719 }
1720
1721 btUuid = Uuid::From128BitBE((uint8_t*)uuidBytes);
1722 if (sBluetoothSocketInterface->connect((RawAddress*)addr, (btsock_type_t)type,
1723 &btUuid, port, &socket_fd, flag,
1724 callingUid) != BT_STATUS_SUCCESS) {
1725 socket_fd = INVALID_FD;
1726 }
1727
1728 done:
1729 if (addr) env->ReleaseByteArrayElements(address, addr, 0);
1730 if (uuidBytes) env->ReleaseByteArrayElements(uuid, uuidBytes, 0);
1731 return socket_fd;
1732 }
1733
createSocketChannelNative(JNIEnv * env,jobject obj,jint type,jstring serviceName,jbyteArray uuid,jint port,jint flag,jint callingUid)1734 static jint createSocketChannelNative(JNIEnv* env, jobject obj, jint type,
1735 jstring serviceName, jbyteArray uuid,
1736 jint port, jint flag, jint callingUid) {
1737 int socket_fd = INVALID_FD;
1738 jbyte* uuidBytes = nullptr;
1739 Uuid btUuid;
1740 const char* nativeServiceName = nullptr;
1741
1742 if (!sBluetoothSocketInterface) {
1743 goto done;
1744 }
1745 uuidBytes = env->GetByteArrayElements(uuid, nullptr);
1746 if (serviceName != nullptr) {
1747 nativeServiceName = env->GetStringUTFChars(serviceName, nullptr);
1748 }
1749 if (uuidBytes == nullptr) {
1750 jniThrowIOException(env, EINVAL);
1751 goto done;
1752 }
1753 btUuid = Uuid::From128BitBE((uint8_t*)uuidBytes);
1754
1755 if (sBluetoothSocketInterface->listen((btsock_type_t)type, nativeServiceName,
1756 &btUuid, port, &socket_fd, flag,
1757 callingUid) != BT_STATUS_SUCCESS) {
1758 socket_fd = INVALID_FD;
1759 }
1760
1761 done:
1762 if (uuidBytes) env->ReleaseByteArrayElements(uuid, uuidBytes, 0);
1763 if (nativeServiceName)
1764 env->ReleaseStringUTFChars(serviceName, nativeServiceName);
1765 return socket_fd;
1766 }
1767
requestMaximumTxDataLengthNative(JNIEnv * env,jobject obj,jbyteArray address)1768 static void requestMaximumTxDataLengthNative(JNIEnv* env, jobject obj,
1769 jbyteArray address) {
1770 if (!sBluetoothSocketInterface) {
1771 return;
1772 }
1773 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1774 if (addr == nullptr) {
1775 jniThrowIOException(env, EINVAL);
1776 return;
1777 }
1778
1779 RawAddress addressVar = *(RawAddress*)addr;
1780 sBluetoothSocketInterface->request_max_tx_data_length(addressVar);
1781 env->ReleaseByteArrayElements(address, addr, 1);
1782 }
1783
getMetricIdNative(JNIEnv * env,jobject obj,jbyteArray address)1784 static int getMetricIdNative(JNIEnv* env, jobject obj, jbyteArray address) {
1785 ALOGV("%s", __func__);
1786 if (!sBluetoothInterface) return 0; // 0 is invalid id
1787 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1788 if (addr == nullptr) {
1789 jniThrowIOException(env, EINVAL);
1790 return 0;
1791 }
1792 RawAddress addr_obj = {};
1793 addr_obj.FromOctets((uint8_t*)addr);
1794 return sBluetoothInterface->get_metric_id(addr_obj);
1795 }
1796
allowLowLatencyAudioNative(JNIEnv * env,jobject obj,jboolean allowed,jbyteArray address)1797 static jboolean allowLowLatencyAudioNative(JNIEnv* env, jobject obj,
1798 jboolean allowed,
1799 jbyteArray address) {
1800 ALOGV("%s", __func__);
1801 if (!sBluetoothInterface) return false;
1802 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1803 if (addr == nullptr) {
1804 jniThrowIOException(env, EINVAL);
1805 return false;
1806 }
1807 RawAddress addr_obj = {};
1808 addr_obj.FromOctets((uint8_t*)addr);
1809 sBluetoothInterface->allow_low_latency_audio(allowed, addr_obj);
1810 return true;
1811 }
1812
metadataChangedNative(JNIEnv * env,jobject obj,jbyteArray address,jint key,jbyteArray value)1813 static void metadataChangedNative(JNIEnv* env, jobject obj, jbyteArray address,
1814 jint key, jbyteArray value) {
1815 ALOGV("%s", __func__);
1816 if (!sBluetoothInterface) return;
1817 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1818 if (addr == nullptr) {
1819 jniThrowIOException(env, EINVAL);
1820 return;
1821 }
1822 RawAddress addr_obj = {};
1823 addr_obj.FromOctets((uint8_t*)addr);
1824
1825 if (value == NULL) {
1826 ALOGE("metadataChangedNative() ignoring NULL array");
1827 return;
1828 }
1829
1830 uint16_t len = (uint16_t)env->GetArrayLength(value);
1831 jbyte* p_value = env->GetByteArrayElements(value, NULL);
1832 if (p_value == NULL) return;
1833
1834 std::vector<uint8_t> val_vec(reinterpret_cast<uint8_t*>(p_value),
1835 reinterpret_cast<uint8_t*>(p_value + len));
1836 env->ReleaseByteArrayElements(value, p_value, 0);
1837
1838 sBluetoothInterface->metadata_changed(addr_obj, key, std::move(val_vec));
1839 return;
1840 }
1841
1842 static JNINativeMethod sMethods[] = {
1843 /* name, signature, funcPtr */
1844 {"classInitNative", "()V", (void*)classInitNative},
1845 {"initNative", "(ZZI[Ljava/lang/String;ZLjava/lang/String;)Z",
1846 (void*)initNative},
1847 {"cleanupNative", "()V", (void*)cleanupNative},
1848 {"enableNative", "()Z", (void*)enableNative},
1849 {"disableNative", "()Z", (void*)disableNative},
1850 {"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative},
1851 {"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative},
1852 {"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative},
1853 {"getDevicePropertyNative", "([BI)Z", (void*)getDevicePropertyNative},
1854 {"setDevicePropertyNative", "([BI[B)Z", (void*)setDevicePropertyNative},
1855 {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
1856 {"cancelDiscoveryNative", "()Z", (void*)cancelDiscoveryNative},
1857 {"createBondNative", "([BI)Z", (void*)createBondNative},
1858 {"createBondOutOfBandNative",
1859 "([BILandroid/bluetooth/OobData;Landroid/bluetooth/OobData;)Z",
1860 (void*)createBondOutOfBandNative},
1861 {"removeBondNative", "([B)Z", (void*)removeBondNative},
1862 {"cancelBondNative", "([B)Z", (void*)cancelBondNative},
1863 {"generateLocalOobDataNative", "(I)V", (void*)generateLocalOobDataNative},
1864 {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative},
1865 {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative},
1866 {"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative},
1867 {"getRemoteServicesNative", "([BI)Z", (void*)getRemoteServicesNative},
1868 {"alarmFiredNative", "()V", (void*)alarmFiredNative},
1869 {"readEnergyInfo", "()I", (void*)readEnergyInfo},
1870 {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V",
1871 (void*)dumpNative},
1872 {"dumpMetricsNative", "()[B", (void*)dumpMetricsNative},
1873 {"factoryResetNative", "()Z", (void*)factoryResetNative},
1874 {"obfuscateAddressNative", "([B)[B", (void*)obfuscateAddressNative},
1875 {"setBufferLengthMillisNative", "(II)Z",
1876 (void*)setBufferLengthMillisNative},
1877 {"getMetricIdNative", "([B)I", (void*)getMetricIdNative},
1878 {"connectSocketNative", "([BI[BIII)I", (void*)connectSocketNative},
1879 {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I",
1880 (void*)createSocketChannelNative},
1881 {"requestMaximumTxDataLengthNative", "([B)V",
1882 (void*)requestMaximumTxDataLengthNative},
1883 {"allowLowLatencyAudioNative", "(Z[B)Z", (void*)allowLowLatencyAudioNative},
1884 {"metadataChangedNative", "([BI[B)V", (void*)metadataChangedNative},
1885 };
1886
register_com_android_bluetooth_btservice_AdapterService(JNIEnv * env)1887 int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
1888 return jniRegisterNativeMethods(
1889 env, "com/android/bluetooth/btservice/AdapterService", sMethods,
1890 NELEM(sMethods));
1891 }
1892
1893 } /* namespace android */
1894
1895 /*
1896 * JNI Initialization
1897 */
JNI_OnLoad(JavaVM * jvm,void * reserved)1898 jint JNI_OnLoad(JavaVM* jvm, void* reserved) {
1899 JNIEnv* e;
1900 int status;
1901
1902 ALOGV("Bluetooth Adapter Service : loading JNI\n");
1903
1904 // Check JNI version
1905 if (jvm->GetEnv((void**)&e, JNI_VERSION_1_6)) {
1906 ALOGE("JNI version mismatch error");
1907 return JNI_ERR;
1908 }
1909
1910 status = android::register_com_android_bluetooth_btservice_AdapterService(e);
1911 if (status < 0) {
1912 ALOGE("jni adapter service registration failure, status: %d", status);
1913 return JNI_ERR;
1914 }
1915
1916 status =
1917 android::register_com_android_bluetooth_btservice_activity_attribution(e);
1918 if (status < 0) {
1919 ALOGE("jni activity attribution registration failure: %d", status);
1920 return JNI_ERR;
1921 }
1922
1923 status =
1924 android::register_com_android_bluetooth_btservice_BluetoothKeystore(e);
1925 if (status < 0) {
1926 ALOGE("jni BluetoothKeyStore registration failure: %d", status);
1927 return JNI_ERR;
1928 }
1929
1930 status = android::register_com_android_bluetooth_hfp(e);
1931 if (status < 0) {
1932 ALOGE("jni hfp registration failure, status: %d", status);
1933 return JNI_ERR;
1934 }
1935
1936 status = android::register_com_android_bluetooth_hfpclient(e);
1937 if (status < 0) {
1938 ALOGE("jni hfp client registration failure, status: %d", status);
1939 return JNI_ERR;
1940 }
1941
1942 status = android::register_com_android_bluetooth_a2dp(e);
1943 if (status < 0) {
1944 ALOGE("jni a2dp source registration failure: %d", status);
1945 return JNI_ERR;
1946 }
1947
1948 status = android::register_com_android_bluetooth_a2dp_sink(e);
1949 if (status < 0) {
1950 ALOGE("jni a2dp sink registration failure: %d", status);
1951 return JNI_ERR;
1952 }
1953
1954 status = android::register_com_android_bluetooth_avrcp_target(e);
1955 if (status < 0) {
1956 ALOGE("jni new avrcp target registration failure: %d", status);
1957 }
1958
1959 status = android::register_com_android_bluetooth_avrcp_controller(e);
1960 if (status < 0) {
1961 ALOGE("jni avrcp controller registration failure: %d", status);
1962 return JNI_ERR;
1963 }
1964
1965 status = android::register_com_android_bluetooth_hid_host(e);
1966 if (status < 0) {
1967 ALOGE("jni hid registration failure: %d", status);
1968 return JNI_ERR;
1969 }
1970
1971 status = android::register_com_android_bluetooth_hid_device(e);
1972 if (status < 0) {
1973 ALOGE("jni hidd registration failure: %d", status);
1974 return JNI_ERR;
1975 }
1976
1977 status = android::register_com_android_bluetooth_pan(e);
1978 if (status < 0) {
1979 ALOGE("jni pan registration failure: %d", status);
1980 return JNI_ERR;
1981 }
1982
1983 status = android::register_com_android_bluetooth_gatt(e);
1984 if (status < 0) {
1985 ALOGE("jni gatt registration failure: %d", status);
1986 return JNI_ERR;
1987 }
1988
1989 status = android::register_com_android_bluetooth_sdp(e);
1990 if (status < 0) {
1991 ALOGE("jni sdp registration failure: %d", status);
1992 return JNI_ERR;
1993 }
1994
1995 status = android::register_com_android_bluetooth_hearing_aid(e);
1996 if (status < 0) {
1997 ALOGE("jni hearing aid registration failure: %d", status);
1998 return JNI_ERR;
1999 }
2000
2001 status = android::register_com_android_bluetooth_hap_client(e);
2002 if (status < 0) {
2003 ALOGE("jni le audio hearing access client registration failure: %d",
2004 status);
2005 return JNI_ERR;
2006 }
2007
2008 status = android::register_com_android_bluetooth_le_audio(e);
2009 if (status < 0) {
2010 ALOGE("jni le_audio registration failure: %d", status);
2011 return JNI_ERR;
2012 }
2013
2014 status = android::register_com_android_bluetooth_vc(e);
2015 if (status < 0) {
2016 ALOGE("jni vc registration failure: %d", status);
2017 return JNI_ERR;
2018 }
2019
2020 status = android::register_com_android_bluetooth_csip_set_coordinator(e);
2021 if (status < 0) {
2022 ALOGE("jni csis client registration failure: %d", status);
2023 return JNI_ERR;
2024 }
2025
2026 return JNI_VERSION_1_6;
2027 }
2028