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