com_android_bluetooth_btservice_AdapterService.cpp revision ede67c26e7b2564ea35db6d9b3027a269c150e13
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"
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <string.h>
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <pthread.h>
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <sys/stat.h>
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <fcntl.h>
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshnamespace android {
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define ADDITIONAL_NREFS 50
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_stateChangeCallback;
35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_adapterPropertyChangedCallback;
36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_devicePropertyChangedCallback;
37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_deviceFoundCallback;
38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_pinRequestCallback;
39ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_sspRequestCallback;
40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_bondStateChangeCallback;
4101a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamystatic jmethodID method_aclStateChangeCallback;
42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_discoveryStateChangeCallback;
43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
44ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic const bt_interface_t *sBluetoothInterface = NULL;
45cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic const btsock_interface_t *sBluetoothSocketInterface = NULL;
46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNIEnv *callbackEnv = NULL;
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jobject sJniCallbacksObj;
49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jfieldID sJniCallbacksField;
50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
51cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieconst bt_interface_t* getBluetoothInterface() {
536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return sBluetoothInterface;
546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew XieJNIEnv* getCallbackEnv() {
576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   return callbackEnv;
586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xievoid checkAndClearExceptionFromCallback(JNIEnv* env,
61ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                               const char* methodName) {
62ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (env->ExceptionCheck()) {
63c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("An exception was thrown by callback '%s'.", methodName);
64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE_EX(env);
65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->ExceptionClear();
66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
68ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
69ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool checkCallbackThread() {
70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    JNIEnv* env = AndroidRuntime::getJNIEnv();
71676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie    if (callbackEnv != env || callbackEnv == NULL) {
72c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Callback env check fail: env: %p, callback: %p", env, callbackEnv);
73676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie        return false;
74676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie    }
75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return true;
76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
77ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
78ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_state_change_callback(bt_state_t status) {
79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
80c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
82ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
83c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: Status is: %d", __FUNCTION__, status);
84ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status);
86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic int get_properties(int num_properties, bt_property_t *properties, jintArray *types,
91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                        jobjectArray *props) {
92edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jbyteArray propVal;
93ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    for (int i = 0; i < num_properties; i++) {
94f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy
95f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy       /* The higher layers expect rssi as a short int value, while the value is sent as a byte
96f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy        * to jni. Converting rssi value to the expected format.*/
97f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy       if (properties[i].type == BT_PROPERTY_REMOTE_RSSI)
98f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy       {
99f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy           jbyte rssi = *((jbyte *) properties[i].val);
100f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy           short rssiValue = rssi;
101f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy           properties[i].len = sizeof(rssiValue);
102f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy           properties[i].val = &rssiValue;
103f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy       }
104f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy
105ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       propVal = callbackEnv->NewByteArray(properties[i].len);
106ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       if (propVal == NULL) goto Fail;
107ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       callbackEnv->SetByteArrayRegion(propVal, 0, properties[i].len,
109ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                            (jbyte*)properties[i].val);
110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       callbackEnv->SetObjectArrayElement(*props, i, propVal);
111d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy       // Delete reference to propVal
112d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy       callbackEnv->DeleteLocalRef(propVal);
113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       callbackEnv->SetIntArrayRegion(*types, i, 1, (jint *)&properties[i].type);
114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return 0;
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (propVal) callbackEnv->DeleteLocalRef(propVal);
118c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGE("Error while allocation of array in %s", __FUNCTION__);
119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return -1;
120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_properties_callback(bt_status_t status, int num_properties,
123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_property_t *properties) {
124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jobjectArray props;
125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jintArray types;
126edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jbyteArray val;
127edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jclass mclass;
128edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
130c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
134c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (status != BT_STATUS_SUCCESS) {
137c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("%s: Status %d is incorrect", __FUNCTION__, status);
138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
141edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
142edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (val == NULL) {
143e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating byteArray", __FUNCTION__);
144edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
145edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
146edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
147edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    mclass = callbackEnv->GetObjectClass(val);
148edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
149edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    /* (BT) Initialize the jobjectArray and jintArray here itself and send the
150edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M     initialized array pointers alone to get_properties */
151edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
152edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    props = callbackEnv->NewObjectArray(num_properties, mclass,
153edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M                                             NULL);
154edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (props == NULL) {
155e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating object Array for properties", __FUNCTION__);
156edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
157edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
158edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
159edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    types = (jintArray)callbackEnv->NewIntArray(num_properties);
160edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
161edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (types == NULL) {
162e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating int Array for values", __FUNCTION__);
163edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
164edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
165edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    // Delete the reference to val and mclass
166edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(mclass);
167edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(val);
168edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
169ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh    if (get_properties(num_properties, properties, &types, &props) < 0) {
170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (props) callbackEnv->DeleteLocalRef(props);
171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (types) callbackEnv->DeleteLocalRef(types);
172ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
173ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
174ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
175ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_adapterPropertyChangedCallback, types,
176ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                props);
177ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
1786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(props);
1796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(types);
180ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
181ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
183ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void remote_device_properties_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
185ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                              int num_properties, bt_property_t *properties) {
186ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
187c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
188ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
189ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
191c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (status != BT_STATUS_SUCCESS) {
194c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("%s: Status %d is incorrect", __FUNCTION__, status);
195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
197ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->PushLocalFrame(ADDITIONAL_NREFS);
1996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jobjectArray props;
2016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyteArray addr;
2026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jintArray types;
203edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jbyteArray val;
204edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jclass mclass;
205edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
206edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
207edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (val == NULL) {
208e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating byteArray", __FUNCTION__);
209edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
210edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
211edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
212edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    mclass = callbackEnv->GetObjectClass(val);
213edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
214edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    /* Initialize the jobjectArray and jintArray here itself and send the
215edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M     initialized array pointers alone to get_properties */
216edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
217edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    props = callbackEnv->NewObjectArray(num_properties, mclass,
218edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M                                             NULL);
219edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (props == NULL) {
220e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating object Array for properties", __FUNCTION__);
221edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
222edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
223edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
224edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    types = (jintArray)callbackEnv->NewIntArray(num_properties);
225edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
226edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (types == NULL) {
227e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("%s: Error allocating int Array for values", __FUNCTION__);
228edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
229edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
230edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    // Delete the reference to val and mclass
231edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(mclass);
232edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(val);
2336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
238ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh    if (get_properties(num_properties, properties, &types, &props) < 0) {
239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (props) callbackEnv->DeleteLocalRef(props);
240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (types) callbackEnv->DeleteLocalRef(types);
2416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        callbackEnv->PopLocalFrame(NULL);
242ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
243ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
245ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_devicePropertyChangedCallback, addr,
246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                types, props);
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
2486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(props);
2496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(types);
250edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(addr);
2516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->PopLocalFrame(NULL);
252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
255c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGE("Error while allocation byte array in %s", __FUNCTION__);
256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void device_found_callback(int num_properties, bt_property_t *properties) {
260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr = NULL;
261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int addr_index;
262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    for (int i = 0; i < num_properties; i++) {
264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (properties[i].type == BT_PROPERTY_BDADDR) {
265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            addr = callbackEnv->NewByteArray(properties[i].len);
266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (addr) {
267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                callbackEnv->SetByteArrayRegion(addr, 0, properties[i].len,
268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                (jbyte*)properties[i].val);
269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                addr_index = i;
270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
271c55a9837c004044051b71bb47182ace156691283Matthew Xie                ALOGE("Address is NULL (unable to allocate) in %s", __FUNCTION__);
272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return;
273ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
275ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
276ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
277c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Address is NULL in %s", __FUNCTION__);
278ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
279ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
280ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
281c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: Properties: %d, Address: %s", __FUNCTION__, num_properties,
282ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        (const char *)properties[addr_index].val);
283ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
284ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    remote_device_properties_callback(BT_STATUS_SUCCESS, (bt_bdaddr_t *)properties[addr_index].val,
285ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                      num_properties, properties);
286ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
287ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, addr);
288ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
2896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
290ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
291ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
292ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void bond_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
293ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_bond_state_t state) {
294ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr;
295ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int i;
296ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
297c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
298ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
299ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
300ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
301c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Address is null in %s", __FUNCTION__);
302ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
303ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
304ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
305ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
306c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Address allocation failed in %s", __FUNCTION__);
307ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
308ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
309ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
310ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
311ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status,
312ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                addr, (jint)state);
313ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
3146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
315ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
316ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
31701a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamystatic void acl_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
31801a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy                                       bt_acl_state_t state)
31901a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy{
32001a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    jbyteArray addr;
32101a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    int i;
32201a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    if (!checkCallbackThread()) {
323e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
32401a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy       return;
32501a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    }
32601a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    if (!bd_addr) {
327e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Address is null in %s", __FUNCTION__);
32801a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy        return;
32901a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    }
33001a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
33101a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    if (addr == NULL) {
332e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie       ALOGE("Address allocation failed in %s", __FUNCTION__);
33301a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy       return;
33401a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    }
33501a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
33601a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy
33701a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, (jint) status,
33801a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy                                addr, (jint)state);
33901a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
34001a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    callbackEnv->DeleteLocalRef(addr);
34101a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy}
34201a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy
343ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void discovery_state_changed_callback(bt_discovery_state_t state) {
344ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr;
345ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
346c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
347ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
348ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
349ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
350c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s: DiscoveryState:%d ", __FUNCTION__, state);
351ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
352ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_discoveryStateChangeCallback,
353ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                (jint)state);
354ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
355ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
356ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
357ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
358ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void pin_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod) {
359ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr, devname;
360ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
361c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
362ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
363ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
364ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
365c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Address is null in %s", __FUNCTION__);
366ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
367ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
368ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
369ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
370ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
37161c4100eb0606f8ba630f5c45d07a88d612fbc85Matthew Xie    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
372ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
373ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
374ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname == NULL) goto Fail;
375ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
376ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
377ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
378ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, addr, devname, cod);
379ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
380ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
3816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
3826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(devname);
383ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
384ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
385ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
386ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->DeleteLocalRef(addr);
387ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname) callbackEnv->DeleteLocalRef(devname);
388c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGE("Error while allocating in: %s", __FUNCTION__);
389ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
390ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
391ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void ssp_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod,
392ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                 bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
393ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr, devname;
394ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
395c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
396ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
397ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
398ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
399c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Address is null in %s", __FUNCTION__);
400ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
401ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
402ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
403ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
404ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
405ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
406ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
407ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
408ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname == NULL) goto Fail;
409ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
410ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
411ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, addr, devname, cod,
412ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                (jint) pairing_variant, pass_key);
413ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
414ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
4156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
4166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(devname);
417ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
418ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
419ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
420ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->DeleteLocalRef(addr);
421ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname) callbackEnv->DeleteLocalRef(devname);
422ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
423c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGE("Error while allocating in: %s", __FUNCTION__);
424ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
425ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
426ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void callback_thread_event(bt_cb_thread_evt event) {
427ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    JavaVM* vm = AndroidRuntime::getJavaVM();
428ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (event  == ASSOCIATE_JVM) {
429ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        JavaVMAttachArgs args;
430ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        char name[] = "BT Service Callback Thread";
431ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        //TODO(BT)
432ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        //args.version = nat->envVer;
433ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        args.name = name;
434ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        args.group = NULL;
435ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        vm->AttachCurrentThread(&callbackEnv, &args);
436c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGV("Callback thread attached: %p", callbackEnv);
437ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else if (event == DISASSOCIATE_JVM) {
438ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (!checkCallbackThread()) {
439c55a9837c004044051b71bb47182ace156691283Matthew Xie            ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
440ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return;
441ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
442ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        vm->DetachCurrentThread();
443ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
444ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
445ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
446ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshbt_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,
458ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh};
459ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
460ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void classInitNative(JNIEnv* env, jclass clazz) {
461ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int err;
462ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    hw_module_t* module;
463ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
464ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jclass jniCallbackClass =
465ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
466ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks",
467ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        "Lcom/android/bluetooth/btservice/JniCallbacks;");
468ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
469ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
470ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
471ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass,
472ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                             "adapterPropertyChangedCallback",
473ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                             "([I[[B)V");
474ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass,
475ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                           "discoveryStateChangeCallback", "(I)V");
476ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
477ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass,
478ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                            "devicePropertyChangedCallback",
479ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                            "([B[I[[B)V");
480ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
481ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback",
482ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                 "([B[BI)V");
483ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback",
484ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                 "([B[BIII)V");
485ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
486ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass,
487ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                     "bondStateChangeCallback", "(I[BI)V");
488ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
48901a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy    method_aclStateChangeCallback = env->GetMethodID(jniCallbackClass,
49001a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy                                                    "aclStateChangeCallback", "(I[BI)V");
491ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    char value[PROPERTY_VALUE_MAX];
492ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    property_get("bluetooth.mock_stack", value, "");
493ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
494ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
495ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
496ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    err = hw_get_module(id, (hw_module_t const**)&module);
497ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
498ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (err == 0) {
499ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        hw_device_t* abstraction;
500ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        err = module->methods->open(module, id, &abstraction);
501ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (err == 0) {
502ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
503ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sBluetoothInterface = btStack->get_bluetooth_interface();
504ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else {
505c55a9837c004044051b71bb47182ace156691283Matthew Xie           ALOGE("Error while opening Bluetooth library");
506ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
507ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else {
508c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("No Bluetooth Library found");
509ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
510ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
511ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
512ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool initNative(JNIEnv* env, jobject obj) {
513c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
514ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
515ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
516ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
517ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (sBluetoothInterface) {
518ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
519ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (ret != BT_STATUS_SUCCESS) {
520c55a9837c004044051b71bb47182ace156691283Matthew Xie            ALOGE("Error while setting the callbacks \n");
521ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sBluetoothInterface = NULL;
522ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return JNI_FALSE;
523ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
524cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        if ( (sBluetoothSocketInterface = (btsock_interface_t *)
525cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                  sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
526c55a9837c004044051b71bb47182ace156691283Matthew Xie                ALOGE("Error getting socket interface");
527cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        }
528ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_TRUE;
529ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
530ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return JNI_FALSE;
531ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
532ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
533ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool cleanupNative(JNIEnv *env, jobject obj) {
534c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
535ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
536ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
537ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
538ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
539ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sBluetoothInterface->cleanup();
540e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGI("%s: return from cleanup",__FUNCTION__);
5416654f5c903de510a70f9e72cd5ad7837b615d93ffredc
542ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->DeleteGlobalRef(sJniCallbacksObj);
543ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return JNI_TRUE;
544ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
545ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
546ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean enableNative(JNIEnv* env, jobject obj) {
547c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
548ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
549ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
550ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
551ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
552ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->enable();
553ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
554ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
555ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
556ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
557ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean disableNative(JNIEnv* env, jobject obj) {
558c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
559ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
560ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
561ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
562ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
563ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->disable();
564ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
565ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
566ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
567ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
568ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
569c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
570ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
571ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
572ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
573ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
574ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->start_discovery();
575ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
576ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
577ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
578ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
579ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) {
580c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
581ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
582ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
583ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
584ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
585ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->cancel_discovery();
586ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
587ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
588ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
589ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
590ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
591c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
592ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
593ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
594ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
595ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
596ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
597ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
598ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
599ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
600ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
601ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
602ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
603ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
604ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr);
605ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
606ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
607ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
608ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
609ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
610ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
611ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
612c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
613ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
614ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
615ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result;
616ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return JNI_FALSE;
617ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
618ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
619ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
620ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
621ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_FALSE;
622ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
623ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
624ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t *)addr);
625ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
626ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
627ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
628ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
629ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
630ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
631ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
632c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
633ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
634ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
635ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result;
636ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return JNI_FALSE;
637ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
638ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
639ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
640ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
641ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_FALSE;
642ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
643ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
644ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t *)addr);
645ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
646ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
647ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
648ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
649ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
650ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
651ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean pinReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept,
652ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                               jint len, jbyteArray pinArray) {
653c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
654ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
655ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr, *pinPtr = NULL;
656ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
657ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
658ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
659ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
660ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
661ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
662ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
663ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
664ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
665ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (accept) {
666ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        pinPtr = env->GetByteArrayElements(pinArray, NULL);
667ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (pinPtr == NULL) {
668ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           jniThrowIOException(env, EINVAL);
669ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           env->ReleaseByteArrayElements(address, addr, NULL);
670ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           return result;
671ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
672ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
673ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
674ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len,
675ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                              (bt_pin_code_t *) pinPtr);
676ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
677ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(pinArray, pinPtr, NULL);
678ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
679ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
680ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
681ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
682ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
683ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean sspReplyNative(JNIEnv *env, jobject obj, jbyteArray address,
684581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh                               jint type, jboolean accept, jint passkey) {
685c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
686ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
687ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
688ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
689ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
690ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
691ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
692ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
693ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
694ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
695ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
696ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
697581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh    int ret = sBluetoothInterface->ssp_reply((bt_bdaddr_t *)addr,
698581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh         (bt_ssp_variant_t) type, accept, passkey);
699ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
700ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
701ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
702ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
703ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
704ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
705ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setAdapterPropertyNative(JNIEnv *env, jobject obj, jint type, jbyteArray value) {
706c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
707ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
708ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *val;
709ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
710ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
711ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
712ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    val = env->GetByteArrayElements(value, NULL);
713ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bt_property_t prop;
714ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.type = (bt_property_type_t) type;
715ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.len = env->GetArrayLength(value);
716ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.val = val;
717ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
718ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->set_adapter_property(&prop);
719ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(value, val, NULL);
720ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
721ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
722ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
723ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
724ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
725ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertiesNative(JNIEnv *env, jobject obj) {
726c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
727ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
728ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
729ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
730ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
731ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_adapter_properties();
732ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
733ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
734ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
735ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
736ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
737ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertyNative(JNIEnv *env, jobject obj, jint type) {
738c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
739ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
740ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
741ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
742ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
743ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t) type);
744ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
745ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
746ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
747ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
748ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
749ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, jint type) {
750c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
751ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
752ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr = NULL;
753ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
754ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
755ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
756ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
757ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
758ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
759ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
760ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
761ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
762ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_remote_device_property((bt_bdaddr_t *)addr,
763ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                              (bt_property_type_t) type);
764ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
765ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
766ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
767ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
768ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
769ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
770ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address,
771ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        jint type, jbyteArray value) {
772c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGV("%s:",__FUNCTION__);
773ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
774ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *val, *addr;
775ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
776ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
777ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
778ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    val = env->GetByteArrayElements(value, NULL);
779ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (val == NULL) {
780ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
781ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
782ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
783ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
784ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
785ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
786ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->ReleaseByteArrayElements(value, val, NULL);
787ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
788ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
789ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
790ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
791ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
792ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bt_property_t prop;
793ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.type = (bt_property_type_t) type;
794ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.len = env->GetArrayLength(value);
795ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.val = val;
796ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
797ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t *)addr, &prop);
798ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(value, val, NULL);
799ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
800ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
801ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
802ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
803ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
804ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
805ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
806c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredcstatic jboolean getRemoteServicesNative(JNIEnv *env, jobject obj, jbyteArray address) {
807e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGV("%s:",__FUNCTION__);
808c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
809c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    jbyte *addr = NULL;
810c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    jboolean result = JNI_FALSE;
811c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    if (!sBluetoothInterface) return result;
812c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
813c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    addr = env->GetByteArrayElements(address, NULL);
814c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    if (addr == NULL) {
815c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc        jniThrowIOException(env, EINVAL);
816c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc        return result;
817c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    }
818c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
819c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t *)addr);
820c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    env->ReleaseByteArrayElements(address, addr, NULL);
821c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
822c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    return result;
823c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc}
824c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
825cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic int connectSocketNative(JNIEnv *env, jobject object, jbyteArray address, jint type,
826cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                                   jbyteArray uuidObj, jint channel, jint flag) {
827cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    jbyte *addr = NULL, *uuid = NULL;
828cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    int socket_fd;
829cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    bt_status_t status;
830cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
831cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!sBluetoothSocketInterface) return NULL;
832cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
833cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
834cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!addr) {
835c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("failed to get Bluetooth device address");
836cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
837cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
838cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
839cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    uuid = env->GetByteArrayElements(uuidObj, NULL);
840cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!uuid) {
841c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("failed to get uuid");
842cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
843cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
844cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
845cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if ( (status = sBluetoothSocketInterface->connect((bt_bdaddr_t *) addr, (btsock_type_t) type,
846cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                       (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) {
847c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Socket connection failed: %d", status);
848cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
849cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
850cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
851cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
852cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (socket_fd < 0) {
853c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Fail to creat file descriptor on socket fd");
854cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
855cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
856cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
857cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    env->ReleaseByteArrayElements(uuidObj, uuid, 0);
858cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return socket_fd;
859cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
860cc80b2261351dc74ad1bed237b0423c12d340514Matthew XieFail:
861cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (addr) env->ReleaseByteArrayElements(address, addr, 0);
862cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
863cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
864cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return -1;
865cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
866cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
867cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic int createSocketChannelNative(JNIEnv *env, jobject object, jint type,
868cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                                         jstring name_str, jbyteArray uuidObj, jint channel, jint flag) {
869cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    const char *service_name;
870cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    jbyte *uuid = NULL;
871cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    int socket_fd;
872cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    bt_status_t status;
873cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
874cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!sBluetoothSocketInterface) return NULL;
875cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
876cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    service_name = env->GetStringUTFChars(name_str, NULL);
877cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
878cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    uuid = env->GetByteArrayElements(uuidObj, NULL);
879cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!uuid) {
880c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("failed to get uuid");
881cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
882cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
883e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGE("SOCK FLAG = %x ***********************",flag);
884cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if ( (status = sBluetoothSocketInterface->listen((btsock_type_t) type, service_name,
885cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                       (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) {
886c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Socket listen failed: %d", status);
887cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
888cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
889cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
890cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (socket_fd < 0) {
891c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Fail to creat file descriptor on socket fd");
892cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
893cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
894cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
895cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
896cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return socket_fd;
897cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
898cc80b2261351dc74ad1bed237b0423c12d340514Matthew XieFail:
899cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
900cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
901cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
902cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return -1;
903cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
904cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
905ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNINativeMethod sMethods[] = {
906ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh     /* name, signature, funcPtr */
907ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"classInitNative", "()V", (void *) classInitNative},
908ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"initNative", "()Z", (void *) initNative},
909ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cleanupNative", "()V", (void*) cleanupNative},
910ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"enableNative", "()Z",  (void*) enableNative},
911ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"disableNative", "()Z",  (void*) disableNative},
912ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative},
913ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative},
914ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative},
915ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative},
916ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative},
917ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative},
918ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative},
919ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"createBondNative", "([B)Z", (void*) createBondNative},
920ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"removeBondNative", "([B)Z", (void*) removeBondNative},
921ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cancelBondNative", "([B)Z", (void*) cancelBondNative},
922ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative},
923581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh    {"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative},
924c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    {"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative},
925cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    {"connectSocketNative", "([BI[BII)I", (void*) connectSocketNative},
926cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    {"createSocketChannelNative", "(ILjava/lang/String;[BII)I",
927cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie     (void*) createSocketChannelNative},
928ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh};
929ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
930ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshint register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env)
931ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{
932ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService",
933ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                    sMethods, NELEM(sMethods));
934ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
935ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
936ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} /* namespace android */
937ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
938ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
939ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
940ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * JNI Initialization
941ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
942ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshjint JNI_OnLoad(JavaVM *jvm, void *reserved)
943ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{
944ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   JNIEnv *e;
9456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   int status;
946ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
947c55a9837c004044051b71bb47182ace156691283Matthew Xie   ALOGV("Bluetooth Adapter Service : loading JNI\n");
948ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
949ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   // Check JNI version
9506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) {
951c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("JNI version mismatch error");
952ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh      return JNI_ERR;
9536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
954ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
9556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if ((status = android::register_com_android_bluetooth_btservice_AdapterService(e)) < 0) {
956c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("jni adapter service registration failure, status: %d", status);
957ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh      return JNI_ERR;
9586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
9596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
9606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if ((status = android::register_com_android_bluetooth_hfp(e)) < 0) {
961c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("jni hfp registration failure, status: %d", status);
9626c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie      return JNI_ERR;
9636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
9646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
9656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if ((status = android::register_com_android_bluetooth_a2dp(e)) < 0) {
966c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("jni a2dp registration failure: %d", status);
9676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie      return JNI_ERR;
9686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
9696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
97035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie   if ((status = android::register_com_android_bluetooth_hid(e)) < 0) {
971c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("jni hid registration failure: %d", status);
972676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie       return JNI_ERR;
973676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie   }
974676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie
975676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie   if ((status = android::register_com_android_bluetooth_hdp(e)) < 0) {
976c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("jni hdp registration failure: %d", status);
97735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie      return JNI_ERR;
97835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie   }
97935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
9806654f5c903de510a70f9e72cd5ad7837b615d93ffredc   if ((status = android::register_com_android_bluetooth_pan(e)) < 0) {
981e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie       ALOGE("jni pan registration failure: %d", status);
9826654f5c903de510a70f9e72cd5ad7837b615d93ffredc      return JNI_ERR;
9836654f5c903de510a70f9e72cd5ad7837b615d93ffredc   }
9846654f5c903de510a70f9e72cd5ad7837b615d93ffredc
985ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   return JNI_VERSION_1_6;
986ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
987