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