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