16654f5c903de510a70f9e72cd5ad7837b615d93ffredc/* 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. 156654f5c903de510a70f9e72cd5ad7837b615d93ffredc */ 166654f5c903de510a70f9e72cd5ad7837b615d93ffredc 176654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define LOG_TAG "BluetoothPanServiceJni" 186654f5c903de510a70f9e72cd5ad7837b615d93ffredc 196654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define LOG_NDEBUG 0 206654f5c903de510a70f9e72cd5ad7837b615d93ffredc 21dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include "android_runtime/AndroidRuntime.h" 226654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "com_android_bluetooth.h" 236654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "hardware/bt_pan.h" 246654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "utils/Log.h" 256654f5c903de510a70f9e72cd5ad7837b615d93ffredc 266654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include <string.h> 276654f5c903de510a70f9e72cd5ad7837b615d93ffredc 286654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include <cutils/log.h> 29dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#define info(fmt, ...) ALOGI("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) 30dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#define debug(fmt, ...) \ 31dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGD("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) 32dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#define warn(fmt, ...) \ 33dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGW("## WARNING : %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__) 34dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#define error(fmt, ...) \ 35dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGE("## ERROR : %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__) 36dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#define asrt(s) \ 37dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!(s)) ALOGE("## %s(L%d): ASSERT %s failed! ##", __func__, __LINE__, #s) 386654f5c903de510a70f9e72cd5ad7837b615d93ffredc 396654f5c903de510a70f9e72cd5ad7837b615d93ffredcnamespace android { 406654f5c903de510a70f9e72cd5ad7837b615d93ffredc 416654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jmethodID method_onConnectStateChanged; 426654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jmethodID method_onControlStateChanged; 436654f5c903de510a70f9e72cd5ad7837b615d93ffredc 44dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic const btpan_interface_t* sPanIf = NULL; 456654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jobject mCallbacksObj = NULL; 466654f5c903de510a70f9e72cd5ad7837b615d93ffredc 47b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic jbyteArray marshall_bda(const RawAddress* bd_addr) { 482116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach CallbackEnv sCallbackEnv(__func__); 492116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!sCallbackEnv.valid()) return NULL; 502116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach 51b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress)); 522116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!addr) { 532116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ALOGE("Fail to new jbyteArray bd addr"); 542116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return NULL; 552116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach } 56b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress), 572116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach (jbyte*)bd_addr); 582116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return addr; 592116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach} 602116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach 61dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void control_state_callback(btpan_control_state_t state, int local_role, 62dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_status_t error, const char* ifname) { 63dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen debug("state:%d, local_role:%d, ifname:%s", state, local_role, ifname); 64dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (mCallbacksObj == NULL) { 65dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen error("Callbacks Obj is NULL: '%s", __func__); 66dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 67dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 68dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 69dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 70479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen ScopedLocalRef<jstring> js_ifname(sCallbackEnv.get(), 71479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen sCallbackEnv->NewStringUTF(ifname)); 72dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onControlStateChanged, 73dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen (jint)local_role, (jint)state, (jint)error, 74479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen js_ifname.get()); 756654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 766654f5c903de510a70f9e72cd5ad7837b615d93ffredc 77dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void connection_state_callback(btpan_connection_state_t state, 78dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_status_t error, 79b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski const RawAddress* bd_addr, int local_role, 80b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski int remote_role) { 81dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen debug("state:%d, local_role:%d, remote_role:%d", state, local_role, 82dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen remote_role); 83dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (mCallbacksObj == NULL) { 84dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen error("Callbacks Obj is NULL: '%s", __func__); 85dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 86dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 87dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen CallbackEnv sCallbackEnv(__func__); 88dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sCallbackEnv.valid()) return; 892116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); 902116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach if (!addr.get()) { 912116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach error("Fail to new jbyteArray bd addr for PAN channel state"); 922116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach return; 932116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach } 94dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectStateChanged, 95479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen addr.get(), (jint)state, (jint)error, 96479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen (jint)local_role, (jint)remote_role); 976654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 986654f5c903de510a70f9e72cd5ad7837b615d93ffredc 996654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic btpan_callbacks_t sBluetoothPanCallbacks = { 100dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sizeof(sBluetoothPanCallbacks), control_state_callback, 101dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen connection_state_callback}; 1026654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1036654f5c903de510a70f9e72cd5ad7837b615d93ffredc// Define native functions 1046654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1056654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void classInitNative(JNIEnv* env, jclass clazz) { 106dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_onConnectStateChanged = 107dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->GetMethodID(clazz, "onConnectStateChanged", "([BIIII)V"); 108dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen method_onControlStateChanged = env->GetMethodID( 109dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen clazz, "onControlStateChanged", "(IIILjava/lang/String;)V"); 1106654f5c903de510a70f9e72cd5ad7837b615d93ffredc 111dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen info("succeeds"); 1126654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 113de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamystatic const bt_interface_t* btIf; 114de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamy 115dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void initializeNative(JNIEnv* env, jobject object) { 116dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen debug("pan"); 117dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (btIf) return; 118dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 119dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen btIf = getBluetoothInterface(); 120dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (btIf == NULL) { 121dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen error("Bluetooth module is not loaded"); 122dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 123dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 124dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 125dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (sPanIf != NULL) { 126dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGW("Cleaning up Bluetooth PAN Interface before initializing..."); 127dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sPanIf->cleanup(); 128dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sPanIf = NULL; 129dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 130dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 131dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (mCallbacksObj != NULL) { 132dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGW("Cleaning up Bluetooth PAN callback object"); 133dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->DeleteGlobalRef(mCallbacksObj); 134dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen mCallbacksObj = NULL; 135dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 136dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 137dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sPanIf = (btpan_interface_t*)btIf->get_profile_interface(BT_PROFILE_PAN_ID); 138dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (sPanIf == NULL) { 139dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen error("Failed to get Bluetooth PAN Interface"); 140dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 141dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 142dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 143dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen mCallbacksObj = env->NewGlobalRef(object); 144dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 145dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_status_t status = sPanIf->init(&sBluetoothPanCallbacks); 146dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status != BT_STATUS_SUCCESS) { 147dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen error("Failed to initialize Bluetooth PAN, status: %d", status); 148dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sPanIf = NULL; 1496654f5c903de510a70f9e72cd5ad7837b615d93ffredc if (mCallbacksObj != NULL) { 150dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGW("initialization failed: Cleaning up Bluetooth PAN callback object"); 151dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->DeleteGlobalRef(mCallbacksObj); 152dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen mCallbacksObj = NULL; 1536654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 154dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return; 155dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 1566654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 1576654f5c903de510a70f9e72cd5ad7837b615d93ffredc 158dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void cleanupNative(JNIEnv* env, jobject object) { 159dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!btIf) return; 160dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 161dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (sPanIf != NULL) { 162dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGW("Cleaning up Bluetooth PAN Interface..."); 163dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sPanIf->cleanup(); 164dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sPanIf = NULL; 165dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 166dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 167dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (mCallbacksObj != NULL) { 168dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ALOGW("Cleaning up Bluetooth PAN callback object"); 169dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->DeleteGlobalRef(mCallbacksObj); 170dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen mCallbacksObj = NULL; 171dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 172dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen btIf = NULL; 1736654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 1746654f5c903de510a70f9e72cd5ad7837b615d93ffredc 175dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean enablePanNative(JNIEnv* env, jobject object, jint local_role) { 176dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen bt_status_t status = BT_STATUS_FAIL; 177dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen debug("in"); 178dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (sPanIf) status = sPanIf->enable(local_role); 179dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen debug("out"); 180dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return status == BT_STATUS_SUCCESS ? JNI_TRUE : JNI_FALSE; 1816654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 182dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jint getPanLocalRoleNative(JNIEnv* env, jobject object) { 183dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen debug("in"); 184dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen int local_role = 0; 185dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (sPanIf) local_role = sPanIf->get_local_role(); 186dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen debug("out"); 187dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return (jint)local_role; 1886654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 1896654f5c903de510a70f9e72cd5ad7837b615d93ffredc 190dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean connectPanNative(JNIEnv* env, jobject object, 191dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray address, jint src_role, 192dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jint dest_role) { 193dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen debug("in"); 194dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sPanIf) return JNI_FALSE; 195dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 196dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 197dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!addr) { 198dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen error("Bluetooth device address null"); 199dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 200dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 201dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 202dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jboolean ret = JNI_TRUE; 203b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski bt_status_t status = sPanIf->connect((RawAddress*)addr, src_role, dest_role); 204dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status != BT_STATUS_SUCCESS) { 205dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen error("Failed PAN channel connection, status: %d", status); 206dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ret = JNI_FALSE; 207dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 208dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 209dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 210dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return ret; 2116654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 2126654f5c903de510a70f9e72cd5ad7837b615d93ffredc 213dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean disconnectPanNative(JNIEnv* env, jobject object, 214dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyteArray address) { 215dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!sPanIf) return JNI_FALSE; 216dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 217dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jbyte* addr = env->GetByteArrayElements(address, NULL); 218dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (!addr) { 219dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen error("Bluetooth device address null"); 220dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return JNI_FALSE; 221dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 222dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 223dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen jboolean ret = JNI_TRUE; 224b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski bt_status_t status = sPanIf->disconnect((RawAddress*)addr); 225dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen if (status != BT_STATUS_SUCCESS) { 226dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen error("Failed disconnect pan channel, status: %d", status); 227dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen ret = JNI_FALSE; 228dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen } 229dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen env->ReleaseByteArrayElements(address, addr, 0); 230dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen 231dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return ret; 2326654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 2336654f5c903de510a70f9e72cd5ad7837b615d93ffredc 2346654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic JNINativeMethod sMethods[] = { 235dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"classInitNative", "()V", (void*)classInitNative}, 236dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"initializeNative", "()V", (void*)initializeNative}, 237dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"cleanupNative", "()V", (void*)cleanupNative}, 238dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"connectPanNative", "([BII)Z", (void*)connectPanNative}, 239dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"enablePanNative", "(I)Z", (void*)enablePanNative}, 240dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"getPanLocalRoleNative", "()I", (void*)getPanLocalRoleNative}, 241dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen {"disconnectPanNative", "([B)Z", (void*)disconnectPanNative}, 2426654f5c903de510a70f9e72cd5ad7837b615d93ffredc // TBD cleanup 2436654f5c903de510a70f9e72cd5ad7837b615d93ffredc}; 2446654f5c903de510a70f9e72cd5ad7837b615d93ffredc 245dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenint register_com_android_bluetooth_pan(JNIEnv* env) { 246dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen return jniRegisterNativeMethods(env, "com/android/bluetooth/pan/PanService", 247dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen sMethods, NELEM(sMethods)); 2486654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 2496654f5c903de510a70f9e72cd5ad7837b615d93ffredc} 250