1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/* 2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project 3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License"); 5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License. 6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at 7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * http://www.apache.org/licenses/LICENSE-2.0 9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software 11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS, 12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and 14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License. 15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#define LOG_TAG "BluetoothServiceJni" 18dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include "android_runtime/AndroidRuntime.h" 19dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include "android_runtime/Log.h" 206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "com_android_bluetooth.h" 21dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include "cutils/properties.h" 22cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie#include "hardware/bt_sock.h" 23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/Log.h" 24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/misc.h" 25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <pthread.h> 27dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include <string.h> 28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <fcntl.h> 307e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker#include <sys/prctl.h> 31dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include <sys/stat.h> 32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshnamespace android { 3433d233cc3a1be101258f7ab3a11fe186300ddf47Jakub Pawlowski// OOB_LE_BD_ADDR_SIZE is 6 bytes addres + 1 byte address type 3533d233cc3a1be101258f7ab3a11fe186300ddf47Jakub Pawlowski#define OOB_LE_BD_ADDR_SIZE 7 36914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski#define OOB_TK_SIZE 16 371d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski#define OOB_LE_SC_C_SIZE 16 381d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski#define OOB_LE_SC_R_SIZE 16 39914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski 40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_stateChangeCallback; 41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_adapterPropertyChangedCallback; 42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_devicePropertyChangedCallback; 43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_deviceFoundCallback; 44ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_pinRequestCallback; 45ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_sspRequestCallback; 46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_bondStateChangeCallback; 4701a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamystatic jmethodID method_aclStateChangeCallback; 48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_discoveryStateChangeCallback; 491e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_setWakeAlarm; 501e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_acquireWakeLock; 511e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jmethodID method_releaseWakeLock; 52f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadhamstatic jmethodID method_energyInfo; 53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 54cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinskistatic struct { 55dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jclass clazz; 56dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jmethodID constructor; 57cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski} android_bluetooth_UidTraffic; 58cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski 59dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic const bt_interface_t* sBluetoothInterface = NULL; 60dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic const btsock_interface_t* sBluetoothSocketInterface = NULL; 61dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic JNIEnv* callbackEnv = NULL; 62ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 631e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic jobject sJniAdapterServiceObj; 64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jobject sJniCallbacksObj; 65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jfieldID sJniCallbacksField; 66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 67dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenconst bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; } 686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 69dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie JanssenJNIEnv* getCallbackEnv() { return callbackEnv; } 706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_state_change_callback(bt_state_t status) { 72dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 73dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 74dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s: Status is: %d", __func__, status); 75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 76dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, 77dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (jint)status); 78ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 80dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int get_properties(int num_properties, bt_property_t* properties, 81dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jintArray* types, jobjectArray* props) { 82dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen for (int i = 0; i < num_properties; i++) { 83479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jbyteArray> propVal( 84479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen callbackEnv, callbackEnv->NewByteArray(properties[i].len)); 85479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!propVal.get()) { 86479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ALOGE("Error while allocation of array in %s", __func__); 87479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen return -1; 88479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen } 89dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 90479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen callbackEnv->SetByteArrayRegion(propVal.get(), 0, properties[i].len, 91dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (jbyte*)properties[i].val); 92479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen callbackEnv->SetObjectArrayElement(*props, i, propVal.get()); 93dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen callbackEnv->SetIntArrayRegion(*types, i, 1, (jint*)&properties[i].type); 94dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 95dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return 0; 96ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 97ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 98ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_properties_callback(bt_status_t status, int num_properties, 99dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_property_t* properties) { 100dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 101dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 102dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 103dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties); 104dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 105dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status != BT_STATUS_SUCCESS) { 106dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("%s: Status %d is incorrect", __func__, status); 107dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 108dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 109dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 110479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jbyteArray> val( 111479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), 112479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen (jbyteArray)sCallbackEnv->NewByteArray(num_properties)); 113479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!val.get()) { 114dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("%s: Error allocating byteArray", __func__); 115dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 116dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 117dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 118479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jclass> mclass(sCallbackEnv.get(), 119479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->GetObjectClass(val.get())); 120dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 121dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen /* (BT) Initialize the jobjectArray and jintArray here itself and send the 122dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen initialized array pointers alone to get_properties */ 123dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 124479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jobjectArray> props( 125479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), 126479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL)); 127479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!props.get()) { 128dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("%s: Error allocating object Array for properties", __func__); 129dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 130dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 131dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 132479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jintArray> types( 133479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties)); 134479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!types.get()) { 135dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("%s: Error allocating int Array for values", __func__); 136dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 137dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 138dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 139479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen jintArray typesPtr = types.get(); 140479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen jobjectArray propsPtr = props.get(); 141479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) { 142dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 143dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 144dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 145479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->CallVoidMethod(sJniCallbacksObj, 146479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen method_adapterPropertyChangedCallback, 147479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen types.get(), props.get()); 148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 150dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void remote_device_properties_callback(bt_status_t status, 151b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski RawAddress* bd_addr, 152dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int num_properties, 153dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_property_t* properties) { 154dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 155dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 156dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 157dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties); 158dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 159dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status != BT_STATUS_SUCCESS) { 160dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("%s: Status %d is incorrect", __func__, status); 161dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 162dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 163dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 164479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jbyteArray> val( 165479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), 166479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen (jbyteArray)sCallbackEnv->NewByteArray(num_properties)); 167479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!val.get()) { 168dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("%s: Error allocating byteArray", __func__); 169dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 170dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 171dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 172479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jclass> mclass(sCallbackEnv.get(), 173479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->GetObjectClass(val.get())); 174dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 175dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen /* Initialize the jobjectArray and jintArray here itself and send the 176dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen initialized array pointers alone to get_properties */ 177dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 178479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jobjectArray> props( 179479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), 180479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL)); 181479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!props.get()) { 182dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("%s: Error allocating object Array for properties", __func__); 183dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 184dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 185dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 186479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jintArray> types( 187479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties)); 188479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!types.get()) { 189dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("%s: Error allocating int Array for values", __func__); 190dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 191dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 192dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1932116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ScopedLocalRef<jbyteArray> addr( 194b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); 1952116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!addr.get()) { 1962116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ALOGE("Error while allocation byte array in %s", __func__); 1972116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return; 1982116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach } 1992116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach 200b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), 2012116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach (jbyte*)bd_addr); 202dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 203479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen jintArray typesPtr = types.get(); 204479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen jobjectArray propsPtr = props.get(); 205479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (get_properties(num_properties, properties, &typesPtr, &propsPtr) < 0) { 206dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 207dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 208dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 209dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod(sJniCallbacksObj, 210479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen method_devicePropertyChangedCallback, addr.get(), 211479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen types.get(), props.get()); 212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 214dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void device_found_callback(int num_properties, 215dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_property_t* properties) { 216dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 217dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 218dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 2192116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), NULL); 220dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int addr_index; 221dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen for (int i = 0; i < num_properties; i++) { 222dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (properties[i].type == BT_PROPERTY_BDADDR) { 2232116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach addr.reset(sCallbackEnv->NewByteArray(properties[i].len)); 2242116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!addr.get()) { 2252116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ALOGE("Address is NULL (unable to allocate) in %s", __func__); 2262116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return; 2272116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach } 2282116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach sCallbackEnv->SetByteArrayRegion(addr.get(), 0, properties[i].len, 2292116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach (jbyte*)properties[i].val); 230479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen addr_index = i; 231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 232dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 2332116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!addr.get()) { 2342116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ALOGE("Address is NULL in %s", __func__); 2352116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return; 2362116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach } 237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 238dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s: Properties: %d, Address: %s", __func__, num_properties, 239dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (const char*)properties[addr_index].val); 240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 241dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen remote_device_properties_callback(BT_STATUS_SUCCESS, 242b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski (RawAddress*)properties[addr_index].val, 243dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen num_properties, properties); 244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 245dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, 246479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen addr.get()); 247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 249b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr, 250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh bt_bond_state_t state) { 251dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 252dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 253dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 254dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!bd_addr) { 255dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Address is null in %s", __func__); 256dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 257dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 258dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 2592116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ScopedLocalRef<jbyteArray> addr( 260b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); 2612116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!addr.get()) { 2622116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ALOGE("Address allocation failed in %s", __func__); 2632116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return; 2642116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach } 265b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), 2662116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach (jbyte*)bd_addr); 267dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 268dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, 269479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen (jint)status, addr.get(), (jint)state); 270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 272b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, 273dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_acl_state_t state) { 274dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!bd_addr) { 275dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Address is null in %s", __func__); 276dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 277dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 278dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 279dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 280dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 281dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 2822116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ScopedLocalRef<jbyteArray> addr( 283b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); 2842116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!addr.get()) { 2852116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ALOGE("Address allocation failed in %s", __func__); 2862116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return; 2872116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach } 288b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), 2892116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach (jbyte*)bd_addr); 290dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 291dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, 292479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen (jint)status, addr.get(), (jint)state); 29301a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy} 29401a8cf98f070a6996b2e8974edc229ac402f3f0cKausik Sinnaswamy 295ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void discovery_state_changed_callback(bt_discovery_state_t state) { 296dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 297dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 298ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 299dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s: DiscoveryState:%d ", __func__, state); 300ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 301dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod( 302dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state); 303ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 304ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 305b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void pin_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname, 306dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen uint32_t cod, bool min_16_digits) { 307dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!bd_addr) { 308dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Address is null in %s", __func__); 309dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 310dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 311ae15d3d42fcb3349c11d394423493020e78c5f43Marie Janssen 312dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 313dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 314ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 3152116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ScopedLocalRef<jbyteArray> addr( 316b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); 3172116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!addr.get()) { 3182116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ALOGE("Error while allocating in: %s", __func__); 3192116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return; 3202116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach } 3212116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach 322b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), 3232116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach (jbyte*)bd_addr); 324ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 325479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jbyteArray> devname( 326479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t))); 327479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!devname.get()) { 328dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Error while allocating in: %s", __func__); 329dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 330dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 331ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 332479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t), 333dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (jbyte*)bdname); 334ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 335dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, 336479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen addr.get(), devname.get(), cod, min_16_digits); 337dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen} 338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 339b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname, 340dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen uint32_t cod, bt_ssp_variant_t pairing_variant, 341dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen uint32_t pass_key) { 342dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!bd_addr) { 343dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Address is null in %s", __func__); 344dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 345dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 346dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 347dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 348dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 3492116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ScopedLocalRef<jbyteArray> addr( 350b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); 3512116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!addr.get()) { 3522116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ALOGE("Error while allocating in: %s", __func__); 3532116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return; 3542116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach } 3552116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach 356b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), 3572116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach (jbyte*)bd_addr); 358dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 359479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jbyteArray> devname( 360479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t))); 361479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!devname.get()) { 362dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Error while allocating in: %s", __func__); 363dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 364dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 365ae15d3d42fcb3349c11d394423493020e78c5f43Marie Janssen 366479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->SetByteArrayRegion(devname.get(), 0, sizeof(bt_bdname_t), 367dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (jbyte*)bdname); 368ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 369dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, 370479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen addr.get(), devname.get(), cod, 371479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen (jint)pairing_variant, pass_key); 372ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 373ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 374ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void callback_thread_event(bt_cb_thread_evt event) { 375dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen JavaVM* vm = AndroidRuntime::getJavaVM(); 376dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (event == ASSOCIATE_JVM) { 377dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen JavaVMAttachArgs args; 378dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen char name[] = "BT Service Callback Thread"; 379dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen args.version = JNI_VERSION_1_6; 380dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen args.name = name; 381dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen args.group = NULL; 382dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen vm->AttachCurrentThread(&callbackEnv, &args); 383dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("Callback thread attached: %p", callbackEnv); 384dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } else if (event == DISASSOCIATE_JVM) { 385dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (callbackEnv != AndroidRuntime::getJNIEnv()) { 386dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Callback: '%s' is not called on the correct thread", __func__); 387dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 388ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 389dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen vm->DetachCurrentThread(); 390dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 391ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 392ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 393dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) { 39403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 39503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta} 39603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 397dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void le_test_mode_recv_callback(bt_status_t status, 398dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen uint16_t packet_count) { 399dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s: status:%d packet_count:%d ", __func__, status, packet_count); 40003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta} 401f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham 402dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void energy_info_recv_callback(bt_activity_energy_info* p_energy_info, 403fe37710d689b7573ddeb901141db42c28b6cab39Marie Janssen bt_uid_traffic_t* uid_data) { 404dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 405dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 406dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 407dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jsize len = 0; 408dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) { 409dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen len++; 410dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 411dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 412479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jobjectArray> array( 413479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), sCallbackEnv->NewObjectArray( 414479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen len, android_bluetooth_UidTraffic.clazz, NULL)); 415dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jsize i = 0; 416dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen for (bt_uid_traffic_t* data = uid_data; data->app_uid != -1; data++) { 417479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jobject> uidObj( 418479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv.get(), 419479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->NewObject(android_bluetooth_UidTraffic.clazz, 420479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen android_bluetooth_UidTraffic.constructor, 421479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen (jint)data->app_uid, (jlong)data->rx_bytes, 422479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen (jlong)data->tx_bytes)); 423479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->SetObjectArrayElement(array.get(), i++, uidObj.get()); 424dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 425dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 426dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod( 427dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sJniAdapterServiceObj, method_energyInfo, p_energy_info->status, 428dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen p_energy_info->ctrl_state, p_energy_info->tx_time, p_energy_info->rx_time, 429479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen p_energy_info->idle_time, p_energy_info->energy_used, array.get()); 430f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham} 431f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham 4321e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic bt_callbacks_t sBluetoothCallbacks = { 433dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sizeof(sBluetoothCallbacks), adapter_state_change_callback, 434dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen adapter_properties_callback, remote_device_properties_callback, 435dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen device_found_callback, discovery_state_changed_callback, 436dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen pin_request_callback, ssp_request_callback, 437dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bond_state_changed_callback, acl_state_changed_callback, 438dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen callback_thread_event, dut_mode_recv_callback, 439dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen le_test_mode_recv_callback, energy_info_recv_callback}; 440ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 4411e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// The callback to call when the wake alarm fires. 4421e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic alarm_cb sAlarmCallback; 4431e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati 4441e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// The data to pass to the wake alarm callback. 445dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void* sAlarmCallbackData; 4461e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati 4477e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panickerclass JNIThreadAttacher { 4487e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker public: 4497e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JNIThreadAttacher() : vm_(nullptr), env_(nullptr) { 4507e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker vm_ = AndroidRuntime::getJavaVM(); 4517e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6); 4527e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker 4537e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker if (status_ != JNI_OK && status_ != JNI_EDETACHED) { 4547e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker ALOGE( 4557e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker "JNIThreadAttacher: unable to get environment for JNI CALL, " 4567e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker "status: %d", 4577e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker status_); 4587e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker env_ = nullptr; 4597e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker return; 4607e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker } 461beccdc6d1647c56c91ddfd14f7990371168fb870Sharvil Nanavati 4627e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker if (status_ == JNI_EDETACHED) { 4637e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker char name[17] = {0}; 4647e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker if (prctl(PR_GET_NAME, (unsigned long)name) != 0) { 4657e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker ALOGE( 4667e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker "JNIThreadAttacher: unable to grab previous thread name, error: %s", 4677e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker strerror(errno)); 4687e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker env_ = nullptr; 4697e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker return; 4707e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker } 471dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 4727e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JavaVMAttachArgs args = { 4737e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker .version = JNI_VERSION_1_6, .name = name, .group = nullptr}; 4747e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker if (vm_->AttachCurrentThread(&env_, &args) != 0) { 4757e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker ALOGE("JNIThreadAttacher: unable to attach thread to VM"); 4767e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker env_ = nullptr; 4777e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker return; 4787e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker } 4797e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker } 4807e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker } 4817e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker 4827e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker ~JNIThreadAttacher() { 4837e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker if (status_ == JNI_EDETACHED) vm_->DetachCurrentThread(); 484dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 485dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 4867e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JNIEnv* getEnv() { return env_; } 4877e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker 4887e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker private: 4897e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JavaVM* vm_; 4907e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JNIEnv* env_; 4917e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker jint status_; 4927e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker}; 4937e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker 4947e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panickerstatic bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake, 4957e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker alarm_cb cb, void* data) { 4967e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JNIThreadAttacher attacher; 4977e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JNIEnv* env = attacher.getEnv(); 4987e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker 4997e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker if (env == nullptr) { 5007e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker ALOGE("%s: Unable to get JNI Env", __func__); 501dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return false; 502dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 503dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 504dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sAlarmCallback = cb; 505dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sAlarmCallbackData = data; 506dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 507dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jboolean jshould_wake = should_wake ? JNI_TRUE : JNI_FALSE; 508dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jboolean ret = 509dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->CallBooleanMethod(sJniAdapterServiceObj, method_setWakeAlarm, 510dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (jlong)delay_millis, jshould_wake); 511dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!ret) { 512dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sAlarmCallback = NULL; 513dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sAlarmCallbackData = NULL; 514dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 515dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 5167e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker return (ret == JNI_TRUE); 5171e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati} 5181e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati 519dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int acquire_wake_lock_callout(const char* lock_name) { 5207e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JNIThreadAttacher attacher; 5217e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JNIEnv* env = attacher.getEnv(); 5227e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker 5237e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker if (env == nullptr) { 5247e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker ALOGE("%s: Unable to get JNI Env", __func__); 525dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return BT_STATUS_JNI_THREAD_ATTACH_ERROR; 526dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 527dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 528dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jint ret = BT_STATUS_SUCCESS; 529479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen { 530479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name)); 531479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (lock_name_jni.get()) { 532479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen bool acquired = env->CallBooleanMethod( 533479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sJniAdapterServiceObj, method_acquireWakeLock, lock_name_jni.get()); 534479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR; 535479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen } else { 536479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ALOGE("%s unable to allocate string: %s", __func__, lock_name); 537479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ret = BT_STATUS_NOMEM; 538479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen } 539dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 540dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 541dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return ret; 5421e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati} 5431e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati 544dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int release_wake_lock_callout(const char* lock_name) { 5457e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JNIThreadAttacher attacher; 5467e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker JNIEnv* env = attacher.getEnv(); 5477e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker 5487e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker if (env == nullptr) { 5497e7f0be7a03ac9fac07ad9ef47522a237ba36a62Ajay Panicker ALOGE("%s: Unable to get JNI Env", __func__); 550dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return BT_STATUS_JNI_THREAD_ATTACH_ERROR; 551dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 552dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 553dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jint ret = BT_STATUS_SUCCESS; 554479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen { 555479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jstring> lock_name_jni(env, env->NewStringUTF(lock_name)); 556479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (lock_name_jni.get()) { 557479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen bool released = env->CallBooleanMethod( 558479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sJniAdapterServiceObj, method_releaseWakeLock, lock_name_jni.get()); 559479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen if (!released) ret = BT_STATUS_WAKELOCK_ERROR; 560479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen } else { 561479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ALOGE("%s unable to allocate string: %s", __func__, lock_name); 562479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ret = BT_STATUS_NOMEM; 563479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen } 564dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 565dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 566dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return ret; 5671e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati} 5681e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati 5691e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// Called by Java code when alarm is fired. A wake lock is held by the caller 5701e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati// over the duration of this callback. 571dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void alarmFiredNative(JNIEnv* env, jobject obj) { 572dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (sAlarmCallback) { 573dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sAlarmCallback(sAlarmCallbackData); 574dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } else { 575dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("%s() - Alarm fired with callback not set!", __func__); 576dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 5771e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati} 5781e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati 5791e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavatistatic bt_os_callouts_t sBluetoothOsCallouts = { 580dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sizeof(sBluetoothOsCallouts), set_wake_alarm_callout, 581dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen acquire_wake_lock_callout, release_wake_lock_callout, 5821e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati}; 5831e9f8a14e120e8786711abdd4a965236191c87adSharvil Nanavati 584ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void classInitNative(JNIEnv* env, jclass clazz) { 585dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic"); 586dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen android_bluetooth_UidTraffic.constructor = 587dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(jniUidTrafficClass, "<init>", "(IJJ)V"); 588dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 589dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jclass jniCallbackClass = 590dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->FindClass("com/android/bluetooth/btservice/JniCallbacks"); 591dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sJniCallbacksField = env->GetFieldID( 592dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;"); 593dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 594dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_stateChangeCallback = 595dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V"); 596dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 597dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_adapterPropertyChangedCallback = env->GetMethodID( 598dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniCallbackClass, "adapterPropertyChangedCallback", "([I[[B)V"); 599dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_discoveryStateChangeCallback = env->GetMethodID( 600dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniCallbackClass, "discoveryStateChangeCallback", "(I)V"); 601dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 602dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_devicePropertyChangedCallback = env->GetMethodID( 603dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniCallbackClass, "devicePropertyChangedCallback", "([B[I[[B)V"); 604dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_deviceFoundCallback = 605dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V"); 606dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_pinRequestCallback = 607dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V"); 608dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_sspRequestCallback = 609dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V"); 610dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 611dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_bondStateChangeCallback = 612dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V"); 613dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 614dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_aclStateChangeCallback = 615dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BI)V"); 616dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 617dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z"); 618dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_acquireWakeLock = 619dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z"); 620dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_releaseWakeLock = 621dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z"); 622dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_energyInfo = env->GetMethodID( 623dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V"); 624dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 625dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen char value[PROPERTY_VALUE_MAX]; 626dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen property_get("bluetooth.mock_stack", value, ""); 627dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 628dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen const char* id = 629dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (strcmp(value, "1") ? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID); 630dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 631dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen hw_module_t* module; 632dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int err = hw_get_module(id, (hw_module_t const**)&module); 633dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 634dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (err == 0) { 635dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen hw_device_t* abstraction; 636dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen err = module->methods->open(module, id, &abstraction); 637ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (err == 0) { 638dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bluetooth_module_t* btStack = (bluetooth_module_t*)abstraction; 639dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sBluetoothInterface = btStack->get_bluetooth_interface(); 640ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else { 641dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Error while opening Bluetooth library"); 642ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 643dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } else { 644dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("No Bluetooth Library found"); 645dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 646ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 647ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 648ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool initNative(JNIEnv* env, jobject obj) { 649dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 650dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 651dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen android_bluetooth_UidTraffic.clazz = 652dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic")); 653dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 654dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sJniAdapterServiceObj = env->NewGlobalRef(obj); 655dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sJniCallbacksObj = 656dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField)); 657dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 658dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) { 659dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 660dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 661dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 662dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->init(&sBluetoothCallbacks); 663dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (ret != BT_STATUS_SUCCESS) { 664dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Error while setting the callbacks: %d\n", ret); 665dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sBluetoothInterface = NULL; 666dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 667dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 668dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts); 669dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (ret != BT_STATUS_SUCCESS) { 670dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Error while setting Bluetooth callouts: %d\n", ret); 671dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sBluetoothInterface->cleanup(); 672dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sBluetoothInterface = NULL; 673dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 674dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 675dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 676dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sBluetoothSocketInterface = 677dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (btsock_interface_t*)sBluetoothInterface->get_profile_interface( 678dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen BT_PROFILE_SOCKETS_ID); 679dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (sBluetoothSocketInterface == NULL) { 680dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Error getting socket interface"); 681dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 682dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 683dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_TRUE; 684ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 685ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 686dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic bool cleanupNative(JNIEnv* env, jobject obj) { 687dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 688ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 689dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 690ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 691dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sBluetoothInterface->cleanup(); 692dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGI("%s: return from cleanup", __func__); 6936654f5c903de510a70f9e72cd5ad7837b615d93ffredc 694dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->DeleteGlobalRef(sJniCallbacksObj); 695dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->DeleteGlobalRef(sJniAdapterServiceObj); 696dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->DeleteGlobalRef(android_bluetooth_UidTraffic.clazz); 697dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen android_bluetooth_UidTraffic.clazz = NULL; 698dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_TRUE; 699ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 700ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 701c63ef51ba5f9d355239959bcfe8803987adb1f38Ajay Panickerstatic jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) { 702dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 703ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 704dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 705dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0); 706dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE 707dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen : JNI_FALSE; 708ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 709ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 710ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean disableNative(JNIEnv* env, jobject obj) { 711dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 712ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 713dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 714ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 715dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->disable(); 716dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen /* Retrun JNI_FALSE only when BTIF explicitly reports 717dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen BT_STATUS_FAIL. It is fine for the BT_STATUS_NOT_READY 718dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen case which indicates that stack had not been enabled. 719dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen */ 720dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_FAIL) ? JNI_FALSE : JNI_TRUE; 721ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 722ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 723ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean startDiscoveryNative(JNIEnv* env, jobject obj) { 724dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 725ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 726dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 727ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 728dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->start_discovery(); 729dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 730ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 731ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 732ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) { 733dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 734ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 735dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 736ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 737dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->cancel_discovery(); 738dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 739ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 740ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 741dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, 742dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jint transport) { 743dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 744ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 745dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 746ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 747dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 748dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 749dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 750dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 751dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 752ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 753b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski int ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport); 754dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 755dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 756ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 757ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 75821f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panickerstatic jbyteArray callByteArrayGetter(JNIEnv* env, jobject object, 75921f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panicker const char* className, 76021f921a43af4c93f23f8d3fd52033c9720200e89Ajay Panicker const char* methodName) { 761dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jclass myClass = env->FindClass(className); 762dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B"); 763dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (jbyteArray)env->CallObjectMethod(object, myMethod); 764914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski} 765914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski 766dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj, 767dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray address, jint transport, 768dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jobject oobData) { 769dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_out_of_band_data_t oob_data; 770dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 771dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen memset(&oob_data, 0, sizeof(oob_data)); 772dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 773dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 774dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 775dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 776dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 777dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 778dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 779dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 780dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 781dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* leBtDeviceAddressBytes = NULL; 782dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* smTKBytes = NULL; 783dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* leScCBytes = NULL; 784dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* leScRBytes = NULL; 785dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray leBtDeviceAddress = NULL; 786dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray smTK = NULL; 787dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray leScC = NULL; 788dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray leScR = NULL; 789dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int status = BT_STATUS_FAIL; 790dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 791dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen leBtDeviceAddress = callByteArrayGetter( 792dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env, oobData, "android/bluetooth/OobData", "getLeBluetoothDeviceAddress"); 793dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (leBtDeviceAddress != NULL) { 794dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen leBtDeviceAddressBytes = env->GetByteArrayElements(leBtDeviceAddress, NULL); 795dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int len = env->GetArrayLength(leBtDeviceAddress); 796dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (len != OOB_LE_BD_ADDR_SIZE) { 797dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGI( 798dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen "%s: wrong length of leBtDeviceAddress, should be empty or %d bytes.", 799dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen __func__, OOB_LE_BD_ADDR_SIZE); 800dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 801dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen goto done; 802dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 803dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen memcpy(oob_data.le_bt_dev_addr, leBtDeviceAddressBytes, len); 804dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 805dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 806dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen smTK = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", 807dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen "getSecurityManagerTk"); 808dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (smTK != NULL) { 809dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen smTKBytes = env->GetByteArrayElements(smTK, NULL); 810dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int len = env->GetArrayLength(smTK); 811dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (len != OOB_TK_SIZE) { 812dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGI("%s: wrong length of smTK, should be empty or %d bytes.", __func__, 813dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen OOB_TK_SIZE); 814dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 815dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen goto done; 816dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 817dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen memcpy(oob_data.sm_tk, smTKBytes, len); 818dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 819dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 820dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen leScC = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", 821dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen "getLeSecureConnectionsConfirmation"); 822dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (leScC != NULL) { 823dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen leScCBytes = env->GetByteArrayElements(leScC, NULL); 824dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int len = env->GetArrayLength(leScC); 825dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (len != OOB_LE_SC_C_SIZE) { 826dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGI( 827dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen "%s: wrong length of LE SC Confirmation, should be empty or %d " 828dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen "bytes.", 829dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen __func__, OOB_LE_SC_C_SIZE); 830dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 831dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen goto done; 832dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 833dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen memcpy(oob_data.le_sc_c, leScCBytes, len); 834dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 835dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 836dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen leScR = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", 837dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen "getLeSecureConnectionsRandom"); 838dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (leScR != NULL) { 839dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen leScRBytes = env->GetByteArrayElements(leScR, NULL); 840dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int len = env->GetArrayLength(leScR); 841dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (len != OOB_LE_SC_R_SIZE) { 842dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGI("%s: wrong length of LE SC Random, should be empty or %d bytes.", 843dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen __func__, OOB_LE_SC_R_SIZE); 844dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 845dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen goto done; 846dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 847dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen memcpy(oob_data.le_sc_r, leScRBytes, len); 848dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 849dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 850b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski status = sBluetoothInterface->create_bond_out_of_band((RawAddress*)addr, 851dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen transport, &oob_data); 852914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski 853914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowskidone: 854dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 855914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski 856dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (leBtDeviceAddress != NULL) 857dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(leBtDeviceAddress, leBtDeviceAddressBytes, 0); 85833d233cc3a1be101258f7ab3a11fe186300ddf47Jakub Pawlowski 859dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (smTK != NULL) env->ReleaseByteArrayElements(smTK, smTKBytes, 0); 860914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski 861dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (leScC != NULL) env->ReleaseByteArrayElements(leScC, leScCBytes, 0); 8621d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski 863dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (leScR != NULL) env->ReleaseByteArrayElements(leScR, leScRBytes, 0); 8641d768333363310f093b6249a5f9c70ad1545c136Jakub Pawlowski 865dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 866914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski} 867914484bd8562ae75b062a669c89020773c8529b5Jakub Pawlowski 868ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 869dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 870ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 871dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 872ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 873dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 874dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 875dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 876dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 877dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 878ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 879b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski int ret = sBluetoothInterface->remove_bond((RawAddress*)addr); 880dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 881ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 882dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 883ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 884ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 885ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) { 886dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 887ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 888dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 889ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 890dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 891dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 892dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 893dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 894dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 895ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 896b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski int ret = sBluetoothInterface->cancel_bond((RawAddress*)addr); 897dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 898dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 899ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 900ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 901dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int getConnectionStateNative(JNIEnv* env, jobject obj, 902dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray address) { 903dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 904dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 9053636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach 906dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 907dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 908dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 909dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 910dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 9113636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach 912b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski int ret = sBluetoothInterface->get_connection_state((RawAddress*)addr); 913dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 9143636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach 915dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return ret; 9163636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach} 9173636f3319fc403e3bf995b6de71dc5e3f2864661Andre Eisenbach 918dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean pinReplyNative(JNIEnv* env, jobject obj, jbyteArray address, 919dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jboolean accept, jint len, jbyteArray pinArray) { 920dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 921ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 922dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 923ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 924dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 925dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 926dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 927dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 928dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 929ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 930dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* pinPtr = NULL; 931dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (accept) { 932dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen pinPtr = env->GetByteArrayElements(pinArray, NULL); 933dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (pinPtr == NULL) { 934dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 935dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 936dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 937ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 938dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 939ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 940b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski int ret = sBluetoothInterface->pin_reply((RawAddress*)addr, accept, len, 941dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (bt_pin_code_t*)pinPtr); 942dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 943dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(pinArray, pinPtr, 0); 944ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 945dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 946ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 947ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 948dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean sspReplyNative(JNIEnv* env, jobject obj, jbyteArray address, 949581bb31a8165ff0f9c7d638cfe4a81aaaafa2dedJaikumar Ganesh jint type, jboolean accept, jint passkey) { 950dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 951ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 952dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 953ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 954dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 955dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 956dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 957dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 958dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 959ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 960dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->ssp_reply( 961b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski (RawAddress*)addr, (bt_ssp_variant_t)type, accept, passkey); 962dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 963ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 964dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 965ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 966ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 967dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean setAdapterPropertyNative(JNIEnv* env, jobject obj, jint type, 968dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray value) { 969dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 970ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 971dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 972ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 973dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* val = env->GetByteArrayElements(value, NULL); 974dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_property_t prop; 975dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen prop.type = (bt_property_type_t)type; 976dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen prop.len = env->GetArrayLength(value); 977dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen prop.val = val; 978ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 979dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->set_adapter_property(&prop); 980dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(value, val, 0); 981ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 982dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 983ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 984ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 985dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getAdapterPropertiesNative(JNIEnv* env, jobject obj) { 986dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 987ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 988dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 989ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 990dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->get_adapter_properties(); 991dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 992ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 993ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 994dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getAdapterPropertyNative(JNIEnv* env, jobject obj, jint type) { 995dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 996ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 997dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 998ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 999dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t)type); 1000dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1001ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 1002ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1003dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getDevicePropertyNative(JNIEnv* env, jobject obj, 1004dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray address, jint type) { 1005dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 1006ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1007dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 1008ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1009dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 1010dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 1011dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 1012dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 1013dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1014ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1015dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->get_remote_device_property( 1016b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski (RawAddress*)addr, (bt_property_type_t)type); 1017dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 1018dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1019ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 1020ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1021dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean setDevicePropertyNative(JNIEnv* env, jobject obj, 1022dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray address, jint type, 1023dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray value) { 1024dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 1025ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1026dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 1027ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1028dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* val = env->GetByteArrayElements(value, NULL); 1029dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (val == NULL) { 1030dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 1031dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 1032dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1033ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1034dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 1035dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 1036dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(value, val, 0); 1037dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 1038dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 1039dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1040ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1041dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_property_t prop; 1042dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen prop.type = (bt_property_type_t)type; 1043dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen prop.len = env->GetArrayLength(value); 1044dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen prop.val = val; 1045ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1046b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski int ret = 1047b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sBluetoothInterface->set_remote_device_property((RawAddress*)addr, &prop); 1048dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(value, val, 0); 1049dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 1050ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1051dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1052ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 1053ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1054dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean getRemoteServicesNative(JNIEnv* env, jobject obj, 1055dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray address) { 1056dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 1057c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc 1058dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 1059c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc 1060dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = addr = env->GetByteArrayElements(address, NULL); 1061dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 1062dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 1063dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 1064dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1065c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc 1066b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski int ret = sBluetoothInterface->get_remote_services((RawAddress*)addr); 1067dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 1068dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1069c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc} 1070c55ac7d42cf2d78c7edc67abf6c66813245b2c93fredc 1071dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int connectSocketNative(JNIEnv* env, jobject object, jbyteArray address, 1072dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jint type, jbyteArray uuidObj, jint channel, 1073dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jint flag, jint callingUid) { 1074dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothSocketInterface) return -1; 1075cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 1076dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 1077dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!addr) { 1078dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("failed to get Bluetooth device address"); 1079dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return -1; 1080dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1081dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1082dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* uuid = NULL; 1083dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (uuidObj != NULL) { 1084dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen uuid = env->GetByteArrayElements(uuidObj, NULL); 1085dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!uuid) { 1086dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("failed to get uuid"); 1087dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 1088dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return -1; 1089dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1090dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1091dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1092dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int socket_fd = -1; 1093dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_status_t status = sBluetoothSocketInterface->connect( 1094b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski (RawAddress*)addr, (btsock_type_t)type, (const uint8_t*)uuid, channel, 1095dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen &socket_fd, flag, callingUid); 1096dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status != BT_STATUS_SUCCESS) { 1097dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Socket connection failed: %d", status); 1098dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen socket_fd = -1; 1099dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } else if (socket_fd < 0) { 1100dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Fail to create file descriptor on socket fd"); 1101dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1102dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1103dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 1104dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1105dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return socket_fd; 1106cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie} 1107cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 1108dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int createSocketChannelNative(JNIEnv* env, jobject object, jint type, 1109244e9c62a85a4b94e21bf1a8dee456e22bc767c4Casper Bonde jstring name_str, jbyteArray uuidObj, 1110cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski jint channel, jint flag, jint callingUid) { 1111dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothSocketInterface) return -1; 1112dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1113dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s: SOCK FLAG = %x", __func__, flag); 1114dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1115dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen const char* service_name = NULL; 1116dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (name_str != NULL) { 1117dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen service_name = env->GetStringUTFChars(name_str, NULL); 1118dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1119dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1120dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* uuid = NULL; 1121dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (uuidObj != NULL) { 1122dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen uuid = env->GetByteArrayElements(uuidObj, NULL); 1123dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!uuid) { 1124dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("failed to get uuid"); 1125dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 1126dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return -1; 1127dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1128dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1129dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1130dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int socket_fd = -1; 1131dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_status_t status = sBluetoothSocketInterface->listen( 1132dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (btsock_type_t)type, service_name, (const uint8_t*)uuid, channel, 1133dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen &socket_fd, flag, callingUid); 1134dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status != BT_STATUS_SUCCESS) { 1135dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Socket listen failed: %d", status); 1136dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen socket_fd = -1; 1137dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } else if (socket_fd < 0) { 1138dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("Fail to creat file descriptor on socket fd"); 1139dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1140dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1141dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (service_name) env->ReleaseStringUTFChars(name_str, service_name); 1142dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); 1143dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return socket_fd; 1144cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie} 1145cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 1146dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic int readEnergyInfo() { 1147dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 1148ae15d3d42fcb3349c11d394423493020e78c5f43Marie Janssen 1149dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 1150dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->read_energy_info(); 1151dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 1152f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham} 1153f6eff2b71e9bc206f995e847e384507fb1c3e239Prerepa Viswanadham 1154dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void dumpNative(JNIEnv* env, jobject obj, jobject fdObj, 1155dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jobjectArray argArray) { 1156dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 1157dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return; 1158f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach 1159dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int fd = jniGetFDFromFileDescriptor(env, fdObj); 1160dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (fd < 0) return; 1161f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach 1162dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int numArgs = env->GetArrayLength(argArray); 1163407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen 1164dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jstring* argObjs = new jstring[numArgs]; 1165dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen const char** args = nullptr; 1166dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (numArgs > 0) args = new const char*[numArgs]; 1167407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen 1168dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen for (int i = 0; i < numArgs; i++) { 1169dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen argObjs[i] = (jstring)env->GetObjectArrayElement(argArray, i); 1170dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen args[i] = env->GetStringUTFChars(argObjs[i], NULL); 1171dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1172407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen 1173dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sBluetoothInterface->dump(fd, args); 1174407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen 1175dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen for (int i = 0; i < numArgs; i++) { 1176dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseStringUTFChars(argObjs[i], args[i]); 1177dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1178407f11ca439f338f84b51e15830446ecd3ae488fMarie Janssen 1179dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen delete[] args; 1180dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen delete[] argObjs; 1181f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach} 1182f5f90873574eefe5f50a7b383fcd8fefb961f66cAndre Eisenbach 1183dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean factoryResetNative(JNIEnv* env, jobject obj) { 1184dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 1185dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return JNI_FALSE; 1186dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int ret = sBluetoothInterface->config_clear(); 1187dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 11886eb32d5f7c30f04da45c3da0974bbb63725a0978Ajay Panicker} 11896eb32d5f7c30f04da45c3da0974bbb63725a0978Ajay Panicker 1190dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void interopDatabaseClearNative(JNIEnv* env, jobject obj) { 1191dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 1192dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return; 1193dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sBluetoothInterface->interop_database_clear(); 1194db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach} 1195db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach 1196dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void interopDatabaseAddNative(JNIEnv* env, jobject obj, int feature, 1197dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray address, int length) { 1198dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("%s", __func__); 1199dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sBluetoothInterface) return; 1200db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach 1201dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 1202dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (addr == NULL) { 1203dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jniThrowIOException(env, EINVAL); 1204dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 1205dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1206db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach 1207b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sBluetoothInterface->interop_database_add(feature, (RawAddress*)addr, length); 1208dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 1209db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach} 1210db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach 1211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNINativeMethod sMethods[] = { 1212b241cda1eec2fbefd6d21e0819532f7a76947635Brian Carlstrom /* name, signature, funcPtr */ 1213dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"classInitNative", "()V", (void*)classInitNative}, 1214dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"initNative", "()Z", (void*)initNative}, 1215dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"cleanupNative", "()V", (void*)cleanupNative}, 1216dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"enableNative", "(Z)Z", (void*)enableNative}, 1217dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"disableNative", "()Z", (void*)disableNative}, 1218dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"setAdapterPropertyNative", "(I[B)Z", (void*)setAdapterPropertyNative}, 1219dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"getAdapterPropertiesNative", "()Z", (void*)getAdapterPropertiesNative}, 1220dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"getAdapterPropertyNative", "(I)Z", (void*)getAdapterPropertyNative}, 1221dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"getDevicePropertyNative", "([BI)Z", (void*)getDevicePropertyNative}, 1222dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"setDevicePropertyNative", "([BI[B)Z", (void*)setDevicePropertyNative}, 1223dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative}, 1224dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"cancelDiscoveryNative", "()Z", (void*)cancelDiscoveryNative}, 1225dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"createBondNative", "([BI)Z", (void*)createBondNative}, 1226dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z", 1227dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (void*)createBondOutOfBandNative}, 1228dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"removeBondNative", "([B)Z", (void*)removeBondNative}, 1229dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"cancelBondNative", "([B)Z", (void*)cancelBondNative}, 1230dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative}, 1231dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative}, 1232dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative}, 1233dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"getRemoteServicesNative", "([B)Z", (void*)getRemoteServicesNative}, 1234dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"connectSocketNative", "([BI[BIII)I", (void*)connectSocketNative}, 1235cbe581021ff654f7450d1403d8896f5d1203c8b6Adam Lesinski {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I", 1236dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (void*)createSocketChannelNative}, 1237dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"alarmFiredNative", "()V", (void*)alarmFiredNative}, 1238dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"readEnergyInfo", "()I", (void*)readEnergyInfo}, 1239dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"dumpNative", "(Ljava/io/FileDescriptor;[Ljava/lang/String;)V", 1240dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (void*)dumpNative}, 1241db32e0ef467d70961b28913fc86c38cd68f8701eAndre Eisenbach {"factoryResetNative", "()Z", (void*)factoryResetNative}, 1242dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"interopDatabaseClearNative", "()V", (void*)interopDatabaseClearNative}, 1243dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"interopDatabaseAddNative", "(I[BI)V", (void*)interopDatabaseAddNative}}; 1244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1245dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenint register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) { 1246dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return jniRegisterNativeMethods( 1247dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env, "com/android/bluetooth/btservice/AdapterService", sMethods, 1248dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen NELEM(sMethods)); 1249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 1250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} /* namespace android */ 1252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/* 1254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * JNI Initialization 1255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 1256dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenjint JNI_OnLoad(JavaVM* jvm, void* reserved) { 1257dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen JNIEnv* e; 1258dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int status; 1259dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1260dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGV("Bluetooth Adapter Service : loading JNI\n"); 1261dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1262dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen // Check JNI version 1263dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (jvm->GetEnv((void**)&e, JNI_VERSION_1_6)) { 1264dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("JNI version mismatch error"); 1265dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1266dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1267dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1268dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_btservice_AdapterService(e); 1269dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1270dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni adapter service registration failure, status: %d", status); 1271dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1272dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1273dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1274dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_hfp(e); 1275dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1276dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni hfp registration failure, status: %d", status); 1277dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1278dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1279dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1280dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_hfpclient(e); 1281dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1282dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni hfp client registration failure, status: %d", status); 1283dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1284dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1285dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1286dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_a2dp(e); 1287dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1288dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni a2dp source registration failure: %d", status); 1289dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1290dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1291dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1292dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_a2dp_sink(e); 1293dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1294dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni a2dp sink registration failure: %d", status); 1295dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1296dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1297dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1298dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_avrcp(e); 1299dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1300dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni avrcp target registration failure: %d", status); 1301dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1302dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1303dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1304dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_avrcp_controller(e); 1305dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1306dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni avrcp controller registration failure: %d", status); 1307dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1308dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1309dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1310dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_hid(e); 1311dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1312dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni hid registration failure: %d", status); 1313dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1314dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1315dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1316cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta status = android::register_com_android_bluetooth_hidd(e); 1317cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta if (status < 0) { 1318cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta ALOGE("jni hidd registration failure: %d", status); 1319cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta return JNI_ERR; 1320cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta } 1321cf27f0ddf906a8f76a22b8a30ff4262526e33477Hemant Gupta 1322dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_hdp(e); 1323dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1324dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni hdp registration failure: %d", status); 1325dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1326dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1327dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1328dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_pan(e); 1329dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1330dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni pan registration failure: %d", status); 1331dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1332dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1333dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1334dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_gatt(e); 1335dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1336dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni gatt registration failure: %d", status); 1337dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1338dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1339dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1340dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen status = android::register_com_android_bluetooth_sdp(e); 1341dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status < 0) { 1342dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("jni sdp registration failure: %d", status); 1343dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_ERR; 1344dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1345dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 1346dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_VERSION_1_6; 1347ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 1348