com_android_bluetooth_btservice_AdapterService.cpp revision 7e7f0be7a03ac9fac07ad9ef47522a237ba36a62
1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project
3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License");
5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License.
6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at
7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *      http://www.apache.org/licenses/LICENSE-2.0
9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software
11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS,
12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and
14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License.
15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#define LOG_TAG "BluetoothServiceJni"
18dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include "android_runtime/AndroidRuntime.h"
19dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include "android_runtime/Log.h"
206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "com_android_bluetooth.h"
21dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include "cutils/properties.h"
22cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie#include "hardware/bt_sock.h"
23479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen#include "nativehelper/ScopedLocalFrame.h"
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/Log.h"
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/misc.h"
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <pthread.h>
28dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include <string.h>
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <fcntl.h>
317e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker#include <sys/prctl.h>
32dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include <sys/stat.h>
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshnamespace android {
3533d233cc3a1be101258f7ab3a11fe186300ddf47Jakub Pawlowski// OOB_LE_BD_ADDR_SIZE is 6 bytes addres + 1 byte address type
3633d233cc3a1be101258f7ab3a11fe186300ddf47Jakub Pawlowski#define OOB_LE_BD_ADDR_SIZE 7
37914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski#define OOB_TK_SIZE 16
381d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski#define OOB_LE_SC_C_SIZE 16
391d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski#define OOB_LE_SC_R_SIZE 16
40914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_stateChangeCallback;
42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_adapterPropertyChangedCallback;
43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_devicePropertyChangedCallback;
44ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_deviceFoundCallback;
45ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_pinRequestCallback;
46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_sspRequestCallback;
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_bondStateChangeCallback;
4801a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamystatic jmethodID method_aclStateChangeCallback;
49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_discoveryStateChangeCallback;
501e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_setWakeAlarm;
511e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_acquireWakeLock;
521e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_releaseWakeLock;
53f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadhamstatic jmethodID method_energyInfo;
54ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
55cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinskistatic struct {
56dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass clazz;
57dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jmethodID constructor;
58cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski} android_bluetooth_UidTraffic;
59cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski
60dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic const bt_interface_t* sBluetoothInterface = NULL;
61dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic const btsock_interface_t* sBluetoothSocketInterface = NULL;
62dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic JNIEnv* callbackEnv = NULL;
63ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
641e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jobject sJniAdapterServiceObj;
65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jobject sJniCallbacksObj;
66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jfieldID sJniCallbacksField;
67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
68dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenconst bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; }
696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
70dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie JanssenJNIEnv* getCallbackEnv() { return callbackEnv; }
716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_state_change_callback(bt_state_t status) {
73dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
74dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
75dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: Status is: %d", __func__, status);
76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
77dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback,
78dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jint)status);
79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
80ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
81dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int get_properties(int num_properties, bt_property_t* properties,
82dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                          jintArray* types, jobjectArray* props) {
83dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < num_properties; i++) {
84479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jbyteArray> propVal(
85479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        callbackEnv, callbackEnv->NewByteArray(properties[i].len));
86479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    if (!propVal.get()) {
87479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ALOGE("Error while allocation of array in %s", __func__);
88479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      return -1;
89479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    }
90dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
91479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    callbackEnv->SetByteArrayRegion(propVal.get(), 0, properties[i].len,
92dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    (jbyte*)properties[i].val);
93479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    callbackEnv->SetObjectArrayElement(*props, i, propVal.get());
94dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    callbackEnv->SetIntArrayRegion(*types, i, 1, (jint*)&properties[i].type);
95dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
96dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return 0;
97ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
98ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
99ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_properties_callback(bt_status_t status, int num_properties,
100dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        bt_property_t* properties) {
101dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
102dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
103dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
104dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties);
105dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
106dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
107dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Status %d is incorrect", __func__, status);
108dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
109dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
110dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
111479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> val(
112479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
113479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
114479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!val.get()) {
115dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating byteArray", __func__);
116dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
117dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
118dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
119479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
120479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                sCallbackEnv->GetObjectClass(val.get()));
121dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
122dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* (BT) Initialize the jobjectArray and jintArray here itself and send the
123dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   initialized array pointers alone to get_properties */
124dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
125479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> props(
126479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
127479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
128479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!props.get()) {
129dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating object Array for properties", __func__);
130dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
131dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
132dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
133479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jintArray> types(
134479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
135479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!types.get()) {
136dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating int Array for values", __func__);
137dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
138dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
139dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
140479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  jintArray typesPtr = types.get();
141479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  jobjectArray propsPtr = props.get();
142479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
143dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
144dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
145dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
146479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
147479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               method_adapterPropertyChangedCallback,
148479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               types.get(), props.get());
149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
151dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void remote_device_properties_callback(bt_status_t status,
152dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                              bt_bdaddr_t* bd_addr,
153dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                              int num_properties,
154dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                              bt_property_t* properties) {
155dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
156dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
157dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
158dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties);
159dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
160dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
161dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Status %d is incorrect", __func__, status);
162dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
163dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
164dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
165479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalFrame local_frame(sCallbackEnv.get());
166dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
167479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> val(
168479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
169479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
170479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!val.get()) {
171dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating byteArray", __func__);
172dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
173dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
174dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
175479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
176479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                sCallbackEnv->GetObjectClass(val.get()));
177dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
178dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* Initialize the jobjectArray and jintArray here itself and send the
179dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   initialized array pointers alone to get_properties */
180dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
181479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> props(
182479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
183479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
184479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!props.get()) {
185dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating object Array for properties", __func__);
186dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
187dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
188dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
189479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jintArray> types(
190479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
191479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!types.get()) {
192dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating int Array for values", __func__);
193dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
194dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
195dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1962116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
1972116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
1982116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1992116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Error while allocation byte array in %s", __func__);
2002116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2012116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
2022116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach
2032116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
2042116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
205dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
206479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  jintArray typesPtr = types.get();
207479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  jobjectArray propsPtr = props.get();
208479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
209dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
210dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
211dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
212dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
213479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               method_devicePropertyChangedCallback, addr.get(),
214479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               types.get(), props.get());
215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
217dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void device_found_callback(int num_properties,
218dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                  bt_property_t* properties) {
219dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
220dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
221dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2222116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), NULL);
223dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int addr_index;
224dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < num_properties; i++) {
225dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (properties[i].type == BT_PROPERTY_BDADDR) {
2262116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      addr.reset(sCallbackEnv->NewByteArray(properties[i].len));
2272116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      if (!addr.get()) {
2282116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach        ALOGE("Address is NULL (unable to allocate) in %s", __func__);
2292116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach        return;
2302116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      }
2312116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv->SetByteArrayRegion(addr.get(), 0, properties[i].len,
2322116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                       (jbyte*)properties[i].val);
233479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      addr_index = i;
234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
235dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
2362116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2372116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Address is NULL in %s", __func__);
2382116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2392116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
241dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: Properties: %d, Address: %s", __func__, num_properties,
242dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        (const char*)properties[addr_index].val);
243ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
244dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  remote_device_properties_callback(BT_STATUS_SUCCESS,
245dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    (bt_bdaddr_t*)properties[addr_index].val,
246dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    num_properties, properties);
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
248dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback,
249479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get());
250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
252dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void bond_state_changed_callback(bt_status_t status,
253dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        bt_bdaddr_t* bd_addr,
254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_bond_state_t state) {
255dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
256dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
257dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
258dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!bd_addr) {
259dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Address is null in %s", __func__);
260dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
261dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
262dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2632116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
2642116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
2652116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2662116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Address allocation failed in %s", __func__);
2672116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2682116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
2692116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
2702116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
271dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
272dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback,
273479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               (jint)status, addr.get(), (jint)state);
274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
275ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
276dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void acl_state_changed_callback(bt_status_t status, bt_bdaddr_t* bd_addr,
277dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                       bt_acl_state_t state) {
278dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!bd_addr) {
279dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Address is null in %s", __func__);
280dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
281dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
282dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
283dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
284dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
285dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2862116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
2872116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
2882116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2892116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Address allocation failed in %s", __func__);
2902116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2912116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
2922116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
2932116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
294dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
295dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback,
296479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               (jint)status, addr.get(), (jint)state);
29701a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy}
29801a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy
299ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void discovery_state_changed_callback(bt_discovery_state_t state) {
300dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
301dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
302ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
303dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: DiscoveryState:%d ", __func__, state);
304ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
305dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(
306dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state);
307ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
308ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
309dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void pin_request_callback(bt_bdaddr_t* bd_addr, bt_bdname_t* bdname,
310dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                 uint32_t cod, bool min_16_digits) {
311dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!bd_addr) {
312dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Address is null in %s", __func__);
313dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
314dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
315ae15d3d42fcb3349c11d394423493020e78c5f43Marie Janssen
316dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
317dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
318ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
3192116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
3202116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
3212116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
3222116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Error while allocating in: %s", __func__);
3232116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
3242116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
3252116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach
3262116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
3272116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
328ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
329479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> devname(
330479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)));
331479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!devname.get()) {
332dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error while allocating in: %s", __func__);
333dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
334dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
335ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
336479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t),
337dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   (jbyte*)bdname);
338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
339dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback,
340479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), devname.get(), cod, min_16_digits);
341dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen}
342ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
343dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void ssp_request_callback(bt_bdaddr_t* bd_addr, bt_bdname_t* bdname,
344dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                 uint32_t cod, bt_ssp_variant_t pairing_variant,
345dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                 uint32_t pass_key) {
346dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!bd_addr) {
347dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Address is null in %s", __func__);
348dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
349dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
350dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
351dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
352dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
3532116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
3542116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
3552116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
3562116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Error while allocating in: %s", __func__);
3572116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
3582116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
3592116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach
3602116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
3612116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
362dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
363479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> devname(
364479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)));
365479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!devname.get()) {
366dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error while allocating in: %s", __func__);
367dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
368dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
369ae15d3d42fcb3349c11d394423493020e78c5f43Marie Janssen
370479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t),
371dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   (jbyte*)bdname);
372ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
373dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback,
374479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), devname.get(), cod,
375479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               (jint)pairing_variant, pass_key);
376ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
377ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
378ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void callback_thread_event(bt_cb_thread_evt event) {
379dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  JavaVM* vm = AndroidRuntime::getJavaVM();
380dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (event == ASSOCIATE_JVM) {
381dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    JavaVMAttachArgs args;
382dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    char name[] = "BT Service Callback Thread";
383dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    args.version = JNI_VERSION_1_6;
384dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    args.name = name;
385dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    args.group = NULL;
386dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    vm->AttachCurrentThread(&callbackEnv, &args);
387dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGV("Callback thread attached: %p", callbackEnv);
388dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else if (event == DISASSOCIATE_JVM) {
389dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (callbackEnv != AndroidRuntime::getJNIEnv()) {
390dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("Callback: '%s' is not called on the correct thread", __func__);
391dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return;
392ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
393dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    vm->DetachCurrentThread();
394dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
395ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
396ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
397dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) {
39803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
39903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta}
40003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
401dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void le_test_mode_recv_callback(bt_status_t status,
402dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                       uint16_t packet_count) {
403dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: status:%d packet_count:%d ", __func__, status, packet_count);
40403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta}
405f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham
406dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void energy_info_recv_callback(bt_activity_energy_info* p_energy_info,
407fe37710d689b7573ddeb901141db42c28b6cab39Marie Janssen                                      bt_uid_traffic_t* uid_data) {
408dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
409dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
410dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
411dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jsize len = 0;
412dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
413dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    len++;
414dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
415dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
416479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> array(
417479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewObjectArray(
418479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                              len, android_bluetooth_UidTraffic.clazz, NULL));
419dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jsize i = 0;
420dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
421479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jobject> uidObj(
422479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv.get(),
423479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->NewObject(android_bluetooth_UidTraffic.clazz,
424479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                android_bluetooth_UidTraffic.constructor,
425479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                (jint)data->app_uid, (jlong)data->rx_bytes,
426479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                (jlong)data->tx_bytes));
427479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetObjectArrayElement(array.get(), i++, uidObj.get());
428dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
429dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
430dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(
431dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sJniAdapterServiceObj, method_energyInfo, p_energy_info->status,
432dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time,
433479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      p_energy_info->idle_time, p_energy_info->energy_used, array.get());
434f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham}
435f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham
4361e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic bt_callbacks_t sBluetoothCallbacks = {
437dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sizeof(sBluetoothCallbacks), adapter_state_change_callback,
438dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    adapter_properties_callback, remote_device_properties_callback,
439dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    device_found_callback,       discovery_state_changed_callback,
440dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    pin_request_callback,        ssp_request_callback,
441dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    bond_state_changed_callback, acl_state_changed_callback,
442dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    callback_thread_event,       dut_mode_recv_callback,
443dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    le_test_mode_recv_callback,  energy_info_recv_callback};
444ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
4451e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// The callback to call when the wake alarm fires.
4461e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic alarm_cb sAlarmCallback;
4471e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4481e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// The data to pass to the wake alarm callback.
449dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void* sAlarmCallbackData;
4501e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4517e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panickerclass JNIThreadAttacher {
4527e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker public:
4537e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIThreadAttacher() : vm_(nullptr), env_(nullptr) {
4547e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    vm_ = AndroidRuntime::getJavaVM();
4557e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6);
4567e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
4577e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    if (status_ != JNI_OK && status_ != JNI_EDETACHED) {
4587e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      ALOGE(
4597e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker          "JNIThreadAttacher: unable to get environment for JNI CALL, "
4607e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker          "status: %d",
4617e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker          status_);
4627e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      env_ = nullptr;
4637e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      return;
4647e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    }
465beccdc6d1647c56c91ddfd14f7990371168fb870Sharvil Nanavati
4667e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    if (status_ == JNI_EDETACHED) {
4677e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      char name[17] = {0};
4687e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      if (prctl(PR_GET_NAME, (unsigned long)name) != 0) {
4697e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        ALOGE(
4707e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker            "JNIThreadAttacher: unable to grab previous thread name, error: %s",
4717e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker            strerror(errno));
4727e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        env_ = nullptr;
4737e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        return;
4747e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      }
475dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
4767e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      JavaVMAttachArgs args = {
4777e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker          .version = JNI_VERSION_1_6, .name = name, .group = nullptr};
4787e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      if (vm_->AttachCurrentThread(&env_, &args) != 0) {
4797e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        ALOGE("JNIThreadAttacher: unable to attach thread to VM");
4807e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        env_ = nullptr;
4817e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        return;
4827e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      }
4837e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    }
4847e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  }
4857e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
4867e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  ~JNIThreadAttacher() {
4877e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    if (status_ == JNI_EDETACHED) vm_->DetachCurrentThread();
488dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
489dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
4907e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* getEnv() { return env_; }
4917e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
4927e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker private:
4937e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JavaVM* vm_;
4947e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* env_;
4957e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  jint status_;
4967e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker};
4977e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
4987e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panickerstatic bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake,
4997e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker                                   alarm_cb cb, void* data) {
5007e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIThreadAttacher attacher;
5017e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* env = attacher.getEnv();
5027e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
5037e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  if (env == nullptr) {
5047e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    ALOGE("%s: Unable to get JNI Env", __func__);
505dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return false;
506dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
507dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
508dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sAlarmCallback = cb;
509dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sAlarmCallbackData = data;
510dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
511dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE;
512dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jboolean ret =
513dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm,
514dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                             (jlong)delay_millis, jshould_wake);
515dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!ret) {
516dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sAlarmCallback = NULL;
517dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sAlarmCallbackData = NULL;
518dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
519dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
5207e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  return (ret == JNI_TRUE);
5211e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5221e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
523dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int acquire_wake_lock_callout(const char* lock_name) {
5247e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIThreadAttacher attacher;
5257e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* env = attacher.getEnv();
5267e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
5277e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  if (env == nullptr) {
5287e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    ALOGE("%s: Unable to get JNI Env", __func__);
529dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
530dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
531dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
532dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jint ret = BT_STATUS_SUCCESS;
533479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  {
534479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
535479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    if (lock_name_jni.get()) {
536479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      bool acquired = env->CallBooleanMethod(
537479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          sJniAdapterServiceObj, method_acquireWakeLock, lock_name_jni.get());
538479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR;
539479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    } else {
540479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ALOGE("%s unable to allocate string: %s", __func__, lock_name);
541479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ret = BT_STATUS_NOMEM;
542479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    }
543dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
544dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
545dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return ret;
5461e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5471e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
548dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int release_wake_lock_callout(const char* lock_name) {
5497e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIThreadAttacher attacher;
5507e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* env = attacher.getEnv();
5517e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
5527e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  if (env == nullptr) {
5537e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    ALOGE("%s: Unable to get JNI Env", __func__);
554dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
555dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
556dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
557dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jint ret = BT_STATUS_SUCCESS;
558479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  {
559479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
560479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    if (lock_name_jni.get()) {
561479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      bool released = env->CallBooleanMethod(
562479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          sJniAdapterServiceObj, method_releaseWakeLock, lock_name_jni.get());
563479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      if (!released) ret = BT_STATUS_WAKELOCK_ERROR;
564479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    } else {
565479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ALOGE("%s unable to allocate string: %s", __func__, lock_name);
566479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ret = BT_STATUS_NOMEM;
567479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    }
568dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
569dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
570dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return ret;
5711e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5721e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5731e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// Called by Java code when alarm is fired. A wake lock is held by the caller
5741e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// over the duration of this callback.
575dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void alarmFiredNative(JNIEnv* env, jobject obj) {
576dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sAlarmCallback) {
577dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sAlarmCallback(sAlarmCallbackData);
578dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else {
579dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s() - Alarm fired with callback not set!", __func__);
580dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
5811e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5821e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5831e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic bt_os_callouts_t sBluetoothOsCallouts = {
584dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sizeof(sBluetoothOsCallouts), set_wake_alarm_callout,
585dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    acquire_wake_lock_callout, release_wake_lock_callout,
5861e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati};
5871e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
588ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void classInitNative(JNIEnv* env, jclass clazz) {
589dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic");
590dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  android_bluetooth_UidTraffic.constructor =
591dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniUidTrafficClass, "<init>", "(IJJ)V");
592dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
593dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass jniCallbackClass =
594dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
595dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sJniCallbacksField = env->GetFieldID(
596dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;");
597dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
598dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_stateChangeCallback =
599dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
600dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
601dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_adapterPropertyChangedCallback = env->GetMethodID(
602dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniCallbackClass, "adapterPropertyChangedCallback", "([I[[B)V");
603dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_discoveryStateChangeCallback = env->GetMethodID(
604dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniCallbackClass, "discoveryStateChangeCallback", "(I)V");
605dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
606dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_devicePropertyChangedCallback = env->GetMethodID(
607dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniCallbackClass, "devicePropertyChangedCallback", "([B[I[[B)V");
608dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_deviceFoundCallback =
609dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
610dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_pinRequestCallback =
611dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V");
612dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_sspRequestCallback =
613dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V");
614dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
615dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_bondStateChangeCallback =
616dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V");
617dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
618dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_aclStateChangeCallback =
619dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BI)V");
620dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
621dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
622dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_acquireWakeLock =
623dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
624dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_releaseWakeLock =
625dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");
626dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_energyInfo = env->GetMethodID(
627dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V");
628dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
629dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  char value[PROPERTY_VALUE_MAX];
630dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  property_get("bluetooth.mock_stack", value, "");
631dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
632dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const char* id =
633dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (strcmp(value, "1") ? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
634dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
635dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  hw_module_t* module;
636dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int err = hw_get_module(id, (hw_module_t const**)&module);
637dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
638dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (err == 0) {
639dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    hw_device_t* abstraction;
640dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    err = module->methods->open(module, id, &abstraction);
641ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (err == 0) {
642dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      bluetooth_module_t* btStack = (bluetooth_module_t*)abstraction;
643dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sBluetoothInterface = btStack->get_bluetooth_interface();
644ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else {
645dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("Error while opening Bluetooth library");
646ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
647dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else {
648dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("No Bluetooth Library found");
649dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
650ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
651ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
652ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool initNative(JNIEnv* env, jobject obj) {
653dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
654dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
655dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  android_bluetooth_UidTraffic.clazz =
656dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic"));
657dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
658dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sJniAdapterServiceObj = env->NewGlobalRef(obj);
659dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sJniCallbacksObj =
660dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
661dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
662dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) {
663dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
664dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
665dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
666dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
667dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (ret != BT_STATUS_SUCCESS) {
668dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error while setting the callbacks: %d\n", ret);
669dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothInterface = NULL;
670dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
671dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
672dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
673dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (ret != BT_STATUS_SUCCESS) {
674dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error while setting Bluetooth callouts: %d\n", ret);
675dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothInterface->cleanup();
676dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothInterface = NULL;
677dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
678dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
679dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
680dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothSocketInterface =
681dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (btsock_interface_t*)sBluetoothInterface->get_profile_interface(
682dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          BT_PROFILE_SOCKETS_ID);
683dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sBluetoothSocketInterface == NULL) {
684dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error getting socket interface");
685dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
686dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
687dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return JNI_TRUE;
688ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
689ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
690dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic bool cleanupNative(JNIEnv* env, jobject obj) {
691dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
692ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
693dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
694ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
695dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothInterface->cleanup();
696dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: return from cleanup", __func__);
6976654f5c903de510a70f9e72cd5ad7837b615d93ffredc
698dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->DeleteGlobalRef(sJniCallbacksObj);
699dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->DeleteGlobalRef(sJniAdapterServiceObj);
700dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->DeleteGlobalRef(android_bluetooth_UidTraffic.clazz);
701dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  android_bluetooth_UidTraffic.clazz = NULL;
702dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return JNI_TRUE;
703ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
704ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
705c63ef51ba5f9d355239959bcfe8803987adb1f38Ajay Panickerstatic jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {
706dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
707ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
708dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
709dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0);
710dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE
711dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                             : JNI_FALSE;
712ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
713ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
714ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean disableNative(JNIEnv* env, jobject obj) {
715dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
716ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
717dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
718ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
719dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->disable();
720dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* Retrun JNI_FALSE only when BTIF explicitly reports
721dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY
722dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     case which indicates that stack had not been enabled.
723dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  */
724dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE;
725ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
726ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
727ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
728dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
729ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
730dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
731ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
732dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->start_discovery();
733dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
734ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
735ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
736ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) {
737dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
738ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
739dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
740ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
741dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->cancel_discovery();
742dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
743ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
744ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
745dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address,
746dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                 jint transport) {
747dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
748ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
749dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
750ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
751dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
752dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
753dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
754dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
755dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
756ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
757dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->create_bond((bt_bdaddr_t*)addr, transport);
758dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
759dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
760ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
761ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
76221f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panickerstatic jbyteArray callByteArrayGetter(JNIEnv* env, jobject object,
76321f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panicker                                      const char* className,
76421f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panicker                                      const char* methodName) {
765dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass myClass = env->FindClass(className);
766dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B");
767dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (jbyteArray)env->CallObjectMethod(object, myMethod);
768914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski}
769914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
770dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj,
771dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                          jbyteArray address, jint transport,
772dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                          jobject oobData) {
773dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_out_of_band_data_t oob_data;
774dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
775dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  memset(&oob_data, 0, sizeof(oob_data));
776dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
777dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
778dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
779dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
780dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
781dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
782dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
783dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
784dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
785dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* leBtDeviceAddressBytes = NULL;
786dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* smTKBytes = NULL;
787dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* leScCBytes = NULL;
788dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* leScRBytes = NULL;
789dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyteArray leBtDeviceAddress = NULL;
790dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyteArray smTK = NULL;
791dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyteArray leScC = NULL;
792dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyteArray leScR = NULL;
793dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int status = BT_STATUS_FAIL;
794dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
795dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  leBtDeviceAddress = callByteArrayGetter(
796dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env, oobData, "android/bluetooth/OobData", "getLeBluetoothDeviceAddress");
797dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leBtDeviceAddress != NULL) {
798dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    leBtDeviceAddressBytes = env->GetByteArrayElements(leBtDeviceAddress, NULL);
799dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    int len = env->GetArrayLength(leBtDeviceAddress);
800dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (len != OOB_LE_BD_ADDR_SIZE) {
801dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGI(
802dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          "%s: wrong length of leBtDeviceAddress, should be empty or %d bytes.",
803dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          __func__, OOB_LE_BD_ADDR_SIZE);
804dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
805dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      goto done;
806dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
807dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    memcpy(oob_data.le_bt_dev_addr, leBtDeviceAddressBytes, len);
808dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
809dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
810dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  smTK = callByteArrayGetter(env, oobData, "android/bluetooth/OobData",
811dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                             "getSecurityManagerTk");
812dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (smTK != NULL) {
813dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    smTKBytes = env->GetByteArrayElements(smTK, NULL);
814dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    int len = env->GetArrayLength(smTK);
815dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (len != OOB_TK_SIZE) {
816dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGI("%s: wrong length of smTK, should be empty or %d bytes.", __func__,
817dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen            OOB_TK_SIZE);
818dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
819dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      goto done;
820dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
821dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    memcpy(oob_data.sm_tk, smTKBytes, len);
822dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
823dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
824dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  leScC = callByteArrayGetter(env, oobData, "android/bluetooth/OobData",
825dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                              "getLeSecureConnectionsConfirmation");
826dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leScC != NULL) {
827dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    leScCBytes = env->GetByteArrayElements(leScC, NULL);
828dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    int len = env->GetArrayLength(leScC);
829dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (len != OOB_LE_SC_C_SIZE) {
830dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGI(
831dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          "%s: wrong length of LE SC Confirmation, should be empty or %d "
832dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          "bytes.",
833dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          __func__, OOB_LE_SC_C_SIZE);
834dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
835dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      goto done;
836dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
837dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    memcpy(oob_data.le_sc_c, leScCBytes, len);
838dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
839dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
840dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  leScR = callByteArrayGetter(env, oobData, "android/bluetooth/OobData",
841dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                              "getLeSecureConnectionsRandom");
842dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leScR != NULL) {
843dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    leScRBytes = env->GetByteArrayElements(leScR, NULL);
844dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    int len = env->GetArrayLength(leScR);
845dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (len != OOB_LE_SC_R_SIZE) {
846dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGI("%s: wrong length of LE SC Random, should be empty or %d bytes.",
847dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen            __func__, OOB_LE_SC_R_SIZE);
848dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
849dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      goto done;
850dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
851dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    memcpy(oob_data.le_sc_r, leScRBytes, len);
852dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
853dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
854dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = sBluetoothInterface->create_bond_out_of_band((bt_bdaddr_t*)addr,
855dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                        transport, &oob_data);
856914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
857914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowskidone:
858dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
859914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
860dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leBtDeviceAddress != NULL)
861dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->ReleaseByteArrayElements(leBtDeviceAddress, leBtDeviceAddressBytes, 0);
86233d233cc3a1be101258f7ab3a11fe186300ddf47Jakub Pawlowski
863dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (smTK != NULL) env->ReleaseByteArrayElements(smTK, smTKBytes, 0);
864914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
865dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leScC != NULL) env->ReleaseByteArrayElements(leScC, leScCBytes, 0);
8661d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski
867dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leScR != NULL) env->ReleaseByteArrayElements(leScR, leScRBytes, 0);
8681d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski
869dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
870914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski}
871914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
872ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
873dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
874ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
875dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
876ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
877dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
878dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
879dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
880dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
881dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
882ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
883dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t*)addr);
884dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
885ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
886dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
887ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
888ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
889ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
890dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
891ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
892dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
893ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
894dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
895dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
896dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
897dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
898dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
899ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
900dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t*)addr);
901dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
902dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
903ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
904ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
905dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int getConnectionStateNative(JNIEnv* env, jobject obj,
906dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    jbyteArray address) {
907dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
908dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
9093636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach
910dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
911dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
912dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
913dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
914dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
9153636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach
916dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->get_connection_state((bt_bdaddr_t*)addr);
917dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9183636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach
919dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return ret;
9203636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach}
9213636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach
922dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean pinReplyNative(JNIEnv* env, jobject obj, jbyteArray address,
923dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               jboolean accept, jint len, jbyteArray pinArray) {
924dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
925ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
926dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
927ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
928dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
929dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
930dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
931dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
932dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
933ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
934dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* pinPtr = NULL;
935dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (accept) {
936dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    pinPtr = env->GetByteArrayElements(pinArray, NULL);
937dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (pinPtr == NULL) {
938dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
939dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->ReleaseByteArrayElements(address, addr, 0);
940dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return JNI_FALSE;
941ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
942dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
943ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
944dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len,
945dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                           (bt_pin_code_t*)pinPtr);
946dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
947dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(pinArray, pinPtr, 0);
948ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
949dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
950ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
951ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
952dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean sspReplyNative(JNIEnv* env, jobject obj, jbyteArray address,
953581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh                               jint type, jboolean accept, jint passkey) {
954dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
955ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
956dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
957ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
958dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
959dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
960dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
961dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
962dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
963ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
964dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->ssp_reply(
965dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (bt_ssp_variant_t)type, accept, passkey);
966dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
967ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
968dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
969ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
970ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
971dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean setAdapterPropertyNative(JNIEnv* env, jobject obj, jint type,
972dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         jbyteArray value) {
973dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
974ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
975dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
976ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
977dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* val = env->GetByteArrayElements(value, NULL);
978dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_property_t prop;
979dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.type = (bt_property_type_t)type;
980dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.len = env->GetArrayLength(value);
981dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.val = val;
982ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
983dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->set_adapter_property(&prop);
984dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(value, val, 0);
985ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
986dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
987ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
988ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
989dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getAdapterPropertiesNative(JNIEnv* env, jobject obj) {
990dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
991ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
992dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
993ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
994dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->get_adapter_properties();
995dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
996ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
997ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
998dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getAdapterPropertyNative(JNIEnv* env, jobject obj, jint type) {
999dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1000ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1001dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1002ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1003dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t)type);
1004dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1005ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1006ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1007dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getDevicePropertyNative(JNIEnv* env, jobject obj,
1008dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray address, jint type) {
1009dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1010ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1011dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1012ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1013dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1014dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
1015dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1016dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
1017dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1018ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1019dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->get_remote_device_property(
1020dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (bt_property_type_t)type);
1021dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1022dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1023ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1024ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1025dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean setDevicePropertyNative(JNIEnv* env, jobject obj,
1026dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray address, jint type,
1027dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray value) {
1028dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1029ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1030dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1031ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1032dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* val = env->GetByteArrayElements(value, NULL);
1033dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (val == NULL) {
1034dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1035dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
1036dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1037ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1038dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1039dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
1040dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->ReleaseByteArrayElements(value, val, 0);
1041dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1042dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
1043dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1044ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1045dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_property_t prop;
1046dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.type = (bt_property_type_t)type;
1047dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.len = env->GetArrayLength(value);
1048dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.val = val;
1049ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1050dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t*)addr,
1051dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                            &prop);
1052dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(value, val, 0);
1053dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1054ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1055dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1056ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1057ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1058dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getRemoteServicesNative(JNIEnv* env, jobject obj,
1059dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray address) {
1060dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1061c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1062dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1063c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1064dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = addr = env->GetByteArrayElements(address, NULL);
1065dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
1066dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1067dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
1068dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1069c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1070dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t*)addr);
1071dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1072dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1073c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc}
1074c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1075dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int connectSocketNative(JNIEnv* env, jobject object, jbyteArray address,
1076dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               jint type, jbyteArray uuidObj, jint channel,
1077dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               jint flag, jint callingUid) {
1078dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothSocketInterface) return -1;
1079cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1080dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1081dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
1082dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("failed to get Bluetooth device address");
1083dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return -1;
1084dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1085dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1086dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* uuid = NULL;
1087dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (uuidObj != NULL) {
1088dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    uuid = env->GetByteArrayElements(uuidObj, NULL);
1089dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (!uuid) {
1090dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("failed to get uuid");
1091dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->ReleaseByteArrayElements(address, addr, 0);
1092dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return -1;
1093dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
1094dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1095dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1096dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int socket_fd = -1;
1097dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothSocketInterface->connect(
1098dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (btsock_type_t)type, (const uint8_t*)uuid, channel,
1099dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      &socket_fd, flag, callingUid);
1100dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
1101dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Socket connection failed: %d", status);
1102dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    socket_fd = -1;
1103dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else if (socket_fd < 0) {
1104dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Fail to create file descriptor on socket fd");
1105dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1106dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1107dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1108dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(uuidObj, uuid, 0);
1109dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return socket_fd;
1110cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
1111cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1112dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int createSocketChannelNative(JNIEnv* env, jobject object, jint type,
1113244e9c62a85a4b94e21bf1a8dee456e22bc767c4Casper Bonde                                     jstring name_str, jbyteArray uuidObj,
1114cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski                                     jint channel, jint flag, jint callingUid) {
1115dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothSocketInterface) return -1;
1116dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1117dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: SOCK FLAG = %x", __func__, flag);
1118dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1119dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const char* service_name = NULL;
1120dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (name_str != NULL) {
1121dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    service_name = env->GetStringUTFChars(name_str, NULL);
1122dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1123dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1124dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* uuid = NULL;
1125dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (uuidObj != NULL) {
1126dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    uuid = env->GetByteArrayElements(uuidObj, NULL);
1127dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (!uuid) {
1128dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("failed to get uuid");
1129dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
1130dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return -1;
1131dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
1132dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1133dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1134dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int socket_fd = -1;
1135dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothSocketInterface->listen(
1136dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (btsock_type_t)type, service_name, (const uint8_t*)uuid, channel,
1137dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      &socket_fd, flag, callingUid);
1138dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
1139dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Socket listen failed: %d", status);
1140dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    socket_fd = -1;
1141dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else if (socket_fd < 0) {
1142dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Fail to creat file descriptor on socket fd");
1143dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1144dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1145dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
1146dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
1147dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return socket_fd;
1148cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
1149cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1150dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean configHciSnoopLogNative(JNIEnv* env, jobject obj,
1151dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jboolean enable) {
1152dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
11539d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
1154dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
11559d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
1156dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->config_hci_snoop_log(enable);
11579d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
1158dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
11599d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu}
11609d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
1161dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int readEnergyInfo() {
1162dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1163ae15d3d42fcb3349c11d394423493020e78c5f43Marie Janssen
1164dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1165dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->read_energy_info();
1166dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1167f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham}
1168f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham
1169dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void dumpNative(JNIEnv* env, jobject obj, jobject fdObj,
1170dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       jobjectArray argArray) {
1171dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1172dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return;
1173f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach
1174dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int fd = jniGetFDFromFileDescriptor(env, fdObj);
1175dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (fd < 0) return;
1176f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach
1177dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int numArgs = env->GetArrayLength(argArray);
1178407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1179dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jstring* argObjs = new jstring[numArgs];
1180dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const char** args = nullptr;
1181dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (numArgs > 0) args = new const char*[numArgs];
1182407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1183dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < numArgs; i++) {
1184dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    argObjs[i] = (jstring)env->GetObjectArrayElement(argArray, i);
1185dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    args[i] = env->GetStringUTFChars(argObjs[i], NULL);
1186dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1187407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1188dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothInterface->dump(fd, args);
1189407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1190dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < numArgs; i++) {
1191dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->ReleaseStringUTFChars(argObjs[i], args[i]);
1192dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1193407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1194dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  delete[] args;
1195dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  delete[] argObjs;
1196f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach}
1197f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach
1198dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean factoryResetNative(JNIEnv* env, jobject obj) {
1199dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1200dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1201dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->config_clear();
1202dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
12036eb32d5f7c30f04da45c3da0974bbb63725a0978Ajay Panicker}
12046eb32d5f7c30f04da45c3da0974bbb63725a0978Ajay Panicker
1205dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void interopDatabaseClearNative(JNIEnv* env, jobject obj) {
1206dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1207dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return;
1208dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothInterface->interop_database_clear();
1209db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach}
1210db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach
1211dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void interopDatabaseAddNative(JNIEnv* env, jobject obj, int feature,
1212dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     jbyteArray address, int length) {
1213dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1214dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return;
1215db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach
1216dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1217dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
1218dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1219dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
1220dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1221db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach
1222dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothInterface->interop_database_add(feature, (bt_bdaddr_t*)addr,
1223dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                            length);
1224dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1225db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach}
1226db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach
1227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNINativeMethod sMethods[] = {
1228b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    /* name, signature, funcPtr */
1229dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"classInitNative", "()V", (void*)classInitNative},
1230dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"initNative", "()Z", (void*)initNative},
1231dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"cleanupNative", "()V", (void*)cleanupNative},
1232dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"enableNative", "(Z)Z", (void*)enableNative},
1233dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"disableNative", "()Z", (void*)disableNative},
1234dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative},
1235dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative},
1236dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative},
1237dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getDevicePropertyNative", "([BI)Z", (void*)getDevicePropertyNative},
1238dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"setDevicePropertyNative", "([BI[B)Z", (void*)setDevicePropertyNative},
1239dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
1240dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"cancelDiscoveryNative", "()Z", (void*)cancelDiscoveryNative},
1241dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"createBondNative", "([BI)Z", (void*)createBondNative},
1242dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z",
1243dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)createBondOutOfBandNative},
1244dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"removeBondNative", "([B)Z", (void*)removeBondNative},
1245dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"cancelBondNative", "([B)Z", (void*)cancelBondNative},
1246dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative},
1247dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative},
1248dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative},
1249dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getRemoteServicesNative", "([B)Z", (void*)getRemoteServicesNative},
1250dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"connectSocketNative", "([BI[BIII)I", (void*)connectSocketNative},
1251cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski    {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I",
1252dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)createSocketChannelNative},
1253dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"configHciSnoopLogNative", "(Z)Z", (void*)configHciSnoopLogNative},
1254dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"alarmFiredNative", "()V", (void*)alarmFiredNative},
1255dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"readEnergyInfo", "()I", (void*)readEnergyInfo},
1256dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V",
1257dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)dumpNative},
1258db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach    {"factoryResetNative", "()Z", (void*)factoryResetNative},
1259dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"interopDatabaseClearNative", "()V", (void*)interopDatabaseClearNative},
1260dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"interopDatabaseAddNative", "(I[BI)V", (void*)interopDatabaseAddNative}};
1261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1262dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenint register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
1263dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return jniRegisterNativeMethods(
1264dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env, "com/android/bluetooth/btservice/AdapterService", sMethods,
1265dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      NELEM(sMethods));
1266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} /* namespace android */
1269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
1271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * JNI Initialization
1272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
1273dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenjint JNI_OnLoad(JavaVM* jvm, void* reserved) {
1274dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  JNIEnv* e;
1275dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int status;
1276dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1277dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("Bluetooth Adapter Service : loading JNI\n");
1278dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1279dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  // Check JNI version
1280dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (jvm->GetEnv((void**)&e, JNI_VERSION_1_6)) {
1281dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("JNI version mismatch error");
1282dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1283dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1284dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1285dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_btservice_AdapterService(e);
1286dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1287dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni adapter service registration failure, status: %d", status);
1288dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1289dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1290dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1291dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_hfp(e);
1292dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1293dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni hfp registration failure, status: %d", status);
1294dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1295dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1296dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1297dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_hfpclient(e);
1298dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1299dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni hfp client registration failure, status: %d", status);
1300dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1301dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1302dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1303dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_a2dp(e);
1304dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1305dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni a2dp source registration failure: %d", status);
1306dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1307dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1308dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1309dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_a2dp_sink(e);
1310dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1311dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni a2dp sink registration failure: %d", status);
1312dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1313dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1314dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1315dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_avrcp(e);
1316dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1317dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni avrcp target registration failure: %d", status);
1318dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1319dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1320dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1321dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_avrcp_controller(e);
1322dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1323dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni avrcp controller registration failure: %d", status);
1324dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1325dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1326dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1327dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_hid(e);
1328dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1329dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni hid registration failure: %d", status);
1330dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1331dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1332dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1333cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta  status = android::register_com_android_bluetooth_hidd(e);
1334cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta  if (status < 0) {
1335cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta    ALOGE("jni hidd registration failure: %d", status);
1336cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta    return JNI_ERR;
1337cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta  }
1338cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta
1339dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_hdp(e);
1340dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1341dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni hdp registration failure: %d", status);
1342dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1343dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1344dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1345dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_pan(e);
1346dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1347dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni pan registration failure: %d", status);
1348dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1349dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1350dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1351dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_gatt(e);
1352dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1353dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni gatt registration failure: %d", status);
1354dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1355dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1356dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1357dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_sdp(e);
1358dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1359dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni sdp registration failure: %d", status);
1360dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1361dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1362dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1363dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return JNI_VERSION_1_6;
1364ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1365