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