blob: 30724f4bf86dd3791444e878e1bce4ed39dc6948 [file] [log] [blame]
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001/*
Zhihai Xuede67c22012-10-23 17:01:01 -07002 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080015 */
16
17#define LOG_TAG "BluetoothServiceJni"
Matthew Xie6c91bc02012-02-16 18:47:53 -080018#include "com_android_bluetooth.h"
Matthew Xiecc80b222012-03-13 17:24:54 -070019#include "hardware/bt_sock.h"
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080020#include "utils/Log.h"
21#include "utils/misc.h"
22#include "cutils/properties.h"
23#include "android_runtime/AndroidRuntime.h"
Ruben Brunkdc8c5332013-09-10 20:35:38 -070024#include "android_runtime/Log.h"
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080025
Manu Viswanadhan382a8f42016-07-12 18:24:08 +053026#include <hardware/vendor.h>
Manu Viswanadhan2cf764c2016-06-03 20:00:48 +053027
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080028#include <string.h>
29#include <pthread.h>
30
31#include <sys/stat.h>
32#include <fcntl.h>
33
34namespace android {
35
Jakub Pawlowski914484b2015-12-29 13:21:30 -080036#define OOB_TK_SIZE 16
37
Matthew Xie6c91bc02012-02-16 18:47:53 -080038#define ADDITIONAL_NREFS 50
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080039static jmethodID method_stateChangeCallback;
40static jmethodID method_adapterPropertyChangedCallback;
41static jmethodID method_devicePropertyChangedCallback;
42static jmethodID method_deviceFoundCallback;
43static jmethodID method_pinRequestCallback;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080044static jmethodID method_sspRequestCallback;
45static jmethodID method_bondStateChangeCallback;
Kausik Sinnaswamy01a8cf92012-04-04 12:09:10 +053046static jmethodID method_aclStateChangeCallback;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080047static jmethodID method_discoveryStateChangeCallback;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -070048static jmethodID method_setWakeAlarm;
49static jmethodID method_acquireWakeLock;
50static jmethodID method_releaseWakeLock;
Prerepa Viswanadhamf6eff2b2014-07-18 21:30:20 -070051static jmethodID method_energyInfo;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080052
Adam Lesinskicbe58102015-12-03 16:17:17 -080053static struct {
54 jclass clazz;
55 jmethodID constructor;
56} android_bluetooth_UidTraffic;
57
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080058static const bt_interface_t *sBluetoothInterface = NULL;
Matthew Xiecc80b222012-03-13 17:24:54 -070059static const btsock_interface_t *sBluetoothSocketInterface = NULL;
Manu Viswanadhan2cf764c2016-06-03 20:00:48 +053060static const btvendor_interface_t *sBluetoothVendorInterface = NULL;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080061static JNIEnv *callbackEnv = NULL;
62
Srinu Jella5f203262014-08-05 18:48:18 +053063static jobject sJniAdapterServiceObj = NULL;
64static jobject sJniCallbacksObj = NULL;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080065static jfieldID sJniCallbacksField;
66
Matthew Xiecc80b222012-03-13 17:24:54 -070067
Matthew Xie6c91bc02012-02-16 18:47:53 -080068const bt_interface_t* getBluetoothInterface() {
69 return sBluetoothInterface;
70}
71
72JNIEnv* getCallbackEnv() {
Brian Carlstromb241cda2013-03-11 23:47:55 -070073 return callbackEnv;
Matthew Xie6c91bc02012-02-16 18:47:53 -080074}
75
76void checkAndClearExceptionFromCallback(JNIEnv* env,
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080077 const char* methodName) {
78 if (env->ExceptionCheck()) {
Matthew Xiec55a9832012-04-07 03:44:13 -070079 ALOGE("An exception was thrown by callback '%s'.", methodName);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080080 LOGE_EX(env);
81 env->ExceptionClear();
82 }
83}
84
85static bool checkCallbackThread() {
86 JNIEnv* env = AndroidRuntime::getJNIEnv();
Matthew Xie676cb1b2012-03-22 17:32:29 -070087 if (callbackEnv != env || callbackEnv == NULL) {
Matthew Xiec55a9832012-04-07 03:44:13 -070088 ALOGE("Callback env check fail: env: %p, callback: %p", env, callbackEnv);
Matthew Xie676cb1b2012-03-22 17:32:29 -070089 return false;
90 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080091 return true;
92}
93
94static void adapter_state_change_callback(bt_state_t status) {
95 if (!checkCallbackThread()) {
Matthew Xiec55a9832012-04-07 03:44:13 -070096 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -080097 return;
98 }
Matthew Xiec55a9832012-04-07 03:44:13 -070099 ALOGV("%s: Status is: %d", __FUNCTION__, status);
Srinu Jella5f203262014-08-05 18:48:18 +0530100 if(sJniCallbacksObj) {
101 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status);
102 } else {
103 ALOGE("JNI ERROR : JNI reference already cleaned : adapter_state_change_callback", __FUNCTION__);
104 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800105 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
106}
107
108static int get_properties(int num_properties, bt_property_t *properties, jintArray *types,
109 jobjectArray *props) {
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700110 jbyteArray propVal;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800111 for (int i = 0; i < num_properties; i++) {
Brian Carlstromb241cda2013-03-11 23:47:55 -0700112 propVal = callbackEnv->NewByteArray(properties[i].len);
113 if (propVal == NULL) goto Fail;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800114
Brian Carlstromb241cda2013-03-11 23:47:55 -0700115 callbackEnv->SetByteArrayRegion(propVal, 0, properties[i].len,
116 (jbyte*)properties[i].val);
117 callbackEnv->SetObjectArrayElement(*props, i, propVal);
118 // Delete reference to propVal
119 callbackEnv->DeleteLocalRef(propVal);
120 callbackEnv->SetIntArrayRegion(*types, i, 1, (jint *)&properties[i].type);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800121 }
122 return 0;
123Fail:
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800124 if (propVal) callbackEnv->DeleteLocalRef(propVal);
Matthew Xiec55a9832012-04-07 03:44:13 -0700125 ALOGE("Error while allocation of array in %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800126 return -1;
127}
128
129static void adapter_properties_callback(bt_status_t status, int num_properties,
130 bt_property_t *properties) {
131 jobjectArray props;
132 jintArray types;
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700133 jbyteArray val;
134 jclass mclass;
135
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800136 if (!checkCallbackThread()) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700137 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800138 return;
139 }
140
Matthew Xiec55a9832012-04-07 03:44:13 -0700141 ALOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800142
143 if (status != BT_STATUS_SUCCESS) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700144 ALOGE("%s: Status %d is incorrect", __FUNCTION__, status);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800145 return;
146 }
147
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700148 val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
149 if (val == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700150 ALOGE("%s: Error allocating byteArray", __FUNCTION__);
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700151 return;
152 }
153
154 mclass = callbackEnv->GetObjectClass(val);
155
156 /* (BT) Initialize the jobjectArray and jintArray here itself and send the
157 initialized array pointers alone to get_properties */
158
159 props = callbackEnv->NewObjectArray(num_properties, mclass,
160 NULL);
161 if (props == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700162 ALOGE("%s: Error allocating object Array for properties", __FUNCTION__);
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700163 return;
164 }
165
166 types = (jintArray)callbackEnv->NewIntArray(num_properties);
167
168 if (types == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700169 ALOGE("%s: Error allocating int Array for values", __FUNCTION__);
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700170 return;
171 }
172 // Delete the reference to val and mclass
173 callbackEnv->DeleteLocalRef(mclass);
174 callbackEnv->DeleteLocalRef(val);
175
Jaikumar Ganeshff681482012-02-21 12:06:55 -0800176 if (get_properties(num_properties, properties, &types, &props) < 0) {
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800177 if (props) callbackEnv->DeleteLocalRef(props);
178 if (types) callbackEnv->DeleteLocalRef(types);
179 return;
180 }
181
Srinu Jella5f203262014-08-05 18:48:18 +0530182 if (sJniCallbacksObj) {
183 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_adapterPropertyChangedCallback, types,
184 props);
185 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800186 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
Matthew Xie6c91bc02012-02-16 18:47:53 -0800187 callbackEnv->DeleteLocalRef(props);
188 callbackEnv->DeleteLocalRef(types);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800189 return;
190
191}
192
193static void remote_device_properties_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
194 int num_properties, bt_property_t *properties) {
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800195 if (!checkCallbackThread()) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700196 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800197 return;
198 }
199
Matthew Xiec55a9832012-04-07 03:44:13 -0700200 ALOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800201
202 if (status != BT_STATUS_SUCCESS) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700203 ALOGE("%s: Status %d is incorrect", __FUNCTION__, status);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800204 return;
205 }
206
Matthew Xie6c91bc02012-02-16 18:47:53 -0800207 callbackEnv->PushLocalFrame(ADDITIONAL_NREFS);
208
209 jobjectArray props;
210 jbyteArray addr;
211 jintArray types;
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700212 jbyteArray val;
213 jclass mclass;
214
215 val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
216 if (val == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700217 ALOGE("%s: Error allocating byteArray", __FUNCTION__);
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700218 return;
219 }
220
221 mclass = callbackEnv->GetObjectClass(val);
222
223 /* Initialize the jobjectArray and jintArray here itself and send the
224 initialized array pointers alone to get_properties */
225
226 props = callbackEnv->NewObjectArray(num_properties, mclass,
227 NULL);
228 if (props == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700229 ALOGE("%s: Error allocating object Array for properties", __FUNCTION__);
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700230 return;
231 }
232
233 types = (jintArray)callbackEnv->NewIntArray(num_properties);
234
235 if (types == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700236 ALOGE("%s: Error allocating int Array for values", __FUNCTION__);
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700237 return;
238 }
239 // Delete the reference to val and mclass
240 callbackEnv->DeleteLocalRef(mclass);
241 callbackEnv->DeleteLocalRef(val);
Matthew Xie6c91bc02012-02-16 18:47:53 -0800242
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800243 addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
244 if (addr == NULL) goto Fail;
245 if (addr) callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
246
Jaikumar Ganeshff681482012-02-21 12:06:55 -0800247 if (get_properties(num_properties, properties, &types, &props) < 0) {
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800248 if (props) callbackEnv->DeleteLocalRef(props);
249 if (types) callbackEnv->DeleteLocalRef(types);
Matthew Xie6c91bc02012-02-16 18:47:53 -0800250 callbackEnv->PopLocalFrame(NULL);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800251 return;
252 }
253
Srinu Jella5f203262014-08-05 18:48:18 +0530254 if (sJniCallbacksObj) {
255 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_devicePropertyChangedCallback, addr,
256 types, props);
257 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800258 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
Matthew Xie6c91bc02012-02-16 18:47:53 -0800259 callbackEnv->DeleteLocalRef(props);
260 callbackEnv->DeleteLocalRef(types);
Syed Ibrahim Medb14a42012-04-11 11:16:16 -0700261 callbackEnv->DeleteLocalRef(addr);
Matthew Xie6c91bc02012-02-16 18:47:53 -0800262 callbackEnv->PopLocalFrame(NULL);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800263 return;
264
265Fail:
Matthew Xiec55a9832012-04-07 03:44:13 -0700266 ALOGE("Error while allocation byte array in %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800267}
268
269
270static void device_found_callback(int num_properties, bt_property_t *properties) {
271 jbyteArray addr = NULL;
272 int addr_index;
273
274 for (int i = 0; i < num_properties; i++) {
275 if (properties[i].type == BT_PROPERTY_BDADDR) {
276 addr = callbackEnv->NewByteArray(properties[i].len);
277 if (addr) {
278 callbackEnv->SetByteArrayRegion(addr, 0, properties[i].len,
279 (jbyte*)properties[i].val);
280 addr_index = i;
281 } else {
Matthew Xiec55a9832012-04-07 03:44:13 -0700282 ALOGE("Address is NULL (unable to allocate) in %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800283 return;
284 }
285 }
286 }
287 if (addr == NULL) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700288 ALOGE("Address is NULL in %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800289 return;
290 }
291
Matthew Xiec55a9832012-04-07 03:44:13 -0700292 ALOGV("%s: Properties: %d, Address: %s", __FUNCTION__, num_properties,
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800293 (const char *)properties[addr_index].val);
294
295 remote_device_properties_callback(BT_STATUS_SUCCESS, (bt_bdaddr_t *)properties[addr_index].val,
296 num_properties, properties);
297
Srinu Jella5f203262014-08-05 18:48:18 +0530298 if (sJniCallbacksObj) {
299 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, addr);
300 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800301 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
Matthew Xie6c91bc02012-02-16 18:47:53 -0800302 callbackEnv->DeleteLocalRef(addr);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800303}
304
305static void bond_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
306 bt_bond_state_t state) {
307 jbyteArray addr;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800308 if (!checkCallbackThread()) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700309 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800310 return;
311 }
312 if (!bd_addr) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700313 ALOGE("Address is null in %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800314 return;
315 }
316 addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
317 if (addr == NULL) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700318 ALOGE("Address allocation failed in %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800319 return;
320 }
321 callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
322
Srinu Jella5f203262014-08-05 18:48:18 +0530323 if (sJniCallbacksObj) {
324 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status,
325 addr, (jint)state);
326 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800327 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
Matthew Xie6c91bc02012-02-16 18:47:53 -0800328 callbackEnv->DeleteLocalRef(addr);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800329}
330
Kausik Sinnaswamy01a8cf92012-04-04 12:09:10 +0530331static void acl_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
332 bt_acl_state_t state)
333{
334 jbyteArray addr;
Kausik Sinnaswamy01a8cf92012-04-04 12:09:10 +0530335 if (!checkCallbackThread()) {
Matthew Xiee469f162012-06-05 23:57:59 -0700336 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
Kausik Sinnaswamy01a8cf92012-04-04 12:09:10 +0530337 return;
338 }
339 if (!bd_addr) {
Matthew Xiee469f162012-06-05 23:57:59 -0700340 ALOGE("Address is null in %s", __FUNCTION__);
Kausik Sinnaswamy01a8cf92012-04-04 12:09:10 +0530341 return;
342 }
343 addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
344 if (addr == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700345 ALOGE("Address allocation failed in %s", __FUNCTION__);
Kausik Sinnaswamy01a8cf92012-04-04 12:09:10 +0530346 return;
347 }
348 callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
349
Srinu Jella5f203262014-08-05 18:48:18 +0530350 if (sJniCallbacksObj) {
351 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, (jint) status,
352 addr, (jint)state);
353 }
Kausik Sinnaswamy01a8cf92012-04-04 12:09:10 +0530354 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
355 callbackEnv->DeleteLocalRef(addr);
356}
357
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800358static void discovery_state_changed_callback(bt_discovery_state_t state) {
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800359 if (!checkCallbackThread()) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700360 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800361 return;
362 }
363
Matthew Xiec55a9832012-04-07 03:44:13 -0700364 ALOGV("%s: DiscoveryState:%d ", __FUNCTION__, state);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800365
Srinu Jella5f203262014-08-05 18:48:18 +0530366 if (sJniCallbacksObj) {
367 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_discoveryStateChangeCallback,
368 (jint)state);
369 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800370 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
371}
372
Casper Bonde244e9c62015-05-08 14:21:12 +0200373static void pin_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod,
374 bool min_16_digits) {
Ajay Panicker21f921a2016-03-01 14:14:56 -0800375 jbyteArray addr = NULL;
376 jbyteArray devname = NULL;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800377 if (!checkCallbackThread()) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700378 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800379 return;
380 }
381 if (!bd_addr) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700382 ALOGE("Address is null in %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800383 return;
384 }
385
386 addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
387 if (addr == NULL) goto Fail;
Matthew Xie61c41002012-02-28 17:52:36 -0800388 callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800389
390 devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
391 if (devname == NULL) goto Fail;
392
393 callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
394
Srinu Jella5f203262014-08-05 18:48:18 +0530395 if (sJniCallbacksObj) {
Casper Bonde244e9c62015-05-08 14:21:12 +0200396 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, addr, devname, cod,
397 min_16_digits);
Srinu Jella5f203262014-08-05 18:48:18 +0530398 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800399
400 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
Matthew Xie6c91bc02012-02-16 18:47:53 -0800401 callbackEnv->DeleteLocalRef(addr);
402 callbackEnv->DeleteLocalRef(devname);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800403 return;
404
405Fail:
406 if (addr) callbackEnv->DeleteLocalRef(addr);
407 if (devname) callbackEnv->DeleteLocalRef(devname);
Matthew Xiec55a9832012-04-07 03:44:13 -0700408 ALOGE("Error while allocating in: %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800409}
410
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800411static void ssp_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod,
412 bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
Ajay Panicker21f921a2016-03-01 14:14:56 -0800413 jbyteArray addr = NULL;
414 jbyteArray devname = NULL;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800415 if (!checkCallbackThread()) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700416 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800417 return;
418 }
419 if (!bd_addr) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700420 ALOGE("Address is null in %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800421 return;
422 }
423
424 addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
425 if (addr == NULL) goto Fail;
426 callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
427
428 devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
429 if (devname == NULL) goto Fail;
430 callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
431
Srinu Jella5f203262014-08-05 18:48:18 +0530432 if (sJniCallbacksObj) {
433 callbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, addr, devname, cod,
434 (jint) pairing_variant, pass_key);
435 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800436
437 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
Matthew Xie6c91bc02012-02-16 18:47:53 -0800438 callbackEnv->DeleteLocalRef(addr);
439 callbackEnv->DeleteLocalRef(devname);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800440 return;
441
442Fail:
443 if (addr) callbackEnv->DeleteLocalRef(addr);
444 if (devname) callbackEnv->DeleteLocalRef(devname);
445
Matthew Xiec55a9832012-04-07 03:44:13 -0700446 ALOGE("Error while allocating in: %s", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800447}
448
449static void callback_thread_event(bt_cb_thread_evt event) {
450 JavaVM* vm = AndroidRuntime::getJavaVM();
451 if (event == ASSOCIATE_JVM) {
452 JavaVMAttachArgs args;
453 char name[] = "BT Service Callback Thread";
Brian Carlstromb241cda2013-03-11 23:47:55 -0700454 args.version = JNI_VERSION_1_6;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800455 args.name = name;
456 args.group = NULL;
457 vm->AttachCurrentThread(&callbackEnv, &args);
Matthew Xiec55a9832012-04-07 03:44:13 -0700458 ALOGV("Callback thread attached: %p", callbackEnv);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800459 } else if (event == DISASSOCIATE_JVM) {
460 if (!checkCallbackThread()) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700461 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800462 return;
463 }
464 vm->DetachCurrentThread();
465 }
466}
467
Ganesh Ganapathi Batta03b83862013-02-05 15:38:27 -0800468static void dut_mode_recv_callback (uint16_t opcode, uint8_t *buf, uint8_t len) {
469
470}
471static void le_test_mode_recv_callback (bt_status_t status, uint16_t packet_count) {
472
473 ALOGV("%s: status:%d packet_count:%d ", __FUNCTION__, status, packet_count);
474}
Prerepa Viswanadhamf6eff2b2014-07-18 21:30:20 -0700475
Adam Lesinskicbe58102015-12-03 16:17:17 -0800476static void energy_info_recv_callback(bt_activity_energy_info *p_energy_info,
477 bt_uid_traffic_t* uid_data)
Prerepa Viswanadhamf6eff2b2014-07-18 21:30:20 -0700478{
479 if (!checkCallbackThread()) {
480 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
481 return;
482 }
483
Adam Lesinskicbe58102015-12-03 16:17:17 -0800484 jsize len = 0;
485 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
486 len++;
487 }
488
489 jobjectArray array = callbackEnv->NewObjectArray(len, android_bluetooth_UidTraffic.clazz, NULL);
490 jsize i = 0;
491 for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) {
492 jobject uidObj = callbackEnv->NewObject(android_bluetooth_UidTraffic.clazz,
493 android_bluetooth_UidTraffic.constructor,
494 (jint) data->app_uid, (jlong) data->rx_bytes,
495 (jlong) data->tx_bytes);
496 callbackEnv->SetObjectArrayElement(array, i++, uidObj);
497 callbackEnv->DeleteLocalRef(uidObj);
498 }
499
Srinu Jella5f203262014-08-05 18:48:18 +0530500 if (sJniAdapterServiceObj) {
501 callbackEnv->CallVoidMethod(sJniAdapterServiceObj, method_energyInfo, p_energy_info->status,
502 p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time,
503 p_energy_info->idle_time, p_energy_info->energy_used, array);
504 } else {
505 ALOGE("JNI ERROR : JNI reference already cleaned : energy_info_recv_callback", __FUNCTION__);
506 }
Prerepa Viswanadhamf6eff2b2014-07-18 21:30:20 -0700507
508 checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
Adam Lesinskicbe58102015-12-03 16:17:17 -0800509 callbackEnv->DeleteLocalRef(array);
Prerepa Viswanadhamf6eff2b2014-07-18 21:30:20 -0700510}
511
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700512static bt_callbacks_t sBluetoothCallbacks = {
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800513 sizeof(sBluetoothCallbacks),
514 adapter_state_change_callback,
515 adapter_properties_callback,
516 remote_device_properties_callback,
517 device_found_callback,
518 discovery_state_changed_callback,
519 pin_request_callback,
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800520 ssp_request_callback,
521 bond_state_changed_callback,
Kausik Sinnaswamy01a8cf92012-04-04 12:09:10 +0530522 acl_state_changed_callback,
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800523 callback_thread_event,
Ganesh Ganapathi Batta03b83862013-02-05 15:38:27 -0800524 dut_mode_recv_callback,
Prerepa Viswanadhamf6eff2b2014-07-18 21:30:20 -0700525 le_test_mode_recv_callback,
Srinu Jellab6ee9442015-04-06 16:59:14 +0530526 energy_info_recv_callback,
527 NULL
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800528};
529
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700530// The callback to call when the wake alarm fires.
531static alarm_cb sAlarmCallback;
532
533// The data to pass to the wake alarm callback.
534static void *sAlarmCallbackData;
535
Sharvil Nanavatibeccdc62014-07-03 13:20:06 -0700536static JavaVMAttachArgs sAttachArgs = {
537 .version = JNI_VERSION_1_6,
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700538 .name = "bluetooth wake",
Sharvil Nanavatibeccdc62014-07-03 13:20:06 -0700539 .group = NULL
540};
541
kschulz5a60e472015-03-17 11:47:46 +0100542static bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake,
543 alarm_cb cb, void *data) {
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700544 JNIEnv *env;
545 JavaVM *vm = AndroidRuntime::getJavaVM();
546 jint status = vm->GetEnv((void **)&env, JNI_VERSION_1_6);
Srinu Jella5f203262014-08-05 18:48:18 +0530547 jboolean ret = JNI_FALSE;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700548
549 if (status != JNI_OK && status != JNI_EDETACHED) {
550 ALOGE("%s unable to get environment for JNI call", __func__);
551 return false;
552 }
553
Sharvil Nanavatibeccdc62014-07-03 13:20:06 -0700554 if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, &sAttachArgs) != 0) {
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700555 ALOGE("%s unable to attach thread to VM", __func__);
556 return false;
557 }
558
Andre Eisenbach717be4e2014-08-28 18:36:28 -0700559 sAlarmCallback = cb;
560 sAlarmCallbackData = data;
561
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700562 jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE;
Srinu Jella5f203262014-08-05 18:48:18 +0530563 if (sJniAdapterServiceObj) {
564 ret = env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm,
kschulz5a60e472015-03-17 11:47:46 +0100565 (jlong)delay_millis, jshould_wake);
Srinu Jella5f203262014-08-05 18:48:18 +0530566 } else {
567 ALOGE("JNI ERROR : JNI reference already cleaned : set_wake_alarm_callout", __FUNCTION__);
568 }
569
Andre Eisenbach717be4e2014-08-28 18:36:28 -0700570 if (!ret) {
Srinu Jella5f203262014-08-05 18:48:18 +0530571 ALOGE("%s setWakeAlarm failed:ret= %d ", __func__, ret);
Andre Eisenbach717be4e2014-08-28 18:36:28 -0700572 sAlarmCallback = NULL;
573 sAlarmCallbackData = NULL;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700574 }
575
576 if (status == JNI_EDETACHED) {
577 vm->DetachCurrentThread();
578 }
579
580 return !!ret;
581}
582
583static int acquire_wake_lock_callout(const char *lock_name) {
584 JNIEnv *env;
585 JavaVM *vm = AndroidRuntime::getJavaVM();
586 jint status = vm->GetEnv((void **)&env, JNI_VERSION_1_6);
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700587 if (status != JNI_OK && status != JNI_EDETACHED) {
588 ALOGE("%s unable to get environment for JNI call", __func__);
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700589 return BT_STATUS_JNI_ENVIRONMENT_ERROR;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700590 }
Sharvil Nanavatibeccdc62014-07-03 13:20:06 -0700591 if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, &sAttachArgs) != 0) {
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700592 ALOGE("%s unable to attach thread to VM", __func__);
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700593 return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700594 }
595
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700596 jint ret = BT_STATUS_SUCCESS;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700597 jstring lock_name_jni = env->NewStringUTF(lock_name);
598 if (lock_name_jni) {
Srinu Jella5f203262014-08-05 18:48:18 +0530599 if (sJniAdapterServiceObj) {
600 bool acquired = env->CallBooleanMethod(sJniAdapterServiceObj,
601 method_acquireWakeLock, lock_name_jni);
602 if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR;
603 env->DeleteLocalRef(lock_name_jni);
604 } else {
605 ALOGE("JNI ERROR : JNI reference already cleaned : acquire_wake_lock_callout", __FUNCTION__);
606 }
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700607 } else {
608 ALOGE("%s unable to allocate string: %s", __func__, lock_name);
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700609 ret = BT_STATUS_NOMEM;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700610 }
611
612 if (status == JNI_EDETACHED) {
613 vm->DetachCurrentThread();
614 }
615
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700616 return ret;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700617}
618
619static int release_wake_lock_callout(const char *lock_name) {
620 JNIEnv *env;
621 JavaVM *vm = AndroidRuntime::getJavaVM();
622 jint status = vm->GetEnv((void **)&env, JNI_VERSION_1_6);
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700623 if (status != JNI_OK && status != JNI_EDETACHED) {
624 ALOGE("%s unable to get environment for JNI call", __func__);
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700625 return BT_STATUS_JNI_ENVIRONMENT_ERROR;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700626 }
Sharvil Nanavatibeccdc62014-07-03 13:20:06 -0700627 if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, &sAttachArgs) != 0) {
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700628 ALOGE("%s unable to attach thread to VM", __func__);
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700629 return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700630 }
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700631
632 jint ret = BT_STATUS_SUCCESS;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700633 jstring lock_name_jni = env->NewStringUTF(lock_name);
634 if (lock_name_jni) {
Srinu Jella5f203262014-08-05 18:48:18 +0530635 if (sJniAdapterServiceObj) {
636 bool released = env->CallBooleanMethod(sJniAdapterServiceObj,
637 method_releaseWakeLock, lock_name_jni);
638 if (!released) ret = BT_STATUS_WAKELOCK_ERROR;
639 env->DeleteLocalRef(lock_name_jni);
640 } else {
641 ALOGE("JNI ERROR : JNI reference already cleaned : release_wake_lock_callout", __FUNCTION__);
642 }
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700643 } else {
644 ALOGE("%s unable to allocate string: %s", __func__, lock_name);
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700645 ret = BT_STATUS_NOMEM;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700646 }
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700647
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700648 if (status == JNI_EDETACHED) {
649 vm->DetachCurrentThread();
650 }
Andre Eisenbach00a465e2016-03-17 16:49:59 -0700651
652 return ret;
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700653}
654
655// Called by Java code when alarm is fired. A wake lock is held by the caller
656// over the duration of this callback.
657static void alarmFiredNative(JNIEnv *env, jobject obj) {
Andre Eisenbach717be4e2014-08-28 18:36:28 -0700658 if (sAlarmCallback) {
659 sAlarmCallback(sAlarmCallbackData);
660 } else {
661 ALOGE("%s() - Alarm fired with callback not set!", __FUNCTION__);
662 }
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700663}
664
665static bt_os_callouts_t sBluetoothOsCallouts = {
666 sizeof(sBluetoothOsCallouts),
667 set_wake_alarm_callout,
668 acquire_wake_lock_callout,
669 release_wake_lock_callout,
670};
671
Casper Bondebbb41102015-04-09 09:20:50 +0200672
Hemant Gupta2c0df052013-08-16 15:01:59 +0530673
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800674static void classInitNative(JNIEnv* env, jclass clazz) {
675 int err;
676 hw_module_t* module;
677
Adam Lesinskicbe58102015-12-03 16:17:17 -0800678
679 jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic");
680 android_bluetooth_UidTraffic.constructor = env->GetMethodID(jniUidTrafficClass,
681 "<init>", "(IJJ)V");
682
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800683 jclass jniCallbackClass =
684 env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
685 sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks",
686 "Lcom/android/bluetooth/btservice/JniCallbacks;");
687
688 method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
689
690 method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass,
691 "adapterPropertyChangedCallback",
692 "([I[[B)V");
693 method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass,
694 "discoveryStateChangeCallback", "(I)V");
695
696 method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass,
697 "devicePropertyChangedCallback",
698 "([B[I[[B)V");
699 method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
700 method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback",
Casper Bonde244e9c62015-05-08 14:21:12 +0200701 "([B[BIZ)V");
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800702 method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback",
703 "([B[BIII)V");
704
705 method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass,
706 "bondStateChangeCallback", "(I[BI)V");
707
Kausik Sinnaswamy01a8cf92012-04-04 12:09:10 +0530708 method_aclStateChangeCallback = env->GetMethodID(jniCallbackClass,
709 "aclStateChangeCallback", "(I[BI)V");
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700710
711 method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
712 method_acquireWakeLock = env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
713 method_releaseWakeLock = env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");
Adam Lesinskicbe58102015-12-03 16:17:17 -0800714 method_energyInfo = env->GetMethodID(clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V");
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700715
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800716 char value[PROPERTY_VALUE_MAX];
717 property_get("bluetooth.mock_stack", value, "");
718
719 const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
720
721 err = hw_get_module(id, (hw_module_t const**)&module);
722
723 if (err == 0) {
724 hw_device_t* abstraction;
725 err = module->methods->open(module, id, &abstraction);
726 if (err == 0) {
727 bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
728 sBluetoothInterface = btStack->get_bluetooth_interface();
729 } else {
Matthew Xiec55a9832012-04-07 03:44:13 -0700730 ALOGE("Error while opening Bluetooth library");
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800731 }
732 } else {
Matthew Xiec55a9832012-04-07 03:44:13 -0700733 ALOGE("No Bluetooth Library found");
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800734 }
735}
736
737static bool initNative(JNIEnv* env, jobject obj) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700738 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800739
Adam Lesinskicbe58102015-12-03 16:17:17 -0800740 android_bluetooth_UidTraffic.clazz = (jclass) env->NewGlobalRef(
741 env->FindClass("android/bluetooth/UidTraffic"));
742
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700743 sJniAdapterServiceObj = env->NewGlobalRef(obj);
juncaoa603a932016-01-13 20:05:25 +0800744 if (sJniCallbacksField) {
745 sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
746 } else {
747 ALOGE("Error: sJniCallbacksField is null\n");
748 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800749
750 if (sBluetoothInterface) {
751 int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
Srinu Jella5f203262014-08-05 18:48:18 +0530752 if (ret != BT_STATUS_SUCCESS && ret != BT_STATUS_DONE) {
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700753 ALOGE("Error while setting the callbacks: %d\n", ret);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800754 sBluetoothInterface = NULL;
755 return JNI_FALSE;
756 }
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -0700757 ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
758 if (ret != BT_STATUS_SUCCESS) {
759 ALOGE("Error while setting Bluetooth callouts: %d\n", ret);
760 sBluetoothInterface->cleanup();
761 sBluetoothInterface = NULL;
762 return JNI_FALSE;
763 }
764
Matthew Xiecc80b222012-03-13 17:24:54 -0700765 if ( (sBluetoothSocketInterface = (btsock_interface_t *)
766 sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700767 ALOGE("Error getting socket interface");
Matthew Xiecc80b222012-03-13 17:24:54 -0700768 }
Hemant Gupta2c0df052013-08-16 15:01:59 +0530769
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800770 return JNI_TRUE;
771 }
772 return JNI_FALSE;
773}
774
775static bool cleanupNative(JNIEnv *env, jobject obj) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700776 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800777
778 jboolean result = JNI_FALSE;
779 if (!sBluetoothInterface) return result;
780
781 sBluetoothInterface->cleanup();
Matthew Xiee469f162012-06-05 23:57:59 -0700782 ALOGI("%s: return from cleanup",__FUNCTION__);
fredc6654f5c2012-04-12 00:18:52 -0700783
Luke Zhange76ce1f2016-01-15 13:30:48 -0800784 if (sJniCallbacksObj) {
785 env->DeleteGlobalRef(sJniCallbacksObj);
786 sJniCallbacksObj = NULL;
787 }
788 if (sJniAdapterServiceObj) {
789 env->DeleteGlobalRef(sJniAdapterServiceObj);
790 sJniAdapterServiceObj = NULL;
791 }
792 if (android_bluetooth_UidTraffic.clazz) {
Srinu Jella5f203262014-08-05 18:48:18 +0530793 env->DeleteGlobalRef(android_bluetooth_UidTraffic.clazz);
794 android_bluetooth_UidTraffic.clazz = NULL;
Luke Zhange76ce1f2016-01-15 13:30:48 -0800795 }
796
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800797 return JNI_TRUE;
798}
799
Ajay Panicker35584022016-03-17 17:12:08 -0700800static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700801 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800802
803 jboolean result = JNI_FALSE;
804 if (!sBluetoothInterface) return result;
Ajay Panicker35584022016-03-17 17:12:08 -0700805 int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0);
Matthew Xie8812b402014-06-05 07:23:34 -0700806 result = (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800807 return result;
808}
809
810static jboolean disableNative(JNIEnv* env, jobject obj) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700811 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800812
813 jboolean result = JNI_FALSE;
814 if (!sBluetoothInterface) return result;
815
816 int ret = sBluetoothInterface->disable();
YK Jeffrey Chaoad9fff22013-04-24 11:55:23 -0700817 /* Retrun JNI_FALSE only when BTIF explicitly reports
818 BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY
819 case which indicates that stack had not been enabled.
820 */
821 result = (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800822 return result;
823}
824
825static jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700826 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800827
828 jboolean result = JNI_FALSE;
829 if (!sBluetoothInterface) return result;
830
831 int ret = sBluetoothInterface->start_discovery();
832 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
833 return result;
834}
835
836static jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700837 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800838
839 jboolean result = JNI_FALSE;
840 if (!sBluetoothInterface) return result;
841
842 int ret = sBluetoothInterface->cancel_discovery();
843 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
844 return result;
845}
846
Andre Eisenbachdb681f32014-08-04 17:51:10 -0700847static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, jint transport) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700848 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800849
850 jbyte *addr;
851 jboolean result = JNI_FALSE;
852
853 if (!sBluetoothInterface) return result;
854
855 addr = env->GetByteArrayElements(address, NULL);
856 if (addr == NULL) {
857 jniThrowIOException(env, EINVAL);
858 return result;
859 }
860
Andre Eisenbachdb681f32014-08-04 17:51:10 -0700861 int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr, transport);
Brian Carlstromb241cda2013-03-11 23:47:55 -0700862 env->ReleaseByteArrayElements(address, addr, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800863 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
864
865 return result;
866}
867
Ajay Panicker21f921a2016-03-01 14:14:56 -0800868static jbyteArray callByteArrayGetter(JNIEnv* env, jobject object,
869 const char* className,
870 const char* methodName) {
Jakub Pawlowski914484b2015-12-29 13:21:30 -0800871 jclass myClass = env->FindClass(className);
872 jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B");
873 return (jbyteArray) env->CallObjectMethod(object, myMethod);
874}
875
876static jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj, jbyteArray address,
877 jint transport, jobject oobData) {
878 jbyte *addr;
879 jboolean result = JNI_FALSE;
880 bt_out_of_band_data_t oob_data;
881
882 memset(&oob_data, 0, sizeof(oob_data));
883
884 if (!sBluetoothInterface) return result;
885
886 addr = env->GetByteArrayElements(address, NULL);
887 if (addr == NULL) {
888 jniThrowIOException(env, EINVAL);
889 return result;
890 }
891
892 jbyte* smTKBytes = NULL;
893 jbyteArray smTK = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", "getSecurityManagerTk");
894 if (smTK != NULL) {
895 smTKBytes = env->GetByteArrayElements(smTK, NULL);
896 int len = env->GetArrayLength(smTK);
897 if (len != OOB_TK_SIZE) {
898 ALOGI("%s: wrong length of smTK, should be empty or %d bytes.", __FUNCTION__, OOB_TK_SIZE);
899 jniThrowIOException(env, EINVAL);
900 goto done;
901 }
902 memcpy(oob_data.sm_tk, smTKBytes, len);
903 }
904
905 if (sBluetoothInterface->create_bond_out_of_band((bt_bdaddr_t *)addr, transport, &oob_data)
906 == BT_STATUS_SUCCESS)
907 result = JNI_TRUE;
908
909done:
910 env->ReleaseByteArrayElements(address, addr, 0);
911
912 if (smTK != NULL)
913 env->ReleaseByteArrayElements(smTK, smTKBytes, 0);
914
915 return result;
916}
917
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800918static jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700919 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800920
921 jbyte *addr;
922 jboolean result;
923 if (!sBluetoothInterface) return JNI_FALSE;
924
925 addr = env->GetByteArrayElements(address, NULL);
926 if (addr == NULL) {
927 jniThrowIOException(env, EINVAL);
928 return JNI_FALSE;
929 }
930
931 int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t *)addr);
Brian Carlstromb241cda2013-03-11 23:47:55 -0700932 env->ReleaseByteArrayElements(address, addr, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800933 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
934
935 return result;
936}
937
938static jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700939 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800940
941 jbyte *addr;
942 jboolean result;
943 if (!sBluetoothInterface) return JNI_FALSE;
944
945 addr = env->GetByteArrayElements(address, NULL);
946 if (addr == NULL) {
947 jniThrowIOException(env, EINVAL);
948 return JNI_FALSE;
949 }
950
951 int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t *)addr);
Brian Carlstromb241cda2013-03-11 23:47:55 -0700952 env->ReleaseByteArrayElements(address, addr, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800953 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
954
955 return result;
956}
957
Andre Eisenbach1e3e1dd2015-02-05 20:07:50 -0800958static int getConnectionStateNative(JNIEnv* env, jobject obj, jbyteArray address) {
Andre Eisenbach3636f332014-06-18 12:20:59 -0700959 ALOGV("%s:",__FUNCTION__);
960 if (!sBluetoothInterface) return JNI_FALSE;
961
962 jbyte *addr = env->GetByteArrayElements(address, NULL);
963 if (addr == NULL) {
964 jniThrowIOException(env, EINVAL);
965 return JNI_FALSE;
966 }
967
968 int ret = sBluetoothInterface->get_connection_state((bt_bdaddr_t *)addr);
969 env->ReleaseByteArrayElements(address, addr, 0);
970
Andre Eisenbach1e3e1dd2015-02-05 20:07:50 -0800971 return ret;
Andre Eisenbach3636f332014-06-18 12:20:59 -0700972}
973
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800974static jboolean pinReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept,
975 jint len, jbyteArray pinArray) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700976 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800977
978 jbyte *addr, *pinPtr = NULL;
979 jboolean result = JNI_FALSE;
980 if (!sBluetoothInterface) return result;
981
982 addr = env->GetByteArrayElements(address, NULL);
983 if (addr == NULL) {
984 jniThrowIOException(env, EINVAL);
985 return result;
986 }
987
988 if (accept) {
989 pinPtr = env->GetByteArrayElements(pinArray, NULL);
990 if (pinPtr == NULL) {
991 jniThrowIOException(env, EINVAL);
Brian Carlstromb241cda2013-03-11 23:47:55 -0700992 env->ReleaseByteArrayElements(address, addr, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -0800993 return result;
994 }
995 }
996
997 int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len,
998 (bt_pin_code_t *) pinPtr);
Brian Carlstromb241cda2013-03-11 23:47:55 -0700999 env->ReleaseByteArrayElements(address, addr, 0);
1000 env->ReleaseByteArrayElements(pinArray, pinPtr, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001001 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1002
1003 return result;
1004}
1005
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001006static jboolean sspReplyNative(JNIEnv *env, jobject obj, jbyteArray address,
Jaikumar Ganesh581bb312012-03-06 12:51:10 -08001007 jint type, jboolean accept, jint passkey) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001008 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001009
1010 jbyte *addr;
1011 jboolean result = JNI_FALSE;
1012 if (!sBluetoothInterface) return result;
1013
1014 addr = env->GetByteArrayElements(address, NULL);
1015 if (addr == NULL) {
1016 jniThrowIOException(env, EINVAL);
1017 return result;
1018 }
1019
Jaikumar Ganesh581bb312012-03-06 12:51:10 -08001020 int ret = sBluetoothInterface->ssp_reply((bt_bdaddr_t *)addr,
1021 (bt_ssp_variant_t) type, accept, passkey);
Brian Carlstromb241cda2013-03-11 23:47:55 -07001022 env->ReleaseByteArrayElements(address, addr, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001023 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1024
1025 return result;
1026}
1027
1028static jboolean setAdapterPropertyNative(JNIEnv *env, jobject obj, jint type, jbyteArray value) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001029 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001030
1031 jbyte *val;
1032 jboolean result = JNI_FALSE;
1033 if (!sBluetoothInterface) return result;
1034
1035 val = env->GetByteArrayElements(value, NULL);
1036 bt_property_t prop;
1037 prop.type = (bt_property_type_t) type;
1038 prop.len = env->GetArrayLength(value);
1039 prop.val = val;
1040
1041 int ret = sBluetoothInterface->set_adapter_property(&prop);
Brian Carlstromb241cda2013-03-11 23:47:55 -07001042 env->ReleaseByteArrayElements(value, val, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001043 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1044
1045 return result;
1046}
1047
1048static jboolean getAdapterPropertiesNative(JNIEnv *env, jobject obj) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001049 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001050
1051 jboolean result = JNI_FALSE;
1052 if (!sBluetoothInterface) return result;
1053
1054 int ret = sBluetoothInterface->get_adapter_properties();
1055 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1056
1057 return result;
1058}
1059
1060static jboolean getAdapterPropertyNative(JNIEnv *env, jobject obj, jint type) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001061 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001062
1063 jboolean result = JNI_FALSE;
1064 if (!sBluetoothInterface) return result;
1065
1066 int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t) type);
1067 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1068
1069 return result;
1070}
1071
1072static jboolean getDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, jint type) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001073 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001074
1075 jbyte *addr = NULL;
1076 jboolean result = JNI_FALSE;
1077 if (!sBluetoothInterface) return result;
1078
1079 addr = env->GetByteArrayElements(address, NULL);
1080 if (addr == NULL) {
1081 jniThrowIOException(env, EINVAL);
1082 return result;
1083 }
1084
1085 int ret = sBluetoothInterface->get_remote_device_property((bt_bdaddr_t *)addr,
1086 (bt_property_type_t) type);
Brian Carlstromb241cda2013-03-11 23:47:55 -07001087 env->ReleaseByteArrayElements(address, addr, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001088 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1089
1090 return result;
1091}
1092
1093static jboolean setDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address,
1094 jint type, jbyteArray value) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001095 ALOGV("%s:",__FUNCTION__);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001096
1097 jbyte *val, *addr;
1098 jboolean result = JNI_FALSE;
1099 if (!sBluetoothInterface) return result;
1100
1101 val = env->GetByteArrayElements(value, NULL);
1102 if (val == NULL) {
1103 jniThrowIOException(env, EINVAL);
1104 return result;
1105 }
1106
1107 addr = env->GetByteArrayElements(address, NULL);
1108 if (addr == NULL) {
Brian Carlstromb241cda2013-03-11 23:47:55 -07001109 env->ReleaseByteArrayElements(value, val, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001110 jniThrowIOException(env, EINVAL);
1111 return result;
1112 }
1113
1114
1115 bt_property_t prop;
1116 prop.type = (bt_property_type_t) type;
1117 prop.len = env->GetArrayLength(value);
1118 prop.val = val;
1119
1120 int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t *)addr, &prop);
Brian Carlstromb241cda2013-03-11 23:47:55 -07001121 env->ReleaseByteArrayElements(value, val, 0);
1122 env->ReleaseByteArrayElements(address, addr, 0);
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001123
1124 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1125
1126 return result;
1127}
1128
Srinu Jellab6949d92013-10-21 11:12:24 +05301129static int getSocketOptNative(JNIEnv *env, jobject obj, jint type, jint channel, jint optionName,
1130 jbyteArray optionVal) {
1131 ALOGV("%s:",__FUNCTION__);
1132
1133 jbyte *option_val = NULL;
1134 int option_len;
1135 bt_status_t status;
1136
1137 if (!sBluetoothSocketInterface) return -1;
1138
1139 option_val = env->GetByteArrayElements(optionVal, NULL);
1140 if (option_val == NULL) {
1141 ALOGE("getSocketOptNative :jniThrowIOException ");
1142 jniThrowIOException(env, EINVAL);
1143 return -1;
1144 }
1145
1146 if ( (status = sBluetoothSocketInterface->get_sock_opt((btsock_type_t)type, channel,
1147 (btsock_option_type_t) optionName, (void *) option_val, &option_len)) !=
1148 BT_STATUS_SUCCESS) {
1149 ALOGE("get_sock_opt failed: %d", status);
1150 goto Fail;
1151 }
1152 env->ReleaseByteArrayElements(optionVal, option_val, 0);
1153
1154 return option_len;
1155Fail:
1156 env->ReleaseByteArrayElements(optionVal, option_val, 0);
1157 return -1;
1158}
1159
1160static int setSocketOptNative(JNIEnv *env, jobject obj, jint type, jint channel, jint optionName,
1161 jbyteArray optionVal, jint optionLen) {
1162 ALOGV("%s:",__FUNCTION__);
1163
1164 jbyte *option_val = NULL;
1165 bt_status_t status;
1166
1167 if (!sBluetoothSocketInterface) return -1;
1168
1169 option_val = env->GetByteArrayElements(optionVal, NULL);
1170 if (option_val == NULL) {
1171 ALOGE("setSocketOptNative:jniThrowIOException ");
1172 jniThrowIOException(env, EINVAL);
1173 return -1;
1174 }
1175
1176 if ( (status = sBluetoothSocketInterface->set_sock_opt((btsock_type_t)type, channel,
1177 (btsock_option_type_t) optionName, (void *) option_val, optionLen)) !=
1178 BT_STATUS_SUCCESS) {
1179 ALOGE("set_sock_opt failed: %d", status);
1180 goto Fail;
1181 }
1182 env->ReleaseByteArrayElements(optionVal, option_val, 0);
1183
1184 return 0;
1185Fail:
1186 env->ReleaseByteArrayElements(optionVal, option_val, 0);
1187 return -1;
1188}
1189
fredcc55ac7d2012-04-06 02:12:06 -07001190static jboolean getRemoteServicesNative(JNIEnv *env, jobject obj, jbyteArray address) {
Matthew Xiee469f162012-06-05 23:57:59 -07001191 ALOGV("%s:",__FUNCTION__);
fredcc55ac7d2012-04-06 02:12:06 -07001192
1193 jbyte *addr = NULL;
1194 jboolean result = JNI_FALSE;
1195 if (!sBluetoothInterface) return result;
1196
1197 addr = env->GetByteArrayElements(address, NULL);
1198 if (addr == NULL) {
1199 jniThrowIOException(env, EINVAL);
1200 return result;
1201 }
1202
1203 int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t *)addr);
Brian Carlstromb241cda2013-03-11 23:47:55 -07001204 env->ReleaseByteArrayElements(address, addr, 0);
fredcc55ac7d2012-04-06 02:12:06 -07001205 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1206 return result;
1207}
1208
Matthew Xiecc80b222012-03-13 17:24:54 -07001209static int connectSocketNative(JNIEnv *env, jobject object, jbyteArray address, jint type,
Adam Lesinskicbe58102015-12-03 16:17:17 -08001210 jbyteArray uuidObj, jint channel, jint flag, jint callingUid) {
Matthew Xiecc80b222012-03-13 17:24:54 -07001211 jbyte *addr = NULL, *uuid = NULL;
1212 int socket_fd;
1213 bt_status_t status;
1214
Brian Carlstromb241cda2013-03-11 23:47:55 -07001215 if (!sBluetoothSocketInterface) return -1;
Matthew Xiecc80b222012-03-13 17:24:54 -07001216
1217 addr = env->GetByteArrayElements(address, NULL);
1218 if (!addr) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001219 ALOGE("failed to get Bluetooth device address");
Matthew Xiecc80b222012-03-13 17:24:54 -07001220 goto Fail;
1221 }
1222
Casper Bondebbb41102015-04-09 09:20:50 +02001223 if(uuidObj != NULL) {
1224 uuid = env->GetByteArrayElements(uuidObj, NULL);
1225 if (!uuid) {
1226 ALOGE("failed to get uuid");
1227 goto Fail;
1228 }
Matthew Xiecc80b222012-03-13 17:24:54 -07001229 }
1230
1231 if ( (status = sBluetoothSocketInterface->connect((bt_bdaddr_t *) addr, (btsock_type_t) type,
Adam Lesinskicbe58102015-12-03 16:17:17 -08001232 (const uint8_t*) uuid, channel, &socket_fd, flag, callingUid))
1233 != BT_STATUS_SUCCESS) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001234 ALOGE("Socket connection failed: %d", status);
Matthew Xiecc80b222012-03-13 17:24:54 -07001235 goto Fail;
1236 }
1237
1238
1239 if (socket_fd < 0) {
Casper Bondebbb41102015-04-09 09:20:50 +02001240 ALOGE("Fail to create file descriptor on socket fd");
Matthew Xiecc80b222012-03-13 17:24:54 -07001241 goto Fail;
1242 }
1243 env->ReleaseByteArrayElements(address, addr, 0);
1244 env->ReleaseByteArrayElements(uuidObj, uuid, 0);
1245 return socket_fd;
1246
1247Fail:
1248 if (addr) env->ReleaseByteArrayElements(address, addr, 0);
1249 if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
1250
1251 return -1;
1252}
1253
1254static int createSocketChannelNative(JNIEnv *env, jobject object, jint type,
Casper Bonde244e9c62015-05-08 14:21:12 +02001255 jstring name_str, jbyteArray uuidObj,
Adam Lesinskicbe58102015-12-03 16:17:17 -08001256 jint channel, jint flag, jint callingUid) {
Casper Bondebbb41102015-04-09 09:20:50 +02001257 const char *service_name = NULL;
Matthew Xiecc80b222012-03-13 17:24:54 -07001258 jbyte *uuid = NULL;
1259 int socket_fd;
1260 bt_status_t status;
1261
Brian Carlstromb241cda2013-03-11 23:47:55 -07001262 if (!sBluetoothSocketInterface) return -1;
Matthew Xiecc80b222012-03-13 17:24:54 -07001263
Matthew Xie8799f442014-05-28 11:02:20 -07001264 ALOGV("%s: SOCK FLAG = %x", __FUNCTION__, flag);
1265
Casper Bondebbb41102015-04-09 09:20:50 +02001266 if(name_str != NULL) {
1267 service_name = env->GetStringUTFChars(name_str, NULL);
1268 }
Matthew Xiecc80b222012-03-13 17:24:54 -07001269
Casper Bondebbb41102015-04-09 09:20:50 +02001270 if(uuidObj != NULL) {
1271 uuid = env->GetByteArrayElements(uuidObj, NULL);
1272 if (!uuid) {
1273 ALOGE("failed to get uuid");
1274 goto Fail;
1275 }
Matthew Xiecc80b222012-03-13 17:24:54 -07001276 }
Matthew Xiecc80b222012-03-13 17:24:54 -07001277 if ( (status = sBluetoothSocketInterface->listen((btsock_type_t) type, service_name,
Adam Lesinskicbe58102015-12-03 16:17:17 -08001278 (const uint8_t*) uuid, channel, &socket_fd, flag, callingUid))
1279 != BT_STATUS_SUCCESS) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001280 ALOGE("Socket listen failed: %d", status);
Matthew Xiecc80b222012-03-13 17:24:54 -07001281 goto Fail;
1282 }
1283
1284 if (socket_fd < 0) {
Matthew Xiec55a9832012-04-07 03:44:13 -07001285 ALOGE("Fail to creat file descriptor on socket fd");
Matthew Xiecc80b222012-03-13 17:24:54 -07001286 goto Fail;
1287 }
1288 if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
1289 if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
1290 return socket_fd;
1291
1292Fail:
1293 if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
1294 if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
Matthew Xiecc80b222012-03-13 17:24:54 -07001295 return -1;
1296}
1297
Zhihai Xu9d80b502013-06-11 13:08:24 -07001298static jboolean configHciSnoopLogNative(JNIEnv* env, jobject obj, jboolean enable) {
1299 ALOGV("%s:",__FUNCTION__);
1300
1301 jboolean result = JNI_FALSE;
1302
1303 if (!sBluetoothInterface) return result;
1304
1305 int ret = sBluetoothInterface->config_hci_snoop_log(enable);
1306
1307 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1308
1309 return result;
1310}
1311
Prerepa Viswanadhamf6eff2b2014-07-18 21:30:20 -07001312static int readEnergyInfo()
1313{
1314 ALOGV("%s:",__FUNCTION__);
1315 jboolean result = JNI_FALSE;
1316 if (!sBluetoothInterface) return result;
1317 int ret = sBluetoothInterface->read_energy_info();
1318 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1319 return result;
1320}
1321
Marie Janssen407f11c2016-01-12 11:03:00 -08001322static void dumpNative(JNIEnv *env, jobject obj, jobject fdObj,
1323 jobjectArray argArray)
Andre Eisenbachf5f90872014-12-05 09:35:40 -08001324{
1325 ALOGV("%s()", __FUNCTION__);
1326 if (!sBluetoothInterface) return;
1327
1328 int fd = jniGetFDFromFileDescriptor(env, fdObj);
1329 if (fd < 0) return;
1330
Marie Janssen407f11c2016-01-12 11:03:00 -08001331 int numArgs = env->GetArrayLength(argArray);
1332
1333 jstring *argObjs = new jstring[numArgs];
Ajay Panickere1ad2a12016-02-08 15:12:49 -08001334 const char **args = nullptr;
1335 if (numArgs > 0)
1336 args = new const char*[numArgs];
Marie Janssen407f11c2016-01-12 11:03:00 -08001337
1338 for (int i = 0; i < numArgs; i++) {
1339 argObjs[i] = (jstring) env->GetObjectArrayElement(argArray, i);
1340 args[i] = env->GetStringUTFChars(argObjs[i], NULL);
1341 }
1342
1343 sBluetoothInterface->dump(fd, args);
1344
1345 for (int i = 0; i < numArgs; i++) {
1346 env->ReleaseStringUTFChars(argObjs[i], args[i]);
1347 }
1348
1349 delete[] args;
1350 delete[] argObjs;
Andre Eisenbachf5f90872014-12-05 09:35:40 -08001351}
1352
Ajay Panicker6eb32d52015-07-28 16:47:54 -07001353static jboolean factoryResetNative(JNIEnv *env, jobject obj) {
1354 ALOGV("%s:", __FUNCTION__);
1355 if (!sBluetoothInterface) return JNI_FALSE;
1356 int ret = sBluetoothInterface->config_clear();
1357 return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
1358}
1359
Andre Eisenbachdb32e0e2016-01-14 02:06:23 -08001360static void interopDatabaseClearNative(JNIEnv *env, jobject obj) {
1361 ALOGV("%s()", __FUNCTION__);
1362 if (!sBluetoothInterface) return;
1363 sBluetoothInterface->interop_database_clear();
1364}
1365
1366static void interopDatabaseAddNative(JNIEnv *env, jobject obj, int feature,
1367 jbyteArray address, int length) {
1368 ALOGV("%s()", __FUNCTION__);
1369 if (!sBluetoothInterface) return;
1370
1371 jbyte *addr = env->GetByteArrayElements(address, NULL);
1372 if (addr == NULL) {
1373 jniThrowIOException(env, EINVAL);
1374 return;
1375 }
1376
1377 sBluetoothInterface->interop_database_add(feature, (bt_bdaddr_t *)addr, length);
1378 env->ReleaseByteArrayElements(address, addr, 0);
1379}
1380
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001381static JNINativeMethod sMethods[] = {
Brian Carlstromb241cda2013-03-11 23:47:55 -07001382 /* name, signature, funcPtr */
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001383 {"classInitNative", "()V", (void *) classInitNative},
1384 {"initNative", "()Z", (void *) initNative},
1385 {"cleanupNative", "()V", (void*) cleanupNative},
Ajay Panicker35584022016-03-17 17:12:08 -07001386 {"enableNative", "(Z)Z", (void*) enableNative},
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001387 {"disableNative", "()Z", (void*) disableNative},
1388 {"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative},
1389 {"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative},
1390 {"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative},
1391 {"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative},
1392 {"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative},
1393 {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative},
1394 {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative},
Andre Eisenbachdb681f32014-08-04 17:51:10 -07001395 {"createBondNative", "([BI)Z", (void*) createBondNative},
Jakub Pawlowski914484b2015-12-29 13:21:30 -08001396 {"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z", (void*) createBondOutOfBandNative},
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001397 {"removeBondNative", "([B)Z", (void*) removeBondNative},
1398 {"cancelBondNative", "([B)Z", (void*) cancelBondNative},
Andre Eisenbach1e3e1dd2015-02-05 20:07:50 -08001399 {"getConnectionStateNative", "([B)I", (void*) getConnectionStateNative},
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001400 {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative},
Jaikumar Ganesh581bb312012-03-06 12:51:10 -08001401 {"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative},
fredcc55ac7d2012-04-06 02:12:06 -07001402 {"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative},
Adam Lesinskicbe58102015-12-03 16:17:17 -08001403 {"connectSocketNative", "([BI[BIII)I", (void*) connectSocketNative},
1404 {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I",
Zhihai Xu9d80b502013-06-11 13:08:24 -07001405 (void*) createSocketChannelNative},
Sharvil Nanavati1e9f8a12014-05-30 16:47:09 -07001406 {"configHciSnoopLogNative", "(Z)Z", (void*) configHciSnoopLogNative},
1407 {"alarmFiredNative", "()V", (void *) alarmFiredNative},
Prerepa Viswanadhamf6eff2b2014-07-18 21:30:20 -07001408 {"readEnergyInfo", "()I", (void*) readEnergyInfo},
Marie Janssen407f11c2016-01-12 11:03:00 -08001409 {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V", (void*) dumpNative},
Andre Eisenbachdb32e0e2016-01-14 02:06:23 -08001410 {"factoryResetNative", "()Z", (void*)factoryResetNative},
1411 {"interopDatabaseClearNative", "()V", (void*) interopDatabaseClearNative},
Srinu Jellab6949d92013-10-21 11:12:24 +05301412 {"interopDatabaseAddNative", "(I[BI)V", (void*) interopDatabaseAddNative},
1413 {"getSocketOptNative", "(III[B)I", (void*) getSocketOptNative},
1414 {"setSocketOptNative", "(III[BI)I", (void*) setSocketOptNative}
1415
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001416};
1417
1418int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env)
1419{
1420 return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService",
1421 sMethods, NELEM(sMethods));
1422}
1423
1424} /* namespace android */
1425
1426
1427/*
1428 * JNI Initialization
1429 */
1430jint JNI_OnLoad(JavaVM *jvm, void *reserved)
1431{
Brian Carlstromb241cda2013-03-11 23:47:55 -07001432 JNIEnv *e;
1433 int status;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001434
Brian Carlstromb241cda2013-03-11 23:47:55 -07001435 ALOGV("Bluetooth Adapter Service : loading JNI\n");
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001436
Brian Carlstromb241cda2013-03-11 23:47:55 -07001437 // Check JNI version
1438 if (jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) {
1439 ALOGE("JNI version mismatch error");
1440 return JNI_ERR;
1441 }
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001442
Brian Carlstromb241cda2013-03-11 23:47:55 -07001443 if ((status = android::register_com_android_bluetooth_btservice_AdapterService(e)) < 0) {
1444 ALOGE("jni adapter service registration failure, status: %d", status);
1445 return JNI_ERR;
1446 }
Matthew Xie6c91bc02012-02-16 18:47:53 -08001447
Brian Carlstromb241cda2013-03-11 23:47:55 -07001448 if ((status = android::register_com_android_bluetooth_hfp(e)) < 0) {
1449 ALOGE("jni hfp registration failure, status: %d", status);
1450 return JNI_ERR;
1451 }
Matthew Xie6c91bc02012-02-16 18:47:53 -08001452
Hemant Guptaaebc7262013-08-19 18:54:29 +05301453 if ((status = android::register_com_android_bluetooth_hfpclient(e)) < 0) {
1454 ALOGE("jni hfp client registration failure, status: %d", status);
1455 return JNI_ERR;
1456 }
1457
Brian Carlstromb241cda2013-03-11 23:47:55 -07001458 if ((status = android::register_com_android_bluetooth_a2dp(e)) < 0) {
Mike Lockwoodc030f082014-06-07 14:04:40 -07001459 ALOGE("jni a2dp source registration failure: %d", status);
1460 return JNI_ERR;
1461 }
1462
1463 if ((status = android::register_com_android_bluetooth_a2dp_sink(e)) < 0) {
1464 ALOGE("jni a2dp sink registration failure: %d", status);
Brian Carlstromb241cda2013-03-11 23:47:55 -07001465 return JNI_ERR;
1466 }
Matthew Xie6c91bc02012-02-16 18:47:53 -08001467
Zhihai Xuc1c259c2013-03-14 11:51:06 -07001468 if ((status = android::register_com_android_bluetooth_avrcp(e)) < 0) {
Mike Lockwood066ad9e2014-06-06 13:04:55 -07001469 ALOGE("jni avrcp target registration failure: %d", status);
1470 return JNI_ERR;
1471 }
1472
1473 if ((status = android::register_com_android_bluetooth_avrcp_controller(e)) < 0) {
1474 ALOGE("jni avrcp controller registration failure: %d", status);
Zhihai Xuc1c259c2013-03-14 11:51:06 -07001475 return JNI_ERR;
1476 }
1477
Brian Carlstromb241cda2013-03-11 23:47:55 -07001478 if ((status = android::register_com_android_bluetooth_hid(e)) < 0) {
1479 ALOGE("jni hid registration failure: %d", status);
1480 return JNI_ERR;
1481 }
Matthew Xie676cb1b2012-03-22 17:32:29 -07001482
Brian Carlstromb241cda2013-03-11 23:47:55 -07001483 if ((status = android::register_com_android_bluetooth_hdp(e)) < 0) {
1484 ALOGE("jni hdp registration failure: %d", status);
1485 return JNI_ERR;
1486 }
Matthew Xie35207a52012-03-21 23:11:40 -07001487
Brian Carlstromb241cda2013-03-11 23:47:55 -07001488 if ((status = android::register_com_android_bluetooth_pan(e)) < 0) {
1489 ALOGE("jni pan registration failure: %d", status);
1490 return JNI_ERR;
1491 }
fredc6654f5c2012-04-12 00:18:52 -07001492
Brian Carlstromb241cda2013-03-11 23:47:55 -07001493 if ((status = android::register_com_android_bluetooth_gatt(e)) < 0) {
1494 ALOGE("jni gatt registration failure: %d", status);
1495 return JNI_ERR;
1496 }
Casper Bondebbb41102015-04-09 09:20:50 +02001497
1498 if ((status = android::register_com_android_bluetooth_sdp(e)) < 0) {
1499 ALOGE("jni sdp registration failure: %d", status);
1500 return JNI_ERR;
1501 }
1502
Manu Viswanadhan2cf764c2016-06-03 20:00:48 +05301503 if ((status = android::register_com_android_bluetooth_btservice_vendor(e)) < 0) {
1504 ALOGE("jni vendor registration failure: %d", status);
1505 return JNI_ERR;
1506 }
1507
Brian Carlstromb241cda2013-03-11 23:47:55 -07001508 return JNI_VERSION_1_6;
Jaikumar Ganeshff4f17b2011-12-19 15:54:50 -08001509}