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