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
216654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define CHECK_CALLBACK_ENV                                                      \
226654f5c903de510a70f9e72cd5ad7837b615d93ffredc   if (!checkCallbackThread()) {                                                \
236654f5c903de510a70f9e72cd5ad7837b615d93ffredc       error("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
246654f5c903de510a70f9e72cd5ad7837b615d93ffredc       return;                                                                  \
256654f5c903de510a70f9e72cd5ad7837b615d93ffredc   }
266654f5c903de510a70f9e72cd5ad7837b615d93ffredc
276654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "com_android_bluetooth.h"
286654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "hardware/bt_pan.h"
296654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "utils/Log.h"
306654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "android_runtime/AndroidRuntime.h"
316654f5c903de510a70f9e72cd5ad7837b615d93ffredc
326654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include <string.h>
336654f5c903de510a70f9e72cd5ad7837b615d93ffredc
346654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include <cutils/log.h>
35e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie#define info(fmt, ...)  ALOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__,  ## __VA_ARGS__)
36e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie#define debug(fmt, ...) ALOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__,  ## __VA_ARGS__)
37e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie#define warn(fmt, ...) ALOGW ("## WARNING : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
38e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie#define error(fmt, ...) ALOGE ("## ERROR : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
39e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie#define asrt(s) if(!(s)) ALOGE ("## %s(L%d): ASSERT %s failed! ##",__FUNCTION__, __LINE__, #s)
406654f5c903de510a70f9e72cd5ad7837b615d93ffredc
416654f5c903de510a70f9e72cd5ad7837b615d93ffredc
426654f5c903de510a70f9e72cd5ad7837b615d93ffredcnamespace android {
436654f5c903de510a70f9e72cd5ad7837b615d93ffredc
446654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jmethodID method_onConnectStateChanged;
456654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jmethodID method_onControlStateChanged;
466654f5c903de510a70f9e72cd5ad7837b615d93ffredc
476654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic const btpan_interface_t *sPanIf = NULL;
486654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jobject mCallbacksObj = NULL;
496654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic JNIEnv *sCallbackEnv = NULL;
506654f5c903de510a70f9e72cd5ad7837b615d93ffredc
516654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic bool checkCallbackThread() {
526654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sCallbackEnv = getCallbackEnv();
536654f5c903de510a70f9e72cd5ad7837b615d93ffredc
546654f5c903de510a70f9e72cd5ad7837b615d93ffredc    JNIEnv* env = AndroidRuntime::getJNIEnv();
556654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
566654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return true;
576654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
586654f5c903de510a70f9e72cd5ad7837b615d93ffredc
59f05fbcfbdb4d4e2b60bd81c80a3922ae24430fbfSharvil Nanavatistatic void control_state_callback(btpan_control_state_t state, int local_role, bt_status_t error,
606654f5c903de510a70f9e72cd5ad7837b615d93ffredc                const char* ifname) {
616654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("state:%d, local_role:%d, ifname:%s", state, local_role, ifname);
626654f5c903de510a70f9e72cd5ad7837b615d93ffredc    CHECK_CALLBACK_ENV
636654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jstring js_ifname = sCallbackEnv->NewStringUTF(ifname);
64f05fbcfbdb4d4e2b60bd81c80a3922ae24430fbfSharvil Nanavati    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onControlStateChanged, (jint)local_role, (jint)state,
65f05fbcfbdb4d4e2b60bd81c80a3922ae24430fbfSharvil Nanavati                                (jint)error, js_ifname);
663237754f492015699fc91508d76c2e123d6f3c42zzy    sCallbackEnv->DeleteLocalRef(js_ifname);
676654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
686654f5c903de510a70f9e72cd5ad7837b615d93ffredc
696654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void connection_state_callback(btpan_connection_state_t state, bt_status_t error, const bt_bdaddr_t *bd_addr,
706654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                      int local_role, int remote_role) {
716654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyteArray addr;
726654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("state:%d, local_role:%d, remote_role:%d", state, local_role, remote_role);
736654f5c903de510a70f9e72cd5ad7837b615d93ffredc    CHECK_CALLBACK_ENV
746654f5c903de510a70f9e72cd5ad7837b615d93ffredc    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
756654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!addr) {
766654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Fail to new jbyteArray bd addr for PAN channel state");
776654f5c903de510a70f9e72cd5ad7837b615d93ffredc        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
786654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
796654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
806654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
816654f5c903de510a70f9e72cd5ad7837b615d93ffredc
826654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectStateChanged, addr, (jint) state,
836654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                    (jint)error, (jint)local_role, (jint)remote_role);
846654f5c903de510a70f9e72cd5ad7837b615d93ffredc    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
856654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sCallbackEnv->DeleteLocalRef(addr);
866654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
876654f5c903de510a70f9e72cd5ad7837b615d93ffredc
886654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic btpan_callbacks_t sBluetoothPanCallbacks = {
896654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sizeof(sBluetoothPanCallbacks),
906654f5c903de510a70f9e72cd5ad7837b615d93ffredc    control_state_callback,
916654f5c903de510a70f9e72cd5ad7837b615d93ffredc    connection_state_callback
926654f5c903de510a70f9e72cd5ad7837b615d93ffredc};
936654f5c903de510a70f9e72cd5ad7837b615d93ffredc
946654f5c903de510a70f9e72cd5ad7837b615d93ffredc// Define native functions
956654f5c903de510a70f9e72cd5ad7837b615d93ffredc
966654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void classInitNative(JNIEnv* env, jclass clazz) {
976654f5c903de510a70f9e72cd5ad7837b615d93ffredc    int err;
986654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
996654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1006654f5c903de510a70f9e72cd5ad7837b615d93ffredc    method_onConnectStateChanged = env->GetMethodID(clazz, "onConnectStateChanged",
1016654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                                    "([BIIII)V");
1026654f5c903de510a70f9e72cd5ad7837b615d93ffredc    method_onControlStateChanged = env->GetMethodID(clazz, "onControlStateChanged",
1036654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                                    "(IIILjava/lang/String;)V");
1046654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1056654f5c903de510a70f9e72cd5ad7837b615d93ffredc    info("succeeds");
1066654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
107de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamystatic const bt_interface_t* btIf;
108de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamy
1096654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void initializeNative(JNIEnv *env, jobject object) {
1106654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("pan");
1116654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if(btIf)
1126654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
1136654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1146654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (btIf = getBluetoothInterface()) == NULL) {
1156654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Bluetooth module is not loaded");
1166654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
1176654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1186654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1196654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sPanIf !=NULL) {
120e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie         ALOGW("Cleaning up Bluetooth PAN Interface before initializing...");
1216654f5c903de510a70f9e72cd5ad7837b615d93ffredc         sPanIf->cleanup();
1226654f5c903de510a70f9e72cd5ad7837b615d93ffredc         sPanIf = NULL;
1236654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1246654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1256654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
126e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie         ALOGW("Cleaning up Bluetooth PAN callback object");
1276654f5c903de510a70f9e72cd5ad7837b615d93ffredc         env->DeleteGlobalRef(mCallbacksObj);
1286654f5c903de510a70f9e72cd5ad7837b615d93ffredc         mCallbacksObj = NULL;
1296654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1306654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1316654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (sPanIf = (btpan_interface_t *)
1326654f5c903de510a70f9e72cd5ad7837b615d93ffredc          btIf->get_profile_interface(BT_PROFILE_PAN_ID)) == NULL) {
1336654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Failed to get Bluetooth PAN Interface");
1346654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
1356654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1366654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1376654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
1386654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (status = sPanIf->init(&sBluetoothPanCallbacks)) != BT_STATUS_SUCCESS) {
1396654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Failed to initialize Bluetooth PAN, status: %d", status);
1406654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sPanIf = NULL;
1416654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
1426654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1436654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1446654f5c903de510a70f9e72cd5ad7837b615d93ffredc    mCallbacksObj = env->NewGlobalRef(object);
1456654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
1466654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1476654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void cleanupNative(JNIEnv *env, jobject object) {
1486654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
149de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamy    if (!btIf) return;
1506654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1516654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sPanIf !=NULL) {
152e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth PAN Interface...");
1536654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sPanIf->cleanup();
1546654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sPanIf = NULL;
1556654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1566654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1576654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
158e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth PAN callback object");
1596654f5c903de510a70f9e72cd5ad7837b615d93ffredc        env->DeleteGlobalRef(mCallbacksObj);
1606654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mCallbacksObj = NULL;
1616654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
162de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamy    btIf = NULL;
1636654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
1646654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1656654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jboolean enablePanNative(JNIEnv *env, jobject object, jint local_role) {
1666654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status = BT_STATUS_FAIL;
1676654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("in");
1686654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyte *addr;
1696654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sPanIf)
1706654f5c903de510a70f9e72cd5ad7837b615d93ffredc        status = sPanIf->enable(local_role);
1716654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("out");
1726654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return status == BT_STATUS_SUCCESS ? JNI_TRUE : JNI_FALSE;
1736654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
1746654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jint getPanLocalRoleNative(JNIEnv *env, jobject object) {
1756654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("in");
1766654f5c903de510a70f9e72cd5ad7837b615d93ffredc    int local_role = 0;
1776654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyte *addr;
1786654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sPanIf)
1796654f5c903de510a70f9e72cd5ad7837b615d93ffredc        local_role  = sPanIf->get_local_role();
1806654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("out");
1816654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return (jint)local_role;
1826654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
1836654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1846654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1856654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1866654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jboolean connectPanNative(JNIEnv *env, jobject object, jbyteArray address,
1876654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                 jint src_role, jint dest_role) {
1886654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("in");
1896654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
1906654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyte *addr;
1916654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jboolean ret = JNI_TRUE;
1926654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!sPanIf) return JNI_FALSE;
1936654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1946654f5c903de510a70f9e72cd5ad7837b615d93ffredc    addr = env->GetByteArrayElements(address, NULL);
1956654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!addr) {
1966654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Bluetooth device address null");
1976654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return JNI_FALSE;
1986654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1996654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2006654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ((status = sPanIf->connect((bt_bdaddr_t *) addr, src_role, dest_role)) !=
2016654f5c903de510a70f9e72cd5ad7837b615d93ffredc         BT_STATUS_SUCCESS) {
2026654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Failed PAN channel connection, status: %d", status);
2036654f5c903de510a70f9e72cd5ad7837b615d93ffredc        ret = JNI_FALSE;
2046654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2056654f5c903de510a70f9e72cd5ad7837b615d93ffredc    env->ReleaseByteArrayElements(address, addr, 0);
2066654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2076654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return ret;
2086654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
2096654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2106654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jboolean disconnectPanNative(JNIEnv *env, jobject object, jbyteArray address) {
2116654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
2126654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyte *addr;
2136654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jboolean ret = JNI_TRUE;
2146654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!sPanIf) return JNI_FALSE;
2156654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2166654f5c903de510a70f9e72cd5ad7837b615d93ffredc    addr = env->GetByteArrayElements(address, NULL);
2176654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!addr) {
2186654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Bluetooth device address null");
2196654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return JNI_FALSE;
2206654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2216654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2226654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (status = sPanIf->disconnect((bt_bdaddr_t *) addr)) !=
2236654f5c903de510a70f9e72cd5ad7837b615d93ffredc         BT_STATUS_SUCCESS) {
2246654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Failed disconnect pan channel, status: %d", status);
2256654f5c903de510a70f9e72cd5ad7837b615d93ffredc        ret = JNI_FALSE;
2266654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2276654f5c903de510a70f9e72cd5ad7837b615d93ffredc    env->ReleaseByteArrayElements(address, addr, 0);
2286654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2296654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return ret;
2306654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
2316654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2326654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic JNINativeMethod sMethods[] = {
2336654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"classInitNative", "()V", (void *) classInitNative},
2346654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"initializeNative", "()V", (void *) initializeNative},
2356654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"cleanupNative", "()V", (void *) cleanupNative},
2366654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"connectPanNative", "([BII)Z", (void *) connectPanNative},
2376654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"enablePanNative", "(I)Z", (void *) enablePanNative},
2386654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"getPanLocalRoleNative", "()I", (void *) getPanLocalRoleNative},
2396654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"disconnectPanNative", "([B)Z", (void *) disconnectPanNative},
2406654f5c903de510a70f9e72cd5ad7837b615d93ffredc    // TBD cleanup
2416654f5c903de510a70f9e72cd5ad7837b615d93ffredc};
2426654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2436654f5c903de510a70f9e72cd5ad7837b615d93ffredcint register_com_android_bluetooth_pan(JNIEnv* env)
2446654f5c903de510a70f9e72cd5ad7837b615d93ffredc{
2456654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return jniRegisterNativeMethods(env, "com/android/bluetooth/pan/PanService",
2466654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                    sMethods, NELEM(sMethods));
2476654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
2486654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2496654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
250