com_android_bluetooth_btservice_AdapterService.cpp revision cc80b2261351dc74ad1bed237b0423c12d340514
1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/* 2ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * Copyright (C) 2012 Google Inc. 3ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 4ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 5ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#define LOG_TAG "BluetoothServiceJni" 6ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 76c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "com_android_bluetooth.h" 8cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie#include "hardware/bt_sock.h" 9ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/Log.h" 10ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/misc.h" 11ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "cutils/properties.h" 12ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "android_runtime/AndroidRuntime.h" 13ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 14ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <string.h> 15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <pthread.h> 16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <sys/stat.h> 18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <fcntl.h> 19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 20ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshnamespace android { 21ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define ADDITIONAL_NREFS 50 236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_stateChangeCallback; 25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_adapterPropertyChangedCallback; 26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_devicePropertyChangedCallback; 27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_deviceFoundCallback; 28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_pinRequestCallback; 29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_sspRequestCallback; 30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_bondStateChangeCallback; 31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_discoveryStateChangeCallback; 32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic const bt_interface_t *sBluetoothInterface = NULL; 34cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic const btsock_interface_t *sBluetoothSocketInterface = NULL; 35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNIEnv *callbackEnv = NULL; 36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jobject sJniCallbacksObj; 38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jfieldID sJniCallbacksField; 39ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 40cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieconst bt_interface_t* getBluetoothInterface() { 426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return sBluetoothInterface; 436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew XieJNIEnv* getCallbackEnv() { 466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return callbackEnv; 476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xievoid checkAndClearExceptionFromCallback(JNIEnv* env, 50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh const char* methodName) { 51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (env->ExceptionCheck()) { 52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("An exception was thrown by callback '%s'.", methodName); 53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE_EX(env); 54ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ExceptionClear(); 55ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 57ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 58ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool checkCallbackThread() { 59ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh JNIEnv* env = AndroidRuntime::getJNIEnv(); 60676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie if (callbackEnv != env || callbackEnv == NULL) { 61676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie LOGE("Callback env check fail: env: %p, callback: %p", env, callbackEnv); 62676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie return false; 63676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie } 64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_state_change_callback(bt_state_t status) { 68ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!checkCallbackThread()) { 69ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s: Status is: %d", __FUNCTION__, status); 73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 74ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status); 75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 77ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 78ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic int get_properties(int num_properties, bt_property_t *properties, jintArray *types, 80ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jobjectArray *props) { 81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyteArray propVal, val; 82ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh val = (jbyteArray) callbackEnv->NewByteArray(num_properties); 83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (val == NULL) goto Fail; 84ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh //TODO(BT) Is this the best way to do it ? 86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *props = callbackEnv->NewObjectArray(num_properties, callbackEnv->GetObjectClass(val), 87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh NULL); 88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (*props == NULL) goto Fail; 89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *types = callbackEnv->NewIntArray(num_properties); 91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (*types == NULL) goto Fail; 92ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 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); 111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->SetIntArrayRegion(*types, i, 1, (jint *)&properties[i].type); 113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return 0; 115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail: 116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (val) callbackEnv->DeleteLocalRef(val); 117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (propVal) callbackEnv->DeleteLocalRef(propVal); 118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("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; 126ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!checkCallbackThread()) { 127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties); 132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (status != BT_STATUS_SUCCESS) { 134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("%s: Status %d is incorrect", __FUNCTION__, status); 135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 138ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh if (get_properties(num_properties, properties, &types, &props) < 0) { 139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (props) callbackEnv->DeleteLocalRef(props); 140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (types) callbackEnv->DeleteLocalRef(types); 141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 142ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->CallVoidMethod(sJniCallbacksObj, method_adapterPropertyChangedCallback, types, 145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh props); 146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 1476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(props); 1486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(types); 149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 151ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 152ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 153ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void remote_device_properties_callback(bt_status_t status, bt_bdaddr_t *bd_addr, 154ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int num_properties, bt_property_t *properties) { 155ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!checkCallbackThread()) { 156ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 157ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 158ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 159ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 160ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties); 161ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 162ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (status != BT_STATUS_SUCCESS) { 163ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("%s: Status %d is incorrect", __FUNCTION__, status); 164ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 165ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 166ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->PushLocalFrame(ADDITIONAL_NREFS); 1686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie jobjectArray props; 1706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie jbyteArray addr; 1716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie jintArray types; 1726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 173ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 174ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) goto Fail; 175ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr) callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr); 176ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 177ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh if (get_properties(num_properties, properties, &types, &props) < 0) { 178ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (props) callbackEnv->DeleteLocalRef(props); 179ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (types) callbackEnv->DeleteLocalRef(types); 1806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->PopLocalFrame(NULL); 181ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 183ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->CallVoidMethod(sJniCallbacksObj, method_devicePropertyChangedCallback, addr, 185ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh types, props); 186ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 1876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(props); 1886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(types); 1896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->PopLocalFrame(NULL); 190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 191ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail: 193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Error while allocation byte array in %s", __FUNCTION__); 194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 197ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void device_found_callback(int num_properties, bt_property_t *properties) { 198ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyteArray addr = NULL; 199ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int addr_index; 200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 201ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh for (int i = 0; i < num_properties; i++) { 202ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (properties[i].type == BT_PROPERTY_BDADDR) { 203ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = callbackEnv->NewByteArray(properties[i].len); 204ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr) { 205ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->SetByteArrayRegion(addr, 0, properties[i].len, 206ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh (jbyte*)properties[i].val); 207ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr_index = i; 208ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else { 209ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Address is NULL (unable to allocate) in %s", __FUNCTION__); 210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 214ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) { 215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Address is NULL in %s", __FUNCTION__); 216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 217ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 218ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 219ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s: Properties: %d, Address: %s", __FUNCTION__, num_properties, 220ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh (const char *)properties[addr_index].val); 221ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh remote_device_properties_callback(BT_STATUS_SUCCESS, (bt_bdaddr_t *)properties[addr_index].val, 223ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh num_properties, properties); 224ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, addr); 226ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 2276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(addr); 228ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 229ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 230ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void bond_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr, 231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh bt_bond_state_t state) { 232ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyteArray addr; 233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int i; 234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!checkCallbackThread()) { 235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!bd_addr) { 239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Address is null in %s", __FUNCTION__); 240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 241ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 242ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 243ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) { 244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Address allocation failed in %s", __FUNCTION__); 245ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr); 248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status, 250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr, (jint)state); 251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 2526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(addr); 253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void discovery_state_changed_callback(bt_discovery_state_t state) { 256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyteArray addr; 257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!checkCallbackThread()) { 258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s: DiscoveryState:%d ", __FUNCTION__, state); 263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->CallVoidMethod(sJniCallbacksObj, method_discoveryStateChangeCallback, 265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh (jint)state); 266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void pin_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod) { 271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyteArray addr, devname; 272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!checkCallbackThread()) { 273ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 275ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 276ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!bd_addr) { 277ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Address is null in %s", __FUNCTION__); 278ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 279ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 280ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 281ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 282ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) goto Fail; 28361c4100eb0606f8ba630f5c45d07a88d612fbc85Matthew Xie callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr); 284ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 285ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t)); 286ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (devname == NULL) goto Fail; 287ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 288ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname); 289ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 290ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, addr, devname, cod); 291ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 292ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 2936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(addr); 2946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(devname); 295ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 296ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 297ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail: 298ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr) callbackEnv->DeleteLocalRef(addr); 299ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (devname) callbackEnv->DeleteLocalRef(devname); 300ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Error while allocating in: %s", __FUNCTION__); 301ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 302ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 303ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void ssp_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod, 304ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh bt_ssp_variant_t pairing_variant, uint32_t pass_key) { 305ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyteArray addr, devname; 306ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!checkCallbackThread()) { 307ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 308ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 309ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 310ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!bd_addr) { 311ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Address is null in %s", __FUNCTION__); 312ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 313ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 314ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 315ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 316ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) goto Fail; 317ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr); 318ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 319ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t)); 320ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (devname == NULL) goto Fail; 321ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname); 322ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 323ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, addr, devname, cod, 324ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh (jint) pairing_variant, pass_key); 325ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 326ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); 3276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(addr); 3286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie callbackEnv->DeleteLocalRef(devname); 329ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 330ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 331ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail: 332ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr) callbackEnv->DeleteLocalRef(addr); 333ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (devname) callbackEnv->DeleteLocalRef(devname); 334ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 335ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Error while allocating in: %s", __FUNCTION__); 336ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 337ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void callback_thread_event(bt_cb_thread_evt event) { 339ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh JavaVM* vm = AndroidRuntime::getJavaVM(); 340ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (event == ASSOCIATE_JVM) { 341ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh JavaVMAttachArgs args; 342ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh char name[] = "BT Service Callback Thread"; 343ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh //TODO(BT) 344ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh //args.version = nat->envVer; 345ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh args.name = name; 346ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh args.group = NULL; 347ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh vm->AttachCurrentThread(&callbackEnv, &args); 348ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("Callback thread attached: %p", callbackEnv); 349ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else if (event == DISASSOCIATE_JVM) { 350ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!checkCallbackThread()) { 351ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 352ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return; 353ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 354ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh vm->DetachCurrentThread(); 355ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 356ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 357ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 358ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshbt_callbacks_t sBluetoothCallbacks = { 359ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sizeof(sBluetoothCallbacks), 360ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh adapter_state_change_callback, 361ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh adapter_properties_callback, 362ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh remote_device_properties_callback, 363ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh device_found_callback, 364ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh discovery_state_changed_callback, 365ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh pin_request_callback, 366ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh ssp_request_callback, 367ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh bond_state_changed_callback, 368ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh callback_thread_event, 369ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}; 370ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 371ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void classInitNative(JNIEnv* env, jclass clazz) { 372ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int err; 373ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh hw_module_t* module; 374ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 375ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jclass jniCallbackClass = 376ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->FindClass("com/android/bluetooth/btservice/JniCallbacks"); 377ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks", 378ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh "Lcom/android/bluetooth/btservice/JniCallbacks;"); 379ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 380ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V"); 381ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 382ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass, 383ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh "adapterPropertyChangedCallback", 384ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh "([I[[B)V"); 385ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass, 386ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh "discoveryStateChangeCallback", "(I)V"); 387ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 388ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass, 389ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh "devicePropertyChangedCallback", 390ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh "([B[I[[B)V"); 391ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V"); 392ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback", 393ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh "([B[BI)V"); 394ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback", 395ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh "([B[BIII)V"); 396ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 397ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass, 398ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh "bondStateChangeCallback", "(I[BI)V"); 399ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 400ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh char value[PROPERTY_VALUE_MAX]; 401ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh property_get("bluetooth.mock_stack", value, ""); 402ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 403ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID); 404ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 405ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh err = hw_get_module(id, (hw_module_t const**)&module); 406ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 407ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (err == 0) { 408ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh hw_device_t* abstraction; 409ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh err = module->methods->open(module, id, &abstraction); 410ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (err == 0) { 411ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction; 412ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sBluetoothInterface = btStack->get_bluetooth_interface(); 413ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else { 414ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Error while opening Bluetooth library"); 415ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 416ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else { 417ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("No Bluetooth Library found"); 418ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 419ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 420ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 421ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool initNative(JNIEnv* env, jobject obj) { 422ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 423ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 424ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField)); 425ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 426ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (sBluetoothInterface) { 427ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->init(&sBluetoothCallbacks); 428ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (ret != BT_STATUS_SUCCESS) { 429ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGE("Error while setting the callbacks \n"); 430ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sBluetoothInterface = NULL; 431ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return JNI_FALSE; 432ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 433cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if ( (sBluetoothSocketInterface = (btsock_interface_t *) 434cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) { 435cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie LOGE("Error getting socket interface"); 436cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie } 437ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return JNI_TRUE; 438ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 439ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return JNI_FALSE; 440ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 441ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 442ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool cleanupNative(JNIEnv *env, jobject obj) { 443ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 444ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 445ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 446ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 447ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 448ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sBluetoothInterface->cleanup(); 449ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->DeleteGlobalRef(sJniCallbacksObj); 450ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return JNI_TRUE; 451ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 452ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 453ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean enableNative(JNIEnv* env, jobject obj) { 454ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 455ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 456ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 457ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 458ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 459ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->enable(); 460ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 461ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 462ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 463ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 464ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean disableNative(JNIEnv* env, jobject obj) { 465ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 466ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 467ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 468ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 469ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 470ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->disable(); 471ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 472ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 473ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 474ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 475ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean startDiscoveryNative(JNIEnv* env, jobject obj) { 476ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 477ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 478ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 479ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 480ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 481ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->start_discovery(); 482ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 483ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 484ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 485ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 486ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) { 487ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 488ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 489ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 490ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 491ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 492ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->cancel_discovery(); 493ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 494ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 495ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 496ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 497ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 498ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 499ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 500ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyte *addr; 501ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 502ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 503ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 504ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 505ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = env->GetByteArrayElements(address, NULL); 506ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) { 507ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jniThrowIOException(env, EINVAL); 508ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 509ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 510ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 511ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr); 512ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(address, addr, NULL); 513ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 514ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 515ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 516ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 517ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 518ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 519ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 520ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 521ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyte *addr; 522ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result; 523ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return JNI_FALSE; 524ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 525ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = env->GetByteArrayElements(address, NULL); 526ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) { 527ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jniThrowIOException(env, EINVAL); 528ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return JNI_FALSE; 529ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 530ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 531ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t *)addr); 532ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(address, addr, NULL); 533ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 534ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 535ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 536ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 537ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 538ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 539ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 540ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 541ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyte *addr; 542ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result; 543ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return JNI_FALSE; 544ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 545ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = env->GetByteArrayElements(address, NULL); 546ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) { 547ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jniThrowIOException(env, EINVAL); 548ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return JNI_FALSE; 549ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 550ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 551ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t *)addr); 552ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(address, addr, NULL); 553ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 554ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 555ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 556ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 557ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 558ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean pinReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept, 559ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jint len, jbyteArray pinArray) { 560ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 561ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 562ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyte *addr, *pinPtr = NULL; 563ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 564ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 565ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 566ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = env->GetByteArrayElements(address, NULL); 567ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) { 568ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jniThrowIOException(env, EINVAL); 569ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 570ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 571ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 572ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (accept) { 573ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh pinPtr = env->GetByteArrayElements(pinArray, NULL); 574ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (pinPtr == NULL) { 575ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jniThrowIOException(env, EINVAL); 576ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(address, addr, NULL); 577ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 578ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 579ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 580ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 581ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len, 582ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh (bt_pin_code_t *) pinPtr); 583ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(address, addr, NULL); 584ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(pinArray, pinPtr, 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 sspReplyNative(JNIEnv *env, jobject obj, jbyteArray address, 591581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh jint type, jboolean accept, jint passkey) { 592ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 593ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 594ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyte *addr; 595ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 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 604581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh int ret = sBluetoothInterface->ssp_reply((bt_bdaddr_t *)addr, 605581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh (bt_ssp_variant_t) type, accept, passkey); 606ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(address, addr, NULL); 607ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 608ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 609ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 610ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 611ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 612ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setAdapterPropertyNative(JNIEnv *env, jobject obj, jint type, jbyteArray value) { 613ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 614ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 615ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyte *val; 616ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 617ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 618ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 619ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh val = env->GetByteArrayElements(value, NULL); 620ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh bt_property_t prop; 621ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh prop.type = (bt_property_type_t) type; 622ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh prop.len = env->GetArrayLength(value); 623ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh prop.val = val; 624ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 625ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->set_adapter_property(&prop); 626ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(value, val, NULL); 627ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 628ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 629ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 630ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 631ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 632ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertiesNative(JNIEnv *env, jobject obj) { 633ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 634ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 635ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 636ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 637ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 638ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->get_adapter_properties(); 639ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 640ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 641ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 642ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 643ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 644ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertyNative(JNIEnv *env, jobject obj, jint type) { 645ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 646ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 647ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 648ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 649ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 650ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t) type); 651ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 652ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 653ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 654ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 655ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 656ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, jint type) { 657ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 658ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 659ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyte *addr = NULL; 660ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 661ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 662ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 663ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = env->GetByteArrayElements(address, NULL); 664ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) { 665ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jniThrowIOException(env, EINVAL); 666ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 667ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 668ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 669ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->get_remote_device_property((bt_bdaddr_t *)addr, 670ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh (bt_property_type_t) type); 671ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(address, addr, NULL); 672ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 673ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 674ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 675ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 676ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 677ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, 678ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jint type, jbyteArray value) { 679ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("%s:",__FUNCTION__); 680ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 681ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jbyte *val, *addr; 682ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jboolean result = JNI_FALSE; 683ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (!sBluetoothInterface) return result; 684ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 685ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh val = env->GetByteArrayElements(value, NULL); 686ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (val == NULL) { 687ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jniThrowIOException(env, EINVAL); 688ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 689ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 690ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 691ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addr = env->GetByteArrayElements(address, NULL); 692ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (addr == NULL) { 693ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(value, val, NULL); 694ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh jniThrowIOException(env, EINVAL); 695ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 696ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 697ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 698ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 699ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh bt_property_t prop; 700ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh prop.type = (bt_property_type_t) type; 701ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh prop.len = env->GetArrayLength(value); 702ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh prop.val = val; 703ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 704ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t *)addr, &prop); 705ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(value, val, NULL); 706ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh env->ReleaseByteArrayElements(address, addr, NULL); 707ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 708ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 709ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 710ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return result; 711ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 712ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 713cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic int connectSocketNative(JNIEnv *env, jobject object, jbyteArray address, jint type, 714cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie jbyteArray uuidObj, jint channel, jint flag) { 715cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie jbyte *addr = NULL, *uuid = NULL; 716cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie int socket_fd; 717cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie bt_status_t status; 718cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 719cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (!sBluetoothSocketInterface) return NULL; 720cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 721cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie addr = env->GetByteArrayElements(address, NULL); 722cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (!addr) { 723cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie LOGE("failed to get Bluetooth device address"); 724cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie goto Fail; 725cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie } 726cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 727cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie uuid = env->GetByteArrayElements(uuidObj, NULL); 728cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (!uuid) { 729cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie LOGE("failed to get uuid"); 730cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie goto Fail; 731cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie } 732cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 733cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if ( (status = sBluetoothSocketInterface->connect((bt_bdaddr_t *) addr, (btsock_type_t) type, 734cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) { 735cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie LOGE("Socket connection failed: %d", status); 736cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie goto Fail; 737cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie } 738cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 739cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 740cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (socket_fd < 0) { 741cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie LOGE("Fail to creat file descriptor on socket fd"); 742cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie goto Fail; 743cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie } 744cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie env->ReleaseByteArrayElements(address, addr, 0); 745cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie env->ReleaseByteArrayElements(uuidObj, uuid, 0); 746cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie return socket_fd; 747cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 748cc80b2261351dc74ad1bed237b0423c12d340514Matthew XieFail: 749cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (addr) env->ReleaseByteArrayElements(address, addr, 0); 750cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); 751cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 752cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie return -1; 753cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie} 754cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 755cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xiestatic int createSocketChannelNative(JNIEnv *env, jobject object, jint type, 756cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie jstring name_str, jbyteArray uuidObj, jint channel, jint flag) { 757cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie const char *service_name; 758cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie jbyte *uuid = NULL; 759cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie int socket_fd; 760cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie bt_status_t status; 761cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 762cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (!sBluetoothSocketInterface) return NULL; 763cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 764cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie service_name = env->GetStringUTFChars(name_str, NULL); 765cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 766cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie uuid = env->GetByteArrayElements(uuidObj, NULL); 767cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (!uuid) { 768cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie LOGE("failed to get uuid"); 769cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie goto Fail; 770cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie } 771cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 772cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if ( (status = sBluetoothSocketInterface->listen((btsock_type_t) type, service_name, 773cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie (const uint8_t*) uuid, channel, &socket_fd, flag)) != BT_STATUS_SUCCESS) { 774cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie LOGE("Socket listen failed: %d", status); 775cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie goto Fail; 776cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie } 777cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 778cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (socket_fd < 0) { 779cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie LOGE("Fail to creat file descriptor on socket fd"); 780cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie goto Fail; 781cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie } 782cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 783cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); 784cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie return socket_fd; 785cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 786cc80b2261351dc74ad1bed237b0423c12d340514Matthew XieFail: 787cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 788cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); 789cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 790cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie return -1; 791cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie} 792cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 793ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNINativeMethod sMethods[] = { 794ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh /* name, signature, funcPtr */ 795ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"classInitNative", "()V", (void *) classInitNative}, 796ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"initNative", "()Z", (void *) initNative}, 797ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"cleanupNative", "()V", (void*) cleanupNative}, 798ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"enableNative", "()Z", (void*) enableNative}, 799ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"disableNative", "()Z", (void*) disableNative}, 800ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative}, 801ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative}, 802ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative}, 803ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative}, 804ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative}, 805ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative}, 806ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative}, 807ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"createBondNative", "([B)Z", (void*) createBondNative}, 808ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"removeBondNative", "([B)Z", (void*) removeBondNative}, 809ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"cancelBondNative", "([B)Z", (void*) cancelBondNative}, 810ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative}, 811581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh {"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative}, 812cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie {"connectSocketNative", "([BI[BII)I", (void*) connectSocketNative}, 813cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie {"createSocketChannelNative", "(ILjava/lang/String;[BII)I", 814cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie (void*) createSocketChannelNative}, 815ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}; 816ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 817ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshint register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) 818ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{ 819ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService", 820ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sMethods, NELEM(sMethods)); 821ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 822ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 823ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} /* namespace android */ 824ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 825ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 826ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/* 827ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * JNI Initialization 828ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 829ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshjint JNI_OnLoad(JavaVM *jvm, void *reserved) 830ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{ 831ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh JNIEnv *e; 8326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie int status; 833ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 834ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh LOGV("Bluetooth Adapter Service : loading JNI\n"); 835ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 836ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh // Check JNI version 8376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) { 8386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie LOGE("JNI version mismatch error"); 839ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return JNI_ERR; 8406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 841ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 8426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if ((status = android::register_com_android_bluetooth_btservice_AdapterService(e)) < 0) { 8436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie LOGE("jni adapter service registration failure, status: %d", status); 844ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return JNI_ERR; 8456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 8466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 8476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if ((status = android::register_com_android_bluetooth_hfp(e)) < 0) { 8486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie LOGE("jni hfp registration failure, status: %d", status); 8496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return JNI_ERR; 8506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 8516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 8526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie if ((status = android::register_com_android_bluetooth_a2dp(e)) < 0) { 8536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie LOGE("jni a2dp registration failure: %d", status); 8546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return JNI_ERR; 8556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 8566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 85735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie if ((status = android::register_com_android_bluetooth_hid(e)) < 0) { 85835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie LOGE("jni hid registration failure: %d", status); 859676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie return JNI_ERR; 860676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie } 861676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie 862676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie if ((status = android::register_com_android_bluetooth_hdp(e)) < 0) { 863676cb1bdd1c14c7af56562bab51f168e7f8f6d62Matthew Xie LOGE("jni hdp registration failure: %d", status); 86435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie return JNI_ERR; 86535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie } 86635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie 867ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return JNI_VERSION_1_6; 868ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 869