1 /*
2 * Copyright (C) 2016-2017 The Linux Foundation
3 * Copyright (C) 2012 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #define LOG_TAG "BluetoothServiceJni"
19
20 #include <dlfcn.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <hardware/bluetooth.h>
24 #include <nativehelper/JNIPlatformHelp.h>
25 #include <pthread.h>
26 #include <string.h>
27 #include <sys/prctl.h>
28 #include <sys/stat.h>
29
30 #include <shared_mutex>
31
32 #include "com_android_bluetooth.h"
33 #include "hardware/bt_sock.h"
34 #include "os/logging/log_adapter.h"
35 #include "utils/misc.h"
36
37 using bluetooth::Uuid;
38 extern bt_interface_t bluetoothInterface;
39
40 namespace fmt {
41 template <>
42 struct formatter<bt_state_t> : enum_formatter<bt_state_t> {};
43 template <>
44 struct formatter<bt_discovery_state_t> : enum_formatter<bt_discovery_state_t> {
45 };
46 } // namespace fmt
47
from_java_uuid(jlong uuid_msb,jlong uuid_lsb)48 static Uuid from_java_uuid(jlong uuid_msb, jlong uuid_lsb) {
49 std::array<uint8_t, Uuid::kNumBytes128> uu;
50 for (int i = 0; i < 8; i++) {
51 uu[7 - i] = (uuid_msb >> (8 * i)) & 0xFF;
52 uu[15 - i] = (uuid_lsb >> (8 * i)) & 0xFF;
53 }
54 return Uuid::From128BitBE(uu);
55 }
56
57 namespace android {
58 // Both
59
60 #define TRANSPORT_AUTO 0
61 #define TRANSPORT_BREDR 1
62 #define TRANSPORT_LE 2
63
64 #define BLE_ADDR_PUBLIC 0x00
65 #define BLE_ADDR_RANDOM 0x01
66
67 const jint INVALID_FD = -1;
68 const jint INVALID_CID = -1;
69
70 static jmethodID method_oobDataReceivedCallback;
71 static jmethodID method_stateChangeCallback;
72 static jmethodID method_adapterPropertyChangedCallback;
73 static jmethodID method_devicePropertyChangedCallback;
74 static jmethodID method_deviceFoundCallback;
75 static jmethodID method_pinRequestCallback;
76 static jmethodID method_sspRequestCallback;
77 static jmethodID method_bondStateChangeCallback;
78 static jmethodID method_addressConsolidateCallback;
79 static jmethodID method_leAddressAssociateCallback;
80 static jmethodID method_aclStateChangeCallback;
81 static jmethodID method_discoveryStateChangeCallback;
82 static jmethodID method_linkQualityReportCallback;
83 static jmethodID method_switchBufferSizeCallback;
84 static jmethodID method_switchCodecCallback;
85 static jmethodID method_acquireWakeLock;
86 static jmethodID method_releaseWakeLock;
87 static jmethodID method_energyInfo;
88 static jmethodID method_keyMissingCallback;
89
90 static struct {
91 jclass clazz;
92 jmethodID constructor;
93 } android_bluetooth_UidTraffic;
94
95 static const bt_interface_t* sBluetoothInterface = NULL;
96 static const btsock_interface_t* sBluetoothSocketInterface = NULL;
97 static JavaVM* vm = NULL;
98 static JNIEnv* callbackEnv = NULL;
99 static pthread_t sCallbackThread;
100 static bool sHaveCallbackThread;
101
102 static jobject sJniAdapterServiceObj;
103 static jobject sJniCallbacksObj;
104 static std::shared_timed_mutex jniObjMutex;
105 static jfieldID sJniCallbacksField;
106
getBluetoothInterface()107 const bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; }
108
getCallbackEnv()109 JNIEnv* getCallbackEnv() { return callbackEnv; }
110
isCallbackThread()111 bool isCallbackThread() {
112 return sHaveCallbackThread && pthread_equal(sCallbackThread, pthread_self());
113 }
114
adapter_state_change_callback(bt_state_t status)115 static void adapter_state_change_callback(bt_state_t status) {
116 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
117 if (!sJniCallbacksObj) {
118 log::error("JNI obj is null. Failed to call JNI callback");
119 return;
120 }
121
122 CallbackEnv sCallbackEnv(__func__);
123 if (!sCallbackEnv.valid()) return;
124 log::verbose("Status is: {}", status);
125
126 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback,
127 (jint)status);
128 }
129
get_properties(int num_properties,bt_property_t * properties,jintArray * types,jobjectArray * props)130 static int get_properties(int num_properties, bt_property_t* properties,
131 jintArray* types, jobjectArray* props) {
132 for (int i = 0; i < num_properties; i++) {
133 ScopedLocalRef<jbyteArray> propVal(
134 callbackEnv, callbackEnv->NewByteArray(properties[i].len));
135 if (!propVal.get()) {
136 log::error("Error while allocation of array");
137 return -1;
138 }
139
140 callbackEnv->SetByteArrayRegion(propVal.get(), 0, properties[i].len,
141 (jbyte*)properties[i].val);
142 callbackEnv->SetObjectArrayElement(*props, i, propVal.get());
143 callbackEnv->SetIntArrayRegion(*types, i, 1, (jint*)&properties[i].type);
144 }
145 return 0;
146 }
147
adapter_properties_callback(bt_status_t status,int num_properties,bt_property_t * properties)148 static void adapter_properties_callback(bt_status_t status, int num_properties,
149 bt_property_t* properties) {
150 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
151 if (!sJniCallbacksObj) {
152 log::error("JNI obj is null. Failed to call JNI callback");
153 return;
154 }
155
156 CallbackEnv sCallbackEnv(__func__);
157 if (!sCallbackEnv.valid()) return;
158
159 log::verbose("Status is: {}, Properties: {}", bt_status_text(status),
160 num_properties);
161
162 if (status != BT_STATUS_SUCCESS) {
163 log::error("Status {} is incorrect", bt_status_text(status));
164 return;
165 }
166
167 ScopedLocalRef<jbyteArray> val(
168 sCallbackEnv.get(),
169 (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
170 if (!val.get()) {
171 log::error("Error allocating byteArray");
172 return;
173 }
174
175 ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
176 sCallbackEnv->GetObjectClass(val.get()));
177
178 /* (BT) Initialize the jobjectArray and jintArray here itself and send the
179 initialized array pointers alone to get_properties */
180
181 ScopedLocalRef<jobjectArray> props(
182 sCallbackEnv.get(),
183 sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
184 if (!props.get()) {
185 log::error("Error allocating object Array for properties");
186 return;
187 }
188
189 ScopedLocalRef<jintArray> types(
190 sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
191 if (!types.get()) {
192 log::error("Error allocating int Array for values");
193 return;
194 }
195
196 jintArray typesPtr = types.get();
197 jobjectArray propsPtr = props.get();
198 if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
199 return;
200 }
201
202 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
203 method_adapterPropertyChangedCallback,
204 types.get(), props.get());
205 }
206
remote_device_properties_callback(bt_status_t status,RawAddress * bd_addr,int num_properties,bt_property_t * properties)207 static void remote_device_properties_callback(bt_status_t status,
208 RawAddress* bd_addr,
209 int num_properties,
210 bt_property_t* properties) {
211 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
212 if (!sJniCallbacksObj) {
213 log::error("JNI obj is null. Failed to call JNI callback");
214 return;
215 }
216
217 CallbackEnv sCallbackEnv(__func__);
218 if (!sCallbackEnv.valid()) return;
219
220 log::verbose("Device: {}, Status: {}, Properties: {}",
221 ADDRESS_TO_LOGGABLE_STR(*bd_addr), bt_status_text(status),
222 num_properties);
223
224 if (status != BT_STATUS_SUCCESS) {
225 log::error("Status {} is incorrect", bt_status_text(status));
226 return;
227 }
228
229 ScopedLocalRef<jbyteArray> val(
230 sCallbackEnv.get(),
231 (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
232 if (!val.get()) {
233 log::error("Error allocating byteArray");
234 return;
235 }
236
237 ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
238 sCallbackEnv->GetObjectClass(val.get()));
239
240 /* Initialize the jobjectArray and jintArray here itself and send the
241 initialized array pointers alone to get_properties */
242
243 ScopedLocalRef<jobjectArray> props(
244 sCallbackEnv.get(),
245 sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
246 if (!props.get()) {
247 log::error("Error allocating object Array for properties");
248 return;
249 }
250
251 ScopedLocalRef<jintArray> types(
252 sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
253 if (!types.get()) {
254 log::error("Error allocating int Array for values");
255 return;
256 }
257
258 ScopedLocalRef<jbyteArray> addr(
259 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
260 if (!addr.get()) {
261 log::error("Error while allocation byte array");
262 return;
263 }
264
265 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
266 (jbyte*)bd_addr);
267
268 jintArray typesPtr = types.get();
269 jobjectArray propsPtr = props.get();
270 if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
271 return;
272 }
273
274 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
275 method_devicePropertyChangedCallback, addr.get(),
276 types.get(), props.get());
277 }
278
device_found_callback(int num_properties,bt_property_t * properties)279 static void device_found_callback(int num_properties,
280 bt_property_t* properties) {
281 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
282 if (!sJniCallbacksObj) {
283 log::error("JNI obj is null. Failed to call JNI callback");
284 return;
285 }
286
287 CallbackEnv sCallbackEnv(__func__);
288 if (!sCallbackEnv.valid()) return;
289
290 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), NULL);
291 int addr_index;
292 for (int i = 0; i < num_properties; i++) {
293 if (properties[i].type == BT_PROPERTY_BDADDR) {
294 addr.reset(sCallbackEnv->NewByteArray(properties[i].len));
295 if (!addr.get()) {
296 log::error("Address is NULL (unable to allocate)");
297 return;
298 }
299 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, properties[i].len,
300 (jbyte*)properties[i].val);
301 addr_index = i;
302 }
303 }
304 if (!addr.get()) {
305 log::error("Address is NULL");
306 return;
307 }
308
309 log::verbose("Properties: {}, Address: {}", num_properties,
310 *(RawAddress*)properties[addr_index].val);
311
312 remote_device_properties_callback(BT_STATUS_SUCCESS,
313 (RawAddress*)properties[addr_index].val,
314 num_properties, properties);
315
316 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback,
317 addr.get());
318 }
319
bond_state_changed_callback(bt_status_t status,RawAddress * bd_addr,bt_bond_state_t state,int fail_reason)320 static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
321 bt_bond_state_t state,
322 int fail_reason) {
323 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
324 if (!sJniCallbacksObj) {
325 log::error("JNI obj is null. Failed to call JNI callback");
326 return;
327 }
328
329 CallbackEnv sCallbackEnv(__func__);
330 if (!sCallbackEnv.valid()) return;
331
332 if (!bd_addr) {
333 log::error("Address is null");
334 return;
335 }
336
337 ScopedLocalRef<jbyteArray> addr(
338 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
339 if (!addr.get()) {
340 log::error("Address allocation failed");
341 return;
342 }
343 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
344 (jbyte*)bd_addr);
345
346 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback,
347 (jint)status, addr.get(), (jint)state,
348 (jint)fail_reason);
349 }
350
address_consolidate_callback(RawAddress * main_bd_addr,RawAddress * secondary_bd_addr)351 static void address_consolidate_callback(RawAddress* main_bd_addr,
352 RawAddress* secondary_bd_addr) {
353 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
354 if (!sJniCallbacksObj) {
355 log::error("JNI obj is null. Failed to call JNI callback");
356 return;
357 }
358
359 CallbackEnv sCallbackEnv(__func__);
360
361 ScopedLocalRef<jbyteArray> main_addr(
362 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
363 if (!main_addr.get()) {
364 log::error("Address allocation failed");
365 return;
366 }
367 sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress),
368 (jbyte*)main_bd_addr);
369
370 ScopedLocalRef<jbyteArray> secondary_addr(
371 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
372 if (!secondary_addr.get()) {
373 log::error("Address allocation failed");
374 return;
375 }
376
377 sCallbackEnv->SetByteArrayRegion(secondary_addr.get(), 0, sizeof(RawAddress),
378 (jbyte*)secondary_bd_addr);
379
380 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
381 method_addressConsolidateCallback,
382 main_addr.get(), secondary_addr.get());
383 }
384
le_address_associate_callback(RawAddress * main_bd_addr,RawAddress * secondary_bd_addr)385 static void le_address_associate_callback(RawAddress* main_bd_addr,
386 RawAddress* secondary_bd_addr) {
387 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
388 if (!sJniCallbacksObj) {
389 log::error("JNI obj is null. Failed to call JNI callback");
390 return;
391 }
392
393 CallbackEnv sCallbackEnv(__func__);
394
395 ScopedLocalRef<jbyteArray> main_addr(
396 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
397 if (!main_addr.get()) {
398 log::error("Address allocation failed");
399 return;
400 }
401 sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress),
402 (jbyte*)main_bd_addr);
403
404 ScopedLocalRef<jbyteArray> secondary_addr(
405 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
406 if (!secondary_addr.get()) {
407 log::error("Address allocation failed");
408 return;
409 }
410
411 sCallbackEnv->SetByteArrayRegion(secondary_addr.get(), 0, sizeof(RawAddress),
412 (jbyte*)secondary_bd_addr);
413
414 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
415 method_leAddressAssociateCallback,
416 main_addr.get(), secondary_addr.get());
417 }
418
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,bt_conn_direction_t,uint16_t acl_handle)419 static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
420 bt_acl_state_t state,
421 int transport_link_type,
422 bt_hci_error_code_t hci_reason,
423 bt_conn_direction_t /* direction */,
424 uint16_t acl_handle) {
425 if (!bd_addr) {
426 log::error("Address is null");
427 return;
428 }
429
430 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
431 if (!sJniCallbacksObj) {
432 log::error("JNI obj is null. Failed to call JNI callback");
433 return;
434 }
435
436 CallbackEnv sCallbackEnv(__func__);
437 if (!sCallbackEnv.valid()) return;
438
439 ScopedLocalRef<jbyteArray> addr(
440 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
441 if (!addr.get()) {
442 log::error("Address allocation failed");
443 return;
444 }
445 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
446 (jbyte*)bd_addr);
447
448 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback,
449 (jint)status, addr.get(), (jint)state,
450 (jint)transport_link_type, (jint)hci_reason,
451 (jint)acl_handle);
452 }
453
discovery_state_changed_callback(bt_discovery_state_t state)454 static void discovery_state_changed_callback(bt_discovery_state_t state) {
455 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
456 if (!sJniCallbacksObj) {
457 log::error("JNI obj is null. Failed to call JNI callback");
458 return;
459 }
460
461 CallbackEnv sCallbackEnv(__func__);
462 if (!sCallbackEnv.valid()) return;
463
464 log::verbose("DiscoveryState:{}", state);
465
466 sCallbackEnv->CallVoidMethod(
467 sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state);
468 }
469
pin_request_callback(RawAddress * bd_addr,bt_bdname_t * bdname,uint32_t cod,bool min_16_digits)470 static void pin_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
471 uint32_t cod, bool min_16_digits) {
472 if (!bd_addr) {
473 log::error("Address is null");
474 return;
475 }
476
477 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
478 if (!sJniCallbacksObj) {
479 log::error("JNI obj is null. Failed to call JNI callback");
480 return;
481 }
482
483 CallbackEnv sCallbackEnv(__func__);
484 if (!sCallbackEnv.valid()) return;
485
486 ScopedLocalRef<jbyteArray> addr(
487 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
488 if (!addr.get()) {
489 log::error("Error while allocating");
490 return;
491 }
492
493 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
494 (jbyte*)bd_addr);
495
496 ScopedLocalRef<jbyteArray> devname(
497 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)));
498 if (!devname.get()) {
499 log::error("Error while allocating");
500 return;
501 }
502
503 sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t),
504 (jbyte*)bdname);
505
506 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback,
507 addr.get(), devname.get(), cod, min_16_digits);
508 }
509
ssp_request_callback(RawAddress * bd_addr,bt_ssp_variant_t pairing_variant,uint32_t pass_key)510 static void ssp_request_callback(RawAddress* bd_addr,
511 bt_ssp_variant_t pairing_variant,
512 uint32_t pass_key) {
513 if (!bd_addr) {
514 log::error("Address is null");
515 return;
516 }
517
518 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
519 if (!sJniCallbacksObj) {
520 log::error("JNI obj is null. Failed to call JNI callback");
521 return;
522 }
523
524 CallbackEnv sCallbackEnv(__func__);
525 if (!sCallbackEnv.valid()) return;
526
527 ScopedLocalRef<jbyteArray> addr(
528 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
529 if (!addr.get()) {
530 log::error("Error while allocating");
531 return;
532 }
533
534 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
535 (jbyte*)bd_addr);
536
537 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback,
538 addr.get(), (jint)pairing_variant, pass_key);
539 }
540
createClassicOobDataObject(JNIEnv * env,bt_oob_data_t oob_data)541 static jobject createClassicOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) {
542 log::verbose("");
543 jmethodID classicBuilderConstructor;
544 jmethodID setRMethod;
545 jmethodID setNameMethod;
546 jmethodID buildMethod;
547
548 const JNIJavaMethod javaMethods[] = {
549 {"<init>", "([B[B[B)V", &classicBuilderConstructor},
550 {"setRandomizerHash", "([B)Landroid/bluetooth/OobData$ClassicBuilder;",
551 &setRMethod},
552 {"setDeviceName", "([B)Landroid/bluetooth/OobData$ClassicBuilder;",
553 &setNameMethod},
554 {"build", "()Landroid/bluetooth/OobData;", &buildMethod},
555 };
556 GET_JAVA_METHODS(env, "android/bluetooth/OobData$ClassicBuilder",
557 javaMethods);
558
559 jbyteArray confirmationHash = env->NewByteArray(OOB_C_SIZE);
560 env->SetByteArrayRegion(confirmationHash, 0, OOB_C_SIZE,
561 reinterpret_cast<jbyte*>(oob_data.c));
562
563 jbyteArray oobDataLength = env->NewByteArray(OOB_DATA_LEN_SIZE);
564 env->SetByteArrayRegion(oobDataLength, 0, OOB_DATA_LEN_SIZE,
565 reinterpret_cast<jbyte*>(oob_data.oob_data_length));
566
567 jbyteArray address = env->NewByteArray(OOB_ADDRESS_SIZE);
568 env->SetByteArrayRegion(address, 0, OOB_ADDRESS_SIZE,
569 reinterpret_cast<jbyte*>(oob_data.address));
570
571 jclass classicBuilderClass =
572 env->FindClass("android/bluetooth/OobData$ClassicBuilder");
573
574 jobject oobDataClassicBuilder =
575 env->NewObject(classicBuilderClass, classicBuilderConstructor,
576 confirmationHash, oobDataLength, address);
577
578 env->DeleteLocalRef(classicBuilderClass);
579
580 jbyteArray randomizerHash = env->NewByteArray(OOB_R_SIZE);
581 env->SetByteArrayRegion(randomizerHash, 0, OOB_R_SIZE,
582 reinterpret_cast<jbyte*>(oob_data.r));
583
584 oobDataClassicBuilder =
585 env->CallObjectMethod(oobDataClassicBuilder, setRMethod, randomizerHash);
586
587 int name_char_count = 0;
588 for (int i = 0; i < OOB_NAME_MAX_SIZE; i++) {
589 if (oob_data.device_name[i] == 0) {
590 name_char_count = i;
591 break;
592 }
593 }
594
595 jbyteArray deviceName = env->NewByteArray(name_char_count);
596 env->SetByteArrayRegion(deviceName, 0, name_char_count,
597 reinterpret_cast<jbyte*>(oob_data.device_name));
598
599 oobDataClassicBuilder =
600 env->CallObjectMethod(oobDataClassicBuilder, setNameMethod, deviceName);
601
602 return env->CallObjectMethod(oobDataClassicBuilder, buildMethod);
603 }
604
createLeOobDataObject(JNIEnv * env,bt_oob_data_t oob_data)605 static jobject createLeOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) {
606 log::verbose("");
607
608 jmethodID leBuilderConstructor;
609 jmethodID setRMethod;
610 jmethodID setNameMethod;
611 jmethodID buildMethod;
612
613 const JNIJavaMethod javaMethods[] = {
614 {"<init>", "([B[BI)V", &leBuilderConstructor},
615 {"setRandomizerHash", "([B)Landroid/bluetooth/OobData$LeBuilder;",
616 &setRMethod},
617 {"setDeviceName", "([B)Landroid/bluetooth/OobData$LeBuilder;",
618 &setNameMethod},
619 {"build", "()Landroid/bluetooth/OobData;", &buildMethod},
620 };
621 GET_JAVA_METHODS(env, "android/bluetooth/OobData$LeBuilder", javaMethods);
622
623 jbyteArray confirmationHash = env->NewByteArray(OOB_C_SIZE);
624 env->SetByteArrayRegion(confirmationHash, 0, OOB_C_SIZE,
625 reinterpret_cast<jbyte*>(oob_data.c));
626
627 jbyteArray address = env->NewByteArray(OOB_ADDRESS_SIZE);
628 env->SetByteArrayRegion(address, 0, OOB_ADDRESS_SIZE,
629 reinterpret_cast<jbyte*>(oob_data.address));
630
631 jint le_role = (jint)oob_data.le_device_role;
632
633 jclass leBuilderClass = env->FindClass("android/bluetooth/OobData$LeBuilder");
634
635 jobject oobDataLeBuilder = env->NewObject(
636 leBuilderClass, leBuilderConstructor, confirmationHash, address, le_role);
637
638 env->DeleteLocalRef(leBuilderClass);
639
640 jbyteArray randomizerHash = env->NewByteArray(OOB_R_SIZE);
641 env->SetByteArrayRegion(randomizerHash, 0, OOB_R_SIZE,
642 reinterpret_cast<jbyte*>(oob_data.r));
643
644 oobDataLeBuilder =
645 env->CallObjectMethod(oobDataLeBuilder, setRMethod, randomizerHash);
646
647 int name_char_count = 0;
648 for (int i = 0; i < OOB_NAME_MAX_SIZE; i++) {
649 if (oob_data.device_name[i] == 0) {
650 name_char_count = i;
651 break;
652 }
653 }
654
655 jbyteArray deviceName = env->NewByteArray(name_char_count);
656 env->SetByteArrayRegion(deviceName, 0, name_char_count,
657 reinterpret_cast<jbyte*>(oob_data.device_name));
658
659 oobDataLeBuilder =
660 env->CallObjectMethod(oobDataLeBuilder, setNameMethod, deviceName);
661
662 return env->CallObjectMethod(oobDataLeBuilder, buildMethod);
663 }
664
generate_local_oob_data_callback(tBT_TRANSPORT transport,bt_oob_data_t oob_data)665 static void generate_local_oob_data_callback(tBT_TRANSPORT transport,
666 bt_oob_data_t oob_data) {
667 log::verbose("");
668
669 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
670 if (!sJniCallbacksObj) {
671 log::error("JNI obj is null. Failed to call JNI callback");
672 return;
673 }
674
675 CallbackEnv sCallbackEnv(__func__);
676 if (!sCallbackEnv.valid()) return;
677
678 if (transport == TRANSPORT_BREDR) {
679 sCallbackEnv->CallVoidMethod(
680 sJniCallbacksObj, method_oobDataReceivedCallback, (jint)transport,
681 ((oob_data.is_valid)
682 ? createClassicOobDataObject(sCallbackEnv.get(), oob_data)
683 : nullptr));
684 } else if (transport == TRANSPORT_LE) {
685 sCallbackEnv->CallVoidMethod(
686 sJniCallbacksObj, method_oobDataReceivedCallback, (jint)transport,
687 ((oob_data.is_valid)
688 ? createLeOobDataObject(sCallbackEnv.get(), oob_data)
689 : nullptr));
690 } else {
691 // TRANSPORT_AUTO is a concept, however, the host stack doesn't fully
692 // implement it So passing it from the java layer is currently useless until
693 // the implementation and concept of TRANSPORT_AUTO is fleshed out.
694 log::error("TRANSPORT: {} not implemented", transport);
695 sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
696 method_oobDataReceivedCallback,
697 (jint)transport, nullptr);
698 }
699 }
700
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)701 static void link_quality_report_callback(
702 uint64_t timestamp, int report_id, int rssi, int snr,
703 int retransmission_count, int packets_not_receive_count,
704 int negative_acknowledgement_count) {
705 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
706 if (!sJniCallbacksObj) {
707 log::error("JNI obj is null. Failed to call JNI callback");
708 return;
709 }
710
711 CallbackEnv sCallbackEnv(__func__);
712 if (!sCallbackEnv.valid()) return;
713
714 log::verbose("LinkQualityReportCallback: {} {} {} {} {} {}", report_id, rssi,
715 snr, retransmission_count, packets_not_receive_count,
716 negative_acknowledgement_count);
717
718 sCallbackEnv->CallVoidMethod(
719 sJniCallbacksObj, method_linkQualityReportCallback,
720 (jlong)timestamp, (jint)report_id, (jint)rssi, (jint)snr,
721 (jint)retransmission_count, (jint)packets_not_receive_count,
722 (jint)negative_acknowledgement_count);
723 }
724
switch_buffer_size_callback(bool is_low_latency_buffer_size)725 static void switch_buffer_size_callback(bool is_low_latency_buffer_size) {
726 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
727 if (!sJniCallbacksObj) {
728 log::error("JNI obj is null. Failed to call JNI callback");
729 return;
730 }
731
732 CallbackEnv sCallbackEnv(__func__);
733 if (!sCallbackEnv.valid()) return;
734
735 log::verbose("SwitchBufferSizeCallback: {}", is_low_latency_buffer_size);
736
737 sCallbackEnv->CallVoidMethod(
738 sJniCallbacksObj, method_switchBufferSizeCallback,
739 (jboolean)is_low_latency_buffer_size);
740 }
741
switch_codec_callback(bool is_low_latency_buffer_size)742 static void switch_codec_callback(bool is_low_latency_buffer_size) {
743 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
744 if (!sJniCallbacksObj) {
745 log::error("JNI obj is null. Failed to call JNI callback");
746 return;
747 }
748
749 CallbackEnv sCallbackEnv(__func__);
750 if (!sCallbackEnv.valid()) return;
751
752 log::verbose("SwitchCodecCallback: {}", is_low_latency_buffer_size);
753
754 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_switchCodecCallback,
755 (jboolean)is_low_latency_buffer_size);
756 }
757
le_rand_callback(uint64_t)758 static void le_rand_callback(uint64_t /* random */) {
759 // Android doesn't support the LeRand API.
760 }
761
key_missing_callback(const RawAddress bd_addr)762 static void key_missing_callback(const RawAddress bd_addr) {
763 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
764 if (!sJniCallbacksObj) {
765 log::error("JNI obj is null. Failed to call JNI callback");
766 return;
767 }
768
769 CallbackEnv sCallbackEnv(__func__);
770 if (!sCallbackEnv.valid()) return;
771
772 ScopedLocalRef<jbyteArray> addr(
773 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
774 if (!addr.get()) {
775 log::error("Address allocation failed");
776 return;
777 }
778 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
779 (jbyte*)&bd_addr);
780
781 sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_keyMissingCallback,
782 addr.get());
783 }
784
callback_thread_event(bt_cb_thread_evt event)785 static void callback_thread_event(bt_cb_thread_evt event) {
786 if (event == ASSOCIATE_JVM) {
787 JavaVMAttachArgs args;
788 char name[] = "BT Service Callback Thread";
789 args.version = JNI_VERSION_1_6;
790 args.name = name;
791 args.group = NULL;
792 vm->AttachCurrentThread(&callbackEnv, &args);
793 sHaveCallbackThread = true;
794 sCallbackThread = pthread_self();
795 log::verbose("Callback thread attached: {}", fmt::ptr(callbackEnv));
796 } else if (event == DISASSOCIATE_JVM) {
797 if (!isCallbackThread()) {
798 log::error("Callback: '' is not called on the correct thread");
799 return;
800 }
801 vm->DetachCurrentThread();
802 sHaveCallbackThread = false;
803 callbackEnv = NULL;
804 }
805 }
806
dut_mode_recv_callback(uint16_t,uint8_t *,uint8_t)807 static void dut_mode_recv_callback(uint16_t /* opcode */, uint8_t* /* buf */,
808 uint8_t /* len */) {}
809
le_test_mode_recv_callback(bt_status_t status,uint16_t packet_count)810 static void le_test_mode_recv_callback(bt_status_t status,
811 uint16_t packet_count) {
812 log::verbose("status:{} packet_count:{}", bt_status_text(status),
813 packet_count);
814 }
815
energy_info_recv_callback(bt_activity_energy_info * p_energy_info,bt_uid_traffic_t * uid_data)816 static void energy_info_recv_callback(bt_activity_energy_info* p_energy_info,
817 bt_uid_traffic_t* uid_data) {
818 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
819 if (!sJniAdapterServiceObj) {
820 log::error("JNI obj is null. Failed to call JNI callback");
821 return;
822 }
823
824 CallbackEnv sCallbackEnv(__func__);
825 if (!sCallbackEnv.valid()) return;
826
827 jsize len = 0;
828 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
829 len++;
830 }
831
832 ScopedLocalRef<jobjectArray> array(
833 sCallbackEnv.get(), sCallbackEnv->NewObjectArray(
834 len, android_bluetooth_UidTraffic.clazz, NULL));
835 jsize i = 0;
836 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
837 ScopedLocalRef<jobject> uidObj(
838 sCallbackEnv.get(),
839 sCallbackEnv->NewObject(android_bluetooth_UidTraffic.clazz,
840 android_bluetooth_UidTraffic.constructor,
841 (jint)data->app_uid, (jlong)data->rx_bytes,
842 (jlong)data->tx_bytes));
843 sCallbackEnv->SetObjectArrayElement(array.get(), i++, uidObj.get());
844 }
845
846 sCallbackEnv->CallVoidMethod(
847 sJniCallbacksObj, method_energyInfo, p_energy_info->status,
848 p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time,
849 p_energy_info->idle_time, p_energy_info->energy_used, array.get());
850 }
851
852 static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks),
853 adapter_state_change_callback,
854 adapter_properties_callback,
855 remote_device_properties_callback,
856 device_found_callback,
857 discovery_state_changed_callback,
858 pin_request_callback,
859 ssp_request_callback,
860 bond_state_changed_callback,
861 address_consolidate_callback,
862 le_address_associate_callback,
863 acl_state_changed_callback,
864 callback_thread_event,
865 dut_mode_recv_callback,
866 le_test_mode_recv_callback,
867 energy_info_recv_callback,
868 link_quality_report_callback,
869 generate_local_oob_data_callback,
870 switch_buffer_size_callback,
871 switch_codec_callback,
872 le_rand_callback,
873 key_missing_callback};
874
875 class JNIThreadAttacher {
876 public:
JNIThreadAttacher(JavaVM * vm)877 JNIThreadAttacher(JavaVM* vm) : vm_(vm), env_(nullptr) {
878 status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6);
879
880 if (status_ != JNI_OK && status_ != JNI_EDETACHED) {
881 log::error(
882 "JNIThreadAttacher: unable to get environment for JNI CALL, status: "
883 "{}",
884 status_);
885 env_ = nullptr;
886 return;
887 }
888
889 if (status_ == JNI_EDETACHED) {
890 char name[17] = {0};
891 if (prctl(PR_GET_NAME, (unsigned long)name) != 0) {
892 log::error(
893 "JNIThreadAttacher: unable to grab previous thread name, error: {}",
894 strerror(errno));
895 env_ = nullptr;
896 return;
897 }
898
899 JavaVMAttachArgs args = {
900 .version = JNI_VERSION_1_6, .name = name, .group = nullptr};
901 if (vm_->AttachCurrentThread(&env_, &args) != 0) {
902 log::error("JNIThreadAttacher: unable to attach thread to VM");
903 env_ = nullptr;
904 return;
905 }
906 }
907 }
908
~JNIThreadAttacher()909 ~JNIThreadAttacher() {
910 if (status_ == JNI_EDETACHED) vm_->DetachCurrentThread();
911 }
912
getEnv()913 JNIEnv* getEnv() { return env_; }
914
915 private:
916 JavaVM* vm_;
917 JNIEnv* env_;
918 jint status_;
919 };
920
acquire_wake_lock_callout(const char * lock_name)921 static int acquire_wake_lock_callout(const char* lock_name) {
922 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
923 if (!sJniAdapterServiceObj) {
924 log::error("JNI obj is null. Failed to call JNI callback");
925 return BT_STATUS_NOT_READY;
926 }
927
928 JNIThreadAttacher attacher(vm);
929 JNIEnv* env = attacher.getEnv();
930
931 if (env == nullptr) {
932 log::error("Unable to get JNI Env");
933 return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
934 }
935
936 jint ret = BT_STATUS_SUCCESS;
937 {
938 ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
939 if (lock_name_jni.get()) {
940 bool acquired = env->CallBooleanMethod(
941 sJniCallbacksObj, method_acquireWakeLock, lock_name_jni.get());
942 if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR;
943 } else {
944 log::error("unable to allocate string: {}", lock_name);
945 ret = BT_STATUS_NOMEM;
946 }
947 }
948
949 return ret;
950 }
951
release_wake_lock_callout(const char * lock_name)952 static int release_wake_lock_callout(const char* lock_name) {
953 std::shared_lock<std::shared_timed_mutex> lock(jniObjMutex);
954 if (!sJniAdapterServiceObj) {
955 log::error("JNI obj is null. Failed to call JNI callback");
956 return BT_STATUS_NOT_READY;
957 }
958
959 JNIThreadAttacher attacher(vm);
960 JNIEnv* env = attacher.getEnv();
961
962 if (env == nullptr) {
963 log::error("Unable to get JNI Env");
964 return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
965 }
966
967 jint ret = BT_STATUS_SUCCESS;
968 {
969 ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
970 if (lock_name_jni.get()) {
971 bool released = env->CallBooleanMethod(
972 sJniCallbacksObj, method_releaseWakeLock, lock_name_jni.get());
973 if (!released) ret = BT_STATUS_WAKELOCK_ERROR;
974 } else {
975 log::error("unable to allocate string: {}", lock_name);
976 ret = BT_STATUS_NOMEM;
977 }
978 }
979
980 return ret;
981 }
982
983 static bt_os_callouts_t sBluetoothOsCallouts = {
984 sizeof(sBluetoothOsCallouts),
985 acquire_wake_lock_callout,
986 release_wake_lock_callout,
987 };
988
hal_util_load_bt_library(const bt_interface_t ** interface)989 int hal_util_load_bt_library(const bt_interface_t** interface) {
990 *interface = &bluetoothInterface;
991 return 0;
992 }
993
initNative(JNIEnv * env,jobject obj,jboolean isGuest,jboolean isCommonCriteriaMode,int configCompareResult,jobjectArray initFlags,jboolean isAtvDevice,jstring userDataDirectory)994 static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest,
995 jboolean isCommonCriteriaMode, int configCompareResult,
996 jobjectArray initFlags, jboolean isAtvDevice,
997 jstring userDataDirectory) {
998 std::unique_lock<std::shared_timed_mutex> lock(jniObjMutex);
999
1000 log::verbose("");
1001
1002 android_bluetooth_UidTraffic.clazz =
1003 (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic"));
1004
1005 sJniAdapterServiceObj = env->NewGlobalRef(obj);
1006 sJniCallbacksObj =
1007 env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
1008
1009 if (!sBluetoothInterface) {
1010 return JNI_FALSE;
1011 }
1012
1013 int flagCount = env->GetArrayLength(initFlags);
1014 jstring* flagObjs = new jstring[flagCount];
1015 const char** flags = nullptr;
1016 if (flagCount > 0) {
1017 flags = new const char*[flagCount + 1];
1018 flags[flagCount] = nullptr;
1019 }
1020
1021 for (int i = 0; i < flagCount; i++) {
1022 flagObjs[i] = (jstring)env->GetObjectArrayElement(initFlags, i);
1023 flags[i] = env->GetStringUTFChars(flagObjs[i], NULL);
1024 }
1025
1026 const char* user_data_directory =
1027 env->GetStringUTFChars(userDataDirectory, NULL);
1028
1029 int ret = sBluetoothInterface->init(
1030 &sBluetoothCallbacks, isGuest == JNI_TRUE ? 1 : 0,
1031 isCommonCriteriaMode == JNI_TRUE ? 1 : 0, configCompareResult, flags,
1032 isAtvDevice == JNI_TRUE ? 1 : 0, user_data_directory);
1033
1034 env->ReleaseStringUTFChars(userDataDirectory, user_data_directory);
1035
1036 for (int i = 0; i < flagCount; i++) {
1037 env->ReleaseStringUTFChars(flagObjs[i], flags[i]);
1038 }
1039
1040 delete[] flags;
1041 delete[] flagObjs;
1042
1043 if (ret != BT_STATUS_SUCCESS) {
1044 log::error("Error while setting the callbacks: {}", ret);
1045 sBluetoothInterface = NULL;
1046 return JNI_FALSE;
1047 }
1048 ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
1049 if (ret != BT_STATUS_SUCCESS) {
1050 log::error("Error while setting Bluetooth callouts: {}", ret);
1051 sBluetoothInterface->cleanup();
1052 sBluetoothInterface = NULL;
1053 return JNI_FALSE;
1054 }
1055
1056 sBluetoothSocketInterface =
1057 (btsock_interface_t*)sBluetoothInterface->get_profile_interface(
1058 BT_PROFILE_SOCKETS_ID);
1059 if (sBluetoothSocketInterface == NULL) {
1060 log::error("Error getting socket interface");
1061 }
1062
1063 return JNI_TRUE;
1064 }
1065
cleanupNative(JNIEnv * env,jobject)1066 static bool cleanupNative(JNIEnv* env, jobject /* obj */) {
1067 std::unique_lock<std::shared_timed_mutex> lock(jniObjMutex);
1068
1069 log::verbose("");
1070
1071 if (!sBluetoothInterface) return JNI_FALSE;
1072
1073 sBluetoothInterface->cleanup();
1074 log::info("return from cleanup");
1075
1076 if (sJniCallbacksObj) {
1077 env->DeleteGlobalRef(sJniCallbacksObj);
1078 sJniCallbacksObj = NULL;
1079 }
1080
1081 if (sJniAdapterServiceObj) {
1082 env->DeleteGlobalRef(sJniAdapterServiceObj);
1083 sJniAdapterServiceObj = NULL;
1084 }
1085
1086 if (android_bluetooth_UidTraffic.clazz) {
1087 env->DeleteGlobalRef(android_bluetooth_UidTraffic.clazz);
1088 android_bluetooth_UidTraffic.clazz = NULL;
1089 }
1090 return JNI_TRUE;
1091 }
1092
enableNative(JNIEnv *,jobject)1093 static jboolean enableNative(JNIEnv* /* env */, jobject /* obj */) {
1094 log::verbose("");
1095
1096 if (!sBluetoothInterface) return JNI_FALSE;
1097 int ret = sBluetoothInterface->enable();
1098 return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE
1099 : JNI_FALSE;
1100 }
1101
disableNative(JNIEnv *,jobject)1102 static jboolean disableNative(JNIEnv* /* env */, jobject /* obj */) {
1103 log::verbose("");
1104
1105 if (!sBluetoothInterface) return JNI_FALSE;
1106
1107 int ret = sBluetoothInterface->disable();
1108 /* Retrun JNI_FALSE only when BTIF explicitly reports
1109 BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY
1110 case which indicates that stack had not been enabled.
1111 */
1112 return (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE;
1113 }
1114
startDiscoveryNative(JNIEnv *,jobject)1115 static jboolean startDiscoveryNative(JNIEnv* /* env */, jobject /* obj */) {
1116 log::verbose("");
1117
1118 if (!sBluetoothInterface) return JNI_FALSE;
1119
1120 int ret = sBluetoothInterface->start_discovery();
1121 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1122 }
1123
cancelDiscoveryNative(JNIEnv *,jobject)1124 static jboolean cancelDiscoveryNative(JNIEnv* /* env */, jobject /* obj */) {
1125 log::verbose("");
1126
1127 if (!sBluetoothInterface) return JNI_FALSE;
1128
1129 int ret = sBluetoothInterface->cancel_discovery();
1130 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1131 }
1132
createBondNative(JNIEnv * env,jobject,jbyteArray address,jint addrType,jint transport)1133 static jboolean createBondNative(JNIEnv* env, jobject /* obj */,
1134 jbyteArray address, jint addrType,
1135 jint transport) {
1136 log::verbose("");
1137
1138 if (!sBluetoothInterface) return JNI_FALSE;
1139
1140 jbyte* addr = env->GetByteArrayElements(address, NULL);
1141 if (addr == NULL) {
1142 jniThrowIOException(env, EINVAL);
1143 return JNI_FALSE;
1144 }
1145
1146 uint8_t addr_type = (uint8_t)addrType;
1147 int ret = BT_STATUS_SUCCESS;
1148 if (addr_type == BLE_ADDR_RANDOM) {
1149 ret = sBluetoothInterface->create_bond_le((RawAddress*)addr, addr_type);
1150 } else {
1151 ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport);
1152 }
1153
1154 if (ret != BT_STATUS_SUCCESS) {
1155 log::warn("Failed to initiate bonding. Status = {}", ret);
1156 }
1157
1158 env->ReleaseByteArrayElements(address, addr, 0);
1159 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1160 }
1161
callByteArrayGetter(JNIEnv * env,jobject object,const char * className,const char * methodName)1162 static jbyteArray callByteArrayGetter(JNIEnv* env, jobject object,
1163 const char* className,
1164 const char* methodName) {
1165 jclass myClass = env->FindClass(className);
1166 jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B");
1167 env->DeleteLocalRef(myClass);
1168 return (jbyteArray)env->CallObjectMethod(object, myMethod);
1169 }
1170
callIntGetter(JNIEnv * env,jobject object,const char * className,const char * methodName)1171 static jint callIntGetter(JNIEnv* env, jobject object, const char* className,
1172 const char* methodName) {
1173 jclass myClass = env->FindClass(className);
1174 jmethodID myMethod = env->GetMethodID(myClass, methodName, "()I");
1175 env->DeleteLocalRef(myClass);
1176 return env->CallIntMethod(object, myMethod);
1177 }
1178
set_data(JNIEnv * env,bt_oob_data_t & oob_data,jobject oobData,jint transport)1179 static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData,
1180 jint transport) {
1181 // Need both arguments to be non NULL
1182 if (oobData == NULL) {
1183 log::error("oobData is null! Nothing to do.");
1184 return JNI_FALSE;
1185 }
1186
1187 memset(&oob_data, 0, sizeof(oob_data));
1188
1189 jbyteArray address = callByteArrayGetter(
1190 env, oobData, "android/bluetooth/OobData", "getDeviceAddressWithType");
1191
1192 // Check the data
1193 int len = env->GetArrayLength(address);
1194 if (len != OOB_ADDRESS_SIZE) {
1195 log::error(
1196 "addressBytes must be 7 bytes in length (address plus type) 6+1!");
1197 jniThrowIOException(env, EINVAL);
1198 return JNI_FALSE;
1199 }
1200
1201 // Convert the address from byte[]
1202 jbyte* addressBytes = env->GetByteArrayElements(address, NULL);
1203 if (addressBytes == NULL) {
1204 log::error("addressBytes cannot be null!");
1205 jniThrowIOException(env, EINVAL);
1206 return JNI_FALSE;
1207 }
1208 memcpy(oob_data.address, addressBytes, len);
1209
1210 // Get the device name byte[] java object
1211 jbyteArray deviceName = callByteArrayGetter(
1212 env, oobData, "android/bluetooth/OobData", "getDeviceName");
1213
1214 // Optional
1215 // Convert it to a jbyte* and copy it to the struct
1216 jbyte* deviceNameBytes = NULL;
1217 if (deviceName != NULL) {
1218 deviceNameBytes = env->GetByteArrayElements(deviceName, NULL);
1219 int len = env->GetArrayLength(deviceName);
1220 if (len > OOB_NAME_MAX_SIZE) {
1221 log::info(
1222 "wrong length of deviceName, should be empty or less than or equal "
1223 "to {} bytes.",
1224 OOB_NAME_MAX_SIZE);
1225 jniThrowIOException(env, EINVAL);
1226 env->ReleaseByteArrayElements(deviceName, deviceNameBytes, 0);
1227 return JNI_FALSE;
1228 }
1229 memcpy(oob_data.device_name, deviceNameBytes, len);
1230 env->ReleaseByteArrayElements(deviceName, deviceNameBytes, 0);
1231 }
1232 // Used by both classic and LE
1233 jbyteArray confirmation = callByteArrayGetter(
1234 env, oobData, "android/bluetooth/OobData", "getConfirmationHash");
1235 if (confirmation == NULL) {
1236 log::error("confirmation cannot be null!");
1237 jniThrowIOException(env, EINVAL);
1238 return JNI_FALSE;
1239 }
1240
1241 // Confirmation is mandatory
1242 jbyte* confirmationBytes = NULL;
1243 confirmationBytes = env->GetByteArrayElements(confirmation, NULL);
1244 len = env->GetArrayLength(confirmation);
1245 if (confirmationBytes == NULL || len != OOB_C_SIZE) {
1246 log::info("wrong length of Confirmation, should be empty or {} bytes.",
1247 OOB_C_SIZE);
1248 jniThrowIOException(env, EINVAL);
1249 env->ReleaseByteArrayElements(confirmation, confirmationBytes, 0);
1250 return JNI_FALSE;
1251 }
1252 memcpy(oob_data.c, confirmationBytes, len);
1253 env->ReleaseByteArrayElements(confirmation, confirmationBytes, 0);
1254
1255 // Random is supposedly optional according to the specification
1256 jbyteArray randomizer = callByteArrayGetter(
1257 env, oobData, "android/bluetooth/OobData", "getRandomizerHash");
1258 jbyte* randomizerBytes = NULL;
1259 if (randomizer != NULL) {
1260 randomizerBytes = env->GetByteArrayElements(randomizer, NULL);
1261 int len = env->GetArrayLength(randomizer);
1262 if (randomizerBytes == NULL || len != OOB_R_SIZE) {
1263 log::info("wrong length of Random, should be empty or {} bytes.",
1264 OOB_R_SIZE);
1265 jniThrowIOException(env, EINVAL);
1266 env->ReleaseByteArrayElements(randomizer, randomizerBytes, 0);
1267 return JNI_FALSE;
1268 }
1269 memcpy(oob_data.r, randomizerBytes, len);
1270 env->ReleaseByteArrayElements(randomizer, randomizerBytes, 0);
1271 }
1272
1273 // Transport specific data fetching/setting
1274 if (transport == TRANSPORT_BREDR) {
1275 // Classic
1276 // Not optional
1277 jbyteArray oobDataLength = callByteArrayGetter(
1278 env, oobData, "android/bluetooth/OobData", "getClassicLength");
1279 jbyte* oobDataLengthBytes = NULL;
1280 if (oobDataLength == NULL ||
1281 env->GetArrayLength(oobDataLength) != OOB_DATA_LEN_SIZE) {
1282 log::info("wrong length of oobDataLength, should be empty or {} bytes.",
1283 OOB_DATA_LEN_SIZE);
1284 jniThrowIOException(env, EINVAL);
1285 env->ReleaseByteArrayElements(oobDataLength, oobDataLengthBytes, 0);
1286 return JNI_FALSE;
1287 }
1288
1289 oobDataLengthBytes = env->GetByteArrayElements(oobDataLength, NULL);
1290 memcpy(oob_data.oob_data_length, oobDataLengthBytes, OOB_DATA_LEN_SIZE);
1291 env->ReleaseByteArrayElements(oobDataLength, oobDataLengthBytes, 0);
1292
1293 // Optional
1294 jbyteArray classOfDevice = callByteArrayGetter(
1295 env, oobData, "android/bluetooth/OobData", "getClassOfDevice");
1296 jbyte* classOfDeviceBytes = NULL;
1297 if (classOfDevice != NULL) {
1298 classOfDeviceBytes = env->GetByteArrayElements(classOfDevice, NULL);
1299 int len = env->GetArrayLength(classOfDevice);
1300 if (len != OOB_COD_SIZE) {
1301 log::info("wrong length of classOfDevice, should be empty or {} bytes.",
1302 OOB_COD_SIZE);
1303 jniThrowIOException(env, EINVAL);
1304 env->ReleaseByteArrayElements(classOfDevice, classOfDeviceBytes, 0);
1305 return JNI_FALSE;
1306 }
1307 memcpy(oob_data.class_of_device, classOfDeviceBytes, len);
1308 env->ReleaseByteArrayElements(classOfDevice, classOfDeviceBytes, 0);
1309 }
1310 } else if (transport == TRANSPORT_LE) {
1311 // LE
1312 jbyteArray temporaryKey = callByteArrayGetter(
1313 env, oobData, "android/bluetooth/OobData", "getLeTemporaryKey");
1314 jbyte* temporaryKeyBytes = NULL;
1315 if (temporaryKey != NULL) {
1316 temporaryKeyBytes = env->GetByteArrayElements(temporaryKey, NULL);
1317 int len = env->GetArrayLength(temporaryKey);
1318 if (len != OOB_TK_SIZE) {
1319 log::info("wrong length of temporaryKey, should be empty or {} bytes.",
1320 OOB_TK_SIZE);
1321 jniThrowIOException(env, EINVAL);
1322 env->ReleaseByteArrayElements(temporaryKey, temporaryKeyBytes, 0);
1323 return JNI_FALSE;
1324 }
1325 memcpy(oob_data.sm_tk, temporaryKeyBytes, len);
1326 env->ReleaseByteArrayElements(temporaryKey, temporaryKeyBytes, 0);
1327 }
1328
1329 jbyteArray leAppearance = callByteArrayGetter(
1330 env, oobData, "android/bluetooth/OobData", "getLeAppearance");
1331 jbyte* leAppearanceBytes = NULL;
1332 if (leAppearance != NULL) {
1333 leAppearanceBytes = env->GetByteArrayElements(leAppearance, NULL);
1334 int len = env->GetArrayLength(leAppearance);
1335 if (len != OOB_LE_APPEARANCE_SIZE) {
1336 log::info("wrong length of leAppearance, should be empty or {} bytes.",
1337 OOB_LE_APPEARANCE_SIZE);
1338 jniThrowIOException(env, EINVAL);
1339 env->ReleaseByteArrayElements(leAppearance, leAppearanceBytes, 0);
1340 return JNI_FALSE;
1341 }
1342 memcpy(oob_data.le_appearance, leAppearanceBytes, len);
1343 env->ReleaseByteArrayElements(leAppearance, leAppearanceBytes, 0);
1344 }
1345
1346 jint leRole = callIntGetter(env, oobData, "android/bluetooth/OobData",
1347 "getLeDeviceRole");
1348 oob_data.le_device_role = leRole;
1349
1350 jint leFlag =
1351 callIntGetter(env, oobData, "android/bluetooth/OobData", "getLeFlags");
1352 oob_data.le_flags = leFlag;
1353 }
1354 return JNI_TRUE;
1355 }
1356
generateLocalOobDataNative(JNIEnv *,jobject,jint transport)1357 static void generateLocalOobDataNative(JNIEnv* /* env */, jobject /* obj */,
1358 jint transport) {
1359 // No BT interface? Can't do anything.
1360 if (!sBluetoothInterface) return;
1361
1362 if (sBluetoothInterface->generate_local_oob_data(transport) !=
1363 BT_STATUS_SUCCESS) {
1364 log::error("Call to generate_local_oob_data failed!");
1365 bt_oob_data_t oob_data;
1366 oob_data.is_valid = false;
1367 generate_local_oob_data_callback(transport, oob_data);
1368 }
1369 }
1370
createBondOutOfBandNative(JNIEnv * env,jobject,jbyteArray address,jint transport,jobject p192Data,jobject p256Data)1371 static jboolean createBondOutOfBandNative(JNIEnv* env, jobject /* obj */,
1372 jbyteArray address, jint transport,
1373 jobject p192Data, jobject p256Data) {
1374 // No BT interface? Can't do anything.
1375 if (!sBluetoothInterface) return JNI_FALSE;
1376
1377 // No data? Can't do anything
1378 if (p192Data == NULL && p256Data == NULL) {
1379 log::error("All OOB Data are null! Nothing to do.");
1380 jniThrowIOException(env, EINVAL);
1381 return JNI_FALSE;
1382 }
1383
1384 // This address is already reversed which is why its being passed...
1385 // In the future we want to remove this and just reverse the address
1386 // for the oobdata in the host stack.
1387 if (address == NULL) {
1388 log::error("Address cannot be null! Nothing to do.");
1389 jniThrowIOException(env, EINVAL);
1390 return JNI_FALSE;
1391 }
1392
1393 // Check the data
1394 int len = env->GetArrayLength(address);
1395 if (len != 6) {
1396 log::error(
1397 "addressBytes must be 6 bytes in length (address plus type) 6+1!");
1398 jniThrowIOException(env, EINVAL);
1399 return JNI_FALSE;
1400 }
1401
1402 jbyte* addr = env->GetByteArrayElements(address, NULL);
1403 if (addr == NULL) {
1404 jniThrowIOException(env, EINVAL);
1405 return JNI_FALSE;
1406 }
1407
1408 // Convert P192 data from Java POJO to C Struct
1409 bt_oob_data_t p192_data;
1410 if (p192Data != NULL) {
1411 if (set_data(env, p192_data, p192Data, transport) == JNI_FALSE) {
1412 jniThrowIOException(env, EINVAL);
1413 return JNI_FALSE;
1414 }
1415 }
1416
1417 // Convert P256 data from Java POJO to C Struct
1418 bt_oob_data_t p256_data;
1419 if (p256Data != NULL) {
1420 if (set_data(env, p256_data, p256Data, transport) == JNI_FALSE) {
1421 jniThrowIOException(env, EINVAL);
1422 return JNI_FALSE;
1423 }
1424 }
1425
1426 return ((sBluetoothInterface->create_bond_out_of_band(
1427 (RawAddress*)addr, transport, &p192_data, &p256_data)) ==
1428 BT_STATUS_SUCCESS)
1429 ? JNI_TRUE
1430 : JNI_FALSE;
1431 }
1432
removeBondNative(JNIEnv * env,jobject,jbyteArray address)1433 static jboolean removeBondNative(JNIEnv* env, jobject /* obj */,
1434 jbyteArray address) {
1435 log::verbose("");
1436
1437 if (!sBluetoothInterface) return JNI_FALSE;
1438
1439 jbyte* addr = env->GetByteArrayElements(address, NULL);
1440 if (addr == NULL) {
1441 jniThrowIOException(env, EINVAL);
1442 return JNI_FALSE;
1443 }
1444
1445 int ret = sBluetoothInterface->remove_bond((RawAddress*)addr);
1446 env->ReleaseByteArrayElements(address, addr, 0);
1447
1448 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1449 }
1450
cancelBondNative(JNIEnv * env,jobject,jbyteArray address)1451 static jboolean cancelBondNative(JNIEnv* env, jobject /* obj */,
1452 jbyteArray address) {
1453 log::verbose("");
1454
1455 if (!sBluetoothInterface) return JNI_FALSE;
1456
1457 jbyte* addr = env->GetByteArrayElements(address, NULL);
1458 if (addr == NULL) {
1459 jniThrowIOException(env, EINVAL);
1460 return JNI_FALSE;
1461 }
1462
1463 int ret = sBluetoothInterface->cancel_bond((RawAddress*)addr);
1464 env->ReleaseByteArrayElements(address, addr, 0);
1465 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1466 }
1467
pairingIsBusyNative(JNIEnv *,jobject)1468 static jboolean pairingIsBusyNative(JNIEnv* /*env*/, jobject /* obj */) {
1469 log::verbose("");
1470
1471 if (!sBluetoothInterface) return JNI_FALSE;
1472
1473 return sBluetoothInterface->pairing_is_busy();
1474 }
1475
getConnectionStateNative(JNIEnv * env,jobject,jbyteArray address)1476 static int getConnectionStateNative(JNIEnv* env, jobject /* obj */,
1477 jbyteArray address) {
1478 log::verbose("");
1479 if (!sBluetoothInterface) return JNI_FALSE;
1480
1481 jbyte* addr = env->GetByteArrayElements(address, NULL);
1482 if (addr == NULL) {
1483 jniThrowIOException(env, EINVAL);
1484 return JNI_FALSE;
1485 }
1486
1487 int ret = sBluetoothInterface->get_connection_state((RawAddress*)addr);
1488 env->ReleaseByteArrayElements(address, addr, 0);
1489
1490 return ret;
1491 }
1492
pinReplyNative(JNIEnv * env,jobject,jbyteArray address,jboolean accept,jint len,jbyteArray pinArray)1493 static jboolean pinReplyNative(JNIEnv* env, jobject /* obj */,
1494 jbyteArray address, jboolean accept, jint len,
1495 jbyteArray pinArray) {
1496 log::verbose("");
1497
1498 if (!sBluetoothInterface) return JNI_FALSE;
1499
1500 jbyte* addr = env->GetByteArrayElements(address, NULL);
1501 if (addr == NULL) {
1502 jniThrowIOException(env, EINVAL);
1503 return JNI_FALSE;
1504 }
1505
1506 jbyte* pinPtr = NULL;
1507 if (accept) {
1508 pinPtr = env->GetByteArrayElements(pinArray, NULL);
1509 if (pinPtr == NULL) {
1510 jniThrowIOException(env, EINVAL);
1511 env->ReleaseByteArrayElements(address, addr, 0);
1512 return JNI_FALSE;
1513 }
1514 }
1515
1516 int ret = sBluetoothInterface->pin_reply((RawAddress*)addr, accept, len,
1517 (bt_pin_code_t*)pinPtr);
1518 env->ReleaseByteArrayElements(address, addr, 0);
1519 env->ReleaseByteArrayElements(pinArray, pinPtr, 0);
1520
1521 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1522 }
1523
sspReplyNative(JNIEnv * env,jobject,jbyteArray address,jint type,jboolean accept,jint passkey)1524 static jboolean sspReplyNative(JNIEnv* env, jobject /* obj */,
1525 jbyteArray address, jint type, jboolean accept,
1526 jint passkey) {
1527 log::verbose("");
1528
1529 if (!sBluetoothInterface) return JNI_FALSE;
1530
1531 jbyte* addr = env->GetByteArrayElements(address, NULL);
1532 if (addr == NULL) {
1533 jniThrowIOException(env, EINVAL);
1534 return JNI_FALSE;
1535 }
1536
1537 int ret = sBluetoothInterface->ssp_reply(
1538 (RawAddress*)addr, (bt_ssp_variant_t)type, accept, passkey);
1539 env->ReleaseByteArrayElements(address, addr, 0);
1540
1541 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1542 }
1543
setAdapterPropertyNative(JNIEnv * env,jobject,jint type,jbyteArray value)1544 static jboolean setAdapterPropertyNative(JNIEnv* env, jobject /* obj */,
1545 jint type, jbyteArray value) {
1546 log::verbose("");
1547
1548 if (!sBluetoothInterface) return JNI_FALSE;
1549
1550 jbyte* val = env->GetByteArrayElements(value, NULL);
1551 bt_property_t prop;
1552 prop.type = (bt_property_type_t)type;
1553 prop.len = env->GetArrayLength(value);
1554 prop.val = val;
1555
1556 int ret = sBluetoothInterface->set_adapter_property(&prop);
1557 env->ReleaseByteArrayElements(value, val, 0);
1558
1559 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1560 }
1561
getAdapterPropertiesNative(JNIEnv *,jobject)1562 static jboolean getAdapterPropertiesNative(JNIEnv* /* env */,
1563 jobject /* obj */) {
1564 log::verbose("");
1565
1566 if (!sBluetoothInterface) return JNI_FALSE;
1567
1568 int ret = sBluetoothInterface->get_adapter_properties();
1569 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1570 }
1571
getAdapterPropertyNative(JNIEnv *,jobject,jint type)1572 static jboolean getAdapterPropertyNative(JNIEnv* /* env */, jobject /* obj */,
1573 jint type) {
1574 log::verbose("");
1575
1576 if (!sBluetoothInterface) return JNI_FALSE;
1577
1578 int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t)type);
1579 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1580 }
1581
getDevicePropertyNative(JNIEnv * env,jobject,jbyteArray address,jint type)1582 static jboolean getDevicePropertyNative(JNIEnv* env, jobject /* obj */,
1583 jbyteArray address, jint type) {
1584 log::verbose("");
1585
1586 if (!sBluetoothInterface) return JNI_FALSE;
1587
1588 jbyte* addr = env->GetByteArrayElements(address, NULL);
1589 if (addr == NULL) {
1590 jniThrowIOException(env, EINVAL);
1591 return JNI_FALSE;
1592 }
1593
1594 int ret = sBluetoothInterface->get_remote_device_property(
1595 (RawAddress*)addr, (bt_property_type_t)type);
1596 env->ReleaseByteArrayElements(address, addr, 0);
1597 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1598 }
1599
setDevicePropertyNative(JNIEnv * env,jobject,jbyteArray address,jint type,jbyteArray value)1600 static jboolean setDevicePropertyNative(JNIEnv* env, jobject /* obj */,
1601 jbyteArray address, jint type,
1602 jbyteArray value) {
1603 log::verbose("");
1604
1605 if (!sBluetoothInterface) return JNI_FALSE;
1606
1607 jbyte* val = env->GetByteArrayElements(value, NULL);
1608 if (val == NULL) {
1609 jniThrowIOException(env, EINVAL);
1610 return JNI_FALSE;
1611 }
1612
1613 jbyte* addr = env->GetByteArrayElements(address, NULL);
1614 if (addr == NULL) {
1615 env->ReleaseByteArrayElements(value, val, 0);
1616 jniThrowIOException(env, EINVAL);
1617 return JNI_FALSE;
1618 }
1619
1620 bt_property_t prop;
1621 prop.type = (bt_property_type_t)type;
1622 prop.len = env->GetArrayLength(value);
1623 prop.val = val;
1624
1625 int ret =
1626 sBluetoothInterface->set_remote_device_property((RawAddress*)addr, &prop);
1627 env->ReleaseByteArrayElements(value, val, 0);
1628 env->ReleaseByteArrayElements(address, addr, 0);
1629
1630 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1631 }
1632
getRemoteServicesNative(JNIEnv * env,jobject,jbyteArray address,jint transport)1633 static jboolean getRemoteServicesNative(JNIEnv* env, jobject /* obj */,
1634 jbyteArray address, jint transport) {
1635 log::verbose("");
1636
1637 if (!sBluetoothInterface) return JNI_FALSE;
1638
1639 jbyte* addr = addr = env->GetByteArrayElements(address, NULL);
1640 if (addr == NULL) {
1641 jniThrowIOException(env, EINVAL);
1642 return JNI_FALSE;
1643 }
1644
1645 int ret =
1646 sBluetoothInterface->get_remote_services((RawAddress*)addr, transport);
1647 env->ReleaseByteArrayElements(address, addr, 0);
1648 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1649 }
1650
readEnergyInfoNative()1651 static int readEnergyInfoNative() {
1652 log::verbose("");
1653
1654 if (!sBluetoothInterface) return JNI_FALSE;
1655 int ret = sBluetoothInterface->read_energy_info();
1656 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1657 }
1658
dumpNative(JNIEnv * env,jobject,jobject fdObj,jobjectArray argArray)1659 static void dumpNative(JNIEnv* env, jobject /* obj */, jobject fdObj,
1660 jobjectArray argArray) {
1661 log::verbose("");
1662 if (!sBluetoothInterface) return;
1663
1664 int fd = jniGetFDFromFileDescriptor(env, fdObj);
1665 if (fd < 0) return;
1666
1667 int numArgs = env->GetArrayLength(argArray);
1668
1669 jstring* argObjs = new jstring[numArgs];
1670 const char** args = nullptr;
1671 if (numArgs > 0) {
1672 args = new const char*[numArgs + 1];
1673 args[numArgs] = nullptr;
1674 }
1675
1676 for (int i = 0; i < numArgs; i++) {
1677 argObjs[i] = (jstring)env->GetObjectArrayElement(argArray, i);
1678 args[i] = env->GetStringUTFChars(argObjs[i], NULL);
1679 }
1680
1681 sBluetoothInterface->dump(fd, args);
1682
1683 for (int i = 0; i < numArgs; i++) {
1684 env->ReleaseStringUTFChars(argObjs[i], args[i]);
1685 }
1686
1687 delete[] args;
1688 delete[] argObjs;
1689 }
1690
dumpMetricsNative(JNIEnv * env,jobject)1691 static jbyteArray dumpMetricsNative(JNIEnv* env, jobject /* obj */) {
1692 log::info("");
1693 if (!sBluetoothInterface) return env->NewByteArray(0);
1694
1695 std::string output;
1696 sBluetoothInterface->dumpMetrics(&output);
1697 jsize output_size = output.size() * sizeof(char);
1698 jbyteArray output_bytes = env->NewByteArray(output_size);
1699 env->SetByteArrayRegion(output_bytes, 0, output_size,
1700 (const jbyte*)output.data());
1701 return output_bytes;
1702 }
1703
factoryResetNative(JNIEnv *,jobject)1704 static jboolean factoryResetNative(JNIEnv* /* env */, jobject /* obj */) {
1705 log::verbose("");
1706 if (!sBluetoothInterface) return JNI_FALSE;
1707 int ret = sBluetoothInterface->config_clear();
1708 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1709 }
1710
obfuscateAddressNative(JNIEnv * env,jobject,jbyteArray address)1711 static jbyteArray obfuscateAddressNative(JNIEnv* env, jobject /* obj */,
1712 jbyteArray address) {
1713 log::verbose("");
1714 if (!sBluetoothInterface) return env->NewByteArray(0);
1715 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1716 if (addr == nullptr) {
1717 jniThrowIOException(env, EINVAL);
1718 return env->NewByteArray(0);
1719 }
1720 RawAddress addr_obj = {};
1721 addr_obj.FromOctets((uint8_t*)addr);
1722 std::string output = sBluetoothInterface->obfuscate_address(addr_obj);
1723 jsize output_size = output.size() * sizeof(char);
1724 jbyteArray output_bytes = env->NewByteArray(output_size);
1725 env->SetByteArrayRegion(output_bytes, 0, output_size,
1726 (const jbyte*)output.data());
1727 return output_bytes;
1728 }
1729
setBufferLengthMillisNative(JNIEnv *,jobject,jint codec,jint size)1730 static jboolean setBufferLengthMillisNative(JNIEnv* /* env */,
1731 jobject /* obj */, jint codec,
1732 jint size) {
1733 log::verbose("");
1734
1735 if (!sBluetoothInterface) return JNI_FALSE;
1736
1737 int ret = sBluetoothInterface->set_dynamic_audio_buffer_size(codec, size);
1738 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1739 }
1740
connectSocketNative(JNIEnv * env,jobject,jbyteArray address,jint type,jbyteArray uuid,jint port,jint flag,jint callingUid)1741 static jint connectSocketNative(JNIEnv* env, jobject /* obj */,
1742 jbyteArray address, jint type, jbyteArray uuid,
1743 jint port, jint flag, jint callingUid) {
1744 int socket_fd = INVALID_FD;
1745 jbyte* addr = nullptr;
1746 jbyte* uuidBytes = nullptr;
1747 Uuid btUuid;
1748
1749 if (!sBluetoothSocketInterface) {
1750 goto done;
1751 }
1752 addr = env->GetByteArrayElements(address, nullptr);
1753 uuidBytes = env->GetByteArrayElements(uuid, nullptr);
1754 if (addr == nullptr || uuidBytes == nullptr) {
1755 jniThrowIOException(env, EINVAL);
1756 goto done;
1757 }
1758
1759 btUuid = Uuid::From128BitBE((uint8_t*)uuidBytes);
1760 if (sBluetoothSocketInterface->connect((RawAddress*)addr, (btsock_type_t)type,
1761 &btUuid, port, &socket_fd, flag,
1762 callingUid) != BT_STATUS_SUCCESS) {
1763 socket_fd = INVALID_FD;
1764 }
1765
1766 done:
1767 if (addr) env->ReleaseByteArrayElements(address, addr, 0);
1768 if (uuidBytes) env->ReleaseByteArrayElements(uuid, uuidBytes, 0);
1769 return socket_fd;
1770 }
1771
createSocketChannelNative(JNIEnv * env,jobject,jint type,jstring serviceName,jbyteArray uuid,jint port,jint flag,jint callingUid)1772 static jint createSocketChannelNative(JNIEnv* env, jobject /* obj */, jint type,
1773 jstring serviceName, jbyteArray uuid,
1774 jint port, jint flag, jint callingUid) {
1775 int socket_fd = INVALID_FD;
1776 jbyte* uuidBytes = nullptr;
1777 Uuid btUuid;
1778 const char* nativeServiceName = nullptr;
1779
1780 if (!sBluetoothSocketInterface) {
1781 goto done;
1782 }
1783 uuidBytes = env->GetByteArrayElements(uuid, nullptr);
1784 if (serviceName != nullptr) {
1785 nativeServiceName = env->GetStringUTFChars(serviceName, nullptr);
1786 }
1787 if (uuidBytes == nullptr) {
1788 jniThrowIOException(env, EINVAL);
1789 goto done;
1790 }
1791 btUuid = Uuid::From128BitBE((uint8_t*)uuidBytes);
1792
1793 if (sBluetoothSocketInterface->listen((btsock_type_t)type, nativeServiceName,
1794 &btUuid, port, &socket_fd, flag,
1795 callingUid) != BT_STATUS_SUCCESS) {
1796 socket_fd = INVALID_FD;
1797 }
1798
1799 done:
1800 if (uuidBytes) env->ReleaseByteArrayElements(uuid, uuidBytes, 0);
1801 if (nativeServiceName)
1802 env->ReleaseStringUTFChars(serviceName, nativeServiceName);
1803 return socket_fd;
1804 }
1805
requestMaximumTxDataLengthNative(JNIEnv * env,jobject,jbyteArray address)1806 static void requestMaximumTxDataLengthNative(JNIEnv* env, jobject /* obj */,
1807 jbyteArray address) {
1808 if (!sBluetoothSocketInterface) {
1809 return;
1810 }
1811 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1812 if (addr == nullptr) {
1813 jniThrowIOException(env, EINVAL);
1814 return;
1815 }
1816
1817 RawAddress addressVar = *(RawAddress*)addr;
1818 sBluetoothSocketInterface->request_max_tx_data_length(addressVar);
1819 env->ReleaseByteArrayElements(address, addr, 1);
1820 }
1821
getMetricIdNative(JNIEnv * env,jobject,jbyteArray address)1822 static int getMetricIdNative(JNIEnv* env, jobject /* obj */,
1823 jbyteArray address) {
1824 log::verbose("");
1825 if (!sBluetoothInterface) return 0; // 0 is invalid id
1826 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1827 if (addr == nullptr) {
1828 jniThrowIOException(env, EINVAL);
1829 return 0;
1830 }
1831 RawAddress addr_obj = {};
1832 addr_obj.FromOctets((uint8_t*)addr);
1833 return sBluetoothInterface->get_metric_id(addr_obj);
1834 }
1835
allowLowLatencyAudioNative(JNIEnv * env,jobject,jboolean allowed,jbyteArray address)1836 static jboolean allowLowLatencyAudioNative(JNIEnv* env, jobject /* obj */,
1837 jboolean allowed,
1838 jbyteArray address) {
1839 log::verbose("");
1840 if (!sBluetoothInterface) return false;
1841 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1842 if (addr == nullptr) {
1843 jniThrowIOException(env, EINVAL);
1844 return false;
1845 }
1846
1847 RawAddress addr_obj = {};
1848 addr_obj.FromOctets((uint8_t*)addr);
1849 sBluetoothInterface->allow_low_latency_audio(allowed, addr_obj);
1850 return true;
1851 }
1852
metadataChangedNative(JNIEnv * env,jobject,jbyteArray address,jint key,jbyteArray value)1853 static void metadataChangedNative(JNIEnv* env, jobject /* obj */,
1854 jbyteArray address, jint key,
1855 jbyteArray value) {
1856 log::verbose("");
1857 if (!sBluetoothInterface) return;
1858 jbyte* addr = env->GetByteArrayElements(address, nullptr);
1859 if (addr == nullptr) {
1860 jniThrowIOException(env, EINVAL);
1861 return;
1862 }
1863 RawAddress addr_obj = {};
1864 addr_obj.FromOctets((uint8_t*)addr);
1865
1866 if (value == NULL) {
1867 log::error("metadataChangedNative() ignoring NULL array");
1868 return;
1869 }
1870
1871 uint16_t len = (uint16_t)env->GetArrayLength(value);
1872 jbyte* p_value = env->GetByteArrayElements(value, NULL);
1873 if (p_value == NULL) return;
1874
1875 std::vector<uint8_t> val_vec(reinterpret_cast<uint8_t*>(p_value),
1876 reinterpret_cast<uint8_t*>(p_value + len));
1877 env->ReleaseByteArrayElements(value, p_value, 0);
1878
1879 sBluetoothInterface->metadata_changed(addr_obj, key, std::move(val_vec));
1880 return;
1881 }
1882
isLogRedactionEnabledNative(JNIEnv *,jobject)1883 static jboolean isLogRedactionEnabledNative(JNIEnv* /* env */,
1884 jobject /* obj */) {
1885 log::verbose("");
1886 return bluetooth::os::should_log_be_redacted();
1887 }
1888
interopMatchAddrNative(JNIEnv * env,jclass,jstring feature_name,jstring address)1889 static jboolean interopMatchAddrNative(JNIEnv* env, jclass /* clazz */,
1890 jstring feature_name, jstring address) {
1891 log::verbose("");
1892
1893 if (!sBluetoothInterface) {
1894 log::warn("sBluetoothInterface is null.");
1895 return JNI_FALSE;
1896 }
1897
1898 const char* tmp_addr = env->GetStringUTFChars(address, NULL);
1899 if (!tmp_addr) {
1900 log::warn("address is null.");
1901 return JNI_FALSE;
1902 }
1903 RawAddress bdaddr;
1904 bool success = RawAddress::FromString(tmp_addr, bdaddr);
1905
1906 env->ReleaseStringUTFChars(address, tmp_addr);
1907
1908 if (!success) {
1909 log::warn("address is invalid.");
1910 return JNI_FALSE;
1911 }
1912
1913 const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
1914 if (!feature_name_str) {
1915 log::warn("feature name is null.");
1916 return JNI_FALSE;
1917 }
1918
1919 bool matched =
1920 sBluetoothInterface->interop_match_addr(feature_name_str, &bdaddr);
1921 env->ReleaseStringUTFChars(feature_name, feature_name_str);
1922
1923 return matched ? JNI_TRUE : JNI_FALSE;
1924 }
1925
interopMatchNameNative(JNIEnv * env,jclass,jstring feature_name,jstring name)1926 static jboolean interopMatchNameNative(JNIEnv* env, jclass /* clazz */,
1927 jstring feature_name, jstring name) {
1928 log::verbose("");
1929
1930 if (!sBluetoothInterface) {
1931 log::warn("sBluetoothInterface is null.");
1932 return JNI_FALSE;
1933 }
1934
1935 const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
1936 if (!feature_name_str) {
1937 log::warn("feature name is null.");
1938 return JNI_FALSE;
1939 }
1940
1941 const char* name_str = env->GetStringUTFChars(name, NULL);
1942 if (!name_str) {
1943 log::warn("name is null.");
1944 env->ReleaseStringUTFChars(feature_name, feature_name_str);
1945 return JNI_FALSE;
1946 }
1947
1948 bool matched =
1949 sBluetoothInterface->interop_match_name(feature_name_str, name_str);
1950 env->ReleaseStringUTFChars(feature_name, feature_name_str);
1951 env->ReleaseStringUTFChars(name, name_str);
1952
1953 return matched ? JNI_TRUE : JNI_FALSE;
1954 }
1955
interopMatchAddrOrNameNative(JNIEnv * env,jclass,jstring feature_name,jstring address)1956 static jboolean interopMatchAddrOrNameNative(JNIEnv* env, jclass /* clazz */,
1957 jstring feature_name,
1958 jstring address) {
1959 log::verbose("");
1960
1961 if (!sBluetoothInterface) {
1962 log::warn("sBluetoothInterface is null.");
1963 return JNI_FALSE;
1964 }
1965
1966 const char* tmp_addr = env->GetStringUTFChars(address, NULL);
1967 if (!tmp_addr) {
1968 log::warn("address is null.");
1969 return JNI_FALSE;
1970 }
1971 RawAddress bdaddr;
1972 bool success = RawAddress::FromString(tmp_addr, bdaddr);
1973
1974 env->ReleaseStringUTFChars(address, tmp_addr);
1975
1976 if (!success) {
1977 log::warn("address is invalid.");
1978 return JNI_FALSE;
1979 }
1980
1981 const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
1982 if (!feature_name_str) {
1983 log::warn("feature name is null.");
1984 return JNI_FALSE;
1985 }
1986
1987 bool matched = sBluetoothInterface->interop_match_addr_or_name(
1988 feature_name_str, &bdaddr);
1989 env->ReleaseStringUTFChars(feature_name, feature_name_str);
1990
1991 return matched ? JNI_TRUE : JNI_FALSE;
1992 }
1993
interopDatabaseAddRemoveAddrNative(JNIEnv * env,jclass,jboolean do_add,jstring feature_name,jstring address,jint length)1994 static void interopDatabaseAddRemoveAddrNative(JNIEnv* env, jclass /* clazz */,
1995 jboolean do_add,
1996 jstring feature_name,
1997 jstring address, jint length) {
1998 log::verbose("");
1999
2000 if (!sBluetoothInterface) {
2001 log::warn("sBluetoothInterface is null.");
2002 return;
2003 }
2004
2005 if ((do_add == JNI_TRUE) && (length <= 0 || length > 6)) {
2006 log::error("address length {} is invalid, valid length is [1,6]", length);
2007 return;
2008 }
2009
2010 const char* tmp_addr = env->GetStringUTFChars(address, NULL);
2011 if (!tmp_addr) {
2012 log::warn("address is null.");
2013 return;
2014 }
2015 RawAddress bdaddr;
2016 bool success = RawAddress::FromString(tmp_addr, bdaddr);
2017
2018 env->ReleaseStringUTFChars(address, tmp_addr);
2019
2020 if (!success) {
2021 log::warn("address is invalid.");
2022 return;
2023 }
2024
2025 const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
2026 if (!feature_name_str) {
2027 log::warn("feature name is null.");
2028 return;
2029 }
2030
2031 sBluetoothInterface->interop_database_add_remove_addr(
2032 (do_add == JNI_TRUE), feature_name_str, &bdaddr, (int)length);
2033
2034 env->ReleaseStringUTFChars(feature_name, feature_name_str);
2035 }
2036
interopDatabaseAddRemoveNameNative(JNIEnv * env,jclass,jboolean do_add,jstring feature_name,jstring name)2037 static void interopDatabaseAddRemoveNameNative(JNIEnv* env, jclass /* clazz */,
2038 jboolean do_add,
2039 jstring feature_name,
2040 jstring name) {
2041 log::verbose("");
2042
2043 if (!sBluetoothInterface) {
2044 log::warn("sBluetoothInterface is null.");
2045 return;
2046 }
2047
2048 const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL);
2049 if (!feature_name_str) {
2050 log::warn("feature name is null.");
2051 return;
2052 }
2053
2054 const char* name_str = env->GetStringUTFChars(name, NULL);
2055 if (!name_str) {
2056 log::warn("name is null.");
2057 env->ReleaseStringUTFChars(feature_name, feature_name_str);
2058 return;
2059 }
2060
2061 sBluetoothInterface->interop_database_add_remove_name(
2062 (do_add == JNI_TRUE), feature_name_str, name_str);
2063
2064 env->ReleaseStringUTFChars(feature_name, feature_name_str);
2065 env->ReleaseStringUTFChars(name, name_str);
2066 }
2067
getRemotePbapPceVersionNative(JNIEnv * env,jobject,jstring address)2068 static int getRemotePbapPceVersionNative(JNIEnv* env, jobject /* obj */,
2069 jstring address) {
2070 log::verbose("");
2071
2072 if (!sBluetoothInterface) return JNI_FALSE;
2073
2074 const char* tmp_addr = env->GetStringUTFChars(address, NULL);
2075 if (!tmp_addr) {
2076 log::warn("address is null.");
2077 return JNI_FALSE;
2078 }
2079
2080 RawAddress bdaddr;
2081 bool success = RawAddress::FromString(tmp_addr, bdaddr);
2082
2083 env->ReleaseStringUTFChars(address, tmp_addr);
2084
2085 if (!success) {
2086 log::warn("address is invalid.");
2087 return JNI_FALSE;
2088 }
2089
2090 return sBluetoothInterface->get_remote_pbap_pce_version(&bdaddr);
2091 }
2092
pbapPseDynamicVersionUpgradeIsEnabledNative(JNIEnv *,jobject)2093 static jboolean pbapPseDynamicVersionUpgradeIsEnabledNative(JNIEnv* /* env */,
2094 jobject /* obj */) {
2095 log::verbose("");
2096
2097 if (!sBluetoothInterface) return JNI_FALSE;
2098
2099 return sBluetoothInterface->pbap_pse_dynamic_version_upgrade_is_enabled()
2100 ? JNI_TRUE
2101 : JNI_FALSE;
2102 }
2103
getSocketL2capLocalChannelIdNative(JNIEnv *,jobject,jlong conn_uuid_lsb,jlong conn_uuid_msb)2104 static jint getSocketL2capLocalChannelIdNative(JNIEnv* /* env */,
2105 jobject /* obj */,
2106 jlong conn_uuid_lsb,
2107 jlong conn_uuid_msb) {
2108 log::verbose("");
2109
2110 if (!sBluetoothSocketInterface) {
2111 return INVALID_CID;
2112 }
2113 uint16_t cid;
2114 Uuid uuid = from_java_uuid(conn_uuid_msb, conn_uuid_lsb);
2115 if (sBluetoothSocketInterface->get_l2cap_local_cid(uuid, &cid) !=
2116 BT_STATUS_SUCCESS) {
2117 return INVALID_CID;
2118 }
2119 return (jint)cid;
2120 }
2121
getSocketL2capRemoteChannelIdNative(JNIEnv *,jobject,jlong conn_uuid_lsb,jlong conn_uuid_msb)2122 static jint getSocketL2capRemoteChannelIdNative(JNIEnv* /* env */,
2123 jobject /* obj */,
2124 jlong conn_uuid_lsb,
2125 jlong conn_uuid_msb) {
2126 log::verbose("");
2127
2128 if (!sBluetoothSocketInterface) {
2129 return INVALID_CID;
2130 }
2131 uint16_t cid;
2132 Uuid uuid = from_java_uuid(conn_uuid_msb, conn_uuid_lsb);
2133 if (sBluetoothSocketInterface->get_l2cap_remote_cid(uuid, &cid) !=
2134 BT_STATUS_SUCCESS) {
2135 return INVALID_CID;
2136 }
2137 return (jint)cid;
2138 }
2139
register_com_android_bluetooth_btservice_AdapterService(JNIEnv * env)2140 int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
2141 const JNINativeMethod methods[] = {
2142 {"initNative", "(ZZI[Ljava/lang/String;ZLjava/lang/String;)Z",
2143 (void*)initNative},
2144 {"cleanupNative", "()V", (void*)cleanupNative},
2145 {"enableNative", "()Z", (void*)enableNative},
2146 {"disableNative", "()Z", (void*)disableNative},
2147 {"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative},
2148 {"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative},
2149 {"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative},
2150 {"getDevicePropertyNative", "([BI)Z", (void*)getDevicePropertyNative},
2151 {"setDevicePropertyNative", "([BI[B)Z", (void*)setDevicePropertyNative},
2152 {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
2153 {"cancelDiscoveryNative", "()Z", (void*)cancelDiscoveryNative},
2154 {"createBondNative", "([BII)Z", (void*)createBondNative},
2155 {"createBondOutOfBandNative",
2156 "([BILandroid/bluetooth/OobData;Landroid/bluetooth/OobData;)Z",
2157 (void*)createBondOutOfBandNative},
2158 {"removeBondNative", "([B)Z", (void*)removeBondNative},
2159 {"cancelBondNative", "([B)Z", (void*)cancelBondNative},
2160 {"pairingIsBusyNative", "()Z", (void*)pairingIsBusyNative},
2161 {"generateLocalOobDataNative", "(I)V", (void*)generateLocalOobDataNative},
2162 {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative},
2163 {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative},
2164 {"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative},
2165 {"getRemoteServicesNative", "([BI)Z", (void*)getRemoteServicesNative},
2166 {"readEnergyInfoNative", "()I", (void*)readEnergyInfoNative},
2167 {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V",
2168 (void*)dumpNative},
2169 {"dumpMetricsNative", "()[B", (void*)dumpMetricsNative},
2170 {"factoryResetNative", "()Z", (void*)factoryResetNative},
2171 {"obfuscateAddressNative", "([B)[B", (void*)obfuscateAddressNative},
2172 {"setBufferLengthMillisNative", "(II)Z",
2173 (void*)setBufferLengthMillisNative},
2174 {"getMetricIdNative", "([B)I", (void*)getMetricIdNative},
2175 {"connectSocketNative", "([BI[BIII)I", (void*)connectSocketNative},
2176 {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I",
2177 (void*)createSocketChannelNative},
2178 {"requestMaximumTxDataLengthNative", "([B)V",
2179 (void*)requestMaximumTxDataLengthNative},
2180 {"allowLowLatencyAudioNative", "(Z[B)Z",
2181 (void*)allowLowLatencyAudioNative},
2182 {"metadataChangedNative", "([BI[B)V", (void*)metadataChangedNative},
2183 {"isLogRedactionEnabledNative", "()Z",
2184 (void*)isLogRedactionEnabledNative},
2185 {"interopMatchAddrNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
2186 (void*)interopMatchAddrNative},
2187 {"interopMatchNameNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
2188 (void*)interopMatchNameNative},
2189 {"interopMatchAddrOrNameNative",
2190 "(Ljava/lang/String;Ljava/lang/String;)Z",
2191 (void*)interopMatchAddrOrNameNative},
2192 {"interopDatabaseAddRemoveAddrNative",
2193 "(ZLjava/lang/String;Ljava/lang/String;I)V",
2194 (void*)interopDatabaseAddRemoveAddrNative},
2195 {"interopDatabaseAddRemoveNameNative",
2196 "(ZLjava/lang/String;Ljava/lang/String;)V",
2197 (void*)interopDatabaseAddRemoveNameNative},
2198 {"getRemotePbapPceVersionNative", "(Ljava/lang/String;)I",
2199 (void*)getRemotePbapPceVersionNative},
2200 {"pbapPseDynamicVersionUpgradeIsEnabledNative", "()Z",
2201 (void*)pbapPseDynamicVersionUpgradeIsEnabledNative},
2202 {"getSocketL2capLocalChannelIdNative", "(JJ)I",
2203 (void*)getSocketL2capLocalChannelIdNative},
2204 {"getSocketL2capRemoteChannelIdNative", "(JJ)I",
2205 (void*)getSocketL2capRemoteChannelIdNative},
2206 };
2207 const int result = REGISTER_NATIVE_METHODS(
2208 env, "com/android/bluetooth/btservice/AdapterNativeInterface", methods);
2209 if (result != 0) {
2210 return result;
2211 }
2212
2213 jclass jniAdapterNativeInterfaceClass =
2214 env->FindClass("com/android/bluetooth/btservice/AdapterNativeInterface");
2215 sJniCallbacksField =
2216 env->GetFieldID(jniAdapterNativeInterfaceClass, "mJniCallbacks",
2217 "Lcom/android/bluetooth/btservice/JniCallbacks;");
2218 env->DeleteLocalRef(jniAdapterNativeInterfaceClass);
2219
2220 const JNIJavaMethod javaMethods[] = {
2221 {"oobDataReceivedCallback", "(ILandroid/bluetooth/OobData;)V",
2222 &method_oobDataReceivedCallback},
2223 {"stateChangeCallback", "(I)V", &method_stateChangeCallback},
2224 {"adapterPropertyChangedCallback", "([I[[B)V",
2225 &method_adapterPropertyChangedCallback},
2226 {"discoveryStateChangeCallback", "(I)V",
2227 &method_discoveryStateChangeCallback},
2228 {"devicePropertyChangedCallback", "([B[I[[B)V",
2229 &method_devicePropertyChangedCallback},
2230 {"deviceFoundCallback", "([B)V", &method_deviceFoundCallback},
2231 {"pinRequestCallback", "([B[BIZ)V", &method_pinRequestCallback},
2232 {"sspRequestCallback", "([BII)V", &method_sspRequestCallback},
2233 {"bondStateChangeCallback", "(I[BII)V", &method_bondStateChangeCallback},
2234 {"addressConsolidateCallback", "([B[B)V",
2235 &method_addressConsolidateCallback},
2236 {"leAddressAssociateCallback", "([B[B)V",
2237 &method_leAddressAssociateCallback},
2238 {"aclStateChangeCallback", "(I[BIIII)V", &method_aclStateChangeCallback},
2239 {"linkQualityReportCallback", "(JIIIIII)V",
2240 &method_linkQualityReportCallback},
2241 {"switchBufferSizeCallback", "(Z)V", &method_switchBufferSizeCallback},
2242 {"switchCodecCallback", "(Z)V", &method_switchCodecCallback},
2243 {"acquireWakeLock", "(Ljava/lang/String;)Z", &method_acquireWakeLock},
2244 {"releaseWakeLock", "(Ljava/lang/String;)Z", &method_releaseWakeLock},
2245 {"energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V",
2246 &method_energyInfo},
2247 {"keyMissingCallback", "([B)V", &method_keyMissingCallback},
2248 };
2249 GET_JAVA_METHODS(env, "com/android/bluetooth/btservice/JniCallbacks",
2250 javaMethods);
2251
2252 const JNIJavaMethod javaUuidTrafficMethods[] = {
2253 {"<init>", "(IJJ)V", &android_bluetooth_UidTraffic.constructor},
2254 };
2255 GET_JAVA_METHODS(env, "android/bluetooth/UidTraffic", javaUuidTrafficMethods);
2256
2257 if (env->GetJavaVM(&vm) != JNI_OK) {
2258 log::error("Could not get JavaVM");
2259 }
2260
2261 if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) {
2262 log::error("No Bluetooth Library found");
2263 }
2264
2265 return 0;
2266 }
2267
2268 } /* namespace android */
2269
2270 /*
2271 * JNI Initialization
2272 */
JNI_OnLoad(JavaVM * jvm,void *)2273 jint JNI_OnLoad(JavaVM* jvm, void* /* reserved */) {
2274 /* Set the default logging level for the process using the tag
2275 * "log.tag.bluetooth" and/or "persist.log.tag.bluetooth" via the android
2276 * logging framework.
2277 */
2278 const char* stack_default_log_tag = "bluetooth";
2279 int default_prio = ANDROID_LOG_INFO;
2280 if (__android_log_is_loggable(ANDROID_LOG_VERBOSE, stack_default_log_tag,
2281 default_prio)) {
2282 __android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
2283 log::info("Set stack default log level to 'VERBOSE'");
2284 } else if (__android_log_is_loggable(ANDROID_LOG_DEBUG, stack_default_log_tag,
2285 default_prio)) {
2286 __android_log_set_minimum_priority(ANDROID_LOG_DEBUG);
2287 log::info("Set stack default log level to 'DEBUG'");
2288 } else if (__android_log_is_loggable(ANDROID_LOG_INFO, stack_default_log_tag,
2289 default_prio)) {
2290 __android_log_set_minimum_priority(ANDROID_LOG_INFO);
2291 log::info("Set stack default log level to 'INFO'");
2292 } else if (__android_log_is_loggable(ANDROID_LOG_WARN, stack_default_log_tag,
2293 default_prio)) {
2294 __android_log_set_minimum_priority(ANDROID_LOG_WARN);
2295 log::info("Set stack default log level to 'WARN'");
2296 } else if (__android_log_is_loggable(ANDROID_LOG_ERROR, stack_default_log_tag,
2297 default_prio)) {
2298 __android_log_set_minimum_priority(ANDROID_LOG_ERROR);
2299 log::info("Set stack default log level to 'ERROR'");
2300 }
2301
2302 JNIEnv* e;
2303 int status;
2304
2305 log::verbose("Bluetooth Adapter Service : loading JNI\n");
2306
2307 // Check JNI version
2308 if (jvm->GetEnv((void**)&e, JNI_VERSION_1_6)) {
2309 log::error("JNI version mismatch error");
2310 return JNI_ERR;
2311 }
2312
2313 status = android::register_com_android_bluetooth_btservice_AdapterService(e);
2314 if (status < 0) {
2315 log::error("jni adapter service registration failure, status: {}", status);
2316 return JNI_ERR;
2317 }
2318
2319 status =
2320 android::register_com_android_bluetooth_btservice_BluetoothKeystore(e);
2321 if (status < 0) {
2322 log::error("jni BluetoothKeyStore registration failure: {}", status);
2323 return JNI_ERR;
2324 }
2325
2326 status = android::register_com_android_bluetooth_hfp(e);
2327 if (status < 0) {
2328 log::error("jni hfp registration failure, status: {}", status);
2329 return JNI_ERR;
2330 }
2331
2332 status = android::register_com_android_bluetooth_hfpclient(e);
2333 if (status < 0) {
2334 log::error("jni hfp client registration failure, status: {}", status);
2335 return JNI_ERR;
2336 }
2337
2338 status = android::register_com_android_bluetooth_a2dp(e);
2339 if (status < 0) {
2340 log::error("jni a2dp source registration failure: {}", status);
2341 return JNI_ERR;
2342 }
2343
2344 status = android::register_com_android_bluetooth_a2dp_sink(e);
2345 if (status < 0) {
2346 log::error("jni a2dp sink registration failure: {}", status);
2347 return JNI_ERR;
2348 }
2349
2350 status = android::register_com_android_bluetooth_avrcp_target(e);
2351 if (status < 0) {
2352 log::error("jni new avrcp target registration failure: {}", status);
2353 }
2354
2355 status = android::register_com_android_bluetooth_avrcp_controller(e);
2356 if (status < 0) {
2357 log::error("jni avrcp controller registration failure: {}", status);
2358 return JNI_ERR;
2359 }
2360
2361 status = android::register_com_android_bluetooth_hid_host(e);
2362 if (status < 0) {
2363 log::error("jni hid registration failure: {}", status);
2364 return JNI_ERR;
2365 }
2366
2367 status = android::register_com_android_bluetooth_hid_device(e);
2368 if (status < 0) {
2369 log::error("jni hidd registration failure: {}", status);
2370 return JNI_ERR;
2371 }
2372
2373 status = android::register_com_android_bluetooth_pan(e);
2374 if (status < 0) {
2375 log::error("jni pan registration failure: {}", status);
2376 return JNI_ERR;
2377 }
2378
2379 status = android::register_com_android_bluetooth_gatt(e);
2380 if (status < 0) {
2381 log::error("jni gatt registration failure: {}", status);
2382 return JNI_ERR;
2383 }
2384
2385 status = android::register_com_android_bluetooth_sdp(e);
2386 if (status < 0) {
2387 log::error("jni sdp registration failure: {}", status);
2388 return JNI_ERR;
2389 }
2390
2391 status = android::register_com_android_bluetooth_hearing_aid(e);
2392 if (status < 0) {
2393 log::error("jni hearing aid registration failure: {}", status);
2394 return JNI_ERR;
2395 }
2396
2397 status = android::register_com_android_bluetooth_hap_client(e);
2398 if (status < 0) {
2399 log::error("jni le audio hearing access client registration failure: {}",
2400 status);
2401 return JNI_ERR;
2402 }
2403
2404 status = android::register_com_android_bluetooth_le_audio(e);
2405 if (status < 0) {
2406 log::error("jni le_audio registration failure: {}", status);
2407 return JNI_ERR;
2408 }
2409
2410 status = android::register_com_android_bluetooth_vc(e);
2411 if (status < 0) {
2412 log::error("jni vc registration failure: {}", status);
2413 return JNI_ERR;
2414 }
2415
2416 status = android::register_com_android_bluetooth_csip_set_coordinator(e);
2417 if (status < 0) {
2418 log::error("jni csis client registration failure: {}", status);
2419 return JNI_ERR;
2420 }
2421
2422 status =
2423 android::register_com_android_bluetooth_btservice_BluetoothQualityReport(
2424 e);
2425 if (status < 0) {
2426 log::error("jni bluetooth quality report registration failure: {}", status);
2427 return JNI_ERR;
2428 }
2429
2430 return JNI_VERSION_1_6;
2431 }
2432
2433 namespace android {
2434
2435 /** Load the java methods or die*/
jniGetMethodsOrDie(JNIEnv * env,const char * className,const JNIJavaMethod * methods,int nMethods)2436 void jniGetMethodsOrDie(JNIEnv* env, const char* className,
2437 const JNIJavaMethod* methods, int nMethods) {
2438 jclass clazz = env->FindClass(className);
2439 if (clazz == nullptr) {
2440 log::fatal("Native registration unable to find class '{}' aborting...",
2441 className);
2442 }
2443
2444 for (int i = 0; i < nMethods; i++) {
2445 const JNIJavaMethod& method = methods[i];
2446 if (method.is_static) {
2447 *method.id = env->GetStaticMethodID(clazz, method.name, method.signature);
2448 } else {
2449 *method.id = env->GetMethodID(clazz, method.name, method.signature);
2450 }
2451 if (method.id == nullptr) {
2452 log::fatal(
2453 "In class {}: Unable to find '{}' with signature={} is_static={}",
2454 className, method.name, method.signature, method.is_static);
2455 }
2456 }
2457
2458 env->DeleteLocalRef(clazz);
2459 }
2460 } // namespace android
2461