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