From 39717b67bd05839b1b6d42c8a8c99b19df201350 Mon Sep 17 00:00:00 2001 From: "jaehong.jo" Date: Wed, 6 May 2015 22:18:36 +0900 Subject: [PATCH] Added Android EDR code Android EDR functionality has been implemented. Signed-off-by: jaehong.jo Change-Id: I036bde692098ea40e28df2b07b40e478a4eb021b Reviewed-on: https://gerrit.iotivity.org/gerrit/757 Tested-by: jenkins-iotivity Reviewed-by: Erich Keane --- resource/csdk/connectivity/inc/caedrclient.h | 295 ----- resource/csdk/connectivity/inc/caedrserver.h | 252 ---- resource/csdk/connectivity/inc/caedrutils.h | 57 - .../src/bt_edr_adapter/android/caedrclient.c | 1171 +++++++------------ .../src/bt_edr_adapter/android/caedrclient.h | 169 +++ .../src/bt_edr_adapter/android/caedrnwmonitor.c | 120 +- .../src/bt_edr_adapter/android/caedrnwmonitor.h | 52 + .../src/bt_edr_adapter/android/caedrserver.c | 1235 +++++++++----------- .../src/bt_edr_adapter/android/caedrserver.h | 142 +++ .../src/bt_edr_adapter/android/caedrutils.c | 786 +++++++++++-- .../src/bt_edr_adapter/android/caedrutils.h | 230 ++++ .../android/org_iotivity_jar_caedrinterface.h | 31 + 12 files changed, 2397 insertions(+), 2143 deletions(-) delete mode 100644 resource/csdk/connectivity/inc/caedrclient.h delete mode 100644 resource/csdk/connectivity/inc/caedrserver.h delete mode 100644 resource/csdk/connectivity/inc/caedrutils.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/android/caedrnwmonitor.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/android/org_iotivity_jar_caedrinterface.h diff --git a/resource/csdk/connectivity/inc/caedrclient.h b/resource/csdk/connectivity/inc/caedrclient.h deleted file mode 100644 index 926abf5..0000000 --- a/resource/csdk/connectivity/inc/caedrclient.h +++ /dev/null @@ -1,295 +0,0 @@ -/* **************************************************************** - * - * Copyright 2014 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. - * - ******************************************************************/ - -/** - * @file - * - * This file contains the APIs for BT EDR communications. - */ - -#ifndef __CA_EDRCORE_H_ -#define __CA_EDRCORE_H_ - -#include - -#include "cacommon.h" -#include "cathreadpool.h" -#include "jni.h" - - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** -* @brief Set context of application -* @param context [IN] context of application -* @return None -*/ -void CAEDRJniSetContext(jobject context); - -/** -* @brief Create JNI Object -* @param context [IN] context of application -* @return None -*/ -void CAEDRCreateJNIInterfaceObject(jobject context); - -/** - * @brief Initialize client for EDR - * @param handle [IN] thread pool handle object - * @return None - */ -void CAEDRInitialize(ca_thread_pool_t handle); - -/** - * @brief Terminate server for EDR - * @return None - */ -void CAEDRTerminate(); - -/** - * @brief Initialize JNI object - * @param env [IN] JNI interface pointer - * @param jvm [IN] java virtual machine pointer - * @return None - */ -void CAEDRCoreJniInit(JNIEnv *env, JavaVM *jvm); - -/** - * @brief Send data for unicast - * @param address [IN] remote address - * @param data [IN] data for transmission - * @param dataLen [IN] data length - * @return #CA_STATUS_OK or Appropriate error code - * @retval #CA_STATUS_OK Successful - * @retval #CA_STATUS_FAILED Operation failed - */ -CAResult_t CAEDRSendUnicastMessage(const char *address, - const char *data, uint32_t dataLen); - -/** - * @brief Send data for multicast - * @param data [IN] data for transmission - * @param dataLen [IN] data length - * @return #CA_STATUS_OK or Appropriate error code - * @retval #CA_STATUS_OK Successful - * @retval #CA_STATUS_FAILED Operation failed - */ -CAResult_t CAEDRSendMulticastMessage(const char *data, uint32_t dataLen); - -/** - * @brief Get Local EDR Address - * @param address [OUT] local address - * @return #CA_STATUS_OK or Appropriate error code - * @retval #CA_STATUS_OK Successful - * @retval #CA_STATUS_FAILED Operation failed - */ -CAResult_t CAEDRGetInterfaceInfo(char **address); - -/** - * @brief Get address from a local device - * @param address [OUT] local address - * @return None - */ -void CAEDRGetLocalAddress(char **address); - -/** - * @brief Send data for unicast (implement) - * @param address [IN] remote address - * @param data [IN] data for transmission - * @param dataLen [IN] data length - * @return #CA_STATUS_OK or Appropriate error code - * @retval #CA_STATUS_OK Successful - * @retval #CA_STATUS_FAILED Operation failed - */ -CAResult_t CAEDRSendUnicastMessageImpl(const char *address, - const char *data, uint32_t dataLen); - -/** - * @brief Send data for multicast (implement) - * @param env [IN] JNI interface pointer - * @param data [IN] data for transmission - * @param dataLen [IN] data length - * @return #CA_STATUS_OK or Appropriate error code - * @retval #CA_STATUS_OK Successful - * @retval #CA_STATUS_FAILED Operation failed - */ -CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char *data, uint32_t dataLen); - -/** - * EDR Method - */ - -/** - * @brief This function will send the data to remote device. - * @param env [IN] JNI interface pointer - * @param address [IN] Remote Address - * @param data [IN] Data to be transmitted from EDR - * @param id [IN] index of remote address - * @return None - */ -void CAEDRNativeSendData(JNIEnv *env, const char *address, const char *data, uint32_t id); - -/** - * @brief This function will connect to remote device. - * @param env [IN] JNI interface pointer - * @param address [IN] Remote Address - * @param id [IN] index of remote address - * @return None - */ -void CAEDRNativeConnect(JNIEnv *env, const char *address, uint32_t id); - -/** - * @brief This function will close socket. - * @param env [IN] JNI interface pointer - * @param address [IN] Remote Address - * @param id [IN] index of remote address - * @return None - */ -void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id); - -/** - * BT State List - */ - -/** - * @brief This function will create the device state list. - * @return None - */ -void CAEDRNativeCreateDeviceStateList(); - -/** - * @brief Update connection state of device - * @param state [IN] connection state - * @param address [IN] remote address - * @return None - */ -void CAEDRUpdateDeviceState(CAConnectedState_t state, const char *address); - -/** - * @brief Add device object to the list - * @param state [IN] connection state object - * @return None - */ -void CAEDRNativeAddDeviceStateToList(state_t *state); - -/** - * @brief Check whether the device exist in the list or not - * @param remoteAddress [IN] remote address - * @return TRUE or FALSE - */ -jboolean CAEDRNativeIsDeviceInList(const char *remoteAddress); - -/** - * @brief Remove all device objects in the list - * @return None - */ -void CAEDRNativeRemoveAllDeviceState(); - -/** - * @brief Remove target device in the list - * @param remoteAddress [IN] remote address - * @return None - */ -void CAEDRNativeRemoveDevice(const char *remoteAddress); - -/** - * @brief Get current device connection state - * @param remoteAddress [IN] remote address - * @return STATE_DISCONNECTED or STATE_CONNECTED - */ -CAConnectedState_t CAEDRIsConnectedDevice(const char *remoteAddress); - -/** - * @brief Reordering for the list - * @param index [IN] index of device list that want to reordering - * @return None - */ -void CAEDRReorderingDeviceList(uint32_t index); - -/** - * Bluetooth Socket Object List - */ - -/** - * @brief This function will create the device socket list. - * @return None - */ -void CAEDRNativeCreateDeviceSocketList(); - -/** - * @brief Add device object to the list - * @param env [IN] JNI interface pointer - * @param deviceSocket [IN] device socket object - * @return None - */ -void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket); - -/** - * @brief Add device object to the list - * @param env [IN] JNI interface pointer - * @param remoteAddress [IN] remote address - * @return TRUE or FALSE - */ -jboolean CAEDRNativeIsDeviceSocketInList(JNIEnv *env, const char *remoteAddress); - -/** - * @brief Add device object to the list - * @param env [IN] JNI interface pointer - * @return None - */ -void CAEDRNativeRemoveAllDeviceSocket(JNIEnv *env); - -/** - * @brief Add device object to the list - * @param env [IN] JNI interface pointer - * @param deviceSocket [IN] device socket object - * @return None - */ -void CAEDRNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket); - -/** - * @brief Get device socket object from the list - * @param idx [IN] index of device list - * @return Device socket object or NULL - */ -jobject CAEDRNativeGetDeviceSocket(uint32_t idx); - -/** - * @brief Get length of device socket list - * @return length of list - */ -uint32_t CAEDRGetSocketListLength(); - -/** - * @brief Reordering for the list - * @param index [IN] index of device list that want to reordering - * @return None - */ -void CAEDRReorderingDeviceSocketList(uint32_t index); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif - diff --git a/resource/csdk/connectivity/inc/caedrserver.h b/resource/csdk/connectivity/inc/caedrserver.h deleted file mode 100644 index b2e6b4f..0000000 --- a/resource/csdk/connectivity/inc/caedrserver.h +++ /dev/null @@ -1,252 +0,0 @@ -/* **************************************************************** - * - * Copyright 2014 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. - * - ******************************************************************/ - -/** - * @file - * - * This file contains the APIs for BT EDR communications. - */ - -#ifndef __CA_EDRCORE_H_ -#define __CA_EDRCORE_H_ - -#include - -#include "cacommon.h" -#include "cathreadpool.h" -#include "jni.h" - - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef void (*CAPacketReceiveCallback)(const char *address, const char *data); - - -/** - * @brief Initialize JNI object - * @param env [IN] JNI interface pointer - * @param jvm [IN] java virtual machine pointer - * @return None - */ -void CAEDRServerJniInit(JNIEnv *env, JavaVM *jvm); - -/** - * @brief Initialize server for EDR - * @param handle [IN] thread pool handle object - * @return None - */ -void CAEDRServerInitialize(ca_thread_pool_t handle); - -/** - * @brief Start unicast server - * @param address [IN] remote address - * @param isSecured [IN] unicast server type - * @return Returns -1 on error and 0 on success - */ -int32_t CAEDRStartUnicastServer(const char *address, bool isSecured); - -/** - * @brief Start multicast server - * @param isSecured [IN] multicst server type - * @return Returns -1 on error and 0 on success - */ -int32_t CAEDRStartMulticastServer(bool isSecured); - -/** - * @brief Stop unicast server - * @param serverID [IN] unicast server id - * @return Returns -1 on error and 0 on success - */ -int32_t CAEDRStopUnicastServer(int32_t serverID); - -/** - * @brief Stop multicast server - * @param serverID [IN] multicast server id - * @return Returns -1 on error and 0 on success - */ -int32_t CAEDRStopMulticastServer(int32_t serverID); - -/** - * EDR Method - */ - -/** - * @brief This function will read the data from remote device. - * @param env [IN] JNI interface pointer - * @param id [IN] index of remote address - * @param type [IN] EDR server type - * @return #CA_STATUS_OK or Appropriate error code - */ -CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type); - -/** - * @brief This function will listen the connection from remote device. - * @param env [IN] JNI interface pointer - * @return server socket object or NULL - */ -jobject CAEDRNativeListen(JNIEnv *env); - -/** - * @brief This function will accept the connection from remote device. - * @param env [IN] JNI interface pointer - * @param severSocketObject [IN] server socket object - * @return None - */ -void CAEDRNativeAccept(JNIEnv *env, jobject severSocketObject); - -/** - * @brief This function will accept the connection from remote device. - * @param env [IN] JNI interface pointer - * @param address [IN] remote address - * @param id [IN] index of remote address - * @return None - */ -void CAEDRNativeServerSocketClose(JNIEnv *env, const char *address, uint32_t id); - -/** - * BT State List - */ - -/** - * @brief This function will create the device state list. - * @return None - */ -void CAEDRServerNativeCreateDeviceStateList(); - -/** - * @brief Update connection state of device - * @param state [IN] connection state - * @param address [IN] remote address - * @return None - */ -void CAEDRServerUpdateDeviceState(uint32_t state, const char *address); - -/** - * @brief Add device object to the list - * @param state [IN] connection state object - * @return None - */ -void CAEDRServerNativeAddDeviceStateToList(state_t *state); - -/** - * @brief Check whether the device exist in the list or not - * @param remoteAddress [IN] remote address - * @return TRUE or FALSE - */ -jboolean CAEDRServerNativeIsDeviceInList(const char *remoteAddress); - -/** - * @brief Remove all device objects in the list - * @return None - */ -void CAEDRServerNativeRemoveAllDeviceState(); - -/** - * @brief Remove target device in the list - * @param remoteAddress [IN] remote address - * @return None - */ -void CAEDRServerNativeRemoveDevice(const char *remoteAddress); - -/** - * @brief Check whether the state is connected or disconnected - * @param remoteAddress [IN] remote address - * @return TRUE or FALSE - */ -jboolean CAEDRServerIsConnectedDevice(const char *remoteAddress); - -/** - * @brief Reordering for the list - * @param index [IN] index of device list that want to reordering - * @return None - */ -void CAEDRServerReorderingDeviceList(uint32_t index); - -/** - * Bluetooth Socket Object List - */ - -/** - * @brief This function will create the device socket list. - * @return None - */ -void CAEDRServerNativeCreateDeviceSocketList(); - -/** - * @brief Add device object to the list - * @param env [IN] JNI interface pointer - * @param deviceSocket [IN] device socket object - * @return None - */ -void CAEDRServerNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket); - -/** - * @brief Add device object to the list - * @param env [IN] JNI interface pointer - * @param remoteAddress [IN] remote address - * @return TRUE or FALSE - */ -jboolean CAEDRServerNativeIsDeviceSocketInList(JNIEnv *env, const char *remoteAddress); - -/** - * @brief Add device object to the list - * @param env [IN] JNI interface pointer - * @return None - */ -void CAEDRServerNativeRemoveAllDeviceSocket(JNIEnv *env); - -/** - * @brief Add device object to the list - * @param env [IN] JNI interface pointer - * @param deviceSocket [IN] device socket object - * @return None - */ -void CAEDRServerNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket); - -/** - * @brief Get device socket object from the list - * @param idx [IN] index of device list - * @return Device socket object or NULL - */ -jobject CAEDRServerNativeGetDeviceSocket(uint32_t idx); - -/** - * @brief Get length of device socket list - * @return length of list - */ -uint32_t CAEDRServerGetSocketListLength(); - -/** - * @brief Reordering for the list - * @param index [IN] index of device list that want to reordering - * @return None - */ -void CAEDRServerReorderingDeviceSocketList(uint32_t index); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif - diff --git a/resource/csdk/connectivity/inc/caedrutils.h b/resource/csdk/connectivity/inc/caedrutils.h deleted file mode 100644 index 57e6e99..0000000 --- a/resource/csdk/connectivity/inc/caedrutils.h +++ /dev/null @@ -1,57 +0,0 @@ -/* **************************************************************** -* -* Copyright 2014 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. -* -******************************************************************/ - -/** - * @file - * - * This file contains the APIs for BT communications. - */ - -#ifndef __CA_EDRUTILES_H_ -#define __CA_EDRUTILES_H_ - -#include "cacommon.h" -#include "cathreadpool.h" -#include "uarraylist.h" -#include "jni.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -jstring CAEDRNativeGetAddressFromDeviceSocket(JNIEnv *env, jobject bluetoothSocketObj); - -jstring CAEDRNativeGetLocalDeviceAddress(JNIEnv *env); - -jobjectArray CAEDRNativeGetBondedDevices(JNIEnv *env); - -jint CAEDRNativeGetBTStateOnInfo(JNIEnv *env); - -jboolean CAEDRNativeIsEnableBTAdapter(JNIEnv *env); - -jstring CAEDRNativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif - diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c index fae5659..bba36ae 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c @@ -1,22 +1,22 @@ /****************************************************************** -* -* Copyright 2014 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. -* -******************************************************************/ + * + * Copyright 2014 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 #include @@ -25,7 +25,6 @@ #include "caedrinterface.h" #include "caedrutils.h" #include "caedrclient.h" -#include "caleserver.h" #include "logger.h" #include "oic_malloc.h" #include "cathreadpool.h" /* for thread pool */ @@ -36,32 +35,25 @@ //#define DEBUG_MODE #define TAG PCF("CA_EDR_CLIENT") -static const char *METHODID_OBJECTNONPARAM = "()Landroid/bluetooth/BluetoothAdapter;"; -static const char *METHODID_STRINGNONPARAM = "()Ljava/lang/String;"; -static const char *CLASSPATH_BT_ADPATER = "android/bluetooth/BluetoothAdapter"; -static const char *CLASSPATH_BT_UUID = "java/util/UUID"; - -static const uint32_t MAX_PDU_BUFFER = 1024; - -static u_arraylist_t *g_deviceStateList = NULL; -static u_arraylist_t *g_deviceObjectList = NULL; +static const char METHODID_CONTEXTNONPARAM[] = "()Landroid/content/Context;"; +static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;"; +static const char METHODID_OUTPUTNONPARAM[] = "()Ljava/io/OutputStream;"; +static const char METHODID_STRINGNONPARAM[] = "()Ljava/lang/String;"; +static const char METHODID_BT_DEVICEPARAM[] = + "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;"; +static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter"; +static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice"; +static const char CLASSPATH_BT_INTERFACE[] = "com/iotivity/jar/caedrinterface"; +static const char CLASSPATH_BT_SOCKET[] = "android/bluetooth/BluetoothSocket"; +static const char CLASSPATH_BT_UUID[] = "java/util/UUID"; +static const char CLASSPATH_CONTEXT[] = "android/content/Context"; +static const char CLASSPATH_OUTPUT[] = "java/io/OutputStream"; static ca_thread_pool_t g_threadPoolHandle = NULL; static JavaVM *g_jvm; static jobject g_context; -static jbyteArray g_sendBuffer; - -/** - * @var g_mutexSocketListManager - * @brief Mutex to synchronize socket list update - */ -static ca_mutex g_mutexSocketListManager; - -// server socket instance -static jobject g_serverSocketObject = NULL; - /** * @var g_mutexUnicastServer * @brief Mutex to synchronize unicast server @@ -92,7 +84,20 @@ static bool g_stopMulticast = false; */ static bool g_stopAccept = false; -typedef struct send_data { +/** + * @var g_mutexStateList + * @brief Mutex to synchronize device state list + */ +static ca_mutex g_mutexStateList = NULL; + +/** + * @var g_mutexObjectList + * @brief Mutex to synchronize device object list + */ +static ca_mutex g_mutexObjectList = NULL; + +typedef struct send_data +{ char* address; char* data; uint32_t id; @@ -112,13 +117,65 @@ typedef struct bool *stopFlag; } CAAdapterAcceptThreadContext_t; - -// TODO: It will be updated when android EDR support is added +/** + * implement for BT-EDR adapter common method + */ CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info) { - OIC_LOG(DEBUG, TAG, "IN"); + OIC_LOG(DEBUG, TAG, "IN - CAEDRGetInterfaceInformation"); - OIC_LOG(DEBUG, TAG, "OUT"); + if (!info) + { + OIC_LOG(ERROR, TAG, "LocalConnectivity info is null"); + return CA_STATUS_FAILED; + } + + int32_t netInfoSize = 1; + + char *macAddress = NULL; + CAResult_t ret = CAEDRGetInterfaceInfo(&macAddress); + OIC_LOG_V(ERROR, TAG, "address : %s", macAddress); + if (NULL == macAddress) + { + OIC_LOG(ERROR, TAG, "mac address is null"); + + return CA_STATUS_FAILED; + } + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "Failed to get interface info [%d]", ret); + + OICFree(macAddress); + return ret; + } + + // Create local endpoint using util function + CALocalConnectivity_t *endpoint = CAAdapterCreateLocalEndpoint(CA_EDR, macAddress); + if (NULL == endpoint) + { + OIC_LOG(ERROR, TAG, "Failed to create Local Endpoint!"); + OICFree(macAddress); + return CA_STATUS_FAILED; + } + + // copy unicast server information + endpoint->isSecured = false; + CALocalConnectivity_t *netInfo = (CALocalConnectivity_t *) OICMalloc( + sizeof(CALocalConnectivity_t) * netInfoSize); + if (NULL == netInfo) + { + OIC_LOG(ERROR, TAG, "Invalid input.."); + OICFree(macAddress); + CAAdapterFreeLocalEndpoint(endpoint); + return CA_MEMORY_ALLOC_FAILED; + } + memcpy(netInfo, endpoint, sizeof(CALocalConnectivity_t)); + *info = netInfo; + + OICFree(macAddress); + CAAdapterFreeLocalEndpoint(endpoint); + + OIC_LOG(DEBUG, TAG, "OUT - CAEDRGetInterfaceInformation"); return CA_STATUS_OK; } @@ -132,6 +189,7 @@ void CAEDRClientTerminate() CAResult_t CAEDRManagerReadData(void) { OIC_LOG(DEBUG, TAG, "IN"); + OIC_LOG(DEBUG, TAG, "OUT"); return CA_NOT_SUPPORTED; } @@ -145,7 +203,6 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser return CA_STATUS_OK; } - CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data, uint32_t dataLength, uint32_t *sentLength) { @@ -155,7 +212,7 @@ CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *dat return CA_STATUS_OK; } -// TODO: It will be updated when android EDR support is added +// It will be updated when android EDR support is added void CAEDRClientUnsetCallbacks(void) { OIC_LOG(DEBUG, TAG, "IN"); @@ -163,7 +220,7 @@ void CAEDRClientUnsetCallbacks(void) OIC_LOG(DEBUG, TAG, "OUT"); } -// TODO: It will be updated when android EDR support is added +// It will be updated when android EDR support is added void CAEDRClientDisconnectAll(void) { OIC_LOG(DEBUG, TAG, "IN"); @@ -179,23 +236,23 @@ CAResult_t CAEDRGetAdapterEnableState(bool *state) OIC_LOG(ERROR, TAG, "g_jvm is null"); return CA_STATUS_INVALID_PARAM; } - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAEDRGetAdapterEnableState - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return CA_STATUS_INVALID_PARAM; } - isAttached = JNI_TRUE; + isAttached = true; } jboolean ret = CAEDRNativeIsEnableBTAdapter(env); - if(ret) + if (ret) { *state = true; } @@ -204,99 +261,71 @@ CAResult_t CAEDRGetAdapterEnableState(bool *state) *state = false; } - if(isAttached) + if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } -//////////////////////////////////////////////////////////////////////////////////////////////////// -//FIXME getting context - -void CAEDRJniSetContext(jobject context) +void CAEDRJniInitContext() { - OIC_LOG(DEBUG, TAG, "caedrSetObject"); + OIC_LOG(DEBUG, TAG, "CAEDRJniInitContext"); - if (!context) - { - OIC_LOG(ERROR, TAG, "context is null"); - return; - } - jboolean isAttached = JNI_FALSE; - JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) - { - OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer"); - res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - - if(res != JNI_OK) - { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); - return; - } - isAttached = JNI_TRUE; - } - - g_context = (*env)->NewGlobalRef(env, context); - - if(isAttached) - (*g_jvm)->DetachCurrentThread(g_jvm); + g_context = (jobject) CANativeJNIGetContext(); } -void CAEDRCreateJNIInterfaceObject(jobject context) +CAResult_t CAEDRCreateJNIInterfaceObject(jobject context) { JNIEnv* env; OIC_LOG(DEBUG, TAG, "[EDRCore] CAEDRCreateJNIInterfaceObject"); if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) { - OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get JNIEnv pointer"); - return; + OIC_LOG(ERROR, TAG, "[EDRCore] Could not get JNIEnv pointer"); + return CA_STATUS_FAILED; } //getApplicationContext - jclass contextClass = (*env)->FindClass(env, "android/content/Context"); - if (contextClass == 0) + jclass contextClass = (*env)->FindClass(env, CLASSPATH_CONTEXT); + if (!contextClass) { - OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get context object class"); - return; + OIC_LOG(ERROR, TAG, "[EDRCore] Could not get context object class"); + return CA_STATUS_FAILED; } jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass, - "getApplicationContext", "()Landroid/content/Context;"); - if (getApplicationContextMethod == 0) + "getApplicationContext", + METHODID_CONTEXTNONPARAM); + if (!getApplicationContextMethod) { - OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get getApplicationContext method"); - return; + OIC_LOG(ERROR, TAG, "[EDRCore] Could not get getApplicationContext method"); + return CA_STATUS_FAILED; } - jobject gApplicationContext = (*env)->CallObjectMethod(env, context, - getApplicationContextMethod); - OIC_LOG_V(DEBUG, TAG, - "[WIFICore] Saving Android application context object %p", gApplicationContext); - - //Create WiFiInterface instance - jclass WiFiJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CAEDRInterface"); - if (!WiFiJniInterface) + //Create EDRJniInterface instance + jclass EDRJniInterface = (*env)->FindClass(env, CLASSPATH_BT_INTERFACE); + if (!EDRJniInterface) { - OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get CAWiFiInterface class"); - return; + OIC_LOG(ERROR, TAG, "[EDRCore] Could not get caedrinterface class"); + return CA_STATUS_FAILED; } - jmethodID WiFiInterfaceConstructorMethod = (*env)->GetMethodID(env, - WiFiJniInterface, "", "(Landroid/content/Context;)V"); - if (!WiFiInterfaceConstructorMethod) + jmethodID EDRInterfaceConstructorMethod = (*env)->GetMethodID(env, EDRJniInterface, "", + "(Landroid/content/Context;)V"); + if (!EDRInterfaceConstructorMethod) { - OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CAWiFiInterface constructor method"); - return; + OIC_LOG(ERROR, TAG, "[EDRCore] Could not get caedrinterface constructor method"); + return CA_STATUS_FAILED; } - (*env)->NewObject(env, WiFiJniInterface, WiFiInterfaceConstructorMethod, gApplicationContext); - OIC_LOG(DEBUG, TAG, "[EDRCore] Create CAWiFiInterface instance"); + (*env)->NewObject(env, EDRJniInterface, EDRInterfaceConstructorMethod, context); OIC_LOG(DEBUG, TAG, "[EDRCore] NewObject Success"); + return CA_STATUS_OK; + } static void CAEDRDestroyMutex() @@ -315,12 +344,17 @@ static void CAEDRDestroyMutex() g_mutexMulticastServer = NULL; } - if(g_mutexSocketListManager) + if (g_mutexStateList) { - ca_mutex_free(g_mutexSocketListManager); - g_mutexSocketListManager = NULL; + ca_mutex_free(g_mutexStateList); + g_mutexStateList = NULL; } + if (g_mutexObjectList) + { + ca_mutex_free(g_mutexObjectList); + g_mutexObjectList = NULL; + } OIC_LOG(DEBUG, TAG, "OUT"); } @@ -344,8 +378,17 @@ static CAResult_t CAEDRCreateMutex() return CA_STATUS_FAILED; } - g_mutexSocketListManager = ca_mutex_new(); - if (!g_mutexSocketListManager) + g_mutexStateList = ca_mutex_new(); + if (!g_mutexStateList) + { + OIC_LOG(ERROR, TAG, "Failed to created mutex!"); + + CAEDRDestroyMutex(); + return CA_STATUS_FAILED; + } + + g_mutexObjectList = ca_mutex_new(); + if (!g_mutexObjectList) { OIC_LOG(ERROR, TAG, "Failed to created mutex!"); @@ -363,39 +406,53 @@ void CAEDRInitialize(ca_thread_pool_t handle) g_threadPoolHandle = handle; + CAEDRCoreJniInit(); + + CAEDRJniInitContext(); + // init mutex CAEDRCreateMutex(); - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return; } - isAttached = JNI_TRUE; + isAttached = true; } - jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env); - if(jni_address) + if (jni_address) { const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL); OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress); + (*env)->ReleaseStringUTFChars(env, jni_address, localAddress); } + ca_mutex_lock(g_mutexStateList); CAEDRNativeCreateDeviceStateList(); + ca_mutex_unlock(g_mutexStateList); + + ca_mutex_lock(g_mutexObjectList); CAEDRNativeCreateDeviceSocketList(); + ca_mutex_unlock(g_mutexObjectList); - if(isAttached) + if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } - // CAEDRCreateJNIInterfaceObject(gContext); /* create java CAEDRInterface instance*/ + if (g_context) + { + CAEDRCreateJNIInterfaceObject(g_context); /* create java caedrinterface instance*/ + } OIC_LOG(DEBUG, TAG, "OUT"); } @@ -404,33 +461,38 @@ void CAEDRTerminate() { OIC_LOG(DEBUG, TAG, "CAEDRTerminate"); - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAEDRTerminate - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return; } - isAttached = JNI_TRUE; + isAttached = true; } g_stopAccept = true; g_stopMulticast = true; g_stopUnicast = true; - if(isAttached) + if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } - if(g_context) + if (g_context) { (*env)->DeleteGlobalRef(env, g_context); } + + CAEDRNativeSocketCloseToAll(env); + // delete mutex CAEDRDestroyMutex(); @@ -438,12 +500,10 @@ void CAEDRTerminate() CAEDRNativeRemoveAllDeviceSocket(env); } -void CAEDRCoreJniInit(JNIEnv *env, JavaVM *jvm) +void CAEDRCoreJniInit() { OIC_LOG(DEBUG, TAG, "CAEdrClientJniInit"); - g_jvm = jvm; - - CAEDRServerJniInit(env, jvm); + g_jvm = (JavaVM*) CANativeJNIGetJavaVM(); } CAResult_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32_t dataLen) @@ -458,27 +518,27 @@ CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen) { OIC_LOG_V(DEBUG, TAG, "CAEDRSendMulticastMessage(%s)", data); - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAEDRSendMulticastMessage - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return CA_STATUS_INVALID_PARAM; } - isAttached = JNI_TRUE; + isAttached = true; } CAEDRSendMulticastMessageImpl(env, data, dataLen); OIC_LOG(DEBUG, TAG, "sent data"); - if(isAttached) + if (isAttached) { OIC_LOG(DEBUG, TAG, "DetachCurrentThread"); (*g_jvm)->DetachCurrentThread(g_jvm); @@ -496,96 +556,94 @@ CAResult_t CAEDRGetInterfaceInfo(char **address) void CAEDRGetLocalAddress(char **address) { - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAEDRGetLocalAddress - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return; } - isAttached = JNI_TRUE; + isAttached = true; } jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env); - if(jni_address) + if (jni_address) { const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL); - *address = (char*)OICMalloc(strlen(localAddress) + 1); + *address = (char*) OICMalloc(strlen(localAddress) + 1); if (*address == NULL) { if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } return; } memcpy(*address, localAddress, strlen(localAddress)); + (*env)->ReleaseStringUTFChars(env, jni_address, localAddress); } OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address); if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } } -CAResult_t CAEDRSendUnicastMessageImpl(const char* address, const char* data, - uint32_t dataLen) +CAResult_t CAEDRSendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen) { OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessageImpl, address: %s, data: %s", address, data); - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAEDRSendUnicastMessageImpl - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return CA_STATUS_INVALID_PARAM; } - isAttached = JNI_TRUE; + isAttached = true; } OIC_LOG(DEBUG, TAG, "[EDR][Native] set byteArray for data"); - if(g_sendBuffer) - { - (*env)->DeleteGlobalRef(env, g_sendBuffer); - } - jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen); - (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*)data); - g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr); // get bonded device list jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env); - if(!jni_arrayPairedDevices) + if (!jni_arrayPairedDevices) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty"); + OIC_LOG(ERROR, TAG, "[EDR][Native] jni_arrayPairedDevices is empty"); if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } return CA_STATUS_INVALID_PARAM; } // Get information from array of devices + jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE); + jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName", + METHODID_STRINGNONPARAM); + jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress", + METHODID_STRINGNONPARAM); + jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices); jsize i; - for( i = 0 ; i < length ; i++ ) + for (i = 0; i < length; i++) { OIC_LOG(DEBUG, TAG, "[EDR][Native] start to check device"); // get name, address from BT device jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i); - - jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice"); - jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, - "getName", "()Ljava/lang/String;"); - jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, - "getAddress", "()Ljava/lang/String;"); - jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName); - if(j_str_name) + if (j_str_name) { const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL); OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name); @@ -595,29 +653,44 @@ CAResult_t CAEDRSendUnicastMessageImpl(const char* address, const char* data, jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress); const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL); OIC_LOG_V(DEBUG, TAG, - "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress); + "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress); - if (!remoteAddress) { + if (!remoteAddress) + { OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null"); if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } return CA_STATUS_INVALID_PARAM; } - if (!address) { + if (!address) + { OIC_LOG(ERROR, TAG, "[EDR][Native] address is null"); if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } + (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress); return CA_STATUS_INVALID_PARAM; } // find address - if(!strcmp(remoteAddress, address)) + if (!strcmp(remoteAddress, address)) { - CAEDRNativeSendData(env, remoteAddress, data, i); + CAResult_t res = CAEDRNativeSendData(env, remoteAddress, data, dataLen, i); + if (CA_STATUS_OK != res) + { + (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress); + return res; + } } + (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress); } if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } return CA_STATUS_OK; } @@ -628,28 +701,27 @@ CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t // get bonded device list jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env); - if(!jni_arrayPairedDevices) + if (!jni_arrayPairedDevices) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty"); + OIC_LOG(ERROR, TAG, "[EDR][Native] jni_arrayPairedDevices is empty"); return CA_STATUS_INVALID_PARAM; } // Get information from array of devices + jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE); + jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName", + METHODID_STRINGNONPARAM); + jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress", + METHODID_STRINGNONPARAM); + jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices); jsize i; - for( i = 0 ; i < length ; i++ ) + for (i = 0; i < length; i++) { // get name, address from BT device jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i); - - jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice"); - jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, - "getName", "()Ljava/lang/String;"); - jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, - "getAddress", "()Ljava/lang/String;"); - jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName); - if(j_str_name) + if (j_str_name) { const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL); OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name); @@ -659,10 +731,15 @@ CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress); const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL); OIC_LOG_V(DEBUG, TAG, - "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress); + "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress); // find address - CAEDRNativeSendData(env, remoteAddress, data, i); + CAResult_t res = CAEDRNativeSendData(env, remoteAddress, data, dataLen, i); + (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress); + if (CA_STATUS_OK != res) + { + return res; + } } return CA_STATUS_OK; @@ -671,270 +748,299 @@ CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t /** * EDR Method */ -void CAEDRNativeSendData(JNIEnv *env, const char *address, const char *data, uint32_t id) +CAResult_t CAEDRNativeSendData(JNIEnv *env, const char *address, const char *data, + uint32_t dataLength, uint32_t id) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData logic start"); + OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData logic start : %s, %d", data, dataLength); - if(STATE_DISCONNECTED == CAEDRIsConnectedDevice(address)) + if (!CAEDRNativeIsEnableBTAdapter(env)) + { + OIC_LOG(ERROR, TAG, "BT adpater is not enable"); + return CA_STATUS_INVALID_PARAM; + } + + if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address)) { // connect before send data OIC_LOG(DEBUG, TAG, "[EDR][Native] connect before send data"); - if(NULL == address) + if (NULL == address) { OIC_LOG(ERROR, TAG, "[EDR][Native] remote address is empty"); - return; + return CA_STATUS_INVALID_PARAM; } else { - CAEDRNativeConnect(env, address, id); + CAResult_t res = CAEDRNativeConnect(env, address, id); + if (CA_STATUS_OK != res) + { + return res; + } } } - if(STATE_CONNECTED == CAEDRIsConnectedDevice(address)) + if (STATE_CONNECTED == CAEDRIsConnectedDevice(address)) { - if(!((*env)->ExceptionCheck(env))) + if (!((*env)->ExceptionCheck(env))) { - jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); - if(!jni_cid_BTsocket) + jclass jni_cid_BTsocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET); + if (!jni_cid_BTsocket) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_BTsocket is null"); - return; + return CA_STATUS_FAILED; } - jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env, - jni_cid_BTsocket, "getOutputStream", - "()Ljava/io/OutputStream;"); - if(!jni_mid_getOutputStream) + jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, + "getOutputStream", + METHODID_OUTPUTNONPARAM); + if (!jni_mid_getOutputStream) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_getOutputStream is null"); - return; + return CA_STATUS_FAILED; } - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream..%d", id); - jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id); - if(!jni_obj_socket) + OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream"); + + jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address); + if (!jni_obj_socket) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_socket is not available"); - return; + return CA_STATUS_FAILED; } - jobject jni_obj_outputStream = (*env)->CallObjectMethod(env, - jni_obj_socket, jni_mid_getOutputStream); - if(!jni_obj_outputStream) + jobject jni_obj_outputStream = (*env)->CallObjectMethod(env, jni_obj_socket, + jni_mid_getOutputStream); + if (!jni_obj_outputStream) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_obj_outputStream is null"); - return; + return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: ready outputStream.."); - jclass jni_cid_OutputStream = (*env)->FindClass(env, "java/io/OutputStream"); - if(!jni_cid_OutputStream) + jclass jni_cid_OutputStream = (*env)->FindClass(env, CLASSPATH_OUTPUT); + if (!jni_cid_OutputStream) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_OutputStream is null"); - return; + return CA_STATUS_FAILED; } - jmethodID jni_mid_write = (*env)->GetMethodID(env, - jni_cid_OutputStream, "write", "([BII)V"); - if(!jni_mid_write) + jmethodID jni_mid_write = (*env)->GetMethodID(env, jni_cid_OutputStream, "write", + "([BII)V"); + if (!jni_mid_write) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_write is null"); - return; + return CA_STATUS_FAILED; } jbyteArray jbuf; - int length = strlen(data); - jbuf = (*env)->NewByteArray(env, length); - (*env)->SetByteArrayRegion(env, jbuf, 0, length, (jbyte*)data); + jbuf = (*env)->NewByteArray(env, dataLength); + (*env)->SetByteArrayRegion(env, jbuf, 0, dataLength, (jbyte*) data); - (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write, - jbuf, (jint) 0, (jint) length); + (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write, jbuf, (jint) 0, + (jint) dataLength); - if((*env)->ExceptionCheck(env)) + if ((*env)->ExceptionCheck(env)) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: Write Error!!!"); (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); - return; + return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Success"); - - // remove socket to list - CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket); - - // update state - CAEDRUpdateDeviceState(STATE_DISCONNECTED, address); } else { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); - OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: error!!"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: error!!"); + return CA_STATUS_FAILED; } } else { OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: BT connection is not completed!!"); } + + return CA_STATUS_OK; } -void CAEDRNativeConnect(JNIEnv *env, const char *address, uint32_t id) +CAResult_t CAEDRNativeConnect(JNIEnv *env, const char *address, uint32_t id) { OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect.."); + if (!CAEDRNativeIsEnableBTAdapter(env)) + { + OIC_LOG(ERROR, TAG, "BT adpater is not enable"); + return CA_STATUS_INVALID_PARAM; + } + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); - if(!jni_cid_BTAdapter) + if (!jni_cid_BTAdapter) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTAdapter is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BTAdapter is null"); + return CA_STATUS_FAILED; } // get BTadpater - jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, - jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM); - if(!jni_mid_getDefaultAdapter) + jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, + "getDefaultAdapter", + METHODID_OBJECTNONPARAM); + if (!jni_mid_getDefaultAdapter) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_getDefaultAdapter is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_getDefaultAdapter is null"); + return CA_STATUS_FAILED; } - jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, - jni_cid_BTAdapter, jni_mid_getDefaultAdapter); - if(!jni_obj_BTAdapter) + jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, + jni_mid_getDefaultAdapter); + if (!jni_obj_BTAdapter) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_BTAdapter is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_BTAdapter is null"); + return CA_STATUS_FAILED; } // get remote bluetooth device - jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, - jni_cid_BTAdapter, "getRemoteDevice", - "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;"); - if(!jni_mid_getRemoteDevice) + jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter, + "getRemoteDevice", + METHODID_BT_DEVICEPARAM); + if (!jni_mid_getRemoteDevice) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_getRemoteDevice is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_getRemoteDevice is null"); + return CA_STATUS_FAILED; } - //jstring jni_address = (*env)->NewStringUTF(env, "B8:5E:7B:54:52:1C"); jstring jni_address = (*env)->NewStringUTF(env, address); - jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, - jni_obj_BTAdapter, jni_mid_getRemoteDevice, jni_address); - if(!jni_obj_remoteBTDevice) + jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, + jni_mid_getRemoteDevice, jni_address); + if (!jni_obj_remoteBTDevice) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_remoteBTDevice is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_remoteBTDevice is null"); + return CA_STATUS_FAILED; } // get create Rfcomm Socket method ID - jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice"); - if(!jni_cid_BluetoothDevice) + jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE); + if (!jni_cid_BluetoothDevice) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BluetoothDevice is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BluetoothDevice is null"); + return CA_STATUS_FAILED; } - jmethodID jni_mid_createSocket = (*env)->GetMethodID(env, - jni_cid_BluetoothDevice, - "createInsecureRfcommSocketToServiceRecord", + jmethodID jni_mid_createSocket = (*env)->GetMethodID( + env, jni_cid_BluetoothDevice, "createInsecureRfcommSocketToServiceRecord", "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;"); - if(!jni_mid_createSocket) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_createSocket is null"); - return; + if (!jni_mid_createSocket) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_createSocket is null"); + return CA_STATUS_FAILED; } - // createInsecureRfcommSocketToServiceRecord / createRfcommSocketToServiceRecord // setting UUID jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID); - if(!jni_cid_uuid) + if (!jni_cid_uuid) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_uuid is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_uuid is null"); + return CA_STATUS_FAILED; } - jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString", - "(Ljava/lang/String;)Ljava/util/UUID;"); - if(!jni_mid_fromString) + jmethodID jni_mid_fromString = (*env)->GetStaticMethodID( + env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;"); + if (!jni_mid_fromString) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_fromString is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_fromString is null"); + return CA_STATUS_FAILED; } - jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, - jni_mid_fromString, OIC_EDR_SERVICE_ID); - if(!jni_obj_uuid) + jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID); + if (!jni_uuid) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_uuid is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_uuid is null"); + return CA_STATUS_FAILED; + } + jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, + jni_uuid); + if (!jni_obj_uuid) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_uuid is null"); + return CA_STATUS_FAILED; } // create socket - jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, - jni_obj_remoteBTDevice, jni_mid_createSocket, jni_obj_uuid); - if(!jni_obj_BTSocket) + jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, jni_obj_remoteBTDevice, + jni_mid_createSocket, jni_obj_uuid); + if (!jni_obj_BTSocket) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_BTSocket is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_BTSocket is null"); + return CA_STATUS_FAILED; } // connect - jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); - if(!jni_cid_BTSocket) + jclass jni_cid_BTSocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET); + if (!jni_cid_BTSocket) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTSocket is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BTSocket is null"); + return CA_STATUS_FAILED; } jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_BTSocket, "connect", "()V"); - if(!jni_mid_connect) + if (!jni_mid_connect) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_connect is null"); - return; + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_connect is null"); + return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: initiating connection..."); (*env)->CallVoidMethod(env, jni_obj_BTSocket, jni_mid_connect); - if((*env)->ExceptionCheck(env)) + if ((*env)->ExceptionCheck(env)) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: Connect is Failed!!!"); + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: Connect is Failed!!!"); (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); - return; + return CA_STATUS_FAILED; } // set socket to list jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket); + if (!jni_socket) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_socket is null"); + return CA_STATUS_FAILED; + } + ca_mutex_lock(g_mutexObjectList); CAEDRNativeAddDeviceSocketToList(env, jni_socket); + ca_mutex_unlock(g_mutexObjectList); // update state + ca_mutex_lock(g_mutexStateList); CAEDRUpdateDeviceState(STATE_CONNECTED, address); + ca_mutex_unlock(g_mutexStateList); OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: connected"); + + return CA_STATUS_OK; } void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id) { jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); - if(!jni_cid_BTSocket) + if (!jni_cid_BTSocket) { OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_cid_BTSocket is null"); return; } jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V"); - if(!jni_mid_close) + if (!jni_mid_close) { OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_mid_close is null"); return; } - jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id); - if(!jni_obj_socket) + jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address); + if (!jni_obj_socket) { OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_obj_socket is not available"); return; @@ -942,9 +1048,9 @@ void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id) (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close); - if((*env)->ExceptionCheck(env)) + if ((*env)->ExceptionCheck(env)) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] close: close is Failed!!!"); + OIC_LOG(ERROR, TAG, "[EDR][Native] close: close is Failed!!!"); (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); return; @@ -954,445 +1060,16 @@ void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id) CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket); // update state + ca_mutex_lock(g_mutexStateList); CAEDRUpdateDeviceState(STATE_DISCONNECTED, address); + ca_mutex_unlock(g_mutexStateList); OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected"); } - -/** - * BT State List - */ -void CAEDRNativeCreateDeviceStateList() -{ - OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceStateList"); - - // create new object array - if (g_deviceStateList == NULL) - { - OIC_LOG(DEBUG, TAG, "Create device list"); - - g_deviceStateList = u_arraylist_create(); - } -} - -void CAEDRUpdateDeviceState(CAConnectedState_t state, const char *address) -{ - state_t *newstate = (state_t*) OICCalloc(1, sizeof(state_t)); - if (!newstate) { - OIC_LOG(ERROR, TAG, "[EDR][Native] newstate is null"); - return; - } - strcpy(newstate->address, address); - newstate->state = state; - - CAEDRNativeAddDeviceStateToList(newstate); -} - -void CAEDRNativeAddDeviceStateToList(state_t *state) -{ - if(!state) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] device is null"); - return; - } - - if(!g_deviceStateList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdevice_list is null"); - return; - } - - if(CAEDRNativeIsDeviceInList(state->address)) { - CAEDRNativeRemoveDevice(state->address); // delete previous state for update new state - } - u_arraylist_add(g_deviceStateList, state); // update new state - OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d", state->state); -} - -jboolean CAEDRNativeIsDeviceInList(const char* remoteAddress){ - - jint index; - if (!remoteAddress) { - OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null"); - return JNI_TRUE; - } - for (index = 0; index < u_arraylist_length(g_deviceStateList); index++) - { - state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); - if(!state) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] state_t object is null"); - return JNI_TRUE; - } - - if(!strcmp(remoteAddress, state->address)) - { - OIC_LOG(DEBUG, TAG, "the device is already set"); - return JNI_TRUE; - } - else - { - continue; - } - } - - OIC_LOG(DEBUG, TAG, "there are no the device in list."); - return JNI_FALSE; -} - -void CAEDRNativeRemoveAllDeviceState() -{ - OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveAllDevices"); - - if(!g_deviceStateList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null"); - return; - } - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceStateList); index++) - { - state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); - if(!state) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null"); - continue; - } - OICFree(state); - } - - OICFree(g_deviceStateList); - g_deviceStateList = NULL; - return; -} - -void CAEDRNativeRemoveDevice(const char *remoteAddress) -{ - OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDeviceforStateList"); - - if(!g_deviceStateList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null"); - return; - } - if (!remoteAddress) { - OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null"); - return; - } - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceStateList); index++) - { - state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); - if(!state) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null"); - continue; - } - - if(!strcmp(state->address, remoteAddress)) - { - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove state : %s", remoteAddress); - OICFree(state); - - CAEDRReorderingDeviceList(index); - break; - } - } - return; -} - -CAConnectedState_t CAEDRIsConnectedDevice(const char *remoteAddress) -{ - OIC_LOG(DEBUG, TAG, "CAEDRIsConnectedDevice"); - - if(!g_deviceStateList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null"); - return STATE_DISCONNECTED; - } - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceStateList); index++) - { - state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); - if(!state) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null"); - continue; - } - - if(!strcmp(state->address, remoteAddress)) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] check whether it is connected or not"); - - return state->state; - } - } - return STATE_DISCONNECTED; -} - -void CAEDRReorderingDeviceList(uint32_t index) -{ - if (index >= g_deviceStateList->length) - { - return; - } - - if (index < g_deviceStateList->length - 1) - { - memmove(&g_deviceStateList->data[index], &g_deviceStateList->data[index + 1], - (g_deviceStateList->length - index - 1) * sizeof(void *)); - } - - g_deviceStateList->size--; - g_deviceStateList->length--; -} - -/** - * Device Socket Object List - */ -void CAEDRNativeCreateDeviceSocketList() -{ - OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceSocketList"); - - // create new object array - if (g_deviceObjectList == NULL) - { - OIC_LOG(DEBUG, TAG, "Create Device object list"); - - g_deviceObjectList = u_arraylist_create(); - } -} - -void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket) -{ - OIC_LOG(DEBUG, TAG, "[EDR][Native] CANativeAddDeviceobjToList"); - - if(!deviceSocket) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] Device is null"); - return; - } - - if(!g_deviceObjectList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); - return; - } - - jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket); - if(!jni_remoteAddress) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] jni_remoteAddress is null"); - return; - } - - ca_mutex_lock(g_mutexSocketListManager); - - const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL); - - if(!CAEDRNativeIsDeviceSocketInList(env, remoteAddress)) - { - jobject gDeviceSocker = (*env)->NewGlobalRef(env, deviceSocket); - u_arraylist_add(g_deviceObjectList, gDeviceSocker); - OIC_LOG(DEBUG, TAG, "Set Socket Object to Array"); - } - - ca_mutex_unlock(g_mutexSocketListManager); -} - -jboolean CAEDRNativeIsDeviceSocketInList(JNIEnv *env, const char* remoteAddress) -{ - OIC_LOG(DEBUG, TAG, "[EDR][Native] CANativeIsDeviceObjInList"); - - jint index; - - if (!remoteAddress) { - OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null"); - return JNI_TRUE; - } - for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++) - { - - jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); - if(!jarrayObj) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null"); - return JNI_TRUE; - } - - jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj); - if(!jni_setAddress) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_setAddress is null"); - return JNI_TRUE; - } - - const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL); - if(!setAddress) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] setAddress is null"); - return JNI_TRUE; - } - - if(!strcmp(remoteAddress, setAddress)) - { - OIC_LOG(DEBUG, TAG, "the device is already set"); - return JNI_TRUE; - } - else - { - continue; - } - } - - OIC_LOG(DEBUG, TAG, "there are no the Device obejct in list. we can add"); - return JNI_FALSE; -} - -void CAEDRNativeRemoveAllDeviceSocket(JNIEnv *env) -{ - OIC_LOG(DEBUG, TAG, "CANativeRemoveAllDeviceObjsList"); - - if(!g_deviceObjectList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); - return; - } - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++) - { - jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); - if(!jarrayObj) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null"); - return; - } - (*env)->DeleteGlobalRef(env, jarrayObj); - } - - OICFree(g_deviceObjectList); - g_deviceObjectList = NULL; - return; -} - -void CAEDRNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket) -{ - OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDeviceSocket"); - - if(!g_deviceObjectList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); - return; - } - - ca_mutex_lock(g_mutexSocketListManager); - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++) - { - jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); - if(!jarrayObj) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null"); - continue; - } - - jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj); - if(!jni_setAddress) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_setAddress is null"); - continue; - } - const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL); - - jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket); - if(!jni_remoteAddress) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_remoteAddress is null"); - continue; - } - const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL); - - if(!strcmp(setAddress, remoteAddress)) - { - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove object : %s", remoteAddress); - (*env)->DeleteGlobalRef(env, jarrayObj); - - CAEDRReorderingDeviceSocketList(index); - break; - } - } - ca_mutex_unlock(g_mutexSocketListManager); - - OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object"); - return; -} - -jobject CAEDRNativeGetDeviceSocket(uint32_t idx) -{ - OIC_LOG(DEBUG, TAG, "CAEDRNativeGetDeviceSocket"); - - if(idx < 0) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] index is not available"); - return NULL; - } - - if(!g_deviceObjectList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); - return NULL; - } - - jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, idx); - if(!jarrayObj) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] jarrayObj is not available"); - return NULL; - } - return jarrayObj; -} - -uint32_t CAEDRGetSocketListLength() -{ - if(!g_deviceObjectList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); - return 0; - } - - uint32_t length = u_arraylist_length(g_deviceObjectList); - - return length; -} - -void CAEDRReorderingDeviceSocketList(uint32_t index) -{ - if (index >= g_deviceObjectList->length) - { - return; - } - - if (index < g_deviceObjectList->length - 1) - { - memmove(&g_deviceObjectList->data[index], &g_deviceObjectList->data[index + 1], - (g_deviceObjectList->length - index - 1) * sizeof(void *)); - } - - g_deviceObjectList->size--; - g_deviceObjectList->length--; -} - void CAEDRInitializeClient(ca_thread_pool_t handle) { OIC_LOG(DEBUG, TAG, "IN"); CAEDRInitialize(handle); OIC_LOG(DEBUG, TAG, "OUT"); } - - diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.h b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.h new file mode 100644 index 0000000..de0cf99 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.h @@ -0,0 +1,169 @@ +/****************************************************************** + * + * Copyright 2014 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. + * + ******************************************************************/ + +/** + * @file + * @brief This file contains the APIs for BT EDR communications. + */ +#ifndef CA_EDR_CLIENT_H_ +#define CA_EDR_CLIENT_H_ + +#include + +#include "cacommon.h" +#include "cathreadpool.h" +#include "jni.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Initialize context of application + * @return None + */ +void CAEDRJniInitContext(); + +/** + * @brief Create JNI Object + * @param context [IN] context of application + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRCreateJNIInterfaceObject(jobject context); + +/** + * @brief Initialize client for EDR + * @param handle [IN] thread pool handle object + * @return None + */ +void CAEDRInitialize(ca_thread_pool_t handle); + +/** + * @brief Terminate server for EDR + * @return None + */ +void CAEDRTerminate(); + +/** + * @brief Initialize JNI object + * @return None + */ +void CAEDRCoreJniInit(); + +/** + * @brief Send data for unicast + * @param address [IN] remote address + * @param data [IN] data for transmission + * @param dataLen [IN] data length + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAEDRSendUnicastMessage(const char *address, const char *data, uint32_t dataLen); + +/** + * @brief Send data for multicast + * @param data [IN] data for transmission + * @param dataLen [IN] data length + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAEDRSendMulticastMessage(const char *data, uint32_t dataLen); + +/** + * @brief Get Local EDR Address + * @param address [OUT] local address + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAEDRGetInterfaceInfo(char **address); + +/** + * @brief Get address from a local device + * @param address [OUT] local address + * @return None + */ +void CAEDRGetLocalAddress(char **address); + +/** + * @brief Send data for unicast (implement) + * @param address [IN] remote address + * @param data [IN] data for transmission + * @param dataLen [IN] data length + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAEDRSendUnicastMessageImpl(const char *address, const char *data, uint32_t dataLen); + +/** + * @brief Send data for multicast (implement) + * @param env [IN] JNI interface pointer + * @param data [IN] data for transmission + * @param dataLen [IN] data length + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char *data, uint32_t dataLen); + +/** + * EDR Method + */ + +/** + * @brief This function will send the data to remote device. + * @param env [IN] JNI interface pointer + * @param address [IN] Remote Address + * @param data [IN] Data to be transmitted from EDR + * @param dataLength [IN] Length of data + * @param id [IN] index of remote address + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRNativeSendData(JNIEnv *env, const char* address, const char* data, + uint32_t dataLength, uint32_t id); + +/** + * @brief This function will connect to remote device. + * @param env [IN] JNI interface pointer + * @param address [IN] Remote Address + * @param id [IN] index of remote address + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRNativeConnect(JNIEnv *env, const char *address, uint32_t id); + +/** + * @brief This function will close socket. + * @param env [IN] JNI interface pointer + * @param address [IN] Remote Address + * @param id [IN] index of remote address + * @return None + */ +void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrnwmonitor.c b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrnwmonitor.c index 055e409..e91e415 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrnwmonitor.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrnwmonitor.c @@ -1,34 +1,77 @@ +/****************************************************************** + * + * Copyright 2014 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 #include #include #include "caedrinterface.h" +#include "caedrnwmonitor.h" #include "logger.h" #include "oic_malloc.h" #include "cathreadpool.h" /* for thread pool */ #include "camutex.h" #include "uarraylist.h" #include "caadapterutils.h" +#include "caedrserver.h" +#include "caedrutils.h" + +#include "org_iotivity_jar_caedrinterface.h" //#define DEBUG_MODE #define TAG PCF("CA_EDR_MONITOR") -// temp method +static JavaVM *g_jvm; +static jobject g_context; +static CAEDRNetworkStatusCallback g_networkChangeCb = NULL; + +static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter"; -CAResult_t CAEDRInitializeNetworkMonitor() +void CAEDRNetworkMonitorJNISetContext() { - OIC_LOG(DEBUG, TAG, "IN"); + OIC_LOG(DEBUG, TAG, "CAEDRNetworkMonitorJNISetContext"); + g_context = (jobject) CANativeJNIGetContext(); +} - OIC_LOG(DEBUG, TAG, "OUT"); - return CA_STATUS_OK; +//getting jvm +void CAEDRNetworkMonitorJniInit() +{ + OIC_LOG(DEBUG, TAG, "CAEDRNetworkMonitorJniInit"); + g_jvm = (JavaVM*) CANativeJNIGetJavaVM(); } -void CAEDRSetNetworkChangeCallback( - CAEDRNetworkStatusCallback networkChangeCallback) +CAResult_t CAEDRInitializeNetworkMonitor(const ca_thread_pool_t threadPool) { OIC_LOG(DEBUG, TAG, "IN"); + CAEDRNetworkMonitorJniInit(); + CANativeJNIGetJavaVM(); + OIC_LOG(DEBUG, TAG, "OUT"); + return CA_STATUS_OK; +} + +void CAEDRSetNetworkChangeCallback(CAEDRNetworkStatusCallback networkChangeCallback) +{ + OIC_LOG(DEBUG, TAG, "CAEDRSetNetworkChangeCallback"); + g_networkChangeCb = networkChangeCallback; } void CAEDRTerminateNetworkMonitor(void) @@ -62,3 +105,66 @@ CAResult_t CAEDRClientSetCallbacks(void) return CA_STATUS_OK; } +JNIEXPORT void JNICALL +Java_org_iotivity_jar_caedrinterface_CAEDRStateChangedCallback(JNIEnv *env, jobject obj, + jint status) +{ + // STATE_ON:12, STATE_OFF:10 + OIC_LOG(DEBUG, TAG, "caedrinterface - Network State Changed"); + + if (NULL == g_networkChangeCb) + { + OIC_LOG_V(DEBUG, TAG, "gNetworkChangeCb is null", status); + } + + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); + if (!jni_cid_BTAdapter) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] 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, "[EDR][Native] 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, "[EDR][Native] 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) + { + CANetworkStatus_t newStatus = CA_INTERFACE_UP; + CAEDRServerStartAcceptThread(); + g_networkChangeCb(newStatus); + } + else if (state_off == status) + { + CANetworkStatus_t newStatus = CA_INTERFACE_DOWN; + CAEDRNativeRemoveAllDeviceSocket(env); + CAEDRNativeRemoveAllDeviceState(env); + g_networkChangeCb(newStatus); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_jar_caedrinterface_CAEDRBondStateChangedCallback(JNIEnv *env, jobject obj, + jstring addr) +{ + OIC_LOG(DEBUG, TAG, "caedrinterface - Bond State Changed"); + + if (addr) + { + CAEDRNativeRemoveDeviceSocketBaseAddr(env, addr); + CAEDRNativeRemoveDevice(addr); + } +} diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrnwmonitor.h b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrnwmonitor.h new file mode 100644 index 0000000..102c507 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrnwmonitor.h @@ -0,0 +1,52 @@ +/****************************************************************** + * + * Copyright 2014 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. + * + ******************************************************************/ + +/** + * @file + * @brief This file contains the APIs for BT LE communications. + */ +#ifndef CA_EDR_NWMONITOR_H_ +#define CA_EDR_NWMONITOR_H_ + +#include "cacommon.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Set context of application + * @return None + */ +void CAEDRNetworkMonitorJNISetContext(); + +/** + * @brief Initialize JNI object + * @return None + */ +void CAEDRNetworkMonitorJniInit(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c index 9c3875f..8705898 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c @@ -1,24 +1,25 @@ /****************************************************************** -* -* Copyright 2014 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. -* -******************************************************************/ + * + * Copyright 2014 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 +#include #include #include @@ -31,26 +32,20 @@ #include "camutex.h" #include "uarraylist.h" #include "caadapterutils.h" +#include "org_iotivity_jar_caedrinterface.h" //#define DEBUG_MODE #define TAG PCF("CA_EDR_SERVER") +#define MAX_PDU_BUFFER (1024) static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;"; -static const char METHODID_STRINGNONPARAM[] = "()Ljava/lang/String;"; static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter"; static const char CLASSPATH_BT_UUID[] = "java/util/UUID"; -static const uint32_t MAX_PDU_BUFFER = 1024; - -static u_arraylist_t *g_deviceStateList = NULL; -static u_arraylist_t *g_deviceObjectList = NULL; - static ca_thread_pool_t g_threadPoolHandle = NULL; static JavaVM *g_jvm; -static jbyteArray g_sendBuffer; - /** * @var g_mMutexSocketListManager * @brief Mutex to synchronize socket list update @@ -85,12 +80,41 @@ static ca_mutex g_mutexMulticastServer = NULL; static bool g_stopMulticast = false; /** + * @var g_mutexAcceptServer + * @brief Mutex to synchronize accept server + */ +static ca_mutex g_mutexAcceptServer = NULL; + +/** * @var g_stopAccept * @brief Flag to control the Accept Thread */ static bool g_stopAccept = false; -typedef struct send_data { +static jobject g_inputStream = NULL; + +/** + * @var g_mutexServerSocket + * @brief Mutex to synchronize server socket + */ +static ca_mutex g_mutexServerSocket = NULL; + +static jobject g_serverSocket = NULL; + +/** + * @var g_mutexStateList + * @brief Mutex to synchronize device state list + */ +static ca_mutex g_mutexStateList = NULL; + +/** + * @var g_mutexObjectList + * @brief Mutex to synchronize device object list + */ +static ca_mutex g_mutexObjectList = NULL; + +typedef struct send_data +{ char* address; char* data; uint32_t id; @@ -110,66 +134,64 @@ typedef struct bool *stopFlag; } CAAdapterAcceptThreadContext_t; -// callback instance - /** - * @var g_EDRPacketReceivedCallback + * @var g_edrPacketReceivedCallback * @brief Maintains the callback to be notified when data received from remote Bluetooth device */ -static CAEDRDataReceivedCallback g_EDRPacketReceivedCallback = NULL; +static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL; static void CAReceiveHandler(void *data) { - OIC_LOG(DEBUG, TAG, "start CAReceiveHandler.."); - OIC_LOG(DEBUG, TAG, "IN"); + OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler.."); // Input validation VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context"); - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return; } - isAttached = JNI_TRUE; + isAttached = true; } - CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)data; + CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data; while (true != *(ctx->stopFlag)) { - uint32_t idx; - // if new socket object is added in socket list after below logic is ran. // new socket will be started to read after next while loop - uint32_t length = CAEDRServerGetSocketListLength(); + uint32_t length = CAEDRGetSocketListLength(); if (0 == length) { OIC_LOG(DEBUG, TAG, "socket list is empty"); + sleep(1); } + uint32_t idx; for (idx = 0; idx < length; idx++) { OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData"); CAEDRNativeReadData(env, idx, ctx->type); + sleep(1); } - } - if(isAttached) + if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } - if(ctx) - OICFree(ctx); + OICFree(ctx); - OIC_LOG(DEBUG, TAG, "OUT"); + OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler"); } static void CAAcceptHandler(void *data) @@ -179,63 +201,107 @@ static void CAAcceptHandler(void *data) OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null"); return; } + OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start"); - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return; } - isAttached = JNI_TRUE; + isAttached = true; } - jobject jni_obj_BTSeverSocket = CAEDRNativeListen(env); - if (!jni_obj_BTSeverSocket) + jobject jni_obj_BTServerSocket = CAEDRNativeListen(env); + if (!jni_obj_BTServerSocket) { - OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTSeverSocket is null"); + OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null"); - if(isAttached) + if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } return; } - CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *)data; + ca_mutex_lock(g_mutexServerSocket); + g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket); + ca_mutex_unlock(g_mutexServerSocket); + + CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data; + + if (NULL == ctx) + { + OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: ctx is null"); + if (isAttached) + { + (*g_jvm)->DetachCurrentThread(g_jvm); + } + return; + } + + // it should be initialized for restart accept thread + ca_mutex_lock(g_mutexAcceptServer); + g_stopAccept = false; + ca_mutex_unlock(g_mutexAcceptServer); while (true != *(ctx->stopFlag)) { OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running"); - CAEDRNativeAccept(env, jni_obj_BTSeverSocket); + + // when BT state is changed with Off. its thread will be stopped + if (!CAEDRNativeIsEnableBTAdapter(env)) + { + OIC_LOG(DEBUG, TAG, "BT adpater is not enable"); + ca_mutex_lock(g_mutexAcceptServer); + g_stopAccept = true; + ca_mutex_unlock(g_mutexAcceptServer); + ca_mutex_lock(g_mutexServerSocket); + g_serverSocket = NULL; + ca_mutex_unlock(g_mutexServerSocket); + } + else + { + CAEDRNativeAccept(env, g_serverSocket); + } } - if(isAttached) + if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } - if(ctx) - OICFree(ctx); + OICFree(ctx); OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish"); return; } - -// adapter common method - +/** + * implement for adapter common method + */ CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, ca_thread_pool_t handle) { OIC_LOG(DEBUG, TAG, "IN"); CAEDRServerInitialize(handle); - // FIXME - CAEDRStartUnicastServer(NULL, false); + CAResult_t res = CAEDRStartUnicastServer(false); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed"); + return CA_STATUS_FAILED; + } + + *serverFD = 1; OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } @@ -246,9 +312,38 @@ CAResult_t CAEDRServerStop(int serverFD) CAEDRStopUnicastServer(-1); CAEDRStopMulticastServer(-1); + ca_mutex_lock(g_mutexAcceptServer); g_stopAccept = true; - g_stopMulticast = true; - g_stopUnicast = true; + ca_mutex_unlock(g_mutexAcceptServer); + + if (!g_jvm) + { + OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null"); + return CA_STATUS_FAILED; + } + + bool isAttached = false; + JNIEnv* env; + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) + { + OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer"); + res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); + + if (JNI_OK != res) + { + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); + return CA_STATUS_FAILED; + } + isAttached = true; + } + + CAEDRNatvieCloseServerTask(env); + + if (isAttached) + { + (*g_jvm)->DetachCurrentThread(g_jvm); + } OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; @@ -256,7 +351,7 @@ CAResult_t CAEDRServerStop(int serverFD) void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback) { - g_EDRPacketReceivedCallback = packetReceivedCallback; + g_edrPacketReceivedCallback = packetReceivedCallback; } /** @@ -278,16 +373,39 @@ static void CAEDRServerDestroyMutex() g_mutexMulticastServer = NULL; } - if(g_mutexSocketListManager) + if (g_mutexSocketListManager) { ca_mutex_free(g_mutexSocketListManager); g_mutexSocketListManager = NULL; } + if (g_mutexAcceptServer) + { + ca_mutex_free(g_mutexAcceptServer); + g_mutexAcceptServer = NULL; + } + + if (g_mutexServerSocket) + { + ca_mutex_free(g_mutexServerSocket); + g_mutexServerSocket = NULL; + } + + if (g_mutexStateList) + { + ca_mutex_free(g_mutexStateList); + g_mutexStateList = NULL; + } + + if (g_mutexObjectList) + { + ca_mutex_free(g_mutexObjectList); + g_mutexObjectList = NULL; + } + OIC_LOG(DEBUG, TAG, "OUT"); } - /* * Create Mutex */ @@ -320,14 +438,50 @@ static CAResult_t CAEDRServerCreateMutex() return CA_STATUS_FAILED; } + g_mutexAcceptServer = ca_mutex_new(); + if (!g_mutexAcceptServer) + { + OIC_LOG(ERROR, TAG, "Failed to created mutex!"); + + CAEDRServerDestroyMutex(); + return CA_STATUS_FAILED; + } + + g_mutexServerSocket = ca_mutex_new(); + if (!g_mutexServerSocket) + { + OIC_LOG(ERROR, TAG, "Failed to created mutex!"); + + CAEDRServerDestroyMutex(); + return CA_STATUS_FAILED; + } + + g_mutexStateList = ca_mutex_new(); + if (!g_mutexStateList) + { + OIC_LOG(ERROR, TAG, "Failed to created mutex!"); + + CAEDRServerDestroyMutex(); + return CA_STATUS_FAILED; + } + + g_mutexObjectList = ca_mutex_new(); + if (!g_mutexObjectList) + { + OIC_LOG(ERROR, TAG, "Failed to created mutex!"); + + CAEDRServerDestroyMutex(); + return CA_STATUS_FAILED; + } + OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } -void CAEDRServerJniInit(JNIEnv *env, JavaVM* jvm) +void CAEDRServerJniInit() { OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit"); - g_jvm = jvm; + g_jvm = CANativeJNIGetJavaVM(); } void CAEDRServerInitialize(ca_thread_pool_t handle) @@ -336,23 +490,32 @@ void CAEDRServerInitialize(ca_thread_pool_t handle) g_threadPoolHandle = handle; + CAEDRServerStartAcceptThread(); + + OIC_LOG(DEBUG, TAG, "OUT"); +} + +void CAEDRServerStartAcceptThread() +{ + CAEDRServerJniInit(); + // init mutex CAEDRServerCreateMutex(); - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return; } - isAttached = JNI_TRUE; + isAttached = true; } jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env); @@ -363,14 +526,21 @@ void CAEDRServerInitialize(ca_thread_pool_t handle) (*env)->ReleaseStringUTFChars(env, jni_address, localAddress); } - CAEDRServerNativeCreateDeviceStateList(); - CAEDRServerNativeCreateDeviceSocketList(); + ca_mutex_lock(g_mutexStateList); + CAEDRNativeCreateDeviceStateList(); + ca_mutex_unlock(g_mutexStateList); + + ca_mutex_lock(g_mutexObjectList); + CAEDRNativeCreateDeviceSocketList(); + ca_mutex_unlock(g_mutexObjectList); - if(isAttached) + if (isAttached) + { (*g_jvm)->DetachCurrentThread(g_jvm); + } - CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) - OICMalloc(sizeof(CAAdapterReceiveThreadContext_t)); + CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc( + sizeof(CAAdapterReceiveThreadContext_t)); if (!ctx) { OIC_LOG(ERROR, TAG, "Out of memory!"); @@ -378,10 +548,10 @@ void CAEDRServerInitialize(ca_thread_pool_t handle) } ctx->stopFlag = &g_stopAccept; - if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *)ctx)) + if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx)) { OIC_LOG(ERROR, TAG, "Failed to create read thread!"); - OICFree((void *)ctx); + OICFree((void *) ctx); return; } @@ -396,49 +566,51 @@ void CAEDRServerTerminate() { return; } - jboolean isAttached = JNI_FALSE; + bool isAttached = false; JNIEnv* env; - jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6); - if(res != JNI_OK) + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); - if(res != JNI_OK) + if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed"); + OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return; } - isAttached = JNI_TRUE; + isAttached = true; } + CAEDRNativeSocketCloseToAll(env); + if (isAttached) { (*g_jvm)->DetachCurrentThread(g_jvm); } - CAEDRServerNativeRemoveAllDeviceState(); - CAEDRServerNativeRemoveAllDeviceSocket(env); + CAEDRNativeRemoveAllDeviceState(); + CAEDRNativeRemoveAllDeviceSocket(env); // delete mutex CAEDRServerDestroyMutex(); } -int32_t CAEDRStartUnicastServer(const char* address, bool isSecured) +CAResult_t CAEDRStartUnicastServer(bool isSecured) { - OIC_LOG_V(DEBUG, TAG, "CAEDRStartUnicastServer(%s)", address); + OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer"); ca_mutex_lock(g_mutexUnicastServer); /** - * The task to listen for data from unicast is added to the thread pool. - * This is a blocking call is made where we try to receive some data.. - * We will keep waiting until some data is received. - * This task will be terminated when thread pool is freed on stopping the adapters. - * Thread context will be freed by thread on exit. - */ - CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) - OICMalloc(sizeof(CAAdapterReceiveThreadContext_t)); + * The task to listen for data from unicast is added to the thread pool. + * This is a blocking call is made where we try to receive some data.. + * We will keep waiting until some data is received. + * This task will be terminated when thread pool is freed on stopping the adapters. + * Thread context will be freed by thread on exit. + */ + CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc( + sizeof(CAAdapterReceiveThreadContext_t)); if (!ctx) { OIC_LOG(ERROR, TAG, "Out of memory!"); @@ -448,11 +620,11 @@ int32_t CAEDRStartUnicastServer(const char* address, bool isSecured) ctx->stopFlag = &g_stopUnicast; ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER; - if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *)ctx)) + if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx)) { OIC_LOG(ERROR, TAG, "Failed to create read thread!"); ca_mutex_unlock(g_mutexUnicastServer); - OICFree((void *)ctx); + OICFree((void *) ctx); return CA_STATUS_FAILED; } ca_mutex_unlock(g_mutexUnicastServer); @@ -461,21 +633,21 @@ int32_t CAEDRStartUnicastServer(const char* address, bool isSecured) return CA_STATUS_OK; } -int32_t CAEDRStartMulticastServer(bool isSecured) +CAResult_t CAEDRStartMulticastServer(bool isSecured) { OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer"); ca_mutex_lock(g_mutexMulticastServer); /** - * The task to listen to data from multicast socket is added to the thread pool. - * This is a blocking call is made where we try to receive some data. - * We will keep waiting until some data is received. - * This task will be terminated when thread pool is freed on stopping the adapters. - * Thread context will be freed by thread on exit. - */ - CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) - OICMalloc(sizeof(CAAdapterReceiveThreadContext_t)); + * The task to listen to data from multicast socket is added to the thread pool. + * This is a blocking call is made where we try to receive some data. + * We will keep waiting until some data is received. + * This task will be terminated when thread pool is freed on stopping the adapters. + * Thread context will be freed by thread on exit. + */ + CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc( + sizeof(CAAdapterReceiveThreadContext_t)); if (!ctx) { OIC_LOG(ERROR, TAG, "Out of memory!"); @@ -488,13 +660,13 @@ int32_t CAEDRStartMulticastServer(bool isSecured) ctx->type = CA_MULTICAST_SERVER; g_stopMulticast = false; - if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *)ctx)) + if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx)) { OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!"); g_stopMulticast = true; ca_mutex_unlock(g_mutexMulticastServer); - OICFree((void *)ctx); + OICFree((void *) ctx); return CA_STATUS_FAILED; } @@ -504,7 +676,7 @@ int32_t CAEDRStartMulticastServer(bool isSecured) return CA_STATUS_OK; } -int32_t CAEDRStopUnicastServer(int32_t serverID) +CAResult_t CAEDRStopUnicastServer(int32_t serverID) { OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer"); @@ -512,10 +684,10 @@ int32_t CAEDRStopUnicastServer(int32_t serverID) g_stopUnicast = true; ca_mutex_unlock(g_mutexUnicastServer); - return 0; + return CA_STATUS_OK; } -int32_t CAEDRStopMulticastServer(int32_t serverID) +CAResult_t CAEDRStopMulticastServer(int32_t serverID) { OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer"); @@ -525,145 +697,257 @@ int32_t CAEDRStopMulticastServer(int32_t serverID) OIC_LOG(INFO, TAG, "Multicast server stopped"); - return 0; + return CA_STATUS_OK; } CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type) { - if(!((*env)->ExceptionCheck(env))) + if (!CAEDRNativeIsEnableBTAdapter(env)) + { + OIC_LOG(ERROR, TAG, "BT adpater is not enable"); + return CA_STATUS_INVALID_PARAM; + } + + if (!((*env)->ExceptionCheck(env))) { // check whether this socket object is connected or not. - jobject jni_obj_socket = CAEDRServerNativeGetDeviceSocket(id); - if(!jni_obj_socket) + jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id); + if (!jni_obj_socket) { return CA_STATUS_INVALID_PARAM; } jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket); + if (!jni_str_address) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null"); + return CA_STATUS_FAILED; + } const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL); - if(STATE_DISCONNECTED == CAEDRServerIsConnectedDevice(address)) + + // check it whether is still connected or not through google api + jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket); + if (!ret) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket"); + } + + // check it whether is still connected or not through socket state list + if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address)) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: it is not connected yet.."); + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet.."); + + // remove socket to list + // this code is related to below read fail exception code + CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket); + (*env)->ReleaseStringUTFChars(env, jni_str_address, address); + return CA_STATUS_FAILED; } // start to read through InputStream jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); - jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, - jni_cid_BTsocket, "getInputStream", "()Ljava/io/InputStream;"); + if (!jni_cid_BTsocket) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null"); + return CA_STATUS_FAILED; + } + jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, + "getInputStream", + "()Ljava/io/InputStream;"); OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address); - if(!jni_obj_socket) + if (!jni_obj_socket) { OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore.."); return CA_STATUS_FAILED; } - jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, - jni_obj_socket, jni_mid_getInputStream); + jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket, + jni_mid_getInputStream); OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream.."); + g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream); + jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream"); + if (!jni_cid_InputStream) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null"); + return CA_STATUS_FAILED; + } jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I"); jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER); - jlong nread; - if(!jni_obj_socket) + if (!jni_obj_socket) { OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..."); return CA_STATUS_FAILED; } - while ((nread = (*env)->CallIntMethod(env, jni_obj_inputStream, - jni_mid_read, jbuf, (jint)0, MAX_PDU_BUFFER)) != -1) + jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0, + MAX_PDU_BUFFER); + + OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream"); + + if (-1 == length) { - if((*env)->ExceptionCheck(env)) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!"); - (*env)->ExceptionDescribe(env); - (*env)->ExceptionClear(env); - return CA_STATUS_FAILED; - } - OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading"); - jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL); - jint length = strlen((char*)buf); - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s", buf); - if (buf == NULL) - { - return CA_STATUS_FAILED; - } + OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty..."); + return CA_STATUS_FAILED; + } - switch (type) - { - case CA_UNICAST_SERVER: - case CA_MULTICAST_SERVER: - // Notify data to upper layer - if (g_EDRPacketReceivedCallback) - { - uint32_t sentLength = 0; - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] data will be sent \ - to callback routine: %s, %d", buf, length); - g_EDRPacketReceivedCallback(address, (void*)buf, length, &sentLength); - } - break; - - default: - // Should never occur - OIC_LOG(DEBUG, TAG, "Invalid server type"); - return CA_STATUS_FAILED; - } - (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0); + if ((*env)->ExceptionCheck(env)) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!"); + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + + // update state to disconnect + // the socket will be close next read thread routine + ca_mutex_lock(g_mutexStateList); + CAEDRUpdateDeviceState(STATE_DISCONNECTED, address); + ca_mutex_unlock(g_mutexStateList); + (*env)->ReleaseStringUTFChars(env, jni_str_address, address); + return CA_STATUS_FAILED; + } + + OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading"); + jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL); + if (NULL == buf) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null"); + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length); + + char responseData[MAX_PDU_BUFFER] = { 0 }; + memcpy(responseData, (const char*) buf, length); - // close socket after data was sent - CAEDRNativeServerSocketClose(env, address, id); - break; + switch (type) + { + case CA_UNICAST_SERVER: + case CA_MULTICAST_SERVER: + // Notify data to upper layer + if (g_edrPacketReceivedCallback) + { + uint32_t sentLength = 0; + OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \ + %s, %d", responseData, length); + g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength); + } + break; + + default: + // Should never occur + OIC_LOG(ERROR, TAG, "Invalid server type"); + return CA_STATUS_FAILED; } + (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0); + (*env)->ReleaseStringUTFChars(env, jni_str_address, address); } else { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); - OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: env error!!"); + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!"); return CA_STATUS_FAILED; } return CA_STATUS_OK; } +jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket) +{ + OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket..."); + + if (!CAEDRNativeIsEnableBTAdapter(env)) + { + OIC_LOG(ERROR, TAG, "BT adpater is not enable"); + return JNI_FALSE; + } + + if (!socket) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null"); + return JNI_FALSE; + } + + jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); + if (!jni_cid_BTsocket) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null"); + return JNI_FALSE; + } + + jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected", + "()Z"); + if (!jni_mid_isConnected) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \ + - jni_mid_isConnected is null."); + return JNI_FALSE; + } + + jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected); + + return jni_isConnected; +} + +void CANativeStartListenTask(JNIEnv *env) +{ + jobject jni_obj_BTServerSocket = CAEDRNativeListen(env); + if (!jni_obj_BTServerSocket) + { + OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null"); + return; + } + + ca_mutex_lock(g_mutexServerSocket); + g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket); + ca_mutex_unlock(g_mutexServerSocket); +} + jobject CAEDRNativeListen(JNIEnv *env) { + if (!CAEDRNativeIsEnableBTAdapter(env)) + { + OIC_LOG(ERROR, TAG, "BT adpater is not enable"); + return NULL; + } + OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen"); - jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); - if(!jni_cid_BTAdapter) + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); + if (!jni_cid_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null"); return NULL; } // get BTadpater - jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, - jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM); - if(!jni_cid_BTAdapter) + jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, + "getDefaultAdapter", + METHODID_OBJECTNONPARAM); + if (!jni_cid_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null"); return NULL; } - jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, - jni_cid_BTAdapter, jni_mid_getDefaultAdapter); - if(!jni_obj_BTAdapter) + jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, + jni_mid_getDefaultAdapter); + if (!jni_obj_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null"); return NULL; } // get listen method ID - jmethodID jni_mid_listen = (*env)->GetMethodID(env, jni_cid_BTAdapter, - "listenUsingInsecureRfcommWithServiceRecord", - "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;"); - if(!jni_mid_listen) + jmethodID jni_mid_listen = (*env)->GetMethodID( + env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord", + "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;"); + if (!jni_mid_listen) { OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null"); return NULL; @@ -671,23 +955,29 @@ jobject CAEDRNativeListen(JNIEnv *env) // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord // setting UUID jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID); - if(!jni_cid_uuid) + if (!jni_cid_uuid) { OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null"); return NULL; } - jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, - "fromString", "(Ljava/lang/String;)Ljava/util/UUID;"); - if(!jni_mid_fromString) + jmethodID jni_mid_fromString = (*env)->GetStaticMethodID( + env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;"); + if (!jni_mid_fromString) { OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null"); return NULL; } - jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, - jni_mid_fromString, OIC_EDR_SERVICE_ID); - if(!jni_obj_uuid) + jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID); + if (!jni_uuid) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null"); + return NULL; + } + jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, + jni_uuid); + if (!jni_obj_uuid) { OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null"); return NULL; @@ -700,35 +990,34 @@ jobject CAEDRNativeListen(JNIEnv *env) OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null"); return NULL; } - jobject jni_obj_BTSeverSocket = (*env)->CallObjectMethod(env, - jni_obj_BTAdapter, jni_mid_listen, jni_name, jni_obj_uuid); - if(!jni_obj_BTSeverSocket) + jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen, + jni_name, jni_obj_uuid); + if (!jni_obj_BTServerSocket) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTSeverSocket is null"); + OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null"); return NULL; } - g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTSeverSocket); + g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket); - return jni_obj_BTSeverSocket; + return jni_obj_BTServerSocket; } -void CAEDRNativeAccept(JNIEnv *env, jobject severSocketObject) +void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject) { - if(severSocketObject != NULL) + if (NULL != serverSocketObject) { - jclass jni_cid_BTServerSocket = (*env)->FindClass(env, - "android/bluetooth/BluetoothServerSocket"); - if(!jni_cid_BTServerSocket) + jclass jni_cid_BTServerSocket = (*env)->FindClass( + env, "android/bluetooth/BluetoothServerSocket"); + if (!jni_cid_BTServerSocket) { OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null"); return; } - jmethodID jni_mid_accept = (*env)->GetMethodID(env, - jni_cid_BTServerSocket, "accept", - "(I)Landroid/bluetooth/BluetoothSocket;"); - if(!jni_mid_accept) + jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept", + "()Landroid/bluetooth/BluetoothSocket;"); + if (!jni_mid_accept) { OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null"); return; @@ -736,526 +1025,88 @@ void CAEDRNativeAccept(JNIEnv *env, jobject severSocketObject) OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept..."); - jobject jni_obj_BTSocket = NULL; - jni_obj_BTSocket = (*env)->CallObjectMethod(env, severSocketObject, jni_mid_accept, 1000); - if(!jni_obj_BTSocket) + jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject, + jni_mid_accept); + if (!jni_obj_BTSocket) { OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null"); - return; + + if ((*env)->ExceptionCheck(env)) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!"); + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + return; + } } // get remote address jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket); + if (!j_str_address) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null"); + return; + } const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL); OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address); // set socket to list jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket); - CAEDRServerNativeAddDeviceSocketToList(env, jni_socket); + ca_mutex_lock(g_mutexObjectList); + CAEDRNativeAddDeviceSocketToList(env, jni_socket); + ca_mutex_unlock(g_mutexObjectList); OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!"); // update state - CAEDRServerUpdateDeviceState(STATE_CONNECTED, address); + ca_mutex_lock(g_mutexStateList); + CAEDRUpdateDeviceState(STATE_CONNECTED, address); + ca_mutex_unlock(g_mutexStateList); (*env)->ReleaseStringUTFChars(env, j_str_address, address); } else { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: severSocket is close previously"); + OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously"); } } -void CAEDRNativeServerSocketClose(JNIEnv *env, const char *address, uint32_t id) -{ - - jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); - if(!jni_cid_BTSocket) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_cid_BTSocket is null"); - return; - } - - jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V"); - if(!jni_mid_close) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_mid_close is null"); - return; - } - - jobject jni_obj_socket = CAEDRServerNativeGetDeviceSocket(id); - if(!jni_obj_socket) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_obj_socket is not available"); - return; - } - - (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close); - - if((*env)->ExceptionCheck(env)) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] close: close is Failed!!!"); - (*env)->ExceptionDescribe(env); - (*env)->ExceptionClear(env); - return; - } - - // remove socket to list - CAEDRServerNativeRemoveDeviceSocket(env, jni_obj_socket); - - // update state - CAEDRServerUpdateDeviceState(STATE_DISCONNECTED, address); - - OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected"); -} - -/** - * BT State List - */ -void CAEDRServerNativeCreateDeviceStateList() -{ - OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceStateList"); - - // create new object array - if (g_deviceStateList == NULL) - { - OIC_LOG(DEBUG, TAG, "Create device list"); - - g_deviceStateList = u_arraylist_create(); - if (g_deviceStateList == NULL) - { - OIC_LOG(DEBUG, TAG, "Create device list is null"); - } - } -} - -void CAEDRServerUpdateDeviceState(uint32_t state, const char *address) -{ - state_t *newstate = (state_t*) OICCalloc(1, sizeof(state_t)); - if (!newstate) { - OIC_LOG(ERROR, TAG, "[BLE][Native] newstate is null"); - return; - } - strcpy(newstate->address, address); - newstate->state = state; - - CAEDRServerNativeAddDeviceStateToList(newstate); -} - -void CAEDRServerNativeAddDeviceStateToList(state_t *state) -{ - if(!state) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] device is null"); - return; - } - - if(!g_deviceStateList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdevice_list is null"); - return; - } - - if(!CAEDRServerNativeIsDeviceInList(state->address)) { - CAEDRServerNativeRemoveDevice(state->address); // delete previous state for update new state - u_arraylist_add(g_deviceStateList, state); // update new state - OIC_LOG(DEBUG, TAG, "Set State to Connected State List"); - } -} - -jboolean CAEDRServerNativeIsDeviceInList(const char* remoteAddress){ - - if (!remoteAddress) { - OIC_LOG(ERROR, TAG, "[BLE][Native] remoteAddress is null"); - return JNI_TRUE; - } - jint index; - for (index = 0; index < u_arraylist_length(g_deviceStateList); index++) - { - state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); - if(!state) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] state_t object is null"); - return JNI_TRUE; - } - - if(!strcmp(remoteAddress, state->address)) - { - OIC_LOG(DEBUG, TAG, "the device is already set"); - return JNI_TRUE; - } - else - { - continue; - } - } - - OIC_LOG(DEBUG, TAG, "there are no the device in list."); - return JNI_FALSE; -} - -void CAEDRServerNativeRemoveAllDeviceState() -{ - OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveAllDevices"); - - if(!g_deviceStateList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null"); - return; - } - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceStateList); index++) - { - state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); - if(!state) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null"); - continue; - } - OICFree(state); - } - - OICFree(g_deviceStateList); - g_deviceStateList = NULL; - return; -} - -void CAEDRServerNativeRemoveDevice(const char *remoteAddress) -{ - OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDevice"); - - if(!g_deviceStateList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null"); - return; - } - if (!remoteAddress) { - OIC_LOG(ERROR, TAG, "[BLE][Native] remoteAddress is null"); - return; - } - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceStateList); index++) - { - state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); - if(!state) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null"); - continue; - } - - if(!strcmp(state->address, remoteAddress)) - { - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove object : %s", remoteAddress); - OICFree(state); - - CAEDRServerReorderingDeviceList(index); - break; - } - } - OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object"); - return; -} - -jboolean CAEDRServerIsConnectedDevice(const char *remoteAddress) -{ - OIC_LOG(DEBUG, TAG, "CAEDRServerIsConnectedDevice"); - - if(!g_deviceStateList) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null"); - return JNI_FALSE; - } - if (!remoteAddress) { - OIC_LOG(ERROR, TAG, "[BLE][Native] remoteAddress is null"); - return JNI_FALSE; - } - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceStateList); index++) - { - state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); - if(!state) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null"); - continue; - } - - if(!strcmp(state->address, remoteAddress)) - { - OIC_LOG(DEBUG, TAG, "[EDR][Native] check whether it is connected or not"); - - return state->state; - } - } - OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object"); - return JNI_FALSE; -} - -void CAEDRServerReorderingDeviceList(uint32_t index) -{ - if (index >= g_deviceStateList->length) - { - return; - } - - if (index < g_deviceStateList->length - 1) - { - memmove(&g_deviceStateList->data[index], &g_deviceStateList->data[index + 1], - (g_deviceStateList->length - index - 1) * sizeof(void *)); - } - - g_deviceStateList->size--; - g_deviceStateList->length--; -} - /** - * Device Socket Object List + * InputStream & BluetoothServerSocket will be close for Terminating */ -void CAEDRServerNativeCreateDeviceSocketList() -{ - OIC_LOG(DEBUG, TAG, "[BLE][Native] CAEDRServerNativeCreateDeviceSocketList"); - - // create new object array - if (g_deviceObjectList == NULL) - { - OIC_LOG(DEBUG, TAG, "Create Device object list"); - - g_deviceObjectList = u_arraylist_create(); - if (g_deviceObjectList == NULL) - { - OIC_LOG(DEBUG, TAG, "Create Device object list is null"); - } - } -} - -void CAEDRServerNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket) -{ - OIC_LOG(DEBUG, TAG, "[BLE][Native] CAEDRServerNativeAddDeviceSocketToList"); - - if(!deviceSocket) - { - OIC_LOG(ERROR, TAG, "[BLE][Native] Device is null"); - return; - } - - if(!g_deviceObjectList) - { - OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null"); - return; - } - - jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket); - if(!jni_remoteAddress) - { - OIC_LOG(ERROR, TAG, "[BLE][Native] jni_remoteAddress is null"); - return; - } - - ca_mutex_lock(g_mutexSocketListManager); - - const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL); - - if(!CAEDRServerNativeIsDeviceSocketInList(env, remoteAddress)) - { - jobject gDeviceSocket = (*env)->NewGlobalRef(env, deviceSocket); - u_arraylist_add(g_deviceObjectList, gDeviceSocket); - OIC_LOG(DEBUG, TAG, "Set Object to Array as Element"); - } - - (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress); - ca_mutex_unlock(g_mutexSocketListManager); -} - -jboolean CAEDRServerNativeIsDeviceSocketInList(JNIEnv *env, const char* remoteAddress) +void CAEDRNatvieCloseServerTask(JNIEnv* env) { - OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeIsDeviceObjInList"); - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++) + if (g_inputStream) { - - jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); - if(!jarrayObj) - { - OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null"); - return JNI_TRUE; - } - - jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj); - if(!jni_setAddress) - { - OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null"); - return JNI_TRUE; - } - - const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL); - if (!setAddress || !remoteAddress) { - OIC_LOG(ERROR, TAG, "[BLE][Native] setAddress or remoteAddress is null"); - return JNI_TRUE; - } - if(!strcmp(remoteAddress, setAddress)) - { - OIC_LOG(DEBUG, TAG, "the device is already set"); - return JNI_TRUE; - } - else - { - continue; - } + OIC_LOG(DEBUG, TAG, "InputStream will be close"); + jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream"); + jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V"); + (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close); + (*env)->DeleteGlobalRef(env, g_inputStream); } - OIC_LOG(DEBUG, TAG, "there are no the Device obejct in list. we can add"); - return JNI_FALSE; -} - -void CAEDRServerNativeRemoveAllDeviceSocket(JNIEnv *env) -{ - OIC_LOG(DEBUG, TAG, "CANativeRemoveAllDeviceObjsList"); - - if(!g_deviceObjectList) + if (g_serverSocket) { - OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null"); - return; - } + OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close"); - jint index; - for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++) - { - jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); - if(!jarrayObj) + jclass jni_cid_BTServerSocket = (*env)->FindClass( + env, "android/bluetooth/BluetoothServerSocket"); + if (!jni_cid_BTServerSocket) { - OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null"); + OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null"); return; } - (*env)->DeleteGlobalRef(env, jarrayObj); - } - - OICFree(g_deviceObjectList); - g_deviceObjectList = NULL; - return; -} - -void CAEDRServerNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket) -{ - OIC_LOG(DEBUG, TAG, "CAEDRServerNativeRemoveDeviceSocket"); - - if(!g_deviceObjectList) - { - OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null"); - return; - } - - ca_mutex_lock(g_mutexSocketListManager); - - jint index; - for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++) - { - jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); - if(!jarrayObj) - { - OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null"); - continue; - } - jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj); - if(!jni_setAddress) + jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V"); + if (!jni_mid_accept) { - OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null"); - continue; - } - const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL); - (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); - - jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket); - if(!jni_remoteAddress) - { - OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null"); - continue; - } - const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL); - (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress); - - if (!setAddress || !remoteAddress) { - OIC_LOG(DEBUG, TAG, "[BLE][Native] setAddress or remoteAddress is null"); - continue; - } - if(!strcmp(setAddress, remoteAddress)) - { - OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress); - (*env)->DeleteGlobalRef(env, jarrayObj); - - CAEDRServerReorderingDeviceSocketList(index); - break; + OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null"); + return; } - } - ca_mutex_unlock(g_mutexSocketListManager); - - OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object"); - return; -} - -jobject CAEDRServerNativeGetDeviceSocket(uint32_t idx) -{ - OIC_LOG(DEBUG, TAG, "CAEDRServerNativeGetDeviceSocket"); - - if(idx < 0) - { - OIC_LOG(DEBUG, TAG, "[BLE][Native] index is not available"); - return NULL; - } - - if(!g_deviceObjectList) - { - OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null"); - return NULL; - } + (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept); + (*env)->DeleteGlobalRef(env, g_serverSocket); - jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, idx); - if(!jarrayObj) - { - OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is not available"); - return NULL; + OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj"); } - return jarrayObj; } -uint32_t CAEDRServerGetSocketListLength() -{ - if(!g_deviceObjectList) - { - OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null"); - return 0; - } - - uint32_t length = u_arraylist_length(g_deviceObjectList); - - return length; -} - -void CAEDRServerReorderingDeviceSocketList(uint32_t index) -{ - if (index >= g_deviceObjectList->length) - { - return; - } - - if (index < g_deviceObjectList->length - 1) - { - memmove(&g_deviceObjectList->data[index], &g_deviceObjectList->data[index + 1], - (g_deviceObjectList->length - index - 1) * sizeof(void *)); - } - - g_deviceObjectList->size--; - g_deviceObjectList->length--; -} - -void CAEDRServerSetPacketReceivedCallback - (CAEDRDataReceivedCallback packetReceivedCallback) -{ - g_EDRPacketReceivedCallback = packetReceivedCallback; -} - - - diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.h b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.h new file mode 100644 index 0000000..6e3a58d --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.h @@ -0,0 +1,142 @@ +/****************************************************************** + * + * Copyright 2014 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. + * + ******************************************************************/ + +/** + * @file + * @brief This file contains the APIs for BT EDR communications. + */ +#ifndef CA_EDR_SERVER_H_ +#define CA_EDR_SERVER_H_ + +#include + +#include "cacommon.h" +#include "cathreadpool.h" +#include "jni.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef void (*CAPacketReceiveCallback)(const char *address, const char *data); + +/** + * @brief Initialize JNI object + * @return None + */ +void CAEDRServerJniInit(); + +/** + * @brief Initialize server for EDR + * @param handle [IN] thread pool handle object + * @return None + */ +void CAEDRServerInitialize(ca_thread_pool_t handle); + +/* + * @brief Start Accept Thread + * @return None + */ +void CAEDRServerStartAcceptThread(); +/** + * @brief Start unicast server + * @param isSecured [IN] unicast server type + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRStartUnicastServer(bool isSecured); + +/** + * @brief Start multicast server + * @param isSecured [IN] multicst server type + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRStartMulticastServer(bool isSecured); + +/** + * @brief Stop unicast server + * @param serverID [IN] unicast server id + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRStopUnicastServer(int32_t serverID); + +/** + * @brief Stop multicast server + * @param serverID [IN] multicast server id + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRStopMulticastServer(int32_t serverID); + +/** + * EDR Method + */ + +/** + * @brief This function will read the data from remote device. + * @param env [IN] JNI interface pointer + * @param id [IN] index of remote address + * @param type [IN] EDR server type + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type); + +/* + * @brief Start Listen Task + * @param env [IN] JNI interface pointer + * @return None + */ +void CANativeStartListenTask(JNIEnv *env); + +/** + * @brief This function will listen the connection from remote device. + * @param env [IN] JNI interface pointer + * @return server socket object or NULL + */ +jobject CAEDRNativeListen(JNIEnv *env); + +/** + * @brief This function will listen the connection from remote device. + * @param env [IN] JNI interface pointer + * @param socket [IN] server socket object + * @return JNI_TRUE or JNI_FALSE + */ +jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket); + +/** + * @brief This function will accept the connection from remote device. + * @param env [IN] JNI interface pointer + * @param severSocketObject [IN] server socket object + * @return None + */ +void CAEDRNativeAccept(JNIEnv *env, jobject severSocketObject); + +/** + * @brief Remove all device objects in the list + * @param env [IN] JNI interface pointer + * @return None + */ +void CAEDRNatvieCloseServerTask(JNIEnv* env); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.c b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.c index 4f96d2b..5044c58 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.c @@ -1,22 +1,22 @@ /****************************************************************** -* -* Copyright 2014 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. -* -******************************************************************/ + * + * Copyright 2014 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 #include @@ -30,62 +30,63 @@ #define ERROR_CODE (-1) #define TAG PCF("CA_EDR_UTILS") -static const char *METHODID_OBJECTNONPARAM = "()Landroid/bluetooth/BluetoothAdapter;"; -static const char *METHODID_STRINGNONPARAM = "()Ljava/lang/String;"; -static const char *CLASSPATH_BT_ADPATER = "android/bluetooth/BluetoothAdapter"; +static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;"; +static const char METHODID_STRINGNONPARAM[] = "()Ljava/lang/String;"; +static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter"; +static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice"; +static const char CLASSPATH_BT_SOCKET[] = "android/bluetooth/BluetoothSocket"; -/** - * BT common - */ +static u_arraylist_t *g_deviceStateList = NULL; +static u_arraylist_t *g_deviceObjectList = NULL; // get address from bluetooth socket jstring CAEDRNativeGetAddressFromDeviceSocket(JNIEnv *env, jobject bluetoothSocketObj) { - if(!bluetoothSocketObj) + if (!bluetoothSocketObj) { + OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: bluetoothSocketObj is null"); return NULL; } - jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); - if(!jni_cid_BTSocket) + jclass jni_cid_BTSocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET); + if (!jni_cid_BTSocket) { OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: jni_cid_BTSocket is null"); return NULL; } - jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, - jni_cid_BTSocket, "getRemoteDevice", - "()Landroid/bluetooth/BluetoothDevice;"); - if(!jni_mid_getRemoteDevice) + jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID( + env, jni_cid_BTSocket, "getRemoteDevice", "()Landroid/bluetooth/BluetoothDevice;"); + if (!jni_mid_getRemoteDevice) { OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: jni_mid_getRemoteDevice is null"); return NULL; } - jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, - bluetoothSocketObj, jni_mid_getRemoteDevice); - if(!jni_obj_remoteBTDevice) + jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, bluetoothSocketObj, + jni_mid_getRemoteDevice); + if (!jni_obj_remoteBTDevice) { OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: jni_obj_remoteBTDevice is null"); return NULL; } - jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice"); - if(!jni_cid_BTDevice) + jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE); + if (!jni_cid_BTDevice) { OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: jni_cid_BTDevice is null"); return NULL; } - jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, - "getAddress", "()Ljava/lang/String;"); - if(!j_mid_getAddress) + jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress", + METHODID_STRINGNONPARAM); + if (!j_mid_getAddress) { OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: j_mid_getAddress is null"); return NULL; } jstring j_str_address = (*env)->CallObjectMethod(env, jni_obj_remoteBTDevice, j_mid_getAddress); - if(!j_str_address) + if (!j_str_address) { OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: j_str_address is null"); return NULL; @@ -96,40 +97,41 @@ jstring CAEDRNativeGetAddressFromDeviceSocket(JNIEnv *env, jobject bluetoothSock jstring CAEDRNativeGetLocalDeviceAddress(JNIEnv* env) { - jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); - if(!jni_cid_BTAdapter) + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); + if (!jni_cid_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] getAddress: jni_cid_BTAdapter is null"); return NULL; } - jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, - jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM); - if(!jni_mid_getDefaultAdapter) + jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, + "getDefaultAdapter", + METHODID_OBJECTNONPARAM); + if (!jni_mid_getDefaultAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] getAddress: jni_mid_getDefaultAdapter is null"); return NULL; } - jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTAdapter, - "getAddress", METHODID_STRINGNONPARAM); - if(!jni_mid_getAddress) + jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTAdapter, "getAddress", + METHODID_STRINGNONPARAM); + if (!jni_mid_getAddress) { OIC_LOG(ERROR, TAG, "[EDR][Native] getAddress: jni_mid_getAddress is null"); return NULL; } - jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, - jni_cid_BTAdapter, jni_mid_getDefaultAdapter); - if(!jni_obj_BTAdapter) + jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, + jni_mid_getDefaultAdapter); + if (!jni_obj_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] getAddress: jni_obj_BTAdapter is null"); return NULL; } - jstring jni_str_address = (jstring)(*env)->CallObjectMethod(env, - jni_obj_BTAdapter, jni_mid_getAddress); - if(!jni_str_address) + jstring jni_str_address = (jstring)(*env)->CallObjectMethod(env, jni_obj_BTAdapter, + jni_mid_getAddress); + if (!jni_str_address) { OIC_LOG(ERROR, TAG, "[EDR][Native] getAddress: jni_str_address is null"); return NULL; @@ -140,19 +142,25 @@ jstring CAEDRNativeGetLocalDeviceAddress(JNIEnv* env) jobjectArray CAEDRNativeGetBondedDevices(JNIEnv *env) { - jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); - if(!jni_cid_BTAdapter) + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); + if (!jni_cid_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_cid_BTAdapter is null"); return NULL; } - jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, - jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM); + jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, + "getDefaultAdapter", + METHODID_OBJECTNONPARAM); + if (!jni_mid_getDefaultAdapter) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: default adapter is null"); + return NULL; + } - jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, - jni_cid_BTAdapter, jni_mid_getDefaultAdapter); - if(!jni_obj_BTAdapter) + jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, + jni_mid_getDefaultAdapter); + if (!jni_obj_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: bluetooth adapter is null"); return NULL; @@ -160,16 +168,17 @@ jobjectArray CAEDRNativeGetBondedDevices(JNIEnv *env) // Get a list of currently paired devices jmethodID jni_mid_getBondedDevices = (*env)->GetMethodID(env, jni_cid_BTAdapter, - "getBondedDevices", "()Ljava/util/Set;"); - if(!jni_mid_getBondedDevices) + "getBondedDevices", + "()Ljava/util/Set;"); + if (!jni_mid_getBondedDevices) { OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_mid_getBondedDevicesr is null"); return NULL; } - jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, - jni_obj_BTAdapter, jni_mid_getBondedDevices); - if(!jni_obj_setPairedDevices) + jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, + jni_mid_getBondedDevices); + if (!jni_obj_setPairedDevices) { OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_obj_setPairedDevices is null"); return NULL; @@ -177,19 +186,24 @@ jobjectArray CAEDRNativeGetBondedDevices(JNIEnv *env) // Convert the set to an object array // object[] array = Set.toArray(); - jclass jni_cid_Set = (*env)->FindClass(env, "java/util/Set"); + jclass jni_cid_Set = (*env)->FindClass(env, "java/util/Set"); + if (!jni_cid_Set) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_cid_Set is null"); + return NULL; + } jmethodID jni_mid_toArray = (*env)->GetMethodID(env, jni_cid_Set, "toArray", - "()[Ljava/lang/Object;"); + "()[Ljava/lang/Object;"); - if(!jni_mid_toArray) + if (!jni_mid_toArray) { OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_mid_toArray is null"); return NULL; } - jobjectArray jni_arrayPairedDevices = (jobjectArray)((*env)->CallObjectMethod(env, - jni_obj_setPairedDevices, jni_mid_toArray)); - if(!jni_arrayPairedDevices) + jobjectArray jni_arrayPairedDevices = (jobjectArray)( + (*env)->CallObjectMethod(env, jni_obj_setPairedDevices, jni_mid_toArray)); + if (!jni_arrayPairedDevices) { OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_arrayPairedDevices is null"); return NULL; @@ -200,8 +214,8 @@ jobjectArray CAEDRNativeGetBondedDevices(JNIEnv *env) jint CAEDRNativeGetBTStateOnInfo(JNIEnv *env) { - jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); - if(!jni_cid_BTAdapter) + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); + if (!jni_cid_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] getBTStateOnInfo: jni_cid_BTAdapter is null"); return ERROR_CODE; @@ -210,45 +224,45 @@ jint CAEDRNativeGetBTStateOnInfo(JNIEnv *env) jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I"); if (jni_fid_stateon == 0) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] get_field_state is 0"); + OIC_LOG(ERROR, TAG, "[EDR][Native] get_field_state is 0"); return ERROR_CODE; } jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon); - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] bluetooth STATE_ON state integer value : %d", jni_int_val); + OIC_LOG_V(DEBUG, TAG, "[EDR][Native] bluetooth state integer value : %d", jni_int_val); return jni_int_val; } jboolean CAEDRNativeIsEnableBTAdapter(JNIEnv *env) { - jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); - if(!jni_cid_BTAdapter) + jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); + if (!jni_cid_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTAdapter: jni_cid_BTAdapter is null"); return JNI_FALSE; } - jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, - jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM); - if(!jni_mid_getDefaultAdapter) + jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, + "getDefaultAdapter", + METHODID_OBJECTNONPARAM); + if (!jni_mid_getDefaultAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_getDefaultAdapter is null"); return JNI_FALSE; } - jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, - jni_cid_BTAdapter, jni_mid_getDefaultAdapter); - if(!jni_obj_BTAdapter) + jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, + jni_mid_getDefaultAdapter); + if (!jni_obj_BTAdapter) { OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_BTAdapter is null"); return JNI_FALSE; } // isEnable() - jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled", - "()Z"); - if(!jni_mid_isEnable) + jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled", "()Z"); + if (!jni_mid_isEnable) { OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_isEnable is null"); return JNI_FALSE; @@ -262,24 +276,29 @@ jboolean CAEDRNativeIsEnableBTAdapter(JNIEnv *env) jstring CAEDRNativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice) { + if (!bluetoothDevice) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] bluetoothDevice is null"); + return NULL; + } jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice"); - if(!jni_cid_device_list) + if (!jni_cid_device_list) { OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_device_list is null"); return NULL; } jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_device_list, "getAddress", - "()Ljava/lang/String;"); - if(!jni_mid_getAddress) + METHODID_STRINGNONPARAM); + if (!jni_mid_getAddress) { OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_getAddress is null"); return NULL; } - jstring jni_address = (jstring)(*env)->CallObjectMethod(env, - bluetoothDevice, jni_mid_getAddress); - if(!jni_address) + jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice, + jni_mid_getAddress); + if (!jni_address) { OIC_LOG(ERROR, TAG, "[EDR][Native] jni_address is null"); return NULL; @@ -287,3 +306,584 @@ jstring CAEDRNativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice) return jni_address; } +/** + * BT State List + */ +void CAEDRNativeCreateDeviceStateList() +{ + OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceStateList"); + + // create new object array + if (NULL == g_deviceStateList) + { + OIC_LOG(DEBUG, TAG, "Create device list"); + + g_deviceStateList = u_arraylist_create(); + } +} + +void CAEDRUpdateDeviceState(CAConnectedState_t state, const char *address) +{ + if (!address) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] address is null"); + return; + } + state_t *newstate = (state_t*) OICCalloc(1, sizeof(state_t)); + if (!newstate) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] newstate is null"); + return; + } + strcpy(newstate->address, address); + newstate->state = state; + + CAEDRNativeAddDeviceStateToList(newstate); +} + +void CAEDRNativeAddDeviceStateToList(state_t *state) +{ + if (!state) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] device is null"); + return; + } + + if (!g_deviceStateList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdevice_list is null"); + return; + } + + if (CAEDRNativeIsDeviceInList(state->address)) + { + CAEDRNativeRemoveDevice(state->address); // delete previous state for update new state + } + u_arraylist_add(g_deviceStateList, state); // update new state + OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d", state->state); +} + +bool CAEDRNativeIsDeviceInList(const char* remoteAddress) +{ + + if (!remoteAddress) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null"); + return false; + } + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); + if (!state) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] state_t object is null"); + return false; + } + + if (!strcmp(remoteAddress, state->address)) + { + OIC_LOG(DEBUG, TAG, "the device is already set"); + return true; + } + else + { + continue; + } + } + + OIC_LOG(DEBUG, TAG, "there are no the device in list."); + return false; +} + +void CAEDRNativeRemoveAllDeviceState() +{ + OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveAllDevices"); + + if (!g_deviceStateList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null"); + return; + } + + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); + if (!state) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null"); + continue; + } + OICFree(state); + } + + OICFree(g_deviceStateList); + g_deviceStateList = NULL; + return; +} + +void CAEDRNativeRemoveDevice(const char *remoteAddress) +{ + OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDeviceforStateList"); + + if (!g_deviceStateList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null"); + return; + } + if (!remoteAddress) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null"); + return; + } + + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); + if (!state) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null"); + continue; + } + + if (!strcmp(state->address, remoteAddress)) + { + OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove state : %s", remoteAddress); + OICFree(state); + + CAEDRReorderingDeviceList(index); + break; + } + } + return; +} + +CAConnectedState_t CAEDRIsConnectedDevice(const char *remoteAddress) +{ + OIC_LOG(DEBUG, TAG, "CAEDRIsConnectedDevice"); + + if (!remoteAddress) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null"); + return STATE_DISCONNECTED; + } + + if (!g_deviceStateList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null"); + return STATE_DISCONNECTED; + } + + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index); + if (!state) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null"); + continue; + } + + if (!strcmp(state->address, remoteAddress)) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] check whether it is connected or not"); + + return state->state; + } + } + return STATE_DISCONNECTED; +} + +void CAEDRReorderingDeviceList(uint32_t index) +{ + if (index >= g_deviceStateList->length) + { + return; + } + + if (index < g_deviceStateList->length - 1) + { + memmove(&g_deviceStateList->data[index], &g_deviceStateList->data[index + 1], + (g_deviceStateList->length - index - 1) * sizeof(void *)); + } + + g_deviceStateList->size--; + g_deviceStateList->length--; +} + +/** + * Device Socket Object List + */ +void CAEDRNativeCreateDeviceSocketList() +{ + OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceSocketList"); + + // create new object array + if (NULL == g_deviceObjectList) + { + OIC_LOG(DEBUG, TAG, "Create Device object list"); + + g_deviceObjectList = u_arraylist_create(); + } +} + +void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket) +{ + OIC_LOG(DEBUG, TAG, "[EDR][Native] CANativeAddDeviceobjToList"); + + if (!deviceSocket) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] Device is null"); + return; + } + + if (!g_deviceObjectList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); + return; + } + + jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket); + if (!jni_remoteAddress) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] jni_remoteAddress is null"); + return; + } + + const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL); + + if (!CAEDRNativeIsDeviceSocketInList(env, remoteAddress)) + { + jobject gDeviceSocker = (*env)->NewGlobalRef(env, deviceSocket); + u_arraylist_add(g_deviceObjectList, gDeviceSocker); + OIC_LOG(DEBUG, TAG, "Set Socket Object to Array"); + } + (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress); +} + +bool CAEDRNativeIsDeviceSocketInList(JNIEnv *env, const char* remoteAddress) +{ + OIC_LOG(DEBUG, TAG, "[EDR][Native] CANativeIsDeviceObjInList"); + + if (!remoteAddress) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null"); + return false; + } + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + + jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); + if (!jarrayObj) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null"); + return false; + } + + jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj); + if (!jni_setAddress) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_setAddress is null"); + return false; + } + + const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL); + if (!setAddress) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] setAddress is null"); + return false; + } + + if (!strcmp(remoteAddress, setAddress)) + { + OIC_LOG(DEBUG, TAG, "the device is already set"); + (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); + return true; + } + else + { + (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); + continue; + } + } + + OIC_LOG(DEBUG, TAG, "there are no the Device obejct in list. we can add"); + return false; +} + +void CAEDRNativeSocketCloseToAll(JNIEnv *env) +{ + OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeSocketCloseToAll"); + + if (!g_deviceObjectList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); + return; + } + + jclass jni_cid_BTSocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET); + if (!jni_cid_BTSocket) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_cid_BTSocket is null"); + return; + } + + jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V"); + if (!jni_mid_close) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_mid_close is null"); + return; + } + + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + jobject jni_obj_socket = (jobject) u_arraylist_get(g_deviceObjectList, index); + if (!jni_obj_socket) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] socket obj is null"); + return; + } + + (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close); + + if ((*env)->ExceptionCheck(env)) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] close: close is Failed!!!"); + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + return; + } + } +} + +void CAEDRNativeRemoveAllDeviceSocket(JNIEnv *env) +{ + OIC_LOG(DEBUG, TAG, "CANativeRemoveAllDeviceObjsList"); + + if (!g_deviceObjectList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); + return; + } + + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); + if (!jarrayObj) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] jarrayObj is null"); + return; + } + (*env)->DeleteGlobalRef(env, jarrayObj); + } + + OICFree(g_deviceObjectList); + g_deviceObjectList = NULL; + return; +} + +void CAEDRNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket) +{ + OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDeviceSocket"); + + if (!g_deviceObjectList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); + return; + } + + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); + if (!jarrayObj) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null"); + continue; + } + + jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj); + if (!jni_setAddress) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_setAddress is null"); + continue; + } + + jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket); + if (!jni_remoteAddress) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_remoteAddress is null"); + continue; + } + + const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL); + const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL); + + if (!strcmp(setAddress, remoteAddress)) + { + OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove object : %s", remoteAddress); + (*env)->DeleteGlobalRef(env, jarrayObj); + (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); + (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress); + + CAEDRReorderingDeviceSocketList(index); + break; + } + (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); + (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress); + } + + OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object"); + return; +} + +void CAEDRNativeRemoveDeviceSocketBaseAddr(JNIEnv *env, jstring address) +{ + OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDeviceSocket"); + + if (!g_deviceObjectList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); + return; + } + + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); + if (!jarrayObj) + { + OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null"); + continue; + } + + jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj); + if (!jni_setAddress) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] jni_setAddress is null"); + continue; + } + const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL); + const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL); + + if (!strcmp(setAddress, remoteAddress)) + { + OIC_LOG_V(ERROR, TAG, "[EDR][Native] remove object : %s", remoteAddress); + (*env)->DeleteGlobalRef(env, jarrayObj); + (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); + (*env)->ReleaseStringUTFChars(env, address, remoteAddress); + + CAEDRReorderingDeviceSocketList(index); + break; + } + (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); + (*env)->ReleaseStringUTFChars(env, address, remoteAddress); + } + + OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object"); + return; +} + +jobject CAEDRNativeGetDeviceSocket(uint32_t idx) +{ + OIC_LOG(DEBUG, TAG, "CAEDRNativeGetDeviceSocket"); + + if (!g_deviceObjectList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); + return NULL; + } + + jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, idx); + if (!jarrayObj) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] jarrayObj is not available"); + return NULL; + } + return jarrayObj; +} + +jobject CAEDRNativeGetDeviceSocketBaseAddr(JNIEnv *env, const char* remoteAddress) +{ + OIC_LOG(DEBUG, TAG, "CAEDRNativeGetDeviceSocket"); + + if (!g_deviceObjectList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); + return NULL; + } + + jint index; + jint length = u_arraylist_length(g_deviceStateList); + for (index = 0; index < length; index++) + { + jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index); + if (!jarrayObj) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] jarrayObj is null"); + continue; + } + + jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj); + if (!jni_setAddress) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] jni_setAddress is null"); + continue; + } + const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL); + + if (!strcmp(setAddress, remoteAddress)) + { + OIC_LOG_V(ERROR, TAG, "[EDR][Native] remove object : %s", remoteAddress); + (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); + return jarrayObj; + } + (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); + } + + return NULL; +} + +uint32_t CAEDRGetSocketListLength() +{ + if (!g_deviceObjectList) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); + return 0; + } + + uint32_t length = u_arraylist_length(g_deviceObjectList); + + return length; +} + +void CAEDRReorderingDeviceSocketList(uint32_t index) +{ + if (index >= g_deviceObjectList->length) + { + return; + } + + if (index < g_deviceObjectList->length - 1) + { + memmove(&g_deviceObjectList->data[index], &g_deviceObjectList->data[index + 1], + (g_deviceObjectList->length - index - 1) * sizeof(void *)); + } + + g_deviceObjectList->size--; + g_deviceObjectList->length--; +} diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.h b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.h new file mode 100644 index 0000000..148ccca --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.h @@ -0,0 +1,230 @@ +/****************************************************************** + * + * Copyright 2014 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. + * + ******************************************************************/ + +/** + * @file + * @brief This file contains the APIs for BT communications. + */ +#ifndef CA_EDR_UTILES_H_ +#define CA_EDR_UTILES_H_ + +#include "cacommon.h" +#include "cathreadpool.h" +#include "uarraylist.h" +#include "caedrinterface.h" +#include "jni.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Get address from device socket + * @param env [IN] JNI interface pointer + * @param bluetoothSocketObj [IN] bluetooth socket object + * @return Bluetooth device address + */ +jstring CAEDRNativeGetAddressFromDeviceSocket(JNIEnv *env, jobject bluetoothSocketObj); + +/** + * @brief Get local device address + * @param env [IN] JNI interface pointer + * @return Bluetooth device address + */ +jstring CAEDRNativeGetLocalDeviceAddress(JNIEnv *env); + +/** + * @brief Get bonded devices list + * @param env [IN] JNI interface pointer + * @return Bonded devices list + */ +jobjectArray CAEDRNativeGetBondedDevices(JNIEnv *env); + +/** + * @brief Get Bluetooth device state + * @param env [IN] JNI interface pointer + * @return Bluetooth device state + */ +jint CAEDRNativeGetBTStateOnInfo(JNIEnv *env); + +/** + * @brief Check the BT Adapter enable + * @param env [IN] JNI interface pointer + * @return JNI_TRUE or JNI_FALSE + */ +jboolean CAEDRNativeIsEnableBTAdapter(JNIEnv *env); + +/** + * @brief Get address from BT device + * @param env [IN] JNI interface pointer + * @param bluetoothSocketObj [IN] bluetooth socket object + * @return Bluetooth device address + */ +jstring CAEDRNativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice); + +/** + * BT State Info List + */ + +/** + * @brief This function will create the device state list. + * @return None + */ +void CAEDRNativeCreateDeviceStateList(); + +/** + * @brief Update connection state of device + * @param state [IN] connection state + * @param address [IN] remote address + * @return None + */ +void CAEDRUpdateDeviceState(CAConnectedState_t state, const char *address); + +/** + * @brief Add device object to the list + * @param state [IN] connection state object + * @return None + */ +void CAEDRNativeAddDeviceStateToList(state_t *state); + +/** + * @brief Check whether the device exist in the list or not + * @param remoteAddress [IN] remote address + * @return true or false + */ +bool CAEDRNativeIsDeviceInList(const char *remoteAddress); + +/** + * @brief Close all socket + * @param env [IN] JNI interface pointer + * @return NONE + */ +void CAEDRNativeSocketCloseToAll(JNIEnv *env); + +/** + * @brief Remove all device objects in the list + * @return None + */ +void CAEDRNativeRemoveAllDeviceState(); + +/** + * @brief Remove target device in the list + * @param remoteAddress [IN] remote address + * @return None + */ +void CAEDRNativeRemoveDevice(const char *remoteAddress); + +/** + * @brief Get current device connection state + * @param remoteAddress [IN] remote address + * @return STATE_DISCONNECTED or STATE_CONNECTED + */ +CAConnectedState_t CAEDRIsConnectedDevice(const char *remoteAddress); + +/** + * @brief Reordering for the list + * @param index [IN] index of device list that want to reordering + * @return None + */ +void CAEDRReorderingDeviceList(uint32_t index); + +/** + * Bluetooth Socket Object List + */ + +/** + * @brief This function will create the device socket list. + * @return None + */ +void CAEDRNativeCreateDeviceSocketList(); + +/** + * @brief Add device object to the list + * @param env [IN] JNI interface pointer + * @param deviceSocket [IN] device socket object + * @return None + */ +void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket); + +/** + * @brief Add device object to the list + * @param env [IN] JNI interface pointer + * @param remoteAddress [IN] remote address + * @return true or false + */ +bool CAEDRNativeIsDeviceSocketInList(JNIEnv *env, const char *remoteAddress); + +/** + * @brief Add device object to the list + * @param env [IN] JNI interface pointer + * @return None + */ +void CAEDRNativeRemoveAllDeviceSocket(JNIEnv *env); + +/** + * @brief Add device object to the list + * @param env [IN] JNI interface pointer + * @param deviceSocket [IN] device socket object + * @return None + */ +void CAEDRNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket); + +/** + * @brief Remove device socket + * @param env [IN] JNI interface pointer + * @param address [IN] remote address + * @return NONE + */ +void CAEDRNativeRemoveDeviceSocketBaseAddr(JNIEnv *env, jstring address); + +/** + * @brief Get device socket object from the list + * @param idx [IN] index of device list + * @return Device socket object or NULL + */ +jobject CAEDRNativeGetDeviceSocket(uint32_t idx); + +/** + * @brief Get device socket address + * @param env [IN] JNI interface pointer + * @param remoteAddress [IN] remote address + * @return Device socket object or NULL + */ +jobject CAEDRNativeGetDeviceSocketBaseAddr(JNIEnv *env, const char* remoteAddress); + +/** + * @brief Get length of device socket list + * @return length of list + */ +uint32_t CAEDRGetSocketListLength(); + +/** + * @brief Reordering for the list + * @param index [IN] index of device list that want to reordering + * @return None + */ +void CAEDRReorderingDeviceSocketList(uint32_t index); +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/org_iotivity_jar_caedrinterface.h b/resource/csdk/connectivity/src/bt_edr_adapter/android/org_iotivity_jar_caedrinterface.h new file mode 100644 index 0000000..fbe3511 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/org_iotivity_jar_caedrinterface.h @@ -0,0 +1,31 @@ +#include +/* Header for class org_iotivity_jar_caedrinterface */ + +#ifndef Included_org_iotivity_jar_caedrinterface +#define Included_org_iotivity_jar_caedrinterface +#ifdef __cplusplus +extern "C" +{ +#endif +/* + * Class: org_iotivity_jar_caedrinterface + * Method: CAEDRStateChangedCallback + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_org_iotivity_jar_caedrinterface_CAEDRStateChangedCallback +(JNIEnv *, jobject, jint); + +/* + * Class: org_iotivity_jar_caedrinterface + * Method: CAEDRStateChangedCallback + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_org_iotivity_jar_caedrinterface_CAEDRBondStateChangedCallback +(JNIEnv *, jobject, jstring); + +#ifdef __cplusplus +} +#endif +#endif -- 2.7.4