From b8e15de214fec2423c4814a0084cb58666d9a2e4 Mon Sep 17 00:00:00 2001 From: "jihwan.seo" Date: Sun, 21 Feb 2016 16:17:18 +0900 Subject: [PATCH] [IOT-955] To separate of pairing BT If there were a number of BT devices near the user device, user device will try to request pairing key exchange regardless BT device owner. it can cause very serious user experience problem. so. i have added BT pairing from discovery procedure. then the iotivity tries to find resources from already paired BT devices provided each platform. Change-Id: I8adee751c8e66e87a54ccc1b27ec0800c1c1edb3 Signed-off-by: jihwan.seo Reviewed-on: https://gerrit.iotivity.org/gerrit/5093 Tested-by: jenkins-iotivity Reviewed-by: Jon A. Cruz --- android/android_api/base/jni/JniCaInterface.c | 54 ++- android/android_api/base/jni/JniCaInterface.h | 40 +++ .../java/org/iotivity/ca/CaBtPairingInterface.java | 105 ++++++ .../src/main/java/org/iotivity/ca/CaInterface.java | 72 ++++ resource/csdk/connectivity/api/cautilinterface.h | 27 ++ resource/csdk/connectivity/util/SConscript | 7 +- .../connectivity/util/inc/cabtpairinginterface.h | 82 +++++ .../util/src/btpairing/android/cabtpairing.c | 370 +++++++++++++++++++++ .../util/src/btpairing/android/cabtpairing.h | 62 ++++ .../csdk/connectivity/util/src/cautilinterface.c | 70 +++- 10 files changed, 878 insertions(+), 11 deletions(-) create mode 100644 android/android_api/base/src/main/java/org/iotivity/ca/CaBtPairingInterface.java create mode 100644 resource/csdk/connectivity/util/inc/cabtpairinginterface.h create mode 100644 resource/csdk/connectivity/util/src/btpairing/android/cabtpairing.c create mode 100644 resource/csdk/connectivity/util/src/btpairing/android/cabtpairing.h diff --git a/android/android_api/base/jni/JniCaInterface.c b/android/android_api/base/jni/JniCaInterface.c index 3cb4019..219ea7c 100644 --- a/android/android_api/base/jni/JniCaInterface.c +++ b/android/android_api/base/jni/JniCaInterface.c @@ -32,6 +32,7 @@ #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +static jobject g_foundDeviceListenerObject = NULL; static jobject g_listenerObject = NULL; static JavaVM *g_jvm = NULL; @@ -220,10 +221,10 @@ Java_org_iotivity_ca_CaInterface_caManagerInitialize(JNIEnv *env, jclass clazz, { LOGI("CaManagere_initialize"); - g_listenerObject = (*env)->NewGlobalRef(env, listener); - CAUtilClientInitialize(env, g_jvm, context); + g_listenerObject = (*env)->NewGlobalRef(env, listener); + CARegisterNetworkMonitorHandler(CAManagerAdapterStateChangedCB, CAManagerConnectionStateChangedCB); } @@ -274,3 +275,52 @@ Java_org_iotivity_ca_CaInterface_caManagerUnsetAutoConnectionDeviceInfo(JNIEnv * CAUnsetAutoConnectionDeviceInfo(address); } + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaInterface_caBtPairingInitialize(JNIEnv *env, jclass clazz, + jobject context, jobject listener) +{ + LOGI("caBtPairingInitialize"); + (void)clazz; + + CAUtilClientInitialize(env, g_jvm, context); + + g_foundDeviceListenerObject = (*env)->NewGlobalRef(env, listener); + CAUtilSetFoundDeviceListener(g_foundDeviceListenerObject); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaInterface_caBtPairingTerminate(JNIEnv *env, jclass clazz) +{ + LOGI("caBtPairingTerminate"); + (void)clazz; + + if (g_foundDeviceListenerObject) + { + (*env)->DeleteGlobalRef(env, g_foundDeviceListenerObject); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaInterface_caBtPairingStartScan(JNIEnv *env, jclass clazz) +{ + LOGI("caBtPairingStartScan"); + (void)clazz; + CAUtilStartScan(env); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaInterface_caBtPairingStopScan(JNIEnv *env, jclass clazz) +{ + LOGI("caBtPairingStopScan"); + (void)clazz; + CAUtilStopScan(env); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaInterface_caBtPairingCreateBond(JNIEnv *env, jclass clazz, jobject device) +{ + LOGI("caBtPairingCreateBond"); + (void)clazz; + CAUtilCreateBond(env, device); +} diff --git a/android/android_api/base/jni/JniCaInterface.h b/android/android_api/base/jni/JniCaInterface.h index d8d36fd..20dc995 100644 --- a/android/android_api/base/jni/JniCaInterface.h +++ b/android/android_api/base/jni/JniCaInterface.h @@ -74,6 +74,46 @@ extern "C" { jstring jaddress); /* + * Class: Java_org_iotivity_ca_CaInterface_caBtPairingInitialize + * Method: caBtPairingInitialize + * Signature: (Landroid/content/Context;)V + */ + JNIEXPORT void JNICALL + Java_org_iotivity_ca_CaInterface_caBtPairingInitialize(JNIEnv *, jclass, jobject, jobject); + + /* + * Class: Java_org_iotivity_ca_CaInterface_caBtPairingTerminate + * Method: caBtPairingTerminate + * Signature: ()V + */ + JNIEXPORT void JNICALL + Java_org_iotivity_ca_CaInterface_caBtPairingTerminate(JNIEnv *env, jclass clazz); + + /* + * Class: Java_org_iotivity_ca_CaInterface_caBtPairingStartScan + * Method: caBtPairingStartScan + * Signature: ()V + */ + JNIEXPORT void JNICALL + Java_org_iotivity_ca_CaInterface_caBtPairingStartScan(JNIEnv *, jclass); + + /* + * Class: Java_org_iotivity_ca_CaInterface_caBtPairingStopScan + * Method: caBtPairingStopScan + * Signature: ()V + */ + JNIEXPORT void JNICALL + Java_org_iotivity_ca_CaInterface_caBtPairingStopScan(JNIEnv *, jclass); + + /* + * Class: Java_org_iotivity_ca_CaInterface_caBtPairingCreateBond + * Method: caBtPairingCreateBond + * Signature: (Landroid/bluetooth/BluetoothDevice;)V + */ + JNIEXPORT void JNICALL + Java_org_iotivity_ca_CaInterface_caBtPairingCreateBond(JNIEnv *, jclass, jobject); + + /* * Class: org_iotivity_ca_CaInterface_Initialize * Method: Initialize * Signature: (Landroid/content/Context;)V diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaBtPairingInterface.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaBtPairingInterface.java new file mode 100644 index 0000000..57b8738 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/ca/CaBtPairingInterface.java @@ -0,0 +1,105 @@ +/****************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +package org.iotivity.ca; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; + +public class CaBtPairingInterface { + private static Context mContext; + + private CaBtPairingInterface(Context context) { + mContext = context; + registerIntentFilter(); + } + + private static IntentFilter registerIntentFilter() { + IntentFilter filter = new IntentFilter(); + filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); + filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + filter.addAction(BluetoothDevice.ACTION_FOUND); + mContext.registerReceiver(mReceiver, filter); + return filter; + } + + public static void destroyEdrInterface() { + mContext.unregisterReceiver(mReceiver); + } + + private native static void oicEdrStateChangedCallback(int state); + + private native static void oicEdrBondStateChangedCallback(String addr); + + private native static void oicEdrFoundDeviceCallback(BluetoothDevice device); + + private static final BroadcastReceiver mReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + + String action = intent.getAction(); + + if (action != null && action.equals(BluetoothDevice.ACTION_FOUND)) { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + + // if found device is not paired with this device + if (device.getBondState() != BluetoothDevice.BOND_BONDED) + { + oicEdrFoundDeviceCallback(device); + } + } + + if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { + + int state = + intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); + + // STATE_ON:12, STATE_OFF:10 + if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF) + { + oicEdrStateChangedCallback(state); + } + } + + if (action != null && action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) { + + int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, + BluetoothDevice.ERROR); + + // unpairing event + if (bondState == BluetoothDevice.BOND_NONE) { + if ((intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, + BluetoothDevice.ERROR) + == BluetoothDevice.BOND_BONDED)) { + BluetoothDevice device + = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + + oicEdrBondStateChangedCallback(device.getAddress()); + } + } + } + } + }; +} diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java index 82f1041..3711f97 100644 --- a/android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java +++ b/android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java @@ -24,6 +24,7 @@ package org.iotivity.ca; import android.content.Context; import android.app.Activity; +import android.bluetooth.BluetoothDevice; import org.iotivity.base.OcException; import org.iotivity.base.OcConnectivityType; @@ -33,6 +34,7 @@ public class CaInterface { System.loadLibrary("ca-interface"); } private static volatile boolean isConnectionManagerInitialized = false; + private static volatile boolean isBtPairingInitialized = false; public static native void initialize(Activity activity, Context context); @@ -105,4 +107,74 @@ public class CaInterface { private static native void caManagerTerminate(); private static native void caManagerSetAutoConnectionDeviceInfo(String address); private static native void caManagerUnsetAutoConnectionDeviceInfo(String address); + + /** + * start bluetooth pairing service. + * @param context application context + */ + public synchronized static void startBtPairingService(Context context, + OnBtDeviceFoundListener listener) { + if (!isBtPairingInitialized) { + CaInterface.caBtPairingInitialize(context, listener); + + isBtPairingInitialized = true; + } + } + + /** + * stop bluetooth pairing service. + */ + public synchronized static void stopBtPairingService() { + if (isBtPairingInitialized) { + CaInterface.caBtPairingTerminate(); + + isBtPairingInitialized = false; + } + } + + /** + * start bluetooth device scan. + */ + public synchronized static void startScan() + throws OcException { + CaInterface.initCheckForBtPairingUtil(); + CaInterface.caBtPairingStartScan(); + } + + /** + * stop bluetooth device scan. + */ + public synchronized static void stopScan() + throws OcException { + CaInterface.initCheckForBtPairingUtil(); + CaInterface.caBtPairingStopScan(); + } + + /** + * create bond + */ + public synchronized static void createBond(BluetoothDevice device) + throws OcException { + CaInterface.initCheckForBtPairingUtil(); + CaInterface.caBtPairingCreateBond(device); + } + + public interface OnBtDeviceFoundListener { + public void onBtDeviceFound(BluetoothDevice device) throws OcException; + } + + private static void initCheckForBtPairingUtil() { + if (!isBtPairingInitialized) { + throw new IllegalStateException("BT pairing Util must be started by making " + + "a call to CaInterface.startBtPairingService before any other API " + + "calls are permitted"); + } + } + + private static native void caBtPairingInitialize(Context context, + OnBtDeviceFoundListener listener); + private static native void caBtPairingTerminate(); + private static native void caBtPairingStartScan(); + private static native void caBtPairingStopScan(); + private static native void caBtPairingCreateBond(BluetoothDevice device); } \ No newline at end of file diff --git a/resource/csdk/connectivity/api/cautilinterface.h b/resource/csdk/connectivity/api/cautilinterface.h index 7e31d3b..5e852d4 100644 --- a/resource/csdk/connectivity/api/cautilinterface.h +++ b/resource/csdk/connectivity/api/cautilinterface.h @@ -76,6 +76,33 @@ CAResult_t CAUtilClientInitialize(JNIEnv *env, JavaVM *jvm, jobject context); * @return ::CA_STATUS_OK or ::CA_STATUS_FAILED or ::CA_MEMORY_ALLOC_FAILED */ CAResult_t CAUtilClientTerminate(JNIEnv *env); + +// BT pairing +/** + * start discovery for BT device which has iotivity UUID. + * @param[in] env JNI interface pointer. + */ +CAResult_t CAUtilStartScan(JNIEnv *env); + +/** + * stop discovery + * @param[in] env JNI interface pointer. + */ +CAResult_t CAUtilStopScan(JNIEnv *env); + +/** + * bonding between devices. + * @param[in] env JNI interface pointer. + * @param[in] device bluetooth device object. + */ +CAResult_t CAUtilCreateBond(JNIEnv *env, jobject device); + + +/** + * set callback listener of found device. + * @param[in] listener callback listener + */ +void CAUtilSetFoundDeviceListener(jobject listener); #endif #ifdef __cplusplus diff --git a/resource/csdk/connectivity/util/SConscript b/resource/csdk/connectivity/util/SConscript index 33b6c12..33e15f6 100644 --- a/resource/csdk/connectivity/util/SConscript +++ b/resource/csdk/connectivity/util/SConscript @@ -39,4 +39,9 @@ if (('BLE' in ca_transport) or ('ALL' in ca_transport)): os.path.join(src_dir,'camanager/android/caleconnectionmanager.c'), os.path.join(src_dir,'camanager/android/caleautoconnector.c'), os.path.join(src_dir,'camanager/android/camanagerleutil.c'), - os.path.join(src_dir,'camanager/android/camanagerdevice.c')]) \ No newline at end of file + os.path.join(src_dir,'camanager/android/camanagerdevice.c')]) + +if (('BT' in ca_transport) or ('ALL' in ca_transport)): + if ca_os == 'android': + env.AppendUnique(CA_SRC = [ + os.path.join(src_dir,'btpairing/android/cabtpairing.c')]) \ No newline at end of file diff --git a/resource/csdk/connectivity/util/inc/cabtpairinginterface.h b/resource/csdk/connectivity/util/inc/cabtpairinginterface.h new file mode 100644 index 0000000..507b063 --- /dev/null +++ b/resource/csdk/connectivity/util/inc/cabtpairinginterface.h @@ -0,0 +1,82 @@ +/* **************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef CA_BT_PAIRING_INTERFACE_H_ +#define CA_BT_PAIRING_INTERFACE_H_ + +#include "cacommon.h" +#include "cautilinterface.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __ANDROID__ +#ifdef EDR_ADAPTER +/** + * initialize BT Pairing manager + * @param[in] env JNI interface pointer. + * @param[in] jvm invocation inferface for JAVA virtual machine. + * @param[in] context application context. + * + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h). + */ +CAResult_t CABTPairingInitialize(JNIEnv *env, JavaVM *jvm, jobject context); + +/** + * start discovery for BT device which has iotivity UUID. + * @param[in] env JNI interface pointer. + * + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h). + */ +CAResult_t CABTPairingStartScan(JNIEnv *env); + +/** + * stop discovery + * @param[in] env JNI interface pointer. + * + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h). + */ +CAResult_t CABTPairingStopScan(JNIEnv *env); + +/** + * bonding between devices. + * @param[in] env JNI interface pointer. + * @param[in] device bluetooth device object. + * + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h). + */ +CAResult_t CABTPairingCreateBond(JNIEnv *env, jobject device); + +/** + * set callback listener of found device. + * @param[in] listener callback listener + */ +void CABTPairingSetFoundDeviceListener(jobject listener); +#endif +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_LE_MANAGER_H_ */ + diff --git a/resource/csdk/connectivity/util/src/btpairing/android/cabtpairing.c b/resource/csdk/connectivity/util/src/btpairing/android/cabtpairing.c new file mode 100644 index 0000000..b982b74 --- /dev/null +++ b/resource/csdk/connectivity/util/src/btpairing/android/cabtpairing.c @@ -0,0 +1,370 @@ +/* **************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "cabtpairinginterface.h" +#include "cabtpairing.h" +#include "cacommon.h" +#include "logger.h" +#include + +#define TAG "OIC_CA_BT_PAIRING" + +/** + * pointer to store JavaVM + */ +static JavaVM *g_jvm = NULL; + +/** + * pointer to store context for android callback interface + */ +static jobject g_context = NULL; +static jobject g_listener = NULL; + +static const char CLASSPATH_CONTEXT[] = "android/content/Context"; +static const char METHODID_CONTEXTNONPARAM[] = "()Landroid/content/Context;"; +static const char CLASSPATH_BT_PAIRING_INTERFACE[] = "org/iotivity/ca/CaBtPairingInterface"; +static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter"; +static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;"; +static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice"; + +static void CABTPaitingCreateJNIInterfaceObject(jobject context) +{ + JNIEnv* env; + OIC_LOG(INFO, TAG, "OICEDRCreateJNIInterfaceObject"); + + if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) + { + OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer"); + return; + } + + //getApplicationContext + jclass contextClass = (*env)->FindClass(env, CLASSPATH_CONTEXT); + if (!contextClass) + { + OIC_LOG(ERROR, TAG, "Could not get context object class"); + return; + } + + jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass, + "getApplicationContext", + METHODID_CONTEXTNONPARAM); + if (!getApplicationContextMethod) + { + OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method"); + return; + } + + //Create EDRJniInterface instance + jclass EDRJniInterface = (*env)->FindClass(env, CLASSPATH_BT_PAIRING_INTERFACE); + if (!EDRJniInterface) + { + OIC_LOG(ERROR, TAG, "Could not get CaEdrInterface class"); + return; + } + + jmethodID EDRInterfaceConstructorMethod = (*env)->GetMethodID(env, EDRJniInterface, "", + "(Landroid/content/Context;)V"); + if (!EDRInterfaceConstructorMethod) + { + OIC_LOG(ERROR, TAG, "Could not get CaEdrInterface constructor method"); + return; + } + + (*env)->NewObject(env, EDRJniInterface, EDRInterfaceConstructorMethod, context); + OIC_LOG(INFO, TAG, "New Object has been created successfully"); +} + +CAResult_t CABTPairingInitialize(JNIEnv *env, JavaVM *jvm, jobject context) +{ + OIC_LOG(INFO, TAG, "CABTPairingInitialize"); + + if (!context) + { + OIC_LOG(ERROR, TAG, "context is null"); + return CA_STATUS_FAILED; + } + + g_jvm = jvm; + g_context = (*env)->NewGlobalRef(env, context); + + if (g_context) + { + /* create java interface instance*/ + CABTPaitingCreateJNIInterfaceObject(g_context); + } + return CA_STATUS_OK; +} + +void CABTPairingSetFoundDeviceListener(jobject listener) +{ + g_listener = listener; +} + +CAResult_t CABTPairingStartScan(JNIEnv *env) +{ + OIC_LOG(INFO, TAG, "CABTPairingStartScan"); + if (!env) + { + OIC_LOG(ERROR, TAG, "parameter is null"); + return CA_STATUS_FAILED; + } + + CABTPairingStopScan(env); + + // get default bt adapter class + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER); + if (!jni_cid_BTAdapter) + { + OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null"); + return CA_STATUS_FAILED; + } + + // get remote bt adapter method ID + jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, + "getDefaultAdapter", + METHODID_OBJECTNONPARAM); + if (!jni_mid_getDefaultAdapter) + { + OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null"); + return CA_STATUS_FAILED; + } + + // get startDiscovery() method ID + jmethodID jni_mid_startDiscovery = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startDiscovery", + "()Z"); + if (!jni_mid_startDiscovery) + { + OIC_LOG(ERROR, TAG, "jni_mid_startDiscovery is null"); + return CA_STATUS_FAILED; + } + + // get bluetooth adapter object + jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, + jni_mid_getDefaultAdapter); + if (!jni_obj_BTAdapter) + { + OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null"); + return CA_STATUS_FAILED; + } + + // call startDiscovery() method + jboolean jni_obj_startDiscovery = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, + jni_mid_startDiscovery); + if (!jni_obj_startDiscovery) + { + OIC_LOG(ERROR, TAG, "startDiscovery has failed"); + return CA_STATUS_FAILED; + } + else + { + OIC_LOG(INFO, TAG, "startDiscovery has started"); + return CA_STATUS_OK; + } +} + +CAResult_t CABTPairingStopScan(JNIEnv *env) +{ + OIC_LOG(INFO, TAG, "CABTPairingStopScan"); + if (!env) + { + OIC_LOG(ERROR, TAG, "parameter is null"); + return CA_STATUS_FAILED; + } + + // get default bt adapter class + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER); + if (!jni_cid_BTAdapter) + { + OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null"); + return CA_STATUS_FAILED; + } + + // get remote bt adapter method ID + jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, + "getDefaultAdapter", + METHODID_OBJECTNONPARAM); + if (!jni_mid_getDefaultAdapter) + { + OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null"); + return CA_STATUS_FAILED; + } + + // get cancelDiscovery() method ID + jmethodID jni_mid_cancelDiscovery = (*env)->GetMethodID(env, jni_cid_BTAdapter, "cancelDiscovery", + "()Z"); + if (!jni_mid_cancelDiscovery) + { + OIC_LOG(ERROR, TAG, "jni_mid_cancelDiscovery is null"); + return CA_STATUS_FAILED; + } + + // gat bt adapter object + jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, + jni_mid_getDefaultAdapter); + if (!jni_obj_BTAdapter) + { + OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null"); + return CA_STATUS_FAILED; + } + + // call cancelDiscovery() method + jboolean jni_obj_cancelDiscovery = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, + jni_mid_cancelDiscovery); + if (!jni_obj_cancelDiscovery) + { + OIC_LOG(ERROR, TAG, "cancelDiscovery has failed"); + return CA_STATUS_FAILED; + } + else + { + OIC_LOG(INFO, TAG, "cancelDiscovery has started"); + return CA_STATUS_OK; + } +} + +CAResult_t CABTPairingCreateBond(JNIEnv *env, jobject device) +{ + OIC_LOG(INFO, TAG, "CABTPairingCreateBond"); + if (!env || !device) + { + OIC_LOG(ERROR, TAG, "parameter is null"); + return CA_STATUS_FAILED; + } + + // get default bt adapter class + jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE); + if (!jni_cid_BTDevice) + { + OIC_LOG(ERROR, TAG, "jni_cid_BTDevice is null"); + return CA_STATUS_FAILED; + } + + // get createBond() method ID + jmethodID jni_mid_createBond = (*env)->GetMethodID(env, jni_cid_BTDevice, "createBond", + "()Z"); + if (!jni_mid_createBond) + { + OIC_LOG(ERROR, TAG, "jni_mid_createBond is null"); + return CA_STATUS_FAILED; + } + + // call createBond() method + jboolean jni_obj_createBond = (*env)->CallBooleanMethod(env, device, jni_mid_createBond); + if (!jni_obj_createBond) + { + OIC_LOG(ERROR, TAG, "createBond has failed"); + return CA_STATUS_FAILED; + } + else + { + OIC_LOG(INFO, TAG, "createBond has started"); + return CA_STATUS_OK; + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaBtPairingInterface_oicEdrStateChangedCallback(JNIEnv *env, jobject obj, + jint status) +{ + OIC_LOG(INFO, TAG, "oicEdrStateChangedCallback"); + if (!env || !obj) + { + OIC_LOG(ERROR, TAG, "parameter is null"); + return; + } + + // STATE_ON:12, STATE_OFF:10 + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER); + if (!jni_cid_BTAdapter) + { + OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null"); + return; + } + + jfieldID id_state_on = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I"); + if (!id_state_on) + { + OIC_LOG(ERROR, TAG, "id_state_on is null"); + return; + } + + jfieldID id_state_off = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_OFF", "I"); + if (!id_state_off) + { + OIC_LOG(ERROR, TAG, "id_state_off is null"); + return; + } + + jint state_on = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, id_state_on); + jint state_off = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, id_state_off); + + if (state_on == status) + { + OIC_LOG(INFO, TAG, "oicEdrStateChangedCallback : state_on"); + } + else if (state_off == status) + { + OIC_LOG(INFO, TAG, "oicEdrStateChangedCaloicEdrFoundDeviceCallbacklback : state_off"); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaBtPairingInterface_oicEdrBondStateChangedCallback(JNIEnv *env, jobject obj, + jstring addr) +{ + OIC_LOG(INFO, TAG, "oicEdrBondStateChangedCallback"); + (void)env; + (void)obj; + (void)addr; +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaBtPairingInterface_oicEdrFoundDeviceCallback(JNIEnv *env, jobject obj, + jobject device) +{ + if (!env || !obj || !device) + { + return; + } + + if (!g_listener) + { + return; + } + + jclass jni_cls_listener = (*env)->GetObjectClass(env, g_listener); + if (!jni_cls_listener) + { + OIC_LOG(ERROR, TAG, "could not get jni_cls_listener"); + return; + } + + jmethodID jni_mid_listener = (*env)->GetMethodID(env, jni_cls_listener, "onBtDeviceFound", + "(Landroid/bluetooth/BluetoothDevice;)V"); + if (!jni_mid_listener) + { + OIC_LOG(ERROR, TAG, "could not get Method ID"); + return; + } + + (*env)->CallVoidMethod(env, g_listener, jni_mid_listener, device); +} + diff --git a/resource/csdk/connectivity/util/src/btpairing/android/cabtpairing.h b/resource/csdk/connectivity/util/src/btpairing/android/cabtpairing.h new file mode 100644 index 0000000..0a0e973 --- /dev/null +++ b/resource/csdk/connectivity/util/src/btpairing/android/cabtpairing.h @@ -0,0 +1,62 @@ +/****************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "jni.h" +/* Header for class org_iotivity_ca_CaBtPairingInterface */ + +#ifndef Included_org_iotivity_ca_CaBtPairingInterface +#define Included_org_iotivity_ca_CaBtPairingInterface +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * Class: org_iotivity_ca_CaBtPairingInterface + * Method: oicEdrStateChangedCallback + * Signature: (I)V + */ +JNIEXPORT void JNICALL +org_iotivity_ca_CaBtPairingInterface_oicEdrStateChangedCallback +(JNIEnv *, jobject, jint); + +/* + * Class: org_iotivity_ca_OicBtUtilClientInterface + * Method: oicEdrBondStateChangedCallback + * Signature: (java/lang/String;)V + */ +JNIEXPORT void JNICALL +org_iotivity_ca_CaBtPairingInterface_oicEdrBondStateChangedCallback +(JNIEnv *, jobject, jstring); + +/* + * Class: org_iotivity_ca_OicBtUtilClientInterface + * Method: oicEdrFoundDeviceCallback + * Signature: (BluetoothDevice)V + */ +JNIEXPORT void JNICALL +org_iotivity_ca_CaBtPairingInterface_oicEdrFoundDeviceCallback +(JNIEnv *, jobject, jobject); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/resource/csdk/connectivity/util/src/cautilinterface.c b/resource/csdk/connectivity/util/src/cautilinterface.c index 311145b..83513f7 100644 --- a/resource/csdk/connectivity/util/src/cautilinterface.c +++ b/resource/csdk/connectivity/util/src/cautilinterface.c @@ -19,12 +19,13 @@ ******************************************************************/ #include "camanagerleinterface.h" +#include "cabtpairinginterface.h" #include "cautilinterface.h" #include "cacommon.h" #include "logger.h" -#define TAG "OIC_CA_UTIL_INF" +#define TAG "OIC_CA_COMMON_UTILS" CAResult_t CARegisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateCB, CAConnectionStateChangedCB connStateCB) @@ -76,15 +77,24 @@ CAResult_t CAUnsetAutoConnectionDeviceInfo(const char *address) CAResult_t CAUtilClientInitialize(JNIEnv *env, JavaVM *jvm, jobject context) { OIC_LOG(DEBUG, TAG, "CAUtilClientInitialize"); + + CAResult_t res = CA_STATUS_OK; #ifdef LE_ADAPTER - return CAManagerLEClientInitialize(env, jvm, context); -#else - OIC_LOG(DEBUG, TAG, "it is not supported"); - (void)env; - (void)jvm; - (void)context; - return CA_NOT_SUPPORTED; + if (CA_STATUS_OK != CAManagerLEClientInitialize(env, jvm, context)) + { + OIC_LOG(ERROR, TAG, "CAManagerLEClientInitialize has failed"); + res = CA_STATUS_FAILED; + } #endif + +#ifdef EDR_ADAPTER + if (CA_STATUS_OK != CABTPairingInitialize(env, jvm, context)) + { + OIC_LOG(ERROR, TAG, "CABTPairingInitialize has failed"); + res = CA_STATUS_FAILED; + } +#endif + return res; } /** @@ -102,4 +112,48 @@ CAResult_t CAUtilClientTerminate(JNIEnv *env) return CA_NOT_SUPPORTED; #endif } + +// BT pairing +CAResult_t CAUtilStartScan(JNIEnv *env) +{ +#ifdef EDR_ADAPTER + return CABTPairingStartScan(env); +#else + OIC_LOG(DEBUG, TAG, "it is not supported"); + (void)env; + return CA_NOT_SUPPORTED; +#endif +} + +CAResult_t CAUtilStopScan(JNIEnv *env) +{ +#ifdef EDR_ADAPTER + return CABTPairingStopScan(env); +#else + OIC_LOG(DEBUG, TAG, "it is not supported"); + (void)env; + return CA_NOT_SUPPORTED; +#endif +} + +CAResult_t CAUtilCreateBond(JNIEnv *env, jobject device) +{ +#ifdef EDR_ADAPTER + return CABTPairingCreateBond(env, device); +#else + OIC_LOG(DEBUG, TAG, "it is not supported"); + (void)env; + (void)device; + return CA_NOT_SUPPORTED; +#endif +} + +void CAUtilSetFoundDeviceListener(jobject listener) +{ +#ifdef EDR_ADAPTER + CABTPairingSetFoundDeviceListener(listener); +#else + (void)listener; +#endif +} #endif -- 2.7.4