com_android_bluetooth_pan.cpp revision de396a46388269221b05dae2760be63fe7254748
16654f5c903de510a70f9e72cd5ad7837b615d93ffredc/*
26654f5c903de510a70f9e72cd5ad7837b615d93ffredc * Copyright (C) 2012 Google Inc.
36654f5c903de510a70f9e72cd5ad7837b615d93ffredc */
46654f5c903de510a70f9e72cd5ad7837b615d93ffredc
56654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define LOG_TAG "BluetoothPanServiceJni"
66654f5c903de510a70f9e72cd5ad7837b615d93ffredc
76654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define LOG_NDEBUG 0
86654f5c903de510a70f9e72cd5ad7837b615d93ffredc
96654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define CHECK_CALLBACK_ENV                                                      \
106654f5c903de510a70f9e72cd5ad7837b615d93ffredc   if (!checkCallbackThread()) {                                                \
116654f5c903de510a70f9e72cd5ad7837b615d93ffredc       error("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
126654f5c903de510a70f9e72cd5ad7837b615d93ffredc       return;                                                                  \
136654f5c903de510a70f9e72cd5ad7837b615d93ffredc   }
146654f5c903de510a70f9e72cd5ad7837b615d93ffredc
156654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "com_android_bluetooth.h"
166654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "hardware/bt_pan.h"
176654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "utils/Log.h"
186654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include "android_runtime/AndroidRuntime.h"
196654f5c903de510a70f9e72cd5ad7837b615d93ffredc
206654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include <string.h>
216654f5c903de510a70f9e72cd5ad7837b615d93ffredc
226654f5c903de510a70f9e72cd5ad7837b615d93ffredc#include <cutils/log.h>
236654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define info(fmt, ...)  LOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__,  ## __VA_ARGS__)
246654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define debug(fmt, ...) LOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__,  ## __VA_ARGS__)
256654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define warn(fmt, ...) LOGW ("## WARNING : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
266654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define error(fmt, ...) LOGE ("## ERROR : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
276654f5c903de510a70f9e72cd5ad7837b615d93ffredc#define asrt(s) if(!(s)) LOGE ("## %s(L%d): ASSERT %s failed! ##",__FUNCTION__, __LINE__, #s)
286654f5c903de510a70f9e72cd5ad7837b615d93ffredc
296654f5c903de510a70f9e72cd5ad7837b615d93ffredc
306654f5c903de510a70f9e72cd5ad7837b615d93ffredcnamespace android {
316654f5c903de510a70f9e72cd5ad7837b615d93ffredc
326654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jmethodID method_onConnectStateChanged;
336654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jmethodID method_onControlStateChanged;
346654f5c903de510a70f9e72cd5ad7837b615d93ffredc
356654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic const btpan_interface_t *sPanIf = NULL;
366654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jobject mCallbacksObj = NULL;
376654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic JNIEnv *sCallbackEnv = NULL;
386654f5c903de510a70f9e72cd5ad7837b615d93ffredc
396654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic bool checkCallbackThread() {
406654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sCallbackEnv = getCallbackEnv();
416654f5c903de510a70f9e72cd5ad7837b615d93ffredc
426654f5c903de510a70f9e72cd5ad7837b615d93ffredc    JNIEnv* env = AndroidRuntime::getJNIEnv();
436654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
446654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return true;
456654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
466654f5c903de510a70f9e72cd5ad7837b615d93ffredc
476654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void control_state_callback(btpan_control_state_t state, bt_status_t error, int local_role,
486654f5c903de510a70f9e72cd5ad7837b615d93ffredc                const char* ifname) {
496654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("state:%d, local_role:%d, ifname:%s", state, local_role, ifname);
506654f5c903de510a70f9e72cd5ad7837b615d93ffredc    CHECK_CALLBACK_ENV
516654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jstring js_ifname = sCallbackEnv->NewStringUTF(ifname);
526654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onControlStateChanged, (jint)state, (jint)error,
536654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                (jint)local_role, js_ifname);
546654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
556654f5c903de510a70f9e72cd5ad7837b615d93ffredc
566654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void connection_state_callback(btpan_connection_state_t state, bt_status_t error, const bt_bdaddr_t *bd_addr,
576654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                      int local_role, int remote_role) {
586654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyteArray addr;
596654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("state:%d, local_role:%d, remote_role:%d", state, local_role, remote_role);
606654f5c903de510a70f9e72cd5ad7837b615d93ffredc    CHECK_CALLBACK_ENV
616654f5c903de510a70f9e72cd5ad7837b615d93ffredc    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
626654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!addr) {
636654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Fail to new jbyteArray bd addr for PAN channel state");
646654f5c903de510a70f9e72cd5ad7837b615d93ffredc        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
656654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
666654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
676654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
686654f5c903de510a70f9e72cd5ad7837b615d93ffredc
696654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectStateChanged, addr, (jint) state,
706654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                    (jint)error, (jint)local_role, (jint)remote_role);
716654f5c903de510a70f9e72cd5ad7837b615d93ffredc    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
726654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sCallbackEnv->DeleteLocalRef(addr);
736654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
746654f5c903de510a70f9e72cd5ad7837b615d93ffredc
756654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic btpan_callbacks_t sBluetoothPanCallbacks = {
766654f5c903de510a70f9e72cd5ad7837b615d93ffredc    sizeof(sBluetoothPanCallbacks),
776654f5c903de510a70f9e72cd5ad7837b615d93ffredc    control_state_callback,
786654f5c903de510a70f9e72cd5ad7837b615d93ffredc    connection_state_callback
796654f5c903de510a70f9e72cd5ad7837b615d93ffredc};
806654f5c903de510a70f9e72cd5ad7837b615d93ffredc
816654f5c903de510a70f9e72cd5ad7837b615d93ffredc// Define native functions
826654f5c903de510a70f9e72cd5ad7837b615d93ffredc
836654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void classInitNative(JNIEnv* env, jclass clazz) {
846654f5c903de510a70f9e72cd5ad7837b615d93ffredc    int err;
856654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
866654f5c903de510a70f9e72cd5ad7837b615d93ffredc
876654f5c903de510a70f9e72cd5ad7837b615d93ffredc    method_onConnectStateChanged = env->GetMethodID(clazz, "onConnectStateChanged",
886654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                                    "([BIIII)V");
896654f5c903de510a70f9e72cd5ad7837b615d93ffredc    method_onControlStateChanged = env->GetMethodID(clazz, "onControlStateChanged",
906654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                                    "(IIILjava/lang/String;)V");
916654f5c903de510a70f9e72cd5ad7837b615d93ffredc
926654f5c903de510a70f9e72cd5ad7837b615d93ffredc    info("succeeds");
936654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
94de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamystatic const bt_interface_t* btIf;
95de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamy
966654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void initializeNative(JNIEnv *env, jobject object) {
976654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("pan");
986654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if(btIf)
996654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
1006654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1016654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (btIf = getBluetoothInterface()) == NULL) {
1026654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Bluetooth module is not loaded");
1036654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
1046654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1056654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1066654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sPanIf !=NULL) {
1076654f5c903de510a70f9e72cd5ad7837b615d93ffredc         LOGW("Cleaning up Bluetooth PAN Interface before initializing...");
1086654f5c903de510a70f9e72cd5ad7837b615d93ffredc         sPanIf->cleanup();
1096654f5c903de510a70f9e72cd5ad7837b615d93ffredc         sPanIf = NULL;
1106654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1116654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1126654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
1136654f5c903de510a70f9e72cd5ad7837b615d93ffredc         LOGW("Cleaning up Bluetooth PAN callback object");
1146654f5c903de510a70f9e72cd5ad7837b615d93ffredc         env->DeleteGlobalRef(mCallbacksObj);
1156654f5c903de510a70f9e72cd5ad7837b615d93ffredc         mCallbacksObj = NULL;
1166654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1176654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1186654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (sPanIf = (btpan_interface_t *)
1196654f5c903de510a70f9e72cd5ad7837b615d93ffredc          btIf->get_profile_interface(BT_PROFILE_PAN_ID)) == NULL) {
1206654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Failed to get Bluetooth PAN Interface");
1216654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
1226654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1236654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1246654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
1256654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (status = sPanIf->init(&sBluetoothPanCallbacks)) != BT_STATUS_SUCCESS) {
1266654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Failed to initialize Bluetooth PAN, status: %d", status);
1276654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sPanIf = NULL;
1286654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
1296654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1306654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1316654f5c903de510a70f9e72cd5ad7837b615d93ffredc    mCallbacksObj = env->NewGlobalRef(object);
1326654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
1336654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1346654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void cleanupNative(JNIEnv *env, jobject object) {
1356654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
136de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamy    if (!btIf) return;
1376654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1386654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sPanIf !=NULL) {
1396654f5c903de510a70f9e72cd5ad7837b615d93ffredc        LOGW("Cleaning up Bluetooth PAN Interface...");
1406654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sPanIf->cleanup();
1416654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sPanIf = NULL;
1426654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1436654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1446654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
1456654f5c903de510a70f9e72cd5ad7837b615d93ffredc        LOGW("Cleaning up Bluetooth PAN callback object");
1466654f5c903de510a70f9e72cd5ad7837b615d93ffredc        env->DeleteGlobalRef(mCallbacksObj);
1476654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mCallbacksObj = NULL;
1486654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
149de396a46388269221b05dae2760be63fe7254748Kausik Sinnaswamy    btIf = NULL;
1506654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
1516654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1526654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jboolean enablePanNative(JNIEnv *env, jobject object, jint local_role) {
1536654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status = BT_STATUS_FAIL;
1546654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("in");
1556654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyte *addr;
1566654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sPanIf)
1576654f5c903de510a70f9e72cd5ad7837b615d93ffredc        status = sPanIf->enable(local_role);
1586654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("out");
1596654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return status == BT_STATUS_SUCCESS ? JNI_TRUE : JNI_FALSE;
1606654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
1616654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jint getPanLocalRoleNative(JNIEnv *env, jobject object) {
1626654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("in");
1636654f5c903de510a70f9e72cd5ad7837b615d93ffredc    int local_role = 0;
1646654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyte *addr;
1656654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sPanIf)
1666654f5c903de510a70f9e72cd5ad7837b615d93ffredc        local_role  = sPanIf->get_local_role();
1676654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("out");
1686654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return (jint)local_role;
1696654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
1706654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1716654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1726654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1736654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jboolean connectPanNative(JNIEnv *env, jobject object, jbyteArray address,
1746654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                 jint src_role, jint dest_role) {
1756654f5c903de510a70f9e72cd5ad7837b615d93ffredc    debug("in");
1766654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
1776654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyte *addr;
1786654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jboolean ret = JNI_TRUE;
1796654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!sPanIf) return JNI_FALSE;
1806654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1816654f5c903de510a70f9e72cd5ad7837b615d93ffredc    addr = env->GetByteArrayElements(address, NULL);
1826654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!addr) {
1836654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Bluetooth device address null");
1846654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return JNI_FALSE;
1856654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1866654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1876654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ((status = sPanIf->connect((bt_bdaddr_t *) addr, src_role, dest_role)) !=
1886654f5c903de510a70f9e72cd5ad7837b615d93ffredc         BT_STATUS_SUCCESS) {
1896654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Failed PAN channel connection, status: %d", status);
1906654f5c903de510a70f9e72cd5ad7837b615d93ffredc        ret = JNI_FALSE;
1916654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1926654f5c903de510a70f9e72cd5ad7837b615d93ffredc    env->ReleaseByteArrayElements(address, addr, 0);
1936654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1946654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return ret;
1956654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
1966654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1976654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic jboolean disconnectPanNative(JNIEnv *env, jobject object, jbyteArray address) {
1986654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
1996654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jbyte *addr;
2006654f5c903de510a70f9e72cd5ad7837b615d93ffredc    jboolean ret = JNI_TRUE;
2016654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!sPanIf) return JNI_FALSE;
2026654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2036654f5c903de510a70f9e72cd5ad7837b615d93ffredc    addr = env->GetByteArrayElements(address, NULL);
2046654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (!addr) {
2056654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Bluetooth device address null");
2066654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return JNI_FALSE;
2076654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2086654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2096654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (status = sPanIf->disconnect((bt_bdaddr_t *) addr)) !=
2106654f5c903de510a70f9e72cd5ad7837b615d93ffredc         BT_STATUS_SUCCESS) {
2116654f5c903de510a70f9e72cd5ad7837b615d93ffredc        error("Failed disconnect pan channel, status: %d", status);
2126654f5c903de510a70f9e72cd5ad7837b615d93ffredc        ret = JNI_FALSE;
2136654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2146654f5c903de510a70f9e72cd5ad7837b615d93ffredc    env->ReleaseByteArrayElements(address, addr, 0);
2156654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2166654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return ret;
2176654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
2186654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2196654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic JNINativeMethod sMethods[] = {
2206654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"classInitNative", "()V", (void *) classInitNative},
2216654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"initializeNative", "()V", (void *) initializeNative},
2226654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"cleanupNative", "()V", (void *) cleanupNative},
2236654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"connectPanNative", "([BII)Z", (void *) connectPanNative},
2246654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"enablePanNative", "(I)Z", (void *) enablePanNative},
2256654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"getPanLocalRoleNative", "()I", (void *) getPanLocalRoleNative},
2266654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"disconnectPanNative", "([B)Z", (void *) disconnectPanNative},
2276654f5c903de510a70f9e72cd5ad7837b615d93ffredc    // TBD cleanup
2286654f5c903de510a70f9e72cd5ad7837b615d93ffredc};
2296654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2306654f5c903de510a70f9e72cd5ad7837b615d93ffredcint register_com_android_bluetooth_pan(JNIEnv* env)
2316654f5c903de510a70f9e72cd5ad7837b615d93ffredc{
2326654f5c903de510a70f9e72cd5ad7837b615d93ffredc    return jniRegisterNativeMethods(env, "com/android/bluetooth/pan/PanService",
2336654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                    sMethods, NELEM(sMethods));
2346654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
2356654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2366654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
237