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"
23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/Log.h"
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/misc.h"
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <pthread.h>
27dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include <string.h>
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <fcntl.h>
307e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker#include <sys/prctl.h>
31dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include <sys/stat.h>
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshnamespace android {
3433d233cc3a1be101258f7ab3a11fe186300ddf47Jakub Pawlowski// OOB_LE_BD_ADDR_SIZE is 6 bytes addres + 1 byte address type
3533d233cc3a1be101258f7ab3a11fe186300ddf47Jakub Pawlowski#define OOB_LE_BD_ADDR_SIZE 7
36914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski#define OOB_TK_SIZE 16
371d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski#define OOB_LE_SC_C_SIZE 16
381d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski#define OOB_LE_SC_R_SIZE 16
39914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_stateChangeCallback;
41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_adapterPropertyChangedCallback;
42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_devicePropertyChangedCallback;
43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_deviceFoundCallback;
44ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_pinRequestCallback;
45ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_sspRequestCallback;
46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_bondStateChangeCallback;
4701a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamystatic jmethodID method_aclStateChangeCallback;
48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_discoveryStateChangeCallback;
491e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_setWakeAlarm;
501e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_acquireWakeLock;
511e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_releaseWakeLock;
52f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadhamstatic jmethodID method_energyInfo;
53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
54cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinskistatic struct {
55dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass clazz;
56dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jmethodID constructor;
57cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski} android_bluetooth_UidTraffic;
58cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski
59dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic const bt_interface_t* sBluetoothInterface = NULL;
60dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic const btsock_interface_t* sBluetoothSocketInterface = NULL;
61dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic JNIEnv* callbackEnv = NULL;
62ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
631e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jobject sJniAdapterServiceObj;
64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jobject sJniCallbacksObj;
65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jfieldID sJniCallbacksField;
66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
67dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenconst bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; }
686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
69dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie JanssenJNIEnv* getCallbackEnv() { return callbackEnv; }
706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_state_change_callback(bt_state_t status) {
72dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
73dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
74dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: Status is: %d", __func__, status);
75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
76dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback,
77dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jint)status);
78ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
80dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int get_properties(int num_properties, bt_property_t* properties,
81dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                          jintArray* types, jobjectArray* props) {
82dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < num_properties; i++) {
83479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jbyteArray> propVal(
84479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        callbackEnv, callbackEnv->NewByteArray(properties[i].len));
85479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    if (!propVal.get()) {
86479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ALOGE("Error while allocation of array in %s", __func__);
87479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      return -1;
88479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    }
89dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
90479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    callbackEnv->SetByteArrayRegion(propVal.get(), 0, properties[i].len,
91dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    (jbyte*)properties[i].val);
92479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    callbackEnv->SetObjectArrayElement(*props, i, propVal.get());
93dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    callbackEnv->SetIntArrayRegion(*types, i, 1, (jint*)&properties[i].type);
94dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
95dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return 0;
96ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
97ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
98ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_properties_callback(bt_status_t status, int num_properties,
99dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        bt_property_t* properties) {
100dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
101dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
102dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
103dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties);
104dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
105dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
106dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Status %d is incorrect", __func__, status);
107dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
108dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
109dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
110479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> val(
111479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
112479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
113479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!val.get()) {
114dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating byteArray", __func__);
115dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
116dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
117dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
118479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
119479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                sCallbackEnv->GetObjectClass(val.get()));
120dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
121dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* (BT) Initialize the jobjectArray and jintArray here itself and send the
122dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   initialized array pointers alone to get_properties */
123dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
124479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> props(
125479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
126479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
127479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!props.get()) {
128dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating object Array for properties", __func__);
129dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
130dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
131dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
132479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jintArray> types(
133479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
134479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!types.get()) {
135dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating int Array for values", __func__);
136dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
137dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
138dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
139479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  jintArray typesPtr = types.get();
140479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  jobjectArray propsPtr = props.get();
141479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
142dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
143dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
144dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
145479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
146479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               method_adapterPropertyChangedCallback,
147479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               types.get(), props.get());
148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
150dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void remote_device_properties_callback(bt_status_t status,
151b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski                                              RawAddress* bd_addr,
152dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                              int num_properties,
153dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                              bt_property_t* properties) {
154dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
155dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
156dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
157dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties);
158dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
159dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
160dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Status %d is incorrect", __func__, status);
161dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
162dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
163dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
164479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> val(
165479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
166479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      (jbyteArray)sCallbackEnv->NewByteArray(num_properties));
167479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!val.get()) {
168dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating byteArray", __func__);
169dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
170dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
171dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
172479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jclass> mclass(sCallbackEnv.get(),
173479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                sCallbackEnv->GetObjectClass(val.get()));
174dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
175dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* Initialize the jobjectArray and jintArray here itself and send the
176dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   initialized array pointers alone to get_properties */
177dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
178479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> props(
179479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
180479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL));
181479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!props.get()) {
182dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating object Array for properties", __func__);
183dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
184dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
185dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
186479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jintArray> types(
187479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties));
188479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!types.get()) {
189dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s: Error allocating int Array for values", __func__);
190dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
191dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
192dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1932116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
194b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
1952116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1962116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Error while allocation byte array in %s", __func__);
1972116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
1982116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
1992116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach
200b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
2012116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
202dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
203479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  jintArray typesPtr = types.get();
204479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  jobjectArray propsPtr = props.get();
205479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) {
206dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
207dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
208dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
209dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj,
210479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               method_devicePropertyChangedCallback, addr.get(),
211479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               types.get(), props.get());
212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
214dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void device_found_callback(int num_properties,
215dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                  bt_property_t* properties) {
216dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
217dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
218dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2192116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), NULL);
220dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int addr_index;
221dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < num_properties; i++) {
222dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (properties[i].type == BT_PROPERTY_BDADDR) {
2232116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      addr.reset(sCallbackEnv->NewByteArray(properties[i].len));
2242116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      if (!addr.get()) {
2252116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach        ALOGE("Address is NULL (unable to allocate) in %s", __func__);
2262116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach        return;
2272116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      }
2282116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv->SetByteArrayRegion(addr.get(), 0, properties[i].len,
2292116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                       (jbyte*)properties[i].val);
230479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      addr_index = i;
231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
232dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
2332116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2342116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Address is NULL in %s", __func__);
2352116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2362116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
238dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: Properties: %d, Address: %s", __func__, num_properties,
239dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        (const char*)properties[addr_index].val);
240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
241dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  remote_device_properties_callback(BT_STATUS_SUCCESS,
242b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski                                    (RawAddress*)properties[addr_index].val,
243dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    num_properties, properties);
244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
245dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback,
246479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get());
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
249b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_bond_state_t state) {
251dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
252dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
253dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
254dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!bd_addr) {
255dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Address is null in %s", __func__);
256dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
257dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
258dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2592116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
260b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
2612116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2622116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Address allocation failed in %s", __func__);
2632116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2642116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
265b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
2662116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
267dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
268dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback,
269479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               (jint)status, addr.get(), (jint)state);
270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
272b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
273dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                       bt_acl_state_t state) {
274dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!bd_addr) {
275dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Address is null in %s", __func__);
276dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
277dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
278dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
279dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
280dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
281dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2822116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
283b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
2842116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2852116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Address allocation failed in %s", __func__);
2862116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2872116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
288b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
2892116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
290dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
291dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback,
292479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               (jint)status, addr.get(), (jint)state);
29301a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy}
29401a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy
295ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void discovery_state_changed_callback(bt_discovery_state_t state) {
296dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
297dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
298ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
299dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: DiscoveryState:%d ", __func__, state);
300ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
301dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(
302dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state);
303ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
304ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
305b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void pin_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
306dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                 uint32_t cod, bool min_16_digits) {
307dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!bd_addr) {
308dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Address is null in %s", __func__);
309dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
310dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
311ae15d3d42fcb3349c11d394423493020e78c5f43Marie Janssen
312dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
313dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
314ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
3152116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
316b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
3172116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
3182116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Error while allocating in: %s", __func__);
3192116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
3202116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
3212116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach
322b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
3232116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
324ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
325479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> devname(
326479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)));
327479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!devname.get()) {
328dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error while allocating in: %s", __func__);
329dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
330dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
331ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
332479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t),
333dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   (jbyte*)bdname);
334ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
335dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback,
336479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), devname.get(), cod, min_16_digits);
337dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen}
338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
339b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
340dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                 uint32_t cod, bt_ssp_variant_t pairing_variant,
341dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                 uint32_t pass_key) {
342dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!bd_addr) {
343dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Address is null in %s", __func__);
344dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
345dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
346dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
347dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
348dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
3492116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
350b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
3512116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
3522116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Error while allocating in: %s", __func__);
3532116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
3542116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
3552116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach
356b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
3572116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
358dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
359479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> devname(
360479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t)));
361479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!devname.get()) {
362dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error while allocating in: %s", __func__);
363dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
364dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
365ae15d3d42fcb3349c11d394423493020e78c5f43Marie Janssen
366479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t),
367dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   (jbyte*)bdname);
368ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
369dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback,
370479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), devname.get(), cod,
371479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               (jint)pairing_variant, pass_key);
372ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
373ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
374ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void callback_thread_event(bt_cb_thread_evt event) {
375dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  JavaVM* vm = AndroidRuntime::getJavaVM();
376dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (event == ASSOCIATE_JVM) {
377dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    JavaVMAttachArgs args;
378dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    char name[] = "BT Service Callback Thread";
379dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    args.version = JNI_VERSION_1_6;
380dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    args.name = name;
381dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    args.group = NULL;
382dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    vm->AttachCurrentThread(&callbackEnv, &args);
383dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGV("Callback thread attached: %p", callbackEnv);
384dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else if (event == DISASSOCIATE_JVM) {
385dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (callbackEnv != AndroidRuntime::getJNIEnv()) {
386dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("Callback: '%s' is not called on the correct thread", __func__);
387dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return;
388ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
389dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    vm->DetachCurrentThread();
390dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
391ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
392ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
393dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) {
39403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
39503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta}
39603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
397dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void le_test_mode_recv_callback(bt_status_t status,
398dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                       uint16_t packet_count) {
399dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: status:%d packet_count:%d ", __func__, status, packet_count);
40003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta}
401f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham
402dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void energy_info_recv_callback(bt_activity_energy_info* p_energy_info,
403fe37710d689b7573ddeb901141db42c28b6cab39Marie Janssen                                      bt_uid_traffic_t* uid_data) {
404dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
405dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
406dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
407dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jsize len = 0;
408dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
409dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    len++;
410dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
411dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
412479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> array(
413479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewObjectArray(
414479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                              len, android_bluetooth_UidTraffic.clazz, NULL));
415dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jsize i = 0;
416dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
417479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jobject> uidObj(
418479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv.get(),
419479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->NewObject(android_bluetooth_UidTraffic.clazz,
420479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                android_bluetooth_UidTraffic.constructor,
421479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                (jint)data->app_uid, (jlong)data->rx_bytes,
422479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                (jlong)data->tx_bytes));
423479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetObjectArrayElement(array.get(), i++, uidObj.get());
424dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
425dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
426dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(
427dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sJniAdapterServiceObj, method_energyInfo, p_energy_info->status,
428dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time,
429479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      p_energy_info->idle_time, p_energy_info->energy_used, array.get());
430f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham}
431f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham
4321e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic bt_callbacks_t sBluetoothCallbacks = {
433dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sizeof(sBluetoothCallbacks), adapter_state_change_callback,
434dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    adapter_properties_callback, remote_device_properties_callback,
435dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    device_found_callback,       discovery_state_changed_callback,
436dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    pin_request_callback,        ssp_request_callback,
437dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    bond_state_changed_callback, acl_state_changed_callback,
438dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    callback_thread_event,       dut_mode_recv_callback,
439dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    le_test_mode_recv_callback,  energy_info_recv_callback};
440ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
4411e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// The callback to call when the wake alarm fires.
4421e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic alarm_cb sAlarmCallback;
4431e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4441e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// The data to pass to the wake alarm callback.
445dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void* sAlarmCallbackData;
4461e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4477e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panickerclass JNIThreadAttacher {
4487e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker public:
4497e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIThreadAttacher() : vm_(nullptr), env_(nullptr) {
4507e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    vm_ = AndroidRuntime::getJavaVM();
4517e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6);
4527e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
4537e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    if (status_ != JNI_OK && status_ != JNI_EDETACHED) {
4547e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      ALOGE(
4557e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker          "JNIThreadAttacher: unable to get environment for JNI CALL, "
4567e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker          "status: %d",
4577e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker          status_);
4587e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      env_ = nullptr;
4597e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      return;
4607e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    }
461beccdc6d1647c56c91ddfd14f7990371168fb870Sharvil Nanavati
4627e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    if (status_ == JNI_EDETACHED) {
4637e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      char name[17] = {0};
4647e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      if (prctl(PR_GET_NAME, (unsigned long)name) != 0) {
4657e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        ALOGE(
4667e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker            "JNIThreadAttacher: unable to grab previous thread name, error: %s",
4677e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker            strerror(errno));
4687e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        env_ = nullptr;
4697e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        return;
4707e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      }
471dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
4727e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      JavaVMAttachArgs args = {
4737e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker          .version = JNI_VERSION_1_6, .name = name, .group = nullptr};
4747e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      if (vm_->AttachCurrentThread(&env_, &args) != 0) {
4757e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        ALOGE("JNIThreadAttacher: unable to attach thread to VM");
4767e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        env_ = nullptr;
4777e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker        return;
4787e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker      }
4797e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    }
4807e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  }
4817e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
4827e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  ~JNIThreadAttacher() {
4837e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    if (status_ == JNI_EDETACHED) vm_->DetachCurrentThread();
484dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
485dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
4867e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* getEnv() { return env_; }
4877e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
4887e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker private:
4897e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JavaVM* vm_;
4907e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* env_;
4917e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  jint status_;
4927e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker};
4937e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
4947e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panickerstatic bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake,
4957e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker                                   alarm_cb cb, void* data) {
4967e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIThreadAttacher attacher;
4977e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* env = attacher.getEnv();
4987e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
4997e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  if (env == nullptr) {
5007e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    ALOGE("%s: Unable to get JNI Env", __func__);
501dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return false;
502dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
503dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
504dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sAlarmCallback = cb;
505dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sAlarmCallbackData = data;
506dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
507dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE;
508dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jboolean ret =
509dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm,
510dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                             (jlong)delay_millis, jshould_wake);
511dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!ret) {
512dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sAlarmCallback = NULL;
513dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sAlarmCallbackData = NULL;
514dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
515dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
5167e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  return (ret == JNI_TRUE);
5171e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5181e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
519dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int acquire_wake_lock_callout(const char* lock_name) {
5207e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIThreadAttacher attacher;
5217e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* env = attacher.getEnv();
5227e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
5237e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  if (env == nullptr) {
5247e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    ALOGE("%s: Unable to get JNI Env", __func__);
525dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
526dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
527dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
528dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jint ret = BT_STATUS_SUCCESS;
529479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  {
530479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
531479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    if (lock_name_jni.get()) {
532479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      bool acquired = env->CallBooleanMethod(
533479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          sJniAdapterServiceObj, method_acquireWakeLock, lock_name_jni.get());
534479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR;
535479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    } else {
536479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ALOGE("%s unable to allocate string: %s", __func__, lock_name);
537479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ret = BT_STATUS_NOMEM;
538479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    }
539dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
540dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
541dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return ret;
5421e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5431e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
544dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int release_wake_lock_callout(const char* lock_name) {
5457e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIThreadAttacher attacher;
5467e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  JNIEnv* env = attacher.getEnv();
5477e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker
5487e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker  if (env == nullptr) {
5497e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker    ALOGE("%s: Unable to get JNI Env", __func__);
550dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
551dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
552dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
553dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jint ret = BT_STATUS_SUCCESS;
554479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  {
555479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name));
556479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    if (lock_name_jni.get()) {
557479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      bool released = env->CallBooleanMethod(
558479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          sJniAdapterServiceObj, method_releaseWakeLock, lock_name_jni.get());
559479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      if (!released) ret = BT_STATUS_WAKELOCK_ERROR;
560479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    } else {
561479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ALOGE("%s unable to allocate string: %s", __func__, lock_name);
562479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      ret = BT_STATUS_NOMEM;
563479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    }
564dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
565dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
566dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return ret;
5671e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5681e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5691e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// Called by Java code when alarm is fired. A wake lock is held by the caller
5701e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// over the duration of this callback.
571dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void alarmFiredNative(JNIEnv* env, jobject obj) {
572dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sAlarmCallback) {
573dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sAlarmCallback(sAlarmCallbackData);
574dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else {
575dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("%s() - Alarm fired with callback not set!", __func__);
576dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
5771e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5781e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5791e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic bt_os_callouts_t sBluetoothOsCallouts = {
580dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sizeof(sBluetoothOsCallouts), set_wake_alarm_callout,
581dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    acquire_wake_lock_callout, release_wake_lock_callout,
5821e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati};
5831e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
584ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void classInitNative(JNIEnv* env, jclass clazz) {
585dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic");
586dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  android_bluetooth_UidTraffic.constructor =
587dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniUidTrafficClass, "<init>", "(IJJ)V");
588dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
589dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass jniCallbackClass =
590dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
591dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sJniCallbacksField = env->GetFieldID(
592dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;");
593dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
594dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_stateChangeCallback =
595dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
596dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
597dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_adapterPropertyChangedCallback = env->GetMethodID(
598dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniCallbackClass, "adapterPropertyChangedCallback", "([I[[B)V");
599dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_discoveryStateChangeCallback = env->GetMethodID(
600dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniCallbackClass, "discoveryStateChangeCallback", "(I)V");
601dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
602dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_devicePropertyChangedCallback = env->GetMethodID(
603dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniCallbackClass, "devicePropertyChangedCallback", "([B[I[[B)V");
604dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_deviceFoundCallback =
605dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
606dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_pinRequestCallback =
607dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V");
608dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_sspRequestCallback =
609dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V");
610dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
611dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_bondStateChangeCallback =
612dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V");
613dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
614dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_aclStateChangeCallback =
615dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BI)V");
616dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
617dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
618dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_acquireWakeLock =
619dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
620dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_releaseWakeLock =
621dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");
622dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_energyInfo = env->GetMethodID(
623dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V");
624dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
625dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  char value[PROPERTY_VALUE_MAX];
626dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  property_get("bluetooth.mock_stack", value, "");
627dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
628dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const char* id =
629dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (strcmp(value, "1") ? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
630dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
631dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  hw_module_t* module;
632dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int err = hw_get_module(id, (hw_module_t const**)&module);
633dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
634dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (err == 0) {
635dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    hw_device_t* abstraction;
636dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    err = module->methods->open(module, id, &abstraction);
637ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (err == 0) {
638dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      bluetooth_module_t* btStack = (bluetooth_module_t*)abstraction;
639dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sBluetoothInterface = btStack->get_bluetooth_interface();
640ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else {
641dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("Error while opening Bluetooth library");
642ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
643dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else {
644dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("No Bluetooth Library found");
645dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
646ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
647ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
648ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool initNative(JNIEnv* env, jobject obj) {
649dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
650dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
651dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  android_bluetooth_UidTraffic.clazz =
652dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic"));
653dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
654dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sJniAdapterServiceObj = env->NewGlobalRef(obj);
655dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sJniCallbacksObj =
656dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
657dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
658dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) {
659dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
660dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
661dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
662dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
663dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (ret != BT_STATUS_SUCCESS) {
664dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error while setting the callbacks: %d\n", ret);
665dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothInterface = NULL;
666dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
667dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
668dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
669dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (ret != BT_STATUS_SUCCESS) {
670dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error while setting Bluetooth callouts: %d\n", ret);
671dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothInterface->cleanup();
672dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothInterface = NULL;
673dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
674dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
675dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
676dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothSocketInterface =
677dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (btsock_interface_t*)sBluetoothInterface->get_profile_interface(
678dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          BT_PROFILE_SOCKETS_ID);
679dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sBluetoothSocketInterface == NULL) {
680dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Error getting socket interface");
681dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
682dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
683dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return JNI_TRUE;
684ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
685ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
686dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic bool cleanupNative(JNIEnv* env, jobject obj) {
687dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
688ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
689dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
690ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
691dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothInterface->cleanup();
692dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: return from cleanup", __func__);
6936654f5c903de510a70f9e72cd5ad7837b615d93ffredc
694dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->DeleteGlobalRef(sJniCallbacksObj);
695dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->DeleteGlobalRef(sJniAdapterServiceObj);
696dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->DeleteGlobalRef(android_bluetooth_UidTraffic.clazz);
697dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  android_bluetooth_UidTraffic.clazz = NULL;
698dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return JNI_TRUE;
699ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
700ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
701c63ef51ba5f9d355239959bcfe8803987adb1f38Ajay Panickerstatic jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {
702dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
703ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
704dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
705dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0);
706dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE
707dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                             : JNI_FALSE;
708ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
709ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
710ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean disableNative(JNIEnv* env, jobject obj) {
711dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
712ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
713dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
714ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
715dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->disable();
716dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* Retrun JNI_FALSE only when BTIF explicitly reports
717dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY
718dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     case which indicates that stack had not been enabled.
719dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  */
720dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE;
721ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
722ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
723ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
724dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
725ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
726dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
727ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
728dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->start_discovery();
729dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
730ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
731ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
732ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) {
733dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
734ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
735dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
736ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
737dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->cancel_discovery();
738dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
739ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
740ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
741dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address,
742dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                 jint transport) {
743dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
744ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
745dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
746ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
747dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
748dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
749dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
750dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
751dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
752ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
753b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  int ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport);
754dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
755dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
756ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
757ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
75821f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panickerstatic jbyteArray callByteArrayGetter(JNIEnv* env, jobject object,
75921f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panicker                                      const char* className,
76021f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panicker                                      const char* methodName) {
761dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass myClass = env->FindClass(className);
762dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B");
763dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (jbyteArray)env->CallObjectMethod(object, myMethod);
764914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski}
765914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
766dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj,
767dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                          jbyteArray address, jint transport,
768dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                          jobject oobData) {
769dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_out_of_band_data_t oob_data;
770dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
771dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  memset(&oob_data, 0, sizeof(oob_data));
772dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
773dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
774dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
775dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
776dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
777dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
778dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
779dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
780dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
781dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* leBtDeviceAddressBytes = NULL;
782dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* smTKBytes = NULL;
783dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* leScCBytes = NULL;
784dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* leScRBytes = NULL;
785dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyteArray leBtDeviceAddress = NULL;
786dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyteArray smTK = NULL;
787dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyteArray leScC = NULL;
788dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyteArray leScR = NULL;
789dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int status = BT_STATUS_FAIL;
790dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
791dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  leBtDeviceAddress = callByteArrayGetter(
792dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env, oobData, "android/bluetooth/OobData", "getLeBluetoothDeviceAddress");
793dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leBtDeviceAddress != NULL) {
794dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    leBtDeviceAddressBytes = env->GetByteArrayElements(leBtDeviceAddress, NULL);
795dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    int len = env->GetArrayLength(leBtDeviceAddress);
796dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (len != OOB_LE_BD_ADDR_SIZE) {
797dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGI(
798dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          "%s: wrong length of leBtDeviceAddress, should be empty or %d bytes.",
799dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          __func__, OOB_LE_BD_ADDR_SIZE);
800dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
801dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      goto done;
802dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
803dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    memcpy(oob_data.le_bt_dev_addr, leBtDeviceAddressBytes, len);
804dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
805dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
806dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  smTK = callByteArrayGetter(env, oobData, "android/bluetooth/OobData",
807dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                             "getSecurityManagerTk");
808dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (smTK != NULL) {
809dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    smTKBytes = env->GetByteArrayElements(smTK, NULL);
810dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    int len = env->GetArrayLength(smTK);
811dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (len != OOB_TK_SIZE) {
812dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGI("%s: wrong length of smTK, should be empty or %d bytes.", __func__,
813dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen            OOB_TK_SIZE);
814dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
815dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      goto done;
816dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
817dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    memcpy(oob_data.sm_tk, smTKBytes, len);
818dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
819dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
820dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  leScC = callByteArrayGetter(env, oobData, "android/bluetooth/OobData",
821dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                              "getLeSecureConnectionsConfirmation");
822dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leScC != NULL) {
823dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    leScCBytes = env->GetByteArrayElements(leScC, NULL);
824dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    int len = env->GetArrayLength(leScC);
825dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (len != OOB_LE_SC_C_SIZE) {
826dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGI(
827dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          "%s: wrong length of LE SC Confirmation, should be empty or %d "
828dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          "bytes.",
829dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          __func__, OOB_LE_SC_C_SIZE);
830dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
831dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      goto done;
832dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
833dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    memcpy(oob_data.le_sc_c, leScCBytes, len);
834dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
835dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
836dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  leScR = callByteArrayGetter(env, oobData, "android/bluetooth/OobData",
837dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                              "getLeSecureConnectionsRandom");
838dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leScR != NULL) {
839dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    leScRBytes = env->GetByteArrayElements(leScR, NULL);
840dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    int len = env->GetArrayLength(leScR);
841dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (len != OOB_LE_SC_R_SIZE) {
842dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGI("%s: wrong length of LE SC Random, should be empty or %d bytes.",
843dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen            __func__, OOB_LE_SC_R_SIZE);
844dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
845dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      goto done;
846dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
847dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    memcpy(oob_data.le_sc_r, leScRBytes, len);
848dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
849dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
850b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  status = sBluetoothInterface->create_bond_out_of_band((RawAddress*)addr,
851dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                        transport, &oob_data);
852914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
853914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowskidone:
854dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
855914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
856dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leBtDeviceAddress != NULL)
857dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->ReleaseByteArrayElements(leBtDeviceAddress, leBtDeviceAddressBytes, 0);
85833d233cc3a1be101258f7ab3a11fe186300ddf47Jakub Pawlowski
859dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (smTK != NULL) env->ReleaseByteArrayElements(smTK, smTKBytes, 0);
860914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
861dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leScC != NULL) env->ReleaseByteArrayElements(leScC, leScCBytes, 0);
8621d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski
863dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (leScR != NULL) env->ReleaseByteArrayElements(leScR, leScRBytes, 0);
8641d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski
865dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
866914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski}
867914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski
868ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
869dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
870ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
871dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
872ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
873dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
874dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
875dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
876dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
877dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
878ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
879b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  int ret = sBluetoothInterface->remove_bond((RawAddress*)addr);
880dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
881ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
882dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
883ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
884ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
885ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
886dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
887ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
888dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
889ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
890dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
891dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
892dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
893dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
894dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
895ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
896b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  int ret = sBluetoothInterface->cancel_bond((RawAddress*)addr);
897dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
898dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
899ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
900ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
901dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int getConnectionStateNative(JNIEnv* env, jobject obj,
902dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    jbyteArray address) {
903dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
904dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
9053636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach
906dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
907dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
908dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
909dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
910dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
9113636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach
912b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  int ret = sBluetoothInterface->get_connection_state((RawAddress*)addr);
913dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9143636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach
915dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return ret;
9163636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach}
9173636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach
918dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean pinReplyNative(JNIEnv* env, jobject obj, jbyteArray address,
919dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               jboolean accept, jint len, jbyteArray pinArray) {
920dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
921ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
922dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
923ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
924dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
925dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
926dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
927dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
928dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
929ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
930dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* pinPtr = NULL;
931dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (accept) {
932dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    pinPtr = env->GetByteArrayElements(pinArray, NULL);
933dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (pinPtr == NULL) {
934dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      jniThrowIOException(env, EINVAL);
935dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->ReleaseByteArrayElements(address, addr, 0);
936dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return JNI_FALSE;
937ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
938dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
939ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
940b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  int ret = sBluetoothInterface->pin_reply((RawAddress*)addr, accept, len,
941dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                           (bt_pin_code_t*)pinPtr);
942dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
943dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(pinArray, pinPtr, 0);
944ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
945dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
946ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
947ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
948dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean sspReplyNative(JNIEnv* env, jobject obj, jbyteArray address,
949581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh                               jint type, jboolean accept, jint passkey) {
950dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
951ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
952dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
953ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
954dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
955dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
956dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
957dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
958dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
959ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
960dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->ssp_reply(
961b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (bt_ssp_variant_t)type, accept, passkey);
962dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
963ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
964dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
965ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
966ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
967dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean setAdapterPropertyNative(JNIEnv* env, jobject obj, jint type,
968dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         jbyteArray value) {
969dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
970ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
971dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
972ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
973dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* val = env->GetByteArrayElements(value, NULL);
974dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_property_t prop;
975dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.type = (bt_property_type_t)type;
976dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.len = env->GetArrayLength(value);
977dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.val = val;
978ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
979dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->set_adapter_property(&prop);
980dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(value, val, 0);
981ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
982dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
983ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
984ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
985dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getAdapterPropertiesNative(JNIEnv* env, jobject obj) {
986dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
987ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
988dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
989ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
990dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->get_adapter_properties();
991dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
992ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
993ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
994dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getAdapterPropertyNative(JNIEnv* env, jobject obj, jint type) {
995dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
996ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
997dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
998ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
999dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t)type);
1000dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1001ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1002ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1003dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getDevicePropertyNative(JNIEnv* env, jobject obj,
1004dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray address, jint type) {
1005dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1006ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1007dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1008ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1009dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1010dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
1011dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1012dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
1013dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1014ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1015dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->get_remote_device_property(
1016b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (bt_property_type_t)type);
1017dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1018dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1019ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1020ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1021dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean setDevicePropertyNative(JNIEnv* env, jobject obj,
1022dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray address, jint type,
1023dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray value) {
1024dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1025ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1026dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1027ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1028dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* val = env->GetByteArrayElements(value, NULL);
1029dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (val == NULL) {
1030dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1031dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
1032dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1033ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1034dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1035dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
1036dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->ReleaseByteArrayElements(value, val, 0);
1037dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1038dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
1039dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1040ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1041dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_property_t prop;
1042dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.type = (bt_property_type_t)type;
1043dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.len = env->GetArrayLength(value);
1044dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  prop.val = val;
1045ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1046b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  int ret =
1047b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sBluetoothInterface->set_remote_device_property((RawAddress*)addr, &prop);
1048dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(value, val, 0);
1049dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1050ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1051dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1052ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1053ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1054dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getRemoteServicesNative(JNIEnv* env, jobject obj,
1055dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray address) {
1056dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1057c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1058dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1059c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1060dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = addr = env->GetByteArrayElements(address, NULL);
1061dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
1062dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1063dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
1064dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1065c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1066b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  int ret = sBluetoothInterface->get_remote_services((RawAddress*)addr);
1067dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1068dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1069c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc}
1070c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
1071dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int connectSocketNative(JNIEnv* env, jobject object, jbyteArray address,
1072dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               jint type, jbyteArray uuidObj, jint channel,
1073dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               jint flag, jint callingUid) {
1074dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothSocketInterface) return -1;
1075cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1076dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1077dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
1078dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("failed to get Bluetooth device address");
1079dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return -1;
1080dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1081dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1082dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* uuid = NULL;
1083dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (uuidObj != NULL) {
1084dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    uuid = env->GetByteArrayElements(uuidObj, NULL);
1085dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (!uuid) {
1086dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("failed to get uuid");
1087dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->ReleaseByteArrayElements(address, addr, 0);
1088dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return -1;
1089dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
1090dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1091dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1092dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int socket_fd = -1;
1093dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothSocketInterface->connect(
1094b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (btsock_type_t)type, (const uint8_t*)uuid, channel,
1095dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      &socket_fd, flag, callingUid);
1096dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
1097dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Socket connection failed: %d", status);
1098dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    socket_fd = -1;
1099dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else if (socket_fd < 0) {
1100dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Fail to create file descriptor on socket fd");
1101dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1102dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1103dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1104dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(uuidObj, uuid, 0);
1105dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return socket_fd;
1106cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
1107cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1108dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int createSocketChannelNative(JNIEnv* env, jobject object, jint type,
1109244e9c62a85a4b94e21bf1a8dee456e22bc767c4Casper Bonde                                     jstring name_str, jbyteArray uuidObj,
1110cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski                                     jint channel, jint flag, jint callingUid) {
1111dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothSocketInterface) return -1;
1112dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1113dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: SOCK FLAG = %x", __func__, flag);
1114dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1115dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const char* service_name = NULL;
1116dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (name_str != NULL) {
1117dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    service_name = env->GetStringUTFChars(name_str, NULL);
1118dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1119dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1120dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* uuid = NULL;
1121dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (uuidObj != NULL) {
1122dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    uuid = env->GetByteArrayElements(uuidObj, NULL);
1123dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    if (!uuid) {
1124dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("failed to get uuid");
1125dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
1126dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return -1;
1127dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
1128dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1129dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1130dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int socket_fd = -1;
1131dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothSocketInterface->listen(
1132dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (btsock_type_t)type, service_name, (const uint8_t*)uuid, channel,
1133dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      &socket_fd, flag, callingUid);
1134dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
1135dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Socket listen failed: %d", status);
1136dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    socket_fd = -1;
1137dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else if (socket_fd < 0) {
1138dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Fail to creat file descriptor on socket fd");
1139dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1140dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1141dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
1142dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
1143dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return socket_fd;
1144cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
1145cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1146dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int readEnergyInfo() {
1147dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1148ae15d3d42fcb3349c11d394423493020e78c5f43Marie Janssen
1149dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1150dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->read_energy_info();
1151dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1152f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham}
1153f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham
1154dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void dumpNative(JNIEnv* env, jobject obj, jobject fdObj,
1155dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       jobjectArray argArray) {
1156dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1157dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return;
1158f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach
1159dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int fd = jniGetFDFromFileDescriptor(env, fdObj);
1160dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (fd < 0) return;
1161f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach
1162dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int numArgs = env->GetArrayLength(argArray);
1163407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1164dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jstring* argObjs = new jstring[numArgs];
1165dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const char** args = nullptr;
1166dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (numArgs > 0) args = new const char*[numArgs];
1167407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1168dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < numArgs; i++) {
1169dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    argObjs[i] = (jstring)env->GetObjectArrayElement(argArray, i);
1170dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    args[i] = env->GetStringUTFChars(argObjs[i], NULL);
1171dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1172407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1173dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothInterface->dump(fd, args);
1174407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1175dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < numArgs; i++) {
1176dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->ReleaseStringUTFChars(argObjs[i], args[i]);
1177dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1178407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen
1179dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  delete[] args;
1180dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  delete[] argObjs;
1181f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach}
1182f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach
1183dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean factoryResetNative(JNIEnv* env, jobject obj) {
1184dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1185dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return JNI_FALSE;
1186dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int ret = sBluetoothInterface->config_clear();
1187dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
11886eb32d5f7c30f04da45c3da0974bbb63725a0978Ajay Panicker}
11896eb32d5f7c30f04da45c3da0974bbb63725a0978Ajay Panicker
1190dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void interopDatabaseClearNative(JNIEnv* env, jobject obj) {
1191dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1192dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return;
1193dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothInterface->interop_database_clear();
1194db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach}
1195db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach
1196dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void interopDatabaseAddNative(JNIEnv* env, jobject obj, int feature,
1197dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     jbyteArray address, int length) {
1198dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
1199dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothInterface) return;
1200db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach
1201dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1202dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (addr == NULL) {
1203dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1204dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
1205dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1206db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach
1207b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sBluetoothInterface->interop_database_add(feature, (RawAddress*)addr, length);
1208dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
1209db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach}
1210db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach
1211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNINativeMethod sMethods[] = {
1212b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    /* name, signature, funcPtr */
1213dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"classInitNative", "()V", (void*)classInitNative},
1214dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"initNative", "()Z", (void*)initNative},
1215dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"cleanupNative", "()V", (void*)cleanupNative},
1216dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"enableNative", "(Z)Z", (void*)enableNative},
1217dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"disableNative", "()Z", (void*)disableNative},
1218dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative},
1219dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative},
1220dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative},
1221dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getDevicePropertyNative", "([BI)Z", (void*)getDevicePropertyNative},
1222dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"setDevicePropertyNative", "([BI[B)Z", (void*)setDevicePropertyNative},
1223dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
1224dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"cancelDiscoveryNative", "()Z", (void*)cancelDiscoveryNative},
1225dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"createBondNative", "([BI)Z", (void*)createBondNative},
1226dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z",
1227dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)createBondOutOfBandNative},
1228dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"removeBondNative", "([B)Z", (void*)removeBondNative},
1229dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"cancelBondNative", "([B)Z", (void*)cancelBondNative},
1230dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative},
1231dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative},
1232dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative},
1233dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getRemoteServicesNative", "([B)Z", (void*)getRemoteServicesNative},
1234dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"connectSocketNative", "([BI[BIII)I", (void*)connectSocketNative},
1235cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski    {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I",
1236dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)createSocketChannelNative},
1237dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"alarmFiredNative", "()V", (void*)alarmFiredNative},
1238dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"readEnergyInfo", "()I", (void*)readEnergyInfo},
1239dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V",
1240dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)dumpNative},
1241db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach    {"factoryResetNative", "()Z", (void*)factoryResetNative},
1242dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"interopDatabaseClearNative", "()V", (void*)interopDatabaseClearNative},
1243dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"interopDatabaseAddNative", "(I[BI)V", (void*)interopDatabaseAddNative}};
1244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1245dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenint register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
1246dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return jniRegisterNativeMethods(
1247dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env, "com/android/bluetooth/btservice/AdapterService", sMethods,
1248dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      NELEM(sMethods));
1249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} /* namespace android */
1252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
1254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * JNI Initialization
1255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
1256dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenjint JNI_OnLoad(JavaVM* jvm, void* reserved) {
1257dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  JNIEnv* e;
1258dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int status;
1259dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1260dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("Bluetooth Adapter Service : loading JNI\n");
1261dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1262dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  // Check JNI version
1263dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (jvm->GetEnv((void**)&e, JNI_VERSION_1_6)) {
1264dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("JNI version mismatch error");
1265dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1266dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1267dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1268dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_btservice_AdapterService(e);
1269dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1270dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni adapter service registration failure, status: %d", status);
1271dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1272dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1273dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1274dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_hfp(e);
1275dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1276dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni hfp registration failure, status: %d", status);
1277dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1278dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1279dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1280dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_hfpclient(e);
1281dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1282dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni hfp client registration failure, status: %d", status);
1283dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1284dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1285dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1286dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_a2dp(e);
1287dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1288dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni a2dp source registration failure: %d", status);
1289dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1290dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1291dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1292dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_a2dp_sink(e);
1293dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1294dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni a2dp sink registration failure: %d", status);
1295dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1296dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1297dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1298dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_avrcp(e);
1299dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1300dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni avrcp target registration failure: %d", status);
1301dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1302dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1303dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1304dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_avrcp_controller(e);
1305dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1306dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni avrcp controller registration failure: %d", status);
1307dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1308dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1309dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1310dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_hid(e);
1311dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1312dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni hid registration failure: %d", status);
1313dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1314dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1315dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1316cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta  status = android::register_com_android_bluetooth_hidd(e);
1317cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta  if (status < 0) {
1318cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta    ALOGE("jni hidd registration failure: %d", status);
1319cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta    return JNI_ERR;
1320cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta  }
1321cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta
1322dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_hdp(e);
1323dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1324dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni hdp registration failure: %d", status);
1325dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1326dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1327dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1328dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_pan(e);
1329dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1330dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni pan registration failure: %d", status);
1331dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1332dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1333dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1334dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_gatt(e);
1335dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1336dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni gatt registration failure: %d", status);
1337dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1338dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1339dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1340dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  status = android::register_com_android_bluetooth_sdp(e);
1341dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status < 0) {
1342dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("jni sdp registration failure: %d", status);
1343dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_ERR;
1344dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1345dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1346dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return JNI_VERSION_1_6;
1347ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1348