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