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