com_android_bluetooth_btservice_AdapterService.cpp revision 1e9f8a14e120e8786711abdd4a965236191c87ad
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"
186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "com_android_bluetooth.h"
19cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie#include "hardware/bt_sock.h"
20ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/Log.h"
21ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/misc.h"
22ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "cutils/properties.h"
23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "android_runtime/AndroidRuntime.h"
24dc8c533e030e6b8625da3dc75c8f768a3242fe16Ruben Brunk#include "android_runtime/Log.h"
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <string.h>
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <pthread.h>
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <sys/stat.h>
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <fcntl.h>
31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshnamespace android {
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define ADDITIONAL_NREFS 50
35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_stateChangeCallback;
36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_adapterPropertyChangedCallback;
37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_devicePropertyChangedCallback;
38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_deviceFoundCallback;
39ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_pinRequestCallback;
40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_sspRequestCallback;
41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_bondStateChangeCallback;
4201a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamystatic jmethodID method_aclStateChangeCallback;
43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_discoveryStateChangeCallback;
441e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_setWakeAlarm;
451e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_acquireWakeLock;
461e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_releaseWakeLock;
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic const bt_interface_t *sBluetoothInterface = NULL;
49cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic const btsock_interface_t *sBluetoothSocketInterface = NULL;
50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNIEnv *callbackEnv = NULL;
51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
521e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jobject sJniAdapterServiceObj;
53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jobject sJniCallbacksObj;
54ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jfieldID sJniCallbacksField;
55ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
56cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieconst bt_interface_t* getBluetoothInterface() {
586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return sBluetoothInterface;
596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew XieJNIEnv* getCallbackEnv() {
62b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    return callbackEnv;
636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xievoid checkAndClearExceptionFromCallback(JNIEnv* env,
66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                               const char* methodName) {
67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (env->ExceptionCheck()) {
68c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("An exception was thrown by callback '%s'.", methodName);
69ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE_EX(env);
70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->ExceptionClear();
71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
74ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool checkCallbackThread() {
75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    JNIEnv* env = AndroidRuntime::getJNIEnv();
76676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie    if (callbackEnv != env || callbackEnv == NULL) {
77c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Callback env check fail: env: %p, callback: %p", env, callbackEnv);
78676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie        return false;
79676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie    }
80ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return true;
81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
82ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_state_change_callback(bt_state_t status) {
84ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
85c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
88c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: Status is: %d", __FUNCTION__, status);
89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status);
91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
92ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
93ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
94ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
95ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic int get_properties(int num_properties, bt_property_t *properties, jintArray *types,
96ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                        jobjectArray *props) {
97edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jbyteArray propVal;
98ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    for (int i = 0; i < num_properties; i++) {
99b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        propVal = callbackEnv->NewByteArray(properties[i].len);
100b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        if (propVal == NULL) goto Fail;
101b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
102b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        callbackEnv->SetByteArrayRegion(propVal, 0, properties[i].len,
103b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom                                             (jbyte*)properties[i].val);
104b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        callbackEnv->SetObjectArrayElement(*props, i, propVal);
105b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        // Delete reference to propVal
106b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        callbackEnv->DeleteLocalRef(propVal);
107b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        callbackEnv->SetIntArrayRegion(*types, i, 1, (jint *)&properties[i].type);
108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
109ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return 0;
110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (propVal) callbackEnv->DeleteLocalRef(propVal);
112c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGE("Error while allocation of array in %s", __FUNCTION__);
113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return -1;
114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_properties_callback(bt_status_t status, int num_properties,
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_property_t *properties) {
118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jobjectArray props;
119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jintArray types;
120edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jbyteArray val;
121edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jclass mclass;
122edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
124c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
126ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
128c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (status != BT_STATUS_SUCCESS) {
131c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("%s: Status %d is incorrect", __FUNCTION__, status);
132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
135edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
136edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (val == NULL) {
137e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating byteArray", __FUNCTION__);
138edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
139edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
140edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
141edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    mclass = callbackEnv->GetObjectClass(val);
142edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
143edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    /* (BT) Initialize the jobjectArray and jintArray here itself and send the
144edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M     initialized array pointers alone to get_properties */
145edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
146edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    props = callbackEnv->NewObjectArray(num_properties, mclass,
147edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M                                             NULL);
148edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (props == NULL) {
149e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating object Array for properties", __FUNCTION__);
150edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
151edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
152edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
153edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    types = (jintArray)callbackEnv->NewIntArray(num_properties);
154edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
155edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (types == NULL) {
156e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating int Array for values", __FUNCTION__);
157edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
158edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
159edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    // Delete the reference to val and mclass
160edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(mclass);
161edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(val);
162edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
163ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh    if (get_properties(num_properties, properties, &types, &props) < 0) {
164ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (props) callbackEnv->DeleteLocalRef(props);
165ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (types) callbackEnv->DeleteLocalRef(types);
166ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
167ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
168ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
169ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_adapterPropertyChangedCallback, types,
170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                props);
171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
1726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(props);
1736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(types);
174ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
175ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
176ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
177ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
178ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void remote_device_properties_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
179ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                              int num_properties, bt_property_t *properties) {
180ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
181c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
183ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
185c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
186ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
187ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (status != BT_STATUS_SUCCESS) {
188c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("%s: Status %d is incorrect", __FUNCTION__, status);
189ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
191ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->PushLocalFrame(ADDITIONAL_NREFS);
1936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jobjectArray props;
1956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyteArray addr;
1966c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jintArray types;
197edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jbyteArray val;
198edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jclass mclass;
199edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
200edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
201edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (val == NULL) {
202e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating byteArray", __FUNCTION__);
203edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
204edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
205edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
206edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    mclass = callbackEnv->GetObjectClass(val);
207edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
208edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    /* Initialize the jobjectArray and jintArray here itself and send the
209edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M     initialized array pointers alone to get_properties */
210edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
211edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    props = callbackEnv->NewObjectArray(num_properties, mclass,
212edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M                                             NULL);
213edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (props == NULL) {
214e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating object Array for properties", __FUNCTION__);
215edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
216edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
217edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
218edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    types = (jintArray)callbackEnv->NewIntArray(num_properties);
219edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
220edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (types == NULL) {
221e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating int Array for values", __FUNCTION__);
222edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
223edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
224edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    // Delete the reference to val and mclass
225edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(mclass);
226edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(val);
2276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
228ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
229ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
230ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
232ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh    if (get_properties(num_properties, properties, &types, &props) < 0) {
233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (props) callbackEnv->DeleteLocalRef(props);
234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (types) callbackEnv->DeleteLocalRef(types);
2356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        callbackEnv->PopLocalFrame(NULL);
236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_devicePropertyChangedCallback, addr,
240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                types, props);
241ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
2426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(props);
2436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(types);
244edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(addr);
2456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->PopLocalFrame(NULL);
246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
249c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGE("Error while allocation byte array in %s", __FUNCTION__);
250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void device_found_callback(int num_properties, bt_property_t *properties) {
254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr = NULL;
255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int addr_index;
256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    for (int i = 0; i < num_properties; i++) {
258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (properties[i].type == BT_PROPERTY_BDADDR) {
259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            addr = callbackEnv->NewByteArray(properties[i].len);
260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (addr) {
261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                callbackEnv->SetByteArrayRegion(addr, 0, properties[i].len,
262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                (jbyte*)properties[i].val);
263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                addr_index = i;
264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
265c55a9837c004044051b71bb47182ace156691283Matthew Xie                ALOGE("Address is NULL (unable to allocate) in %s", __FUNCTION__);
266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return;
267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
271c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Address is NULL in %s", __FUNCTION__);
272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
273ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
275c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: Properties: %d, Address: %s", __FUNCTION__, num_properties,
276ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        (const char *)properties[addr_index].val);
277ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
278ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    remote_device_properties_callback(BT_STATUS_SUCCESS, (bt_bdaddr_t *)properties[addr_index].val,
279ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                      num_properties, properties);
280ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
281ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, addr);
282ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
2836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
284ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
285ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
286ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void bond_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
287ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_bond_state_t state) {
288ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr;
289ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int i;
290ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
291c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
292ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
293ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
294ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
295c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Address is null in %s", __FUNCTION__);
296ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
297ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
298ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
299ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
300c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Address allocation failed in %s", __FUNCTION__);
301ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
302ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
303ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
304ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
305ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status,
306ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                addr, (jint)state);
307ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
3086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
309ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
310ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
31101a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamystatic void acl_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
31201a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy                                       bt_acl_state_t state)
31301a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy{
31401a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    jbyteArray addr;
31501a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    int i;
31601a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    if (!checkCallbackThread()) {
317e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
31801a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy       return;
31901a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    }
32001a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    if (!bd_addr) {
321e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Address is null in %s", __FUNCTION__);
32201a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy        return;
32301a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    }
32401a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
32501a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    if (addr == NULL) {
326e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie       ALOGE("Address allocation failed in %s", __FUNCTION__);
32701a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy       return;
32801a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    }
32901a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
33001a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy
33101a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, (jint) status,
33201a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy                                addr, (jint)state);
33301a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
33401a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    callbackEnv->DeleteLocalRef(addr);
33501a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy}
33601a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy
337ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void discovery_state_changed_callback(bt_discovery_state_t state) {
338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr;
339ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
340c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
341ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
342ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
343ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
344c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: DiscoveryState:%d ", __FUNCTION__, state);
345ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
346ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_discoveryStateChangeCallback,
347ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                (jint)state);
348ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
349ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
350ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
351ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
352ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void pin_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod) {
353ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr, devname;
354ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
355c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
356ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
357ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
358ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
359c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Address is null in %s", __FUNCTION__);
360ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
361ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
362ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
363ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
364ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
36561c4100eb0606f8ba630f5c45d07a88d612fbc85Matthew Xie    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
366ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
367ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
368ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname == NULL) goto Fail;
369ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
370ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
371ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
372ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, addr, devname, cod);
373ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
374ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
3756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
3766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(devname);
377ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
378ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
379ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
380ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->DeleteLocalRef(addr);
381ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname) callbackEnv->DeleteLocalRef(devname);
382c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGE("Error while allocating in: %s", __FUNCTION__);
383ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
384ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
385ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void ssp_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod,
386ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                 bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
387ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr, devname;
388ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
389c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
390ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
391ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
392ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
393c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Address is null in %s", __FUNCTION__);
394ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
395ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
396ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
397ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
398ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
399ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
400ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
401ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
402ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname == NULL) goto Fail;
403ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
404ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
405ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, addr, devname, cod,
406ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                (jint) pairing_variant, pass_key);
407ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
408ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
4096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
4106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(devname);
411ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
412ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
413ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
414ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->DeleteLocalRef(addr);
415ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname) callbackEnv->DeleteLocalRef(devname);
416ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
417c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGE("Error while allocating in: %s", __FUNCTION__);
418ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
419ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
420ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void callback_thread_event(bt_cb_thread_evt event) {
421ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    JavaVM* vm = AndroidRuntime::getJavaVM();
422ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (event  == ASSOCIATE_JVM) {
423ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        JavaVMAttachArgs args;
424ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        char name[] = "BT Service Callback Thread";
425b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        args.version = JNI_VERSION_1_6;
426ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        args.name = name;
427ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        args.group = NULL;
428ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        vm->AttachCurrentThread(&callbackEnv, &args);
429c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGV("Callback thread attached: %p", callbackEnv);
430ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else if (event == DISASSOCIATE_JVM) {
431ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (!checkCallbackThread()) {
432c55a9837c004044051b71bb47182ace156691283Matthew Xie            ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
433ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return;
434ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
435ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        vm->DetachCurrentThread();
436ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
437ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
438ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
43903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battastatic void dut_mode_recv_callback (uint16_t opcode, uint8_t *buf, uint8_t len) {
44003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
44103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta}
44203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battastatic void le_test_mode_recv_callback (bt_status_t status, uint16_t packet_count) {
44303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
44403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    ALOGV("%s: status:%d packet_count:%d ", __FUNCTION__, status, packet_count);
44503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta}
4461e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic bt_callbacks_t sBluetoothCallbacks = {
447ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sizeof(sBluetoothCallbacks),
448ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    adapter_state_change_callback,
449ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    adapter_properties_callback,
450ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    remote_device_properties_callback,
451ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    device_found_callback,
452ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    discovery_state_changed_callback,
453ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    pin_request_callback,
454ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    ssp_request_callback,
455ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bond_state_changed_callback,
45601a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    acl_state_changed_callback,
457ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callback_thread_event,
45803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    dut_mode_recv_callback,
45903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
46003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    le_test_mode_recv_callback
461ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh};
462ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
4631e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// The callback to call when the wake alarm fires.
4641e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic alarm_cb sAlarmCallback;
4651e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4661e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// The data to pass to the wake alarm callback.
4671e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic void *sAlarmCallbackData;
4681e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4691e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data) {
4701e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    JNIEnv *env;
4711e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    JavaVM *vm = AndroidRuntime::getJavaVM();
4721e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    jint status = vm->GetEnv((void **)&env, JNI_VERSION_1_6);
4731e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4741e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (status != JNI_OK && status != JNI_EDETACHED) {
4751e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ALOGE("%s unable to get environment for JNI call", __func__);
4761e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        return false;
4771e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
4781e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4791e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, NULL) != 0) {
4801e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ALOGE("%s unable to attach thread to VM", __func__);
4811e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        return false;
4821e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
4831e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4841e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE;
4851e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    jboolean ret = env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm, (jlong)delay_millis, jshould_wake);
4861e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (ret) {
4871e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        sAlarmCallback = cb;
4881e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        sAlarmCallbackData = data;
4891e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
4901e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4911e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (status == JNI_EDETACHED) {
4921e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        vm->DetachCurrentThread();
4931e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
4941e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4951e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    return !!ret;
4961e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
4971e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
4981e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic int acquire_wake_lock_callout(const char *lock_name) {
4991e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    JNIEnv *env;
5001e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    JavaVM *vm = AndroidRuntime::getJavaVM();
5011e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    jint status = vm->GetEnv((void **)&env, JNI_VERSION_1_6);
5021e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5031e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (status != JNI_OK && status != JNI_EDETACHED) {
5041e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ALOGE("%s unable to get environment for JNI call", __func__);
5051e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        return BT_STATUS_FAIL;
5061e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
5071e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5081e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, NULL) != 0) {
5091e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ALOGE("%s unable to attach thread to VM", __func__);
5101e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        return BT_STATUS_FAIL;
5111e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
5121e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5131e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    jboolean ret = JNI_FALSE;
5141e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    jstring lock_name_jni = env->NewStringUTF(lock_name);
5151e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (lock_name_jni) {
5161e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ret = env->CallBooleanMethod(sJniAdapterServiceObj, method_acquireWakeLock, lock_name_jni);
5171e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        env->DeleteLocalRef(lock_name_jni);
5181e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    } else {
5191e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ALOGE("%s unable to allocate string: %s", __func__, lock_name);
5201e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
5211e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5221e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (status == JNI_EDETACHED) {
5231e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        vm->DetachCurrentThread();
5241e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
5251e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5261e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
5271e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5281e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5291e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic int release_wake_lock_callout(const char *lock_name) {
5301e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    JNIEnv *env;
5311e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    JavaVM *vm = AndroidRuntime::getJavaVM();
5321e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    jint status = vm->GetEnv((void **)&env, JNI_VERSION_1_6);
5331e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5341e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (status != JNI_OK && status != JNI_EDETACHED) {
5351e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ALOGE("%s unable to get environment for JNI call", __func__);
5361e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        return BT_STATUS_FAIL;
5371e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
5381e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5391e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (status == JNI_EDETACHED && vm->AttachCurrentThread(&env, NULL) != 0) {
5401e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ALOGE("%s unable to attach thread to VM", __func__);
5411e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        return BT_STATUS_FAIL;
5421e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
5431e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5441e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    jboolean ret = JNI_FALSE;
5451e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    jstring lock_name_jni = env->NewStringUTF(lock_name);
5461e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (lock_name_jni) {
5471e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ret = env->CallBooleanMethod(sJniAdapterServiceObj, method_releaseWakeLock, lock_name_jni);
5481e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        env->DeleteLocalRef(lock_name_jni);
5491e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    } else {
5501e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ALOGE("%s unable to allocate string: %s", __func__, lock_name);
5511e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
5521e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5531e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    if (status == JNI_EDETACHED) {
5541e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        vm->DetachCurrentThread();
5551e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    }
5561e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5571e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
5581e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5591e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5601e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// Called by Java code when alarm is fired. A wake lock is held by the caller
5611e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// over the duration of this callback.
5621e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic void alarmFiredNative(JNIEnv *env, jobject obj) {
5631e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    sAlarmCallback(sAlarmCallbackData);
5641e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}
5651e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
5661e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic bt_os_callouts_t sBluetoothOsCallouts = {
5671e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    sizeof(sBluetoothOsCallouts),
5681e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    set_wake_alarm_callout,
5691e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    acquire_wake_lock_callout,
5701e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    release_wake_lock_callout,
5711e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati};
5721e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
573ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void classInitNative(JNIEnv* env, jclass clazz) {
574ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int err;
575ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    hw_module_t* module;
576ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
577ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jclass jniCallbackClass =
578ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
579ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks",
580ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        "Lcom/android/bluetooth/btservice/JniCallbacks;");
581ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
582ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
583ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
584ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass,
585ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                             "adapterPropertyChangedCallback",
586ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                             "([I[[B)V");
587ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass,
588ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                           "discoveryStateChangeCallback", "(I)V");
589ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
590ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass,
591ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                            "devicePropertyChangedCallback",
592ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                            "([B[I[[B)V");
593ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
594ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback",
595ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                 "([B[BI)V");
596ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback",
597ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                 "([B[BIII)V");
598ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
599ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass,
600ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                     "bondStateChangeCallback", "(I[BI)V");
601ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
60201a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    method_aclStateChangeCallback = env->GetMethodID(jniCallbackClass,
60301a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy                                                    "aclStateChangeCallback", "(I[BI)V");
6041e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
6051e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
6061e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    method_acquireWakeLock = env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
6071e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    method_releaseWakeLock = env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");
6081e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
609ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    char value[PROPERTY_VALUE_MAX];
610ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    property_get("bluetooth.mock_stack", value, "");
611ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
612ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
613ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
614ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    err = hw_get_module(id, (hw_module_t const**)&module);
615ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
616ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (err == 0) {
617ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        hw_device_t* abstraction;
618ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        err = module->methods->open(module, id, &abstraction);
619ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (err == 0) {
620ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
621ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sBluetoothInterface = btStack->get_bluetooth_interface();
622ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else {
623c55a9837c004044051b71bb47182ace156691283Matthew Xie           ALOGE("Error while opening Bluetooth library");
624ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
625ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else {
626c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("No Bluetooth Library found");
627ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
628ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
629ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
630ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool initNative(JNIEnv* env, jobject obj) {
631c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
632ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
6331e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    sJniAdapterServiceObj = env->NewGlobalRef(obj);
634ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
635ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
636ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (sBluetoothInterface) {
637ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
638ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (ret != BT_STATUS_SUCCESS) {
6391e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati            ALOGE("Error while setting the callbacks: %d\n", ret);
6401e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati            sBluetoothInterface = NULL;
6411e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati            return JNI_FALSE;
6421e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        }
6431e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
6441e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati        if (ret != BT_STATUS_SUCCESS) {
6451e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati            ALOGE("Error while setting Bluetooth callouts: %d\n", ret);
6461e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati            sBluetoothInterface->cleanup();
647ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sBluetoothInterface = NULL;
648ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return JNI_FALSE;
649ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
6501e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati
651cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        if ( (sBluetoothSocketInterface = (btsock_interface_t *)
652cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                  sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
653c55a9837c004044051b71bb47182ace156691283Matthew Xie                ALOGE("Error getting socket interface");
654cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        }
655ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_TRUE;
656ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
657ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return JNI_FALSE;
658ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
659ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
660ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool cleanupNative(JNIEnv *env, jobject obj) {
661c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
662ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
663ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
664ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
665ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
666ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sBluetoothInterface->cleanup();
667e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGI("%s: return from cleanup",__FUNCTION__);
6686654f5c903de510a70f9e72cd5ad7837b615d93ffredc
669ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->DeleteGlobalRef(sJniCallbacksObj);
6701e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    env->DeleteGlobalRef(sJniAdapterServiceObj);
671ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return JNI_TRUE;
672ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
673ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
674ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean enableNative(JNIEnv* env, jobject obj) {
675c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
676ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
677ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
678ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
679ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
680ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->enable();
681ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
682ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
683ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
684ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
685ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean disableNative(JNIEnv* env, jobject obj) {
686c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
687ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
688ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
689ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
690ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
691ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->disable();
692ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao    /* Retrun JNI_FALSE only when BTIF explicitly reports
693ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao       BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY
694ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao       case which indicates that stack had not been enabled.
695ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao    */
696ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao    result = (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE;
697ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
698ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
699ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
700ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
701c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
702ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
703ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
704ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
705ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
706ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->start_discovery();
707ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
708ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
709ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
710ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
711ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) {
712c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
713ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
714ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
715ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
716ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
717ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->cancel_discovery();
718ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
719ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
720ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
721ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
722ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
723c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
724ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
725ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
726ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
727ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
728ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
729ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
730ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
731ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
732ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
733ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
734ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
735ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
736ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr);
737b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(address, addr, 0);
738ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
739ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
740ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
741ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
742ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
743ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
744c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
745ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
746ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
747ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result;
748ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return JNI_FALSE;
749ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
750ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
751ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
752ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
753ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_FALSE;
754ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
755ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
756ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t *)addr);
757b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(address, addr, 0);
758ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
759ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
760ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
761ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
762ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
763ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
764c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
765ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
766ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
767ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result;
768ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return JNI_FALSE;
769ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
770ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
771ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
772ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
773ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_FALSE;
774ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
775ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
776ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t *)addr);
777b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(address, addr, 0);
778ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
779ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
780ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
781ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
782ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
783ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean pinReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept,
784ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                               jint len, jbyteArray pinArray) {
785c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
786ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
787ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr, *pinPtr = NULL;
788ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
789ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
790ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
791ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
792ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
793ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
794ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
795ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
796ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
797ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (accept) {
798ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        pinPtr = env->GetByteArrayElements(pinArray, NULL);
799ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (pinPtr == NULL) {
800ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           jniThrowIOException(env, EINVAL);
801b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom           env->ReleaseByteArrayElements(address, addr, 0);
802ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           return result;
803ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
804ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
805ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
806ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len,
807ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                              (bt_pin_code_t *) pinPtr);
808b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(address, addr, 0);
809b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(pinArray, pinPtr, 0);
810ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
811ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
812ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
813ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
814ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
815ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean sspReplyNative(JNIEnv *env, jobject obj, jbyteArray address,
816581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh                               jint type, jboolean accept, jint passkey) {
817c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
818ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
819ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
820ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
821ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
822ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
823ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
824ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
825ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
826ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
827ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
828ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
829581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh    int ret = sBluetoothInterface->ssp_reply((bt_bdaddr_t *)addr,
830581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh         (bt_ssp_variant_t) type, accept, passkey);
831b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(address, addr, 0);
832ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
833ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
834ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
835ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
836ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
837ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setAdapterPropertyNative(JNIEnv *env, jobject obj, jint type, jbyteArray value) {
838c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
839ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
840ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *val;
841ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
842ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
843ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
844ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    val = env->GetByteArrayElements(value, NULL);
845ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bt_property_t prop;
846ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.type = (bt_property_type_t) type;
847ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.len = env->GetArrayLength(value);
848ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.val = val;
849ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
850ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->set_adapter_property(&prop);
851b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(value, val, 0);
852ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
853ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
854ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
855ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
856ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
857ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertiesNative(JNIEnv *env, jobject obj) {
858c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
859ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
860ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
861ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
862ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
863ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_adapter_properties();
864ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
865ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
866ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
867ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
868ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
869ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertyNative(JNIEnv *env, jobject obj, jint type) {
870c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
871ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
872ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
873ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
874ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
875ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t) type);
876ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
877ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
878ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
879ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
880ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
881ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, jint type) {
882c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
883ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
884ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr = NULL;
885ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
886ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
887ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
888ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
889ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
890ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
891ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
892ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
893ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
894ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_remote_device_property((bt_bdaddr_t *)addr,
895ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                              (bt_property_type_t) type);
896b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(address, addr, 0);
897ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
898ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
899ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
900ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
901ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
902ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address,
903ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        jint type, jbyteArray value) {
904c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
905ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
906ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *val, *addr;
907ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
908ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
909ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
910ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    val = env->GetByteArrayElements(value, NULL);
911ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (val == NULL) {
912ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
913ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
914ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
915ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
916ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
917ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
918b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        env->ReleaseByteArrayElements(value, val, 0);
919ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
920ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
921ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
922ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
923ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
924ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bt_property_t prop;
925ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.type = (bt_property_type_t) type;
926ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.len = env->GetArrayLength(value);
927ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.val = val;
928ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
929ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t *)addr, &prop);
930b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(value, val, 0);
931b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(address, addr, 0);
932ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
933ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
934ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
935ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
936ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
937ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
938c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredcstatic jboolean getRemoteServicesNative(JNIEnv *env, jobject obj, jbyteArray address) {
939e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGV("%s:",__FUNCTION__);
940c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
941c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    jbyte *addr = NULL;
942c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    jboolean result = JNI_FALSE;
943c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    if (!sBluetoothInterface) return result;
944c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
945c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    addr = env->GetByteArrayElements(address, NULL);
946c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    if (addr == NULL) {
947c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc        jniThrowIOException(env, EINVAL);
948c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc        return result;
949c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    }
950c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
951c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t *)addr);
952b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    env->ReleaseByteArrayElements(address, addr, 0);
953c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
954c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    return result;
955c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc}
956c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
957cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic int connectSocketNative(JNIEnv *env, jobject object, jbyteArray address, jint type,
958cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                                   jbyteArray uuidObj, jint channel, jint flag) {
959cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    jbyte *addr = NULL, *uuid = NULL;
960cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    int socket_fd;
961cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    bt_status_t status;
962cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
963b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if (!sBluetoothSocketInterface) return -1;
964cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
965cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
966cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!addr) {
967c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("failed to get Bluetooth device address");
968cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
969cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
970cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
971cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    uuid = env->GetByteArrayElements(uuidObj, NULL);
972cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!uuid) {
973c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("failed to get uuid");
974cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
975cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
976cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
977cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if ( (status = sBluetoothSocketInterface->connect((bt_bdaddr_t *) addr, (btsock_type_t) type,
978cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                       (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) {
979c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Socket connection failed: %d", status);
980cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
981cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
982cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
983cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
984cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (socket_fd < 0) {
985c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Fail to creat file descriptor on socket fd");
986cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
987cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
988cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
989cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    env->ReleaseByteArrayElements(uuidObj, uuid, 0);
990cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return socket_fd;
991cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
992cc80b2261351dc74ad1bed237b0423c12d340514Matthew XieFail:
993cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (addr) env->ReleaseByteArrayElements(address, addr, 0);
994cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
995cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
996cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return -1;
997cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
998cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
999cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic int createSocketChannelNative(JNIEnv *env, jobject object, jint type,
1000b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom                                     jstring name_str, jbyteArray uuidObj, jint channel, jint flag) {
1001cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    const char *service_name;
1002cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    jbyte *uuid = NULL;
1003cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    int socket_fd;
1004cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    bt_status_t status;
1005cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1006b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if (!sBluetoothSocketInterface) return -1;
1007cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
10088799f44e07ff7cde70a8d58893e995d3a9fa1e76Matthew Xie    ALOGV("%s: SOCK FLAG = %x", __FUNCTION__, flag);
10098799f44e07ff7cde70a8d58893e995d3a9fa1e76Matthew Xie
1010cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    service_name = env->GetStringUTFChars(name_str, NULL);
1011cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1012cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    uuid = env->GetByteArrayElements(uuidObj, NULL);
1013cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!uuid) {
1014c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("failed to get uuid");
1015cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
1016cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
1017cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if ( (status = sBluetoothSocketInterface->listen((btsock_type_t) type, service_name,
1018cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                       (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) {
1019c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Socket listen failed: %d", status);
1020cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
1021cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
1022cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1023cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (socket_fd < 0) {
1024c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Fail to creat file descriptor on socket fd");
1025cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
1026cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
1027cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
1028cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
1029cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return socket_fd;
1030cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1031cc80b2261351dc74ad1bed237b0423c12d340514Matthew XieFail:
1032cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
1033cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
1034cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
1035cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return -1;
1036cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
1037cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
10389d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xustatic jboolean configHciSnoopLogNative(JNIEnv* env, jobject obj, jboolean enable) {
10399d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu    ALOGV("%s:",__FUNCTION__);
10409d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
10419d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu    jboolean result = JNI_FALSE;
10429d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
10439d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu    if (!sBluetoothInterface) return result;
10449d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
10459d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu    int ret = sBluetoothInterface->config_hci_snoop_log(enable);
10469d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
10479d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
10489d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
10499d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu    return result;
10509d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu}
10519d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu
1052ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNINativeMethod sMethods[] = {
1053b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    /* name, signature, funcPtr */
1054ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"classInitNative", "()V", (void *) classInitNative},
1055ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"initNative", "()Z", (void *) initNative},
1056ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cleanupNative", "()V", (void*) cleanupNative},
1057ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"enableNative", "()Z",  (void*) enableNative},
1058ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"disableNative", "()Z",  (void*) disableNative},
1059ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative},
1060ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative},
1061ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative},
1062ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative},
1063ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative},
1064ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative},
1065ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative},
1066ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"createBondNative", "([B)Z", (void*) createBondNative},
1067ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"removeBondNative", "([B)Z", (void*) removeBondNative},
1068ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cancelBondNative", "([B)Z", (void*) cancelBondNative},
1069ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative},
1070581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh    {"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative},
1071c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    {"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative},
1072cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    {"connectSocketNative", "([BI[BII)I", (void*) connectSocketNative},
1073cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    {"createSocketChannelNative", "(ILjava/lang/String;[BII)I",
10749d80b509f715a3c3f2ebd0de373d427fc31a6e6cZhihai Xu     (void*) createSocketChannelNative},
10751e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    {"configHciSnoopLogNative", "(Z)Z", (void*) configHciSnoopLogNative},
10761e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati    {"alarmFiredNative", "()V", (void *) alarmFiredNative},
1077ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh};
1078ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1079ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshint register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env)
1080ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{
1081ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService",
1082ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                    sMethods, NELEM(sMethods));
1083ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1084ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1085ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} /* namespace android */
1086ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1087ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1088ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
1089ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * JNI Initialization
1090ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
1091ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshjint JNI_OnLoad(JavaVM *jvm, void *reserved)
1092ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{
1093b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    JNIEnv *e;
1094b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    int status;
1095b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
1096b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    ALOGV("Bluetooth Adapter Service : loading JNI\n");
1097b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
1098b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    // Check JNI version
1099b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if (jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) {
1100b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        ALOGE("JNI version mismatch error");
1101b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        return JNI_ERR;
1102b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    }
1103b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
1104b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if ((status = android::register_com_android_bluetooth_btservice_AdapterService(e)) < 0) {
1105b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        ALOGE("jni adapter service registration failure, status: %d", status);
1106b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        return JNI_ERR;
1107b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    }
1108b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
1109b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if ((status = android::register_com_android_bluetooth_hfp(e)) < 0) {
1110b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        ALOGE("jni hfp registration failure, status: %d", status);
1111b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        return JNI_ERR;
1112b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    }
1113b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
1114b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if ((status = android::register_com_android_bluetooth_a2dp(e)) < 0) {
1115b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        ALOGE("jni a2dp registration failure: %d", status);
1116b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        return JNI_ERR;
1117b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    }
1118b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
1119c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu    if ((status = android::register_com_android_bluetooth_avrcp(e)) < 0) {
1120c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu        ALOGE("jni avrcp registration failure: %d", status);
1121c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu        return JNI_ERR;
1122c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu    }
1123c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu
1124b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if ((status = android::register_com_android_bluetooth_hid(e)) < 0) {
1125b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        ALOGE("jni hid registration failure: %d", status);
1126b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        return JNI_ERR;
1127b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    }
1128b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
1129b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if ((status = android::register_com_android_bluetooth_hdp(e)) < 0) {
1130b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        ALOGE("jni hdp registration failure: %d", status);
1131b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        return JNI_ERR;
1132b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    }
1133b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
1134b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if ((status = android::register_com_android_bluetooth_pan(e)) < 0) {
1135b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        ALOGE("jni pan registration failure: %d", status);
1136b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        return JNI_ERR;
1137b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    }
1138b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom
1139b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    if ((status = android::register_com_android_bluetooth_gatt(e)) < 0) {
1140b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        ALOGE("jni gatt registration failure: %d", status);
1141b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom        return JNI_ERR;
1142b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    }
1143b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom    return JNI_VERSION_1_6;
1144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
1145