com_android_bluetooth_btservice_AdapterService.cpp revision 6654f5c903de510a70f9e72cd5ad7837b615d93f
1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
2ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * Copyright (C) 2012 Google Inc.
3ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
4ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
5ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#define LOG_TAG "BluetoothServiceJni"
66c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "com_android_bluetooth.h"
7cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie#include "hardware/bt_sock.h"
8ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/Log.h"
9ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/misc.h"
10ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "cutils/properties.h"
11ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "android_runtime/AndroidRuntime.h"
12ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
13ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <string.h>
14ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <pthread.h>
15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <sys/stat.h>
17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <fcntl.h>
18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshnamespace android {
20ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define ADDITIONAL_NREFS 50
226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_stateChangeCallback;
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_adapterPropertyChangedCallback;
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_devicePropertyChangedCallback;
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_deviceFoundCallback;
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_pinRequestCallback;
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_sspRequestCallback;
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_bondStateChangeCallback;
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_discoveryStateChangeCallback;
31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic const bt_interface_t *sBluetoothInterface = NULL;
33cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic const btsock_interface_t *sBluetoothSocketInterface = NULL;
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNIEnv *callbackEnv = NULL;
35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jobject sJniCallbacksObj;
37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jfieldID sJniCallbacksField;
38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
39cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieconst bt_interface_t* getBluetoothInterface() {
416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return sBluetoothInterface;
426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew XieJNIEnv* getCallbackEnv() {
456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   return callbackEnv;
466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xievoid checkAndClearExceptionFromCallback(JNIEnv* env,
49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                               const char* methodName) {
50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (env->ExceptionCheck()) {
51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("An exception was thrown by callback '%s'.", methodName);
52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE_EX(env);
53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->ExceptionClear();
54ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
55ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
57ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool checkCallbackThread() {
58ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    JNIEnv* env = AndroidRuntime::getJNIEnv();
59676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie    if (callbackEnv != env || callbackEnv == NULL) {
60676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie        LOGE("Callback env check fail: env: %p, callback: %p", env, callbackEnv);
61676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie        return false;
62676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie    }
63ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return true;
64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_state_change_callback(bt_state_t status) {
67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
68ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
69ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: Status is: %d", __FUNCTION__, status);
72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status);
74ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
77ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
78ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic int get_properties(int num_properties, bt_property_t *properties, jintArray *types,
79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                        jobjectArray *props) {
80edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jbyteArray propVal;
81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    for (int i = 0; i < num_properties; i++) {
82f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy
83f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy       /* The higher layers expect rssi as a short int value, while the value is sent as a byte
84f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy        * to jni. Converting rssi value to the expected format.*/
85f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy       if (properties[i].type == BT_PROPERTY_REMOTE_RSSI)
86f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy       {
87f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy           jbyte rssi = *((jbyte *) properties[i].val);
88f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy           short rssiValue = rssi;
89f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy           properties[i].len = sizeof(rssiValue);
90f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy           properties[i].val = &rssiValue;
91f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy       }
92f8d98da947bbb9e2380a60df89acbcbd4ca680afKausik Sinnaswamy
93ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       propVal = callbackEnv->NewByteArray(properties[i].len);
94ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       if (propVal == NULL) goto Fail;
95ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
96ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       callbackEnv->SetByteArrayRegion(propVal, 0, properties[i].len,
97ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                            (jbyte*)properties[i].val);
98ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       callbackEnv->SetObjectArrayElement(*props, i, propVal);
99d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy       // Delete reference to propVal
100d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy       callbackEnv->DeleteLocalRef(propVal);
101ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       callbackEnv->SetIntArrayRegion(*types, i, 1, (jint *)&properties[i].type);
102ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
103ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return 0;
104ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
105ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (propVal) callbackEnv->DeleteLocalRef(propVal);
106ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGE("Error while allocation of array in %s", __FUNCTION__);
107ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return -1;
108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
109ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_properties_callback(bt_status_t status, int num_properties,
111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_property_t *properties) {
112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jobjectArray props;
113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jintArray types;
114edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jbyteArray val;
115edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jclass mclass;
116edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (status != BT_STATUS_SUCCESS) {
125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("%s: Status %d is incorrect", __FUNCTION__, status);
126ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
129edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
130edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (val == NULL) {
131edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        LOGE("%s: Error allocating byteArray", __FUNCTION__);
132edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
133edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
134edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
135edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    mclass = callbackEnv->GetObjectClass(val);
136edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
137edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    /* (BT) Initialize the jobjectArray and jintArray here itself and send the
138edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M     initialized array pointers alone to get_properties */
139edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
140edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    props = callbackEnv->NewObjectArray(num_properties, mclass,
141edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M                                             NULL);
142edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (props == NULL) {
143edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        LOGE("%s: Error allocating object Array for properties", __FUNCTION__);
144edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
145edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
146edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
147edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    types = (jintArray)callbackEnv->NewIntArray(num_properties);
148edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
149edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (types == NULL) {
150edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        LOGE("%s: Error allocating int Array for values", __FUNCTION__);
151edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
152edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
153edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    // Delete the reference to val and mclass
154edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(mclass);
155edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(val);
156edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
157ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh    if (get_properties(num_properties, properties, &types, &props) < 0) {
158ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (props) callbackEnv->DeleteLocalRef(props);
159ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (types) callbackEnv->DeleteLocalRef(types);
160ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
161ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
162ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
163ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_adapterPropertyChangedCallback, types,
164ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                props);
165ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
1666c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(props);
1676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(types);
168ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
169ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
172ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void remote_device_properties_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
173ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                              int num_properties, bt_property_t *properties) {
174ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
175ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
176ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
177ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
178ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
179ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
180ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
181ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (status != BT_STATUS_SUCCESS) {
182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("%s: Status %d is incorrect", __FUNCTION__, status);
183ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
185ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
1866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->PushLocalFrame(ADDITIONAL_NREFS);
1876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jobjectArray props;
1896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyteArray addr;
1906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jintArray types;
191edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jbyteArray val;
192edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    jclass mclass;
193edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
194edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
195edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (val == NULL) {
196edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        LOGE("%s: Error allocating byteArray", __FUNCTION__);
197edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
198edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
199edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
200edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    mclass = callbackEnv->GetObjectClass(val);
201edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
202edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    /* Initialize the jobjectArray and jintArray here itself and send the
203edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M     initialized array pointers alone to get_properties */
204edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
205edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    props = callbackEnv->NewObjectArray(num_properties, mclass,
206edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M                                             NULL);
207edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (props == NULL) {
208edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        LOGE("%s: Error allocating object Array for properties", __FUNCTION__);
209edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
210edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
211edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
212edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    types = (jintArray)callbackEnv->NewIntArray(num_properties);
213edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M
214edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    if (types == NULL) {
215edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        LOGE("%s: Error allocating int Array for values", __FUNCTION__);
216edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M        return;
217edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    }
218edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    // Delete the reference to val and mclass
219edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(mclass);
220edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(val);
2216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
223ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
224ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
226ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh    if (get_properties(num_properties, properties, &types, &props) < 0) {
227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (props) callbackEnv->DeleteLocalRef(props);
228ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (types) callbackEnv->DeleteLocalRef(types);
2296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        callbackEnv->PopLocalFrame(NULL);
230ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
232ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_devicePropertyChangedCallback, addr,
234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                types, props);
235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
2366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(props);
2376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(types);
238edb14a4944d66ca9255b2ab9b384c583b626fd94Syed Ibrahim M    callbackEnv->DeleteLocalRef(addr);
2396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->PopLocalFrame(NULL);
240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
241ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
242ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
243ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGE("Error while allocation byte array in %s", __FUNCTION__);
244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
245ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void device_found_callback(int num_properties, bt_property_t *properties) {
248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr = NULL;
249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int addr_index;
250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    for (int i = 0; i < num_properties; i++) {
252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (properties[i].type == BT_PROPERTY_BDADDR) {
253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            addr = callbackEnv->NewByteArray(properties[i].len);
254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (addr) {
255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                callbackEnv->SetByteArrayRegion(addr, 0, properties[i].len,
256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                (jbyte*)properties[i].val);
257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                addr_index = i;
258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                LOGE("Address is NULL (unable to allocate) in %s", __FUNCTION__);
260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return;
261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("Address is NULL in %s", __FUNCTION__);
266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: Properties: %d, Address: %s", __FUNCTION__, num_properties,
270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        (const char *)properties[addr_index].val);
271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    remote_device_properties_callback(BT_STATUS_SUCCESS, (bt_bdaddr_t *)properties[addr_index].val,
273ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                      num_properties, properties);
274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
275ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, addr);
276ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
2776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
278ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
279ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
280ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void bond_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
281ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_bond_state_t state) {
282ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr;
283ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int i;
284ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
285ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
286ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
287ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
288ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
289ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("Address is null in %s", __FUNCTION__);
290ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
291ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
292ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
293ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
294ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Address allocation failed in %s", __FUNCTION__);
295ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
296ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
297ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
298ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
299ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status,
300ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                addr, (jint)state);
301ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
3026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
303ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
304ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
305ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void discovery_state_changed_callback(bt_discovery_state_t state) {
306ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr;
307ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
308ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
309ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
310ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
311ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
312ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: DiscoveryState:%d ", __FUNCTION__, state);
313ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
314ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_discoveryStateChangeCallback,
315ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                (jint)state);
316ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
317ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
318ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
319ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
320ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void pin_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod) {
321ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr, devname;
322ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
323ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
324ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
325ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
326ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
327ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("Address is null in %s", __FUNCTION__);
328ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
329ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
330ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
331ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
332ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
33361c4100eb0606f8ba630f5c45d07a88d612fbc85Matthew Xie    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
334ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
335ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
336ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname == NULL) goto Fail;
337ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
339ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
340ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, addr, devname, cod);
341ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
342ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
3436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
3446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(devname);
345ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
346ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
347ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
348ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->DeleteLocalRef(addr);
349ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname) callbackEnv->DeleteLocalRef(devname);
350ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGE("Error while allocating in: %s", __FUNCTION__);
351ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
352ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
353ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void ssp_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod,
354ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                 bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
355ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr, devname;
356ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
357ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
358ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
359ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
360ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
361ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("Address is null in %s", __FUNCTION__);
362ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
363ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
364ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
365ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
366ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
367ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
368ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
369ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
370ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname == NULL) goto Fail;
371ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
372ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
373ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, addr, devname, cod,
374ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                (jint) pairing_variant, pass_key);
375ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
376ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
3776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(addr);
3786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    callbackEnv->DeleteLocalRef(devname);
379ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
380ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
381ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
382ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->DeleteLocalRef(addr);
383ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname) callbackEnv->DeleteLocalRef(devname);
384ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
385ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGE("Error while allocating in: %s", __FUNCTION__);
386ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
387ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
388ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void callback_thread_event(bt_cb_thread_evt event) {
389ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    JavaVM* vm = AndroidRuntime::getJavaVM();
390ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (event  == ASSOCIATE_JVM) {
391ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        JavaVMAttachArgs args;
392ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        char name[] = "BT Service Callback Thread";
393ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        //TODO(BT)
394ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        //args.version = nat->envVer;
395ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        args.name = name;
396ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        args.group = NULL;
397ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        vm->AttachCurrentThread(&callbackEnv, &args);
398ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGV("Callback thread attached: %p", callbackEnv);
399ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else if (event == DISASSOCIATE_JVM) {
400ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (!checkCallbackThread()) {
401ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
402ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return;
403ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
404ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        vm->DetachCurrentThread();
405ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
406ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
407ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
408ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshbt_callbacks_t sBluetoothCallbacks = {
409ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sizeof(sBluetoothCallbacks),
410ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    adapter_state_change_callback,
411ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    adapter_properties_callback,
412ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    remote_device_properties_callback,
413ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    device_found_callback,
414ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    discovery_state_changed_callback,
415ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    pin_request_callback,
416ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    ssp_request_callback,
417ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bond_state_changed_callback,
418ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callback_thread_event,
419ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh};
420ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
421ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void classInitNative(JNIEnv* env, jclass clazz) {
422ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int err;
423ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    hw_module_t* module;
424ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
425ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jclass jniCallbackClass =
426ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
427ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks",
428ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        "Lcom/android/bluetooth/btservice/JniCallbacks;");
429ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
430ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
431ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
432ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass,
433ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                             "adapterPropertyChangedCallback",
434ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                             "([I[[B)V");
435ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass,
436ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                           "discoveryStateChangeCallback", "(I)V");
437ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
438ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass,
439ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                            "devicePropertyChangedCallback",
440ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                            "([B[I[[B)V");
441ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
442ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback",
443ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                 "([B[BI)V");
444ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback",
445ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                 "([B[BIII)V");
446ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
447ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass,
448ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                     "bondStateChangeCallback", "(I[BI)V");
449ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
450ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    char value[PROPERTY_VALUE_MAX];
451ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    property_get("bluetooth.mock_stack", value, "");
452ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
453ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
454ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
455ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    err = hw_get_module(id, (hw_module_t const**)&module);
456ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
457ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (err == 0) {
458ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        hw_device_t* abstraction;
459ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        err = module->methods->open(module, id, &abstraction);
460ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (err == 0) {
461ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
462ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sBluetoothInterface = btStack->get_bluetooth_interface();
463ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else {
464ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           LOGE("Error while opening Bluetooth library");
465ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
466ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else {
467ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("No Bluetooth Library found");
468ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
469ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
470ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
471ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool initNative(JNIEnv* env, jobject obj) {
472ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
473ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
474ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
475ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
476ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (sBluetoothInterface) {
477ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
478ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (ret != BT_STATUS_SUCCESS) {
479ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            LOGE("Error while setting the callbacks \n");
480ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sBluetoothInterface = NULL;
481ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return JNI_FALSE;
482ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
483cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        if ( (sBluetoothSocketInterface = (btsock_interface_t *)
484cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                  sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
485cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                LOGE("Error getting socket interface");
486cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        }
487ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_TRUE;
488ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
489ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return JNI_FALSE;
490ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
491ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
492ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool cleanupNative(JNIEnv *env, jobject obj) {
493ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
494ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
495ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
496ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
497ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
498ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sBluetoothInterface->cleanup();
4996654f5c903de510a70f9e72cd5ad7837b615d93ffredc    LOGV("%s: return from cleanup",__FUNCTION__);
5006654f5c903de510a70f9e72cd5ad7837b615d93ffredc
501ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->DeleteGlobalRef(sJniCallbacksObj);
502ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return JNI_TRUE;
503ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
504ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
505ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean enableNative(JNIEnv* env, jobject obj) {
506ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
507ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
508ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
509ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
510ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
511ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->enable();
512ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
513ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
514ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
515ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
516ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean disableNative(JNIEnv* env, jobject obj) {
517ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
518ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
519ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
520ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
521ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
522ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->disable();
523ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
524ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
525ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
526ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
527ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
528ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
529ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
530ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
531ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
532ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
533ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->start_discovery();
534ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
535ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
536ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
537ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
538ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) {
539ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
540ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
541ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
542ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
543ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
544ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->cancel_discovery();
545ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
546ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
547ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
548ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
549ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
550ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
551ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
552ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
553ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
554ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
555ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
556ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
557ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
558ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
559ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
560ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
561ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
562ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
563ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr);
564ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
565ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
566ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
567ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
568ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
569ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
570ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
571ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
572ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
573ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
574ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result;
575ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return JNI_FALSE;
576ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
577ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
578ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
579ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
580ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_FALSE;
581ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
582ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
583ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t *)addr);
584ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
585ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
586ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
587ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
588ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
589ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
590ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
591ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
592ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
593ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
594ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result;
595ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return JNI_FALSE;
596ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
597ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
598ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
599ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
600ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_FALSE;
601ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
602ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
603ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t *)addr);
604ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
605ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
606ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
607ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
608ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
609ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
610ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean pinReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept,
611ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                               jint len, jbyteArray pinArray) {
612ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
613ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
614ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr, *pinPtr = NULL;
615ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
616ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
617ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
618ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
619ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
620ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
621ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
622ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
623ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
624ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (accept) {
625ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        pinPtr = env->GetByteArrayElements(pinArray, NULL);
626ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (pinPtr == NULL) {
627ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           jniThrowIOException(env, EINVAL);
628ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           env->ReleaseByteArrayElements(address, addr, NULL);
629ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           return result;
630ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
631ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
632ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
633ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len,
634ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                              (bt_pin_code_t *) pinPtr);
635ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
636ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(pinArray, pinPtr, NULL);
637ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
638ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
639ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
640ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
641ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
642ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean sspReplyNative(JNIEnv *env, jobject obj, jbyteArray address,
643581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh                               jint type, jboolean accept, jint passkey) {
644ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
645ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
646ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
647ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
648ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
649ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
650ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
651ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
652ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
653ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
654ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
655ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
656581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh    int ret = sBluetoothInterface->ssp_reply((bt_bdaddr_t *)addr,
657581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh         (bt_ssp_variant_t) type, accept, passkey);
658ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
659ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
660ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
661ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
662ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
663ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
664ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setAdapterPropertyNative(JNIEnv *env, jobject obj, jint type, jbyteArray value) {
665ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
666ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
667ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *val;
668ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
669ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
670ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
671ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    val = env->GetByteArrayElements(value, NULL);
672ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bt_property_t prop;
673ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.type = (bt_property_type_t) type;
674ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.len = env->GetArrayLength(value);
675ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.val = val;
676ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
677ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->set_adapter_property(&prop);
678ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(value, val, NULL);
679ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
680ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
681ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
682ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
683ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
684ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertiesNative(JNIEnv *env, jobject obj) {
685ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
686ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
687ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
688ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
689ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
690ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_adapter_properties();
691ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
692ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
693ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
694ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
695ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
696ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertyNative(JNIEnv *env, jobject obj, jint type) {
697ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
698ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
699ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
700ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
701ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
702ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t) type);
703ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
704ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
705ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
706ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
707ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
708ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, jint type) {
709ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
710ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
711ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr = NULL;
712ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
713ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
714ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
715ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
716ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
717ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
718ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
719ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
720ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
721ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_remote_device_property((bt_bdaddr_t *)addr,
722ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                              (bt_property_type_t) type);
723ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
724ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
725ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
726ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
727ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
728ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
729ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address,
730ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        jint type, jbyteArray value) {
731ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
732ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
733ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *val, *addr;
734ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
735ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
736ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
737ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    val = env->GetByteArrayElements(value, NULL);
738ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (val == NULL) {
739ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
740ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
741ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
742ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
743ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
744ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
745ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->ReleaseByteArrayElements(value, val, NULL);
746ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
747ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
748ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
749ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
750ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
751ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bt_property_t prop;
752ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.type = (bt_property_type_t) type;
753ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.len = env->GetArrayLength(value);
754ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.val = val;
755ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
756ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t *)addr, &prop);
757ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(value, val, NULL);
758ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
759ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
760ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
761ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
762ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
763ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
764ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
765c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredcstatic jboolean getRemoteServicesNative(JNIEnv *env, jobject obj, jbyteArray address) {
766c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    LOGV("%s:",__FUNCTION__);
767c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
768c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    jbyte *addr = NULL;
769c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    jboolean result = JNI_FALSE;
770c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    if (!sBluetoothInterface) return result;
771c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
772c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    addr = env->GetByteArrayElements(address, NULL);
773c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    if (addr == NULL) {
774c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc        jniThrowIOException(env, EINVAL);
775c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc        return result;
776c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    }
777c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
778c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t *)addr);
779c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    env->ReleaseByteArrayElements(address, addr, NULL);
780c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
781c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    return result;
782c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc}
783c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc
784cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic int connectSocketNative(JNIEnv *env, jobject object, jbyteArray address, jint type,
785cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                                   jbyteArray uuidObj, jint channel, jint flag) {
786cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    jbyte *addr = NULL, *uuid = NULL;
787cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    int socket_fd;
788cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    bt_status_t status;
789cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
790cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!sBluetoothSocketInterface) return NULL;
791cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
792cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
793cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!addr) {
794cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        LOGE("failed to get Bluetooth device address");
795cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
796cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
797cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
798cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    uuid = env->GetByteArrayElements(uuidObj, NULL);
799cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!uuid) {
800cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        LOGE("failed to get uuid");
801cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
802cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
803cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
804cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if ( (status = sBluetoothSocketInterface->connect((bt_bdaddr_t *) addr, (btsock_type_t) type,
805cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                       (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) {
806cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        LOGE("Socket connection failed: %d", status);
807cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
808cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
809cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
810cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
811cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (socket_fd < 0) {
812cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        LOGE("Fail to creat file descriptor on socket fd");
813cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
814cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
815cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
816cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    env->ReleaseByteArrayElements(uuidObj, uuid, 0);
817cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return socket_fd;
818cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
819cc80b2261351dc74ad1bed237b0423c12d340514Matthew XieFail:
820cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (addr) env->ReleaseByteArrayElements(address, addr, 0);
821cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
822cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
823cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return -1;
824cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
825cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
826cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic int createSocketChannelNative(JNIEnv *env, jobject object, jint type,
827cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                                         jstring name_str, jbyteArray uuidObj, jint channel, jint flag) {
828cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    const char *service_name;
829cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    jbyte *uuid = NULL;
830cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    int socket_fd;
831cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    bt_status_t status;
832cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
833cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!sBluetoothSocketInterface) return NULL;
834cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
835cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    service_name = env->GetStringUTFChars(name_str, NULL);
836cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
837cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    uuid = env->GetByteArrayElements(uuidObj, NULL);
838cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (!uuid) {
839cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        LOGE("failed to get uuid");
840cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
841cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
8426654f5c903de510a70f9e72cd5ad7837b615d93ffredc    LOGE("SOCK FLAG = %x ***********************",flag);
843cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if ( (status = sBluetoothSocketInterface->listen((btsock_type_t) type, service_name,
844cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie                       (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) {
845cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        LOGE("Socket listen failed: %d", status);
846cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
847cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
848cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
849cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (socket_fd < 0) {
850cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        LOGE("Fail to creat file descriptor on socket fd");
851cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie        goto Fail;
852cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    }
853cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
854cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
855cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return socket_fd;
856cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
857cc80b2261351dc74ad1bed237b0423c12d340514Matthew XieFail:
858cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (service_name) env->ReleaseStringUTFChars(name_str, service_name);
859cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0);
860cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
861cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    return -1;
862cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie}
863cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie
864ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNINativeMethod sMethods[] = {
865ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh     /* name, signature, funcPtr */
866ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"classInitNative", "()V", (void *) classInitNative},
867ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"initNative", "()Z", (void *) initNative},
868ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cleanupNative", "()V", (void*) cleanupNative},
869ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"enableNative", "()Z",  (void*) enableNative},
870ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"disableNative", "()Z",  (void*) disableNative},
871ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative},
872ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative},
873ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative},
874ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative},
875ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative},
876ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative},
877ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative},
878ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"createBondNative", "([B)Z", (void*) createBondNative},
879ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"removeBondNative", "([B)Z", (void*) removeBondNative},
880ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cancelBondNative", "([B)Z", (void*) cancelBondNative},
881ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative},
882581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh    {"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative},
883c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc    {"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative},
884cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    {"connectSocketNative", "([BI[BII)I", (void*) connectSocketNative},
885cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie    {"createSocketChannelNative", "(ILjava/lang/String;[BII)I",
886cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie     (void*) createSocketChannelNative},
887ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh};
888ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
889ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshint register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env)
890ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{
891ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService",
892ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                    sMethods, NELEM(sMethods));
893ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
894ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
895ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} /* namespace android */
896ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
897ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
898ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
899ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * JNI Initialization
900ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
901ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshjint JNI_OnLoad(JavaVM *jvm, void *reserved)
902ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{
903ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   JNIEnv *e;
9046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   int status;
905ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
906ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   LOGV("Bluetooth Adapter Service : loading JNI\n");
907ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
908ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   // Check JNI version
9096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) {
9106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie       LOGE("JNI version mismatch error");
911ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh      return JNI_ERR;
9126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
913ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
9146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if ((status = android::register_com_android_bluetooth_btservice_AdapterService(e)) < 0) {
9156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie       LOGE("jni adapter service registration failure, status: %d", status);
916ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh      return JNI_ERR;
9176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
9186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
9196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if ((status = android::register_com_android_bluetooth_hfp(e)) < 0) {
9206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie       LOGE("jni hfp registration failure, status: %d", status);
9216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie      return JNI_ERR;
9226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
9236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
9246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if ((status = android::register_com_android_bluetooth_a2dp(e)) < 0) {
9256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie       LOGE("jni a2dp registration failure: %d", status);
9266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie      return JNI_ERR;
9276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
9286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
92935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie   if ((status = android::register_com_android_bluetooth_hid(e)) < 0) {
93035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie       LOGE("jni hid registration failure: %d", status);
931676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie       return JNI_ERR;
932676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie   }
933676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie
934676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie   if ((status = android::register_com_android_bluetooth_hdp(e)) < 0) {
935676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie       LOGE("jni hdp registration failure: %d", status);
93635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie      return JNI_ERR;
93735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie   }
93835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
9396654f5c903de510a70f9e72cd5ad7837b615d93ffredc   if ((status = android::register_com_android_bluetooth_pan(e)) < 0) {
9406654f5c903de510a70f9e72cd5ad7837b615d93ffredc       LOGE("jni pan registration failure: %d", status);
9416654f5c903de510a70f9e72cd5ad7837b615d93ffredc      return JNI_ERR;
9426654f5c903de510a70f9e72cd5ad7837b615d93ffredc   }
9436654f5c903de510a70f9e72cd5ad7837b615d93ffredc
944ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   return JNI_VERSION_1_6;
945ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
946