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