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