For adapting new platforms at adapter level , common logic is added for each adapter.
Platform related calls are divided into client, server and network monitor.
Change-Id: I0086619ae5207e79fee08a6776bbc1a033ac6f44
Signed-off-by: Ashok Channa <ashok.channa@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/143
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Sudarshan Prasad <sudarshan.prasad@intel.com>
PROJECT_COMMON_INC_PATH = $(PROJECT_COMMON_PATH)/inc
PROJECT_COMMON_SRC_PATH = $(PROJECT_COMMON_PATH)/src
PROJECT_LIB_PATH = $(PROJECT_ROOT_PATH)/lib
-DTLS_LIB = $(PROJECT_LIB_PATH)/extlibs/tinydtls
+PROJECT_EXTERNAL_PATH = $(PROJECT_ROOT_PATH)/external/inc
+DTLS_LIB = $(PROJECT_LIB_PATH)/tinydtls
#Modify below values to enable/disable the Adapter
-#Suffix "NO_" to disable given adapter
+#Suffix "NO_" to disable given adapter
EDR = EDR_ADAPTER
WIFI = WIFI_ADAPTER
LE = LE_ADAPTER
LOCAL_C_INCLUDES += $(PROJECT_COMMON_INC_PATH)
LOCAL_C_INCLUDES += $(PROJECT_INC_PATH)
LOCAL_C_INCLUDES += $(PROJECT_LIB_PATH)/libcoap-4.1.1
+LOCAL_C_INCLUDES += $(PROJECT_EXTERNAL_PATH)
LOCAL_C_INCLUDES += $(DTLS_LIB)
LOCAL_CFLAGS += $(BUILD_FLAG)
$(ADAPTER_UTILS)/camsgparser.c $(EDR_ADAPTER_PATH)/caedradapter.c \
$(LE_ADAPTER_PATH)/caleadapter.c $(LE_ADAPTER_PATH)/caleclient.c \
$(LE_ADAPTER_PATH)/caleserver.c $(LE_ADAPTER_PATH)/caleutils.c \
+ $(LE_ADAPTER_PATH)/calenwmonitor.c \
+ $(EDR_ADAPTER_PATH)/caedrcore.c \
wifi_adapter/cawifiadapter.c $(WIFI_ADAPTER_PATH)/cawifiserver.c \
$(WIFI_ADAPTER_PATH)/cawificlient.c $(WIFI_ADAPTER_PATH)/cawifinwmonitor.c \
- $(LE_ADAPTER_PATH)/calenwmonitor.c \
include $(BUILD_STATIC_LIBRARY)
libdir=${prefix}/lib
includedir=${prefix}/include/interfaceHeaders
-Name: com.samsung.oicca
+Name: com.oic.ca
Description: Oic core library
Version: 1.0
-Cflags: -I${includedir}
\ No newline at end of file
+Cflags: -I${includedir}
-%define PREFIX /usr/apps/com.samsung.oicca
+%define PREFIX /usr/apps/com.oic.ca
%define ROOTDIR %{_builddir}/%{name}-%{version}
%define USR_INC_DIR /usr/include
%define DEST_INC_DIR %{buildroot}%{USR_INC_DIR}/interfaceHeaders
%define DEST_LIB_DIR %{buildroot}/usr/lib
-Name: com.samsung.oicca
+Name: com.oic.ca
Version: 0.1
Release: 1
Summary: Tizen oicca application
URL: http://slp-source.sec.samsung.net
Source: %{name}-%{version}.tar.gz
-License: SAMSUNG
-Group: Samsung/Application
+License: Apache License, Version 2.0
+Group: OIC/Application
#BuildRequires: cmake
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: boost-thread
BuildRequires: boost-system
BuildRequires: boost-filesystem
+BuildRequires: scons
#BuildRequires: oic-core
%description
SLP oicca application
%prep
+
%setup -q
%build
-make clean
-make
+echo %{ROOTDIR}
-#make %{?jobs:-j%jobs}
+scons TARGET_OS=tizen -c
+scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT}
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}/usr/share/license
mkdir -p %{buildroot}/usr/share/packages
mkdir -p %{buildroot}/etc/smack/accesses2.d
-mkdir -p %{buildroot}/usr/apps/com.samsung.oicca/bin/
+mkdir -p %{buildroot}/usr/apps/com.oic.ca/bin/
mkdir -p %{buildroot}/usr/lib
mkdir -p %{DEST_INC_DIR}
mkdir -p %{DEST_LIB_DIR}/pkgconfig
-cp -rf %{ROOTDIR}/liboicinterface.a %{buildroot}/usr/lib
-cp -rf %{ROOTDIR}/cacommon.h* %{DEST_INC_DIR}/
-cp -rf %{ROOTDIR}/caadapterinterface.h* %{DEST_INC_DIR}/
-cp -rf %{ROOTDIR}/uthreadpool.h* %{DEST_INC_DIR}/
-cp -rf %{ROOTDIR}/cawifiadapter.h* %{DEST_INC_DIR}/
-cp -rf %{ROOTDIR}/caethernetadapter.h* %{DEST_INC_DIR}/
-cp -rf %{ROOTDIR}/caedradapter.h* %{DEST_INC_DIR}/
-cp -rf %{ROOTDIR}/caleadapter.h* %{DEST_INC_DIR}/
-cp -rf %{ROOTDIR}/cainterface.h* %{DEST_INC_DIR}/
-cp -rf %{ROOTDIR}/com.samsung.oicca.pc %{DEST_LIB_DIR}/pkgconfig/
+cp -rf %{ROOTDIR}/con/libconnectivity_abstraction.a %{buildroot}/usr/lib
+cp -rf %{ROOTDIR}/con/lib/libcoap-4.1.1/libcoap.a %{buildroot}/usr/lib
+cp -rf %{ROOTDIR}/con/api/cacommon.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/con/inc/caadapterinterface.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/con/common/inc/uthreadpool.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/con/inc/cawifiadapter.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/con/inc/caethernetadapter.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/con/inc/caedradapter.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/con/inc/caleadapter.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/con/api/cainterface.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/com.oic.ca.pc %{DEST_LIB_DIR}/pkgconfig/
%files
char *OICStrdup(const char *str)
{
// Allocate memory for original string length and 1 extra byte for '\0'
- size_t length = strlen(str) + 1;
- char *dup = OICMalloc(length);
+ size_t length = strlen(str);
+ char *dup = (char *)OICMalloc(length + 1);
if (NULL != dup)
{
memcpy(dup, str, length);
+ dup[length] = '\0';
}
return dup;
}
*
******************************************************************/
/**
- * @file caedradapter.h
- * @brief This file contains the APIs for EDR adapters to be implemented
+ * @file caedradapter.h
+ * @brief This file contains the APIs for EDR adapters.
*/
#ifndef __CA_EDRADAPTER_H_
#define __CA_EDRADAPTER_H_
/**
- * BT Interface AP
+ * EDR Interface AP
**/
#include "cacommon.h"
#include "caadapterinterface.h"
#endif
/**
- * @fn CAInitializeEDR
- * @brief Initialize EDR connectivity interface.
- *
- * @param[in] registerCallback To register EDR interfaces to Connectivity Abstraction Layer
- * @param[in] reqRespCallback Callback to be notified on receival of request/responses from
- * peer bluetooth devices.
- * @param[in] netCallback Callback to be notified when network adapter state changes.
- * @param[in] threadPool Thread pool for handling asynchronous tasks.
- *
- * @return #CA_STATUS_OK or #CA_ADAPTER_NOT_ENABLED on success otherwise proper error code.
+ * @brief Initialize EDR Interface.
+ * @param registerCallback [IN] Callback to register EDR interface to Connectivity
+ * Abstraction Layer
+ * @param reqRespCallback [IN] Callback to notify request and response messages from server(s)
+ * started at Connectivity Abstraction Layer.
+ * @param netCallback [IN] Callback to intimate the network additions to Connectivity
+ * Abstraction Layer.
+ * @param handle [IN] Threadpool Handle
+ * @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
* @retval #CA_ADAPTER_NOT_ENABLED Initialization is successful, but bluetooth adapter is
- * not enabled
+ * not enabled
* @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
u_thread_pool_t handle);
/**
- * @fn CAStartEDR
- * @brief Starting EDR connectivity adapters. As its peer to peer it doesnot require to start
- * any servers.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @brief Starts EDR connectivity adapters. As its peer to peer it doesnot require to start
+ * any servers.
+ * @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_ADAPTER_NOT_ENABLED Bluetooth adapter is not enabled
* @retval #CA_STATUS_FAILED Operation failed
CAResult_t CAStartEDR();
/**
- * @fn CAStartEDRListeningServer
- * @brief Starting listening server for receiving multicast search requests.
- * Starts RFCOMM Server with prefixed UUID as per OIC specification.
+ * @brief Starts listening server for receiving multicast search requests.
+ * Starts RFCOMM Server with prefixed UUID as per OIC specification.
*
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_SERVER_STARTED_ALREADY Server is already started and running for the predefined
- * service UUID
- * @retval #CA_STATUS_FAILED Operation failed
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_SERVER_STARTED_ALREADY Server is already started and running for the predefined
+ * service UUID
+ * @retval #CA_STATUS_FAILED Operation failed
*
*/
CAResult_t CAStartEDRListeningServer();
/**
- * @fn CAStartEDRDiscoveryServer
* @brief Starting discovery server for receiving multicast advertisements.
- * Starts RFCOMM Server with prefixed UUID as per OIC specification.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_SERVER_STARTED_ALREADY Server is already started and running for the predefined
- * service UUID
- * @retval #CA_STATUS_FAILED Operation failed
+ * Starts RFCOMM Server with prefixed UUID as per OIC specification.
*
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_SERVER_STARTED_ALREADY Server is already started and running for the predefined
+ * service UUID
+ * @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAStartEDRDiscoveryServer();
/**
- * @fn CASendEDRUnicastData
* @brief Sends data to the peer bluetooth OIC device using the adapter connectivity.
- *
- * @param[in] remoteEndpoint Information about peer device to which data needs to be send.
- * @param[in] data Data which needs to be send to peer OIC device.
- * @param[in] dataLength Length of data in bytes.
- *
- * @return Number of bytes sent on the network. 0 indicates failed to send data.
+ * @param remoteEndpoint [IN] Remote Endpoint information (like ipaddress, port, reference uri and
+ * connectivity type) to which the unicast data has to be sent.
+ * @param data [IN] Data to be sent.
+ * @param dataLength [IN] Size of data to be sent.
+ * @return The number of bytes sent on the network. Returns 0 on error.
*
*/
uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
uint32_t dataLength);
/**
- * @fn CASendEDRMulticastData
* @brief Sends multicast data to all discovered bluetooth OIC devices using the adapter
- * connectivity.
- *
- * @param[in] data Data which needs to be send to all discovered bluetooth OIC device.
- * @param[in] dataLength Length of data in bytes.
- *
- * @return Number of bytes sent on the network. 0 indicates failed to send data.
- *
+ * connectivity.
+ * @param data [IN] Data which needs to be sent to all discovered bluetooth OIC device.
+ * @param dataLength [IN] Length of data in bytes.
+ * @return Number of bytes sent on the network. Returns 0 on error.
*/
uint32_t CASendEDRMulticastData(void *data, uint32_t dataLength);
/**
- * @fn CAGetEDRInterfaceInformation
* @brief Get EDR Connectivity network information.
*
- * @param[out] info Array of local connectivity information structures.
- * @param[out] size Size of the array @info.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
- * @retval #CA_MEMORY_ALLOC_FAILED Failed to allocate memory
- * @retval #CA_STATUS_FAILED Operation failed
+ * @param info [OUT] Array of local connectivity information structures.
+ * @param size [OUT] Size of the array @info.
*
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
+ * @retval #CA_MEMORY_ALLOC_FAILED Failed to allocate memory
+ * @retval #CA_STATUS_FAILED Operation failed
+ * @remarks info is allocated in this API and should be freed by the caller.
*/
CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
/**
- * @fn CAReadEDRData
* @brief Read Synchronous API callback.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_FAILED Operation failed
- *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAReadEDRData();
/**
- * @fn CAStopEDR
- * @brief Stopping the adapters and close socket connections
- * EDR Stops all RFCOMM servers and close sockets.
- *
- * @return #CA_STATUS_OK on success
- *
+ * @brief EDR Stops all RFCOMM servers and close sockets.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStopEDR();
/**
- * @fn CATerminateEDR
* @brief Terminate the EDR connectivity adapter.
* Configuration information will be deleted from further use.
- *
+ * @return NONE
*/
void CATerminateEDR();
+/**
+ * @brief Initializes the adapter queues.
+ * This will initiates both server and receiver adapter queues.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
+ * @retval #CA_MEMORY_ALLOC_FAILED Failed to allocate memory
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAAdapterStartQueue();
+
#ifdef __cplusplus
} /* extern "C" */
#endif
--- /dev/null
+/******************************************************************
+ *
+ * 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 caedrcore.h
+ * @brief This file contains the APIs for BT EDR communications.
+ */
+#ifndef __CA_EDRCORE_H_
+#define __CA_EDRCORE_H_
+
+#include <stdbool.h>
+
+#include "cacommon.h"
+#include "uthreadpool.h"
+#include "jni.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct connected_state {
+ char address[CA_MACADDR_SIZE];
+ uint32_t state;
+} state_t;
+
+/**
+ * @enum CAAdapterServerType_t
+ * @brief Enum for defining different server types.
+ */
+typedef enum
+{
+ CA_UNICAST_SERVER = 0, /**< Unicast Server */
+ CA_MULTICAST_SERVER, /**< Multicast Server */
+ CA_SECURED_UNICAST_SERVER /**< Secured Unicast Server */
+} CAAdapterServerType_t;
+
+typedef void (*CAPacketReceiveCallback)(const char *address, const char *data);
+
+void CAEDRClientJNISetContext(JNIEnv *env, jobject context);
+
+void CAEDRCreateJniInterfaceObject();
+
+void CAEDRInitialize(u_thread_pool_t handle);
+
+void CAEDRTerminate();
+
+void CAEDRCoreJniInit(JNIEnv *env, JavaVM* jvm);
+
+int32_t CAEDRSendUnicastMessage(const char *address, const char *data, uint32_t dataLen);
+
+int32_t CAEDRSendMulticastMessage(const char *data, uint32_t dataLen);
+
+int32_t CAEDRStartUnicastServer(const char *address, bool isSecured);
+
+int32_t CAEDRStartMulticastServer(bool isSecured);
+
+int32_t CAEDRStopUnicastServer(int32_t serverID);
+
+int32_t CAEDRStopMulticastServer(int32_t serverID);
+
+void CAEDRSetCallback(CAPacketReceiveCallback callback);
+
+CAResult_t CAEDRGetInterfaceInfo(char **address);
+
+void CAEDRGetLocalAddress(char** address);
+
+int32_t CAEDRSendUnicastMessageImpl(const char *address, const char *data, uint32_t dataLen);
+
+int32_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char *data, uint32_t dataLen);
+
+/**
+ * EDR Method
+ */
+void CAEDRNativeSendData(JNIEnv *env, const char* address, const char* data, uint32_t id);
+
+int CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type);
+
+jobject CAEDRNativeListen(JNIEnv *env);
+
+void CAEDRNativeAccept(JNIEnv *env, jobject severSocketObject);
+
+void CAEDRNativeConnect(JNIEnv *env, const char* address, uint32_t id);
+
+void CAEDRNativeSocketClose(JNIEnv *env, const char* address, uint32_t id);
+
+/**
+ * BT Common Method : JNI
+ */
+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);
+
+/**
+ * BT State List
+ */
+void CAEDRNativeCreateDeviceStateList();
+
+void CAEDRUpdateDeviceState(uint32_t state, const char* address);
+
+void CAEDRNativeAddDeviceStateToList(state_t* state);
+
+jboolean CAEDRNativeIsDeviceInList(const char *remoteAddress);
+
+void CAEDRNativeRemoveAllDeviceState();
+
+void CAEDRNativeRemoveDevice(const char* remoteAddress);
+
+jboolean CAEDRIsConnectedDevice(const char* remoteAddress);
+
+void CAEDRReorderingDeviceList(uint32_t index);
+
+/**
+ * Bluetooth Socket Object List
+ */
+void CAEDRNativeCreateDeviceSocketList();
+
+void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket);
+
+jboolean CAEDRNativeIsDeviceSocketInList(JNIEnv *env, const char *remoteAddress);
+
+void CAEDRNativeRemoveAllDeviceSocket(JNIEnv *env);
+
+void CAEDRNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket);
+
+jobject CAEDRNativeGetDeviceSocket(uint32_t idx);
+
+uint32_t CAEDRGetSocketListLength();
+
+void CAEDRReorderingDeviceSocketList(uint32_t index);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
--- /dev/null
+/******************************************************************
+ *
+ * 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 caedrinterface.h
+ * @brief This file provides APIs for EDR adapter - client, server, network monitor modules
+ */
+
+#ifndef __CA_EDR_INTERFACE_H_
+#define __CA_EDR_INTERFACE_H_
+
+#include <string.h>
+#include "caedradapter.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifndef OIC_EDR_SERVICE_ID
+#define OIC_EDR_SERVICE_ID "12341234-1C25-481F-9DFB-59193D238280"
+#endif //OIC_EDR_SERVICE_ID
+
+/**
+ * @struct CAEDRData
+ * @brief Structure to maintain the information of data in message queue.
+ */
+typedef struct
+{
+ CARemoteEndpoint_t *remoteEndpoint; /**< Remote Endpoint */
+ void *data; /**< Data to be sent */
+ uint32_t dataLen; /**< Length of the data to be sent */
+} CAEDRData;
+
+/**
+ * @struct CAEDRNetworkEvent
+ * @brief Structure to maintain the adapter information and its status.
+ */
+typedef struct
+{
+ CALocalConnectivity_t *info; /**< Local Connectivity Information */
+ CANetworkStatus_t status; /**< Network Status */
+} CAEDRNetworkEvent;
+
+/**
+ * @brief This will be used during the recive of network requests and response.
+ * @param remoteAddress [IN] EDR address of remote OIC device
+ * @param data [IN] Data received
+ * @param dataLength [IN] Length of the Data received
+ * @param sentLength [IN] Length of the sent data
+ * @return NONE
+ * @pre Callback must be registered using CAEDRSetPacketReceivedCallback()
+ */
+typedef void (*CAEDRDataReceivedCallback)(const char *remoteAddress, void *data, uint32_t dataLength,
+ uint32_t *sentLength);
+
+/**
+ * @brief This will be used during change in network status.
+ * @param status [IN] Network Status of the adapter
+ * @return NONE
+ */
+typedef void (*CAEDRNetworkStatusCallback)(CANetworkStatus_t status);
+
+/**
+ * @brief Initialize the network monitor module
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_ADAPTER_NOT_ENABLED Initialization is successful, but bluetooth adapter is
+ * not enabled.
+ * @retval #CA_STATUS_FAILED Operation failed
+ * @see CAEDRTerminateNetworkMonitor()
+ */
+CAResult_t CAEDRInitializeNetworkMonitor();
+
+/**
+ * @brief Deinitialize with bluetooth adapter.
+ * @return NONE
+ * @pre CAEDRInitializeNetworkMonitor() should be invoked before using this API.
+ * @see CAEDRInitializeNetworkMonitor()
+ */
+void CAEDRTerminateNetworkMonitor(void);
+
+/**
+ * @brief Start Network Monitoring Process
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAEDRStartNetworkMonitor();
+
+/**
+ * @brief Stop Network Monitoring Process
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAEDRStopNetworkMonitor();
+
+/**
+ * @brief Sets the callback and Starts discovery for nearby OIC bluetooth devices.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEDRClientSetCallbacks(void);
+
+/**
+ * @brief Resetting callbacks with bluetooth framework and stop OIC device discovery.
+ * @return NONE
+ * @pre CAEDRClientSetCallbacks() should be invoked before using this API.
+ * @see CAEDRClientSetCallbacks()
+ */
+void CAEDRClientUnsetCallbacks(void);
+
+/**
+ * @brief Used to initialize the EDR client module where mutex is initialized
+ * @return NONE
+ */
+void CAEDRInitializeClient();
+
+/**
+ * @brief Destroys the Device list and mutex.
+ * @return NONE
+ */
+void CAEDRTerminateClient();
+
+/**
+ * @brief Closes all the client connection to peer bluetooth devices.
+ * @return NONE
+ */
+void CAEDRClientDisconnectAll(void);
+
+/**
+ * @brief Register callback to send the received packets from remote bluetooth device to BTAdapter.
+ *
+ * @param packetReceivedCallback [IN] Callback function to register for sending network
+ * packets to EDR Adapter.
+ * @return NONE
+ */
+void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback);
+
+/**
+ * @brief Register callback for receiving local bluetooth adapter state.
+ *
+ * @param networkStateChangeCallback [IN] Callback function to register for receiving local
+ * bluetooth adapter status.
+ * @return NONE
+ */
+void CAEDRSetNetworkChangeCallback(CAEDRNetworkStatusCallback networkStateChangeCallback);
+
+
+/**
+ * @brief Get the local bluetooth adapter information.
+ *
+ * @param info [IN] Local bluetooth adapter information
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ *
+ * @see #CALocalConnectivity_t
+ *
+ */
+CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info);
+
+/**
+ * @brief Start RFCOMM server for given service UUID
+ *
+ * @param serviceUUID [IN] The UUID of service with which RFCOMM server needs to be started.
+ * @param serverFD [IN] The RFCOMM server socket file descriptor.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ *
+ */
+CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD);
+
+/**
+ * @brief Stop RFCOMM server
+ *
+ * @param serverFD [IN] The RFCOMM server socket file descriptor which needs to be stopped.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEDRServerStop(const int32_t serverFD);
+
+/**
+ * @brief All received data will be notified to upper layer.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ *
+ */
+CAResult_t CAEDRManagerReadData(void);
+
+/**
+ * @brief This function gets bluetooth adapter enable state.
+ * @param state [OUT] State of the Adapter.
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAEDRGetAdapterEnableState(CABool_t *state);
+
+/**
+ * @brief This function sends data to specified remote bluetooth device.
+ * @param remoteAddress [IN] Remote EDR Address
+ * @param serviceUUID [IN] Service UUID of the device
+ * @param data [IN] Data to be sent
+ * @param dataLength [IN] Length of the data to be sent
+ * @param sentLength [IN] Length of the actual sent data
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength);
+
+/**
+ * @brief This function sends data to all bluetooth devices running OIC service.
+ * @param serviceUUID [IN] Service UUID of the device
+ * @param data [IN] Data to be sent
+ * @param dataLength [IN] Length of the data to be sent
+ * @param sentLength [IN] Length of the actual sent data
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, void *data,
+ uint32_t dataLength, uint32_t *sentLength);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif //__CA_EDR_INTERFACE_H_
+
#endif
/**
- * @Structure CABLEData
+ * @struct CABLEData
* @brief Stores the information of the Data to be sent from the queues.
- * This structure will be pushed to the sender/receiver queue for processing.
+ * This structure will be pushed to the sender/receiver queue for processing.
*/
typedef struct
{
CARemoteEndpoint_t
- *remoteEndpoint; /**< Remote endpoint contains the inforamtion of remote device */
- void *data; /**< Data to be transmitted over LE tranport */
- uint32_t dataLen; /**< Length of the data being transmitted */
+ *remoteEndpoint; /**< Remote endpoint contains the inforamtion of remote device */
+ void *data; /**< Data to be transmitted over LE tranport */
+ uint32_t dataLen; /**< Length of the data being transmitted */
} CABLEData;
-/** @brief Initialize LE connectivity interface.
- * @param registerCallback [IN] To register LE interfaces to Connectivity Abstraction Layer
- * @param reqRespCallback [IN] sending responses and discovery messages from unicast , \
- * multicast servers
- * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+/**
+ * @brief Initialize LE connectivity interface.
+ * @param registerCallback [IN] Callback to register LE interfaces to Connectivity
+ * Abstraction Layer
+ * @param reqRespCallback [IN] Callback to notify request and response messages from server(s)
+ * started at Connectivity Abstraction Layer.
+ * @param netCallback [IN] Callback to intimate the network additions to Connectivity
+ * Abstraction Layer.
+ * @param handle [IN] Threadpool Handle
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
CANetworkPacketReceivedCallback reqRespCallback,
u_thread_pool_t handle);
/**
- * @brief Starting LE connectivity adapters . \
- * As its peer to peer it doesnot require to start any servers
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @brief Starting LE connectivity adapters.
+ * As its peer to peer it doesnot require to start any servers
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStartLE();
* @brief Starting listening server for receiving multicast search requests
* Transport Specific Behavior:
* LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStartLEListeningServer();
* @brief for starting discovery servers for receiving multicast advertisements
* Transport Specific Behavior:
* LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStartLEDiscoveryServer();
/**
* @brief Sends data to the endpoint using the adapter connectivity.
- * Note: length must be > 0.
* @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri \
* and connectivity type) to which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
+ * @param data [IN] Data which required to be sent.
* @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
+ * @return The number of bytes sent on the network. Returns 0 on error.
+ * @remarks dataLen must be > 0.
*/
uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
uint32_t dataLen);
/**
* @brief Sends Multicast data to the endpoint using the LE connectivity.
- * Note: length must be > 0.
* @param data [IN] Data which required to be sent.
* @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
+ * @return The number of bytes sent on the network. Returns 0 on error.
+ * @remarks dataLen must be > 0.
*/
uint32_t CASendLEMulticastData(void *data, uint32_t dataLen);
/**
* @brief Starts notification server on EDR adapters.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStartLENotifyServer();
/**
- * @brief Send notification information.
- * Note: length must be > 0.
+ * @brief Send notification information.
* @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri \
* and connectivity type) to which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
+ * @param data [IN] Data which required to be sent.
* @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
+ * @return The number of bytes sent on the network. Returns 0 on error.
+ * @remarks dataLen must be > 0.
*/
uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data,
uint32_t dataLen);
/**
- * @brief Get LE Connectivity network information
- * @param info [OUT] Local connectivity information structures
- * @param size [OUT] Number of local connectivity structures.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @brief Get LE Connectivity network information
+ * @param info [OUT] Local connectivity information structures
+ * @param size [OUT] Number of local connectivity structures.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
/**
* @brief Read Synchronous API callback.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAReadLEData();
/**
* @brief Stopping the adapters and close socket connections
- * LE Stops all GATT servers and close sockets.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * LE Stops all GATT servers and GATT Clients.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStopLE();
*/
void CATerminateLE();
+/**
+ * @brief This function will receive the data from the GattServer and add the data to
+ * the Server receiver queue.
+ * @param remoteAddress [IN] Remote address of the device from where data is received.
+ * @param serviceUUID [IN] Uuid of the OIC service running on the remote device
+ * @param data [IN] Actual data recevied from the remote device.
+ * @param dataLength [IN] Length of the data received from the remote device.
+ * @param sentLength [IN] Length of the data sent from the remote device.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ *
+ */
CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID,
void *data, uint32_t dataLength, uint32_t *sentLength);
+/**
+ * @brief This function will receive the data from the GattClient and add the data into the
+ * Client receiver queue.
+ * @param remoteAddress [IN] Remote address of the device from where data is received.
+ * @param serviceUUID [IN] Uuid of the OIC service running on the remote device
+ * @param data [IN] Actual data recevied from the remote device.
+ * @param dataLength [IN] Length of the data received from the remote device.
+ * @param sentLength [IN] Length of the data sent from the remote device.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID,
void *data, uint32_t dataLength, uint32_t *sentLength);
+/**
+ * @brief This function is used to set the NetworkPacket received callback to CA layer from
+ * adapter layer.
+ * @param callback [IN] callback handle sent from the upper layer.
+ * @return NONE
+ */
void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback);
+/**
+ * @brief This function will push the data from CA layer to the Sender processor queue.
+ *
+ * @param remoteEndpoint [IN] Remote endpoint information of the server.
+ * @param data [IN] Data to be transmitted from LE.
+ * @param dataLen [IN] length of the Data being transmitted.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
void *data, uint32_t dataLen);
+/**
+ * @brief This function will push the data from CA layer to the Sender processor queue.
+ *
+ * @param remoteEndpoint [IN] Remote endpoint information of the server.
+ * @param data [IN] Data to be transmitted from LE.
+ * @param dataLen [IN] length of the Data being transmitted.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
void *data, uint32_t dataLen);
-void CABLEClientSendDataThread(void *threadData);
-
-void CABLEClientDataReceiverHandler(void *threadData);
+/**
+ * @brief This function will be associated with the sender queue for GattServer.This function will
+ * fragment the data to the MTU of the transport and send the data in fragments to the
+ * adapters. The function will be blocked untill all data is sent out from the adapter.
+ *
+ * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
+ * and Data.
+ *
+ * @return NONE
+ */
+void CABLEServerSendDataThread(void *threadData);
-void CATerminateBleQueues();
+/**
+ * @brief This function will be associated with the sender queue for GattClient.This function will
+ * fragment the data to the MTU of the transport and send the data in fragments to the
+ * adapters. The function will be blocked untill all data is sent out from the adapter.
+ *
+ * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
+ * and Data.
+ *
+ * @return NONE
+ */
+void CABLEClientSendDataThread(void *threadData);
-CAResult_t CAInitBleClientReceiverQueue();
+/**
+ * @brief This function will be associated with the receiver queue of GattServer. This function
+ * will defragment the data received and will send the data UP to the CA layer only after
+ * it collects all the data from the adapter layer. Adapter Header will provide the
+ * length of the data sent from the server.
+ *
+ * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
+ * and Data.
+ *
+ * @return NONE
+ */
+void CABLEServerDataReceiverHandler(void *threadData);
-CAResult_t CAInitBleServerReceiverQueue();
+/**
+ * @brief This function will be associated with the receiver queue of GattClient. This function
+ * will defragment the data received and will send the data UP to the CA layer only after
+ * it collects all the data from the adapter layer. Adapter Header will provide the length
+ * of the data sent from the server.
+ *
+ * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
+ * and Data.
+ * @return NONE
+ */
+void CABLEClientDataReceiverHandler(void *threadData);
+/**
+ * @brief This function is used to Initalize both GattServer and GattClient queues. All four
+ * queues will be initialized with this function invocations.
+ * @return NONE
+ */
void CAInitBleQueues();
+/**
+ * @brief This function will stop all queues created for GattServer and GattClient. All
+ * four queues will be be stopped with this function invocations.
+ * @return NONE
+ */
+void CAStopBleQueues();
+
+/**
+ * @brief This function will terminate all queues created for GattServer and GattClient. All
+ * four queues will be be terminated with this function invocations.
+ * @return NONE
+ */
void CATerminateBleQueues();
+/**
+ * @brief This function will initalize the Receiver and Sender queues for GattServer. This
+ * function will inturn call the functions CAInitBleServerReceiverQueue() and
+ * CAInitBleServerSenderQueue() to initialize the queues.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitBleServerQueues();
+/**
+ * @brief This function will initalize the Receiver and Sender queues for GattClient. This
+ * function will inturn call the functions CAInitBleClientReceiverQueue() and
+ * CAInitBleClientSenderQueue() to initialize the queues.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ *
+ */
CAResult_t CAInitBleClientQueues();
+/**
+ * @brief This function will initalize the Receiver queue for GattServer. This will initlialize
+ * the queue to process the function CABLEServerSendDataThread() when ever the task is
+ * added to this queue.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitBleServerSenderQueue();
+/**
+ * @brief This function will initalize the Receiver queue for GattClient. This will initlialize
+ * the queue to process the function CABLEClientSendDataThread() when ever the task is
+ * added to this queue.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitBleClientSenderQueue();
-
-
/**
- * @fn CABLEDataReceiverHandler
- * @brief This function handles data from recv message queue.
+ * @brief This function will initalize the Receiver queue for GattServer. This will initlialize
+ * the queue to process the function CABLEServerDataReceiverHandler() when ever the task
+ * is added to this queue.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ *
*/
-void CABLEServerDataReceiverHandler(void *context);
+CAResult_t CAInitBleServerReceiverQueue();
/**
- * @fn CABLESendDataThread
- * @brief This function handles data from sender message queue.
+ * @brief This function will initalize the Receiver queue for GattClient. This will initlialize
+ * the queue to process the function CABLEClientDataReceiverHandler() when ever the task
+ * is added to this queue.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
*/
-void CABLEServerSendDataThread(void *threadData);
+CAResult_t CAInitBleClientReceiverQueue();
/**
-* @fn CACreateBLEData
-* @brief This function will create the Data required to send it in the queue.
-*
-* @param[in] remoteEndpoint Remote endpoint information of the server.
-* @param[in] data Data to be transmitted from LE.
-* @param[in] length of the Data being transmitted.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief This function will create the Data required to send it in the queue.
+ *
+ * @param remoteEndpoint [IN] Remote endpoint information of the server.
+ * @param data [IN] Data to be transmitted from LE.
+ * @param dataLength [IN] length of the Data being transmitted.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CABLEData *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
uint32_t dataLength);
/**
-* @fn CAFreeBLEData
-* @brief Used to free the BLE information stored in the sender/receiver queues.
-*
-* @param[in] bleData Structure contains the information of a particular data segment.
-*
-* @return none.
-*/
+ * @brief Used to free the BLE information stored in the sender/receiver queues.
+ * @param bleData [IN] Structure contains the information of a particular data segment.
+ * @return NONE
+ */
void CAFreeBLEData(CABLEData *bleData);
+/**
+ * @brief This will be used to intimate device status changes to the LE adapter layer
+ * @param adapter_state [IN] State of the adapter
+ * @return NONE
+ */
+typedef void (*CALEDeviceStateChangedCallback)(CAAdapterState_t adapter_state);
+
+/**
+ * @brief This will be used to intimate network packet recieved from GATTClient to adapter layer.
+ * @param remoteAddress [IN] Remote endpoint Address
+ * @param serviceUUID [IN] Service UUID
+ * @param data [IN] Data received
+ * @param dataLength [IN] Length of the data received
+ * @param sentLength [IN] Length of the data sent
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+typedef CAResult_t (*CABLEClientDataReceivedCallback)(const char *remoteAddress,
+ const char *serviceUUID, void *data,
+ uint32_t dataLength, uint32_t *sentLength);
+
+/**
+ * @brief This will be used to intimate network packet recieved from GATTServer to adapter layer.
+ * @param remoteAddress [IN] Remote endpoint Address
+ * @param serviceUUID [IN] Service UUID
+ * @param data [IN] Data received
+ * @param dataLength [IN] Length of the data received
+ * @param sentLength [IN] Length of the data sent
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+typedef CAResult_t (*CABLEServerDataReceivedCallback)(const char *remoteAddress,
+ const char *serviceUUID, void *data,
+ uint32_t dataLength, uint32_t *sentLength);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif
/**
- * @Structure CABLEData
+ * @struct CABLEData
* @brief Stores the information of the Data to be sent from the queues.
- * This structure will be pushed to the sender/receiver queue for processing.
+ * This structure will be pushed to the sender/receiver queue for processing.
*/
typedef struct
{
CARemoteEndpoint_t
*remoteEndpoint; /**< Remote endpoint contains the inforamtion of remote device */
- void *data; /**< Data to be transmitted over LE tranport */
- uint32_t dataLen; /**< Length of the data being transmitted */
+ void *data; /**< Data to be transmitted over LE tranport */
+ uint32_t dataLen; /**< Length of the data being transmitted */
} CABLEData;
-/** @brief Initialize LE connectivity interface.
- * @param registerCallback [IN] To register LE interfaces to Connectivity Abstraction Layer
- * @param reqRespCallback [IN] sending responses and discovery messages from unicast , \
- * multicast servers
- * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+/**
+ * @brief Initialize LE connectivity interface.
+ * @param registerCallback [IN] Callback to register LE interfaces to Connectivity Abstraction Layer
+ * @param reqRespCallback [IN] Callback to notify request and response messages from server(s)
+ * started at Connectivity Abstraction Layer.
+ * @param netCallback [IN] Callback to intimate the network additions to Connectivity
+ * Abstraction Layer.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
CANetworkPacketReceivedCallback reqRespCallback,
CANetworkChangeCallback netCallback);
/**
- * @brief Starting LE connectivity adapters . \
- * As its peer to peer it doesnot require to start any servers
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @brief Starting LE connectivity adapters.
+ * As its peer to peer it doesnot require to start any servers
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStartLE();
* @brief Starting listening server for receiving multicast search requests
* Transport Specific Behavior:
* LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStartLEListeningServer();
* @brief for starting discovery servers for receiving multicast advertisements
* Transport Specific Behavior:
* LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStartLEDiscoveryServer();
/**
* @brief Sends data to the endpoint using the adapter connectivity.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri \
- * and connectivity type) to which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
+ * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri
+ * and connectivity type) to which the unicast data has to be sent.
+ * @param data [IN] Data which required to be sent.
+ * @param dataLen [IN] Size of data to be sent.
+ * @return The number of bytes sent on the network. Returns 0 on error.
+ * @remarks dataLen must be > 0.
*/
uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
uint32_t dataLen);
/**
* @brief Sends Multicast data to the endpoint using the LE connectivity.
- * Note: length must be > 0.
* @param data [IN] Data which required to be sent.
* @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
+ * @return The number of bytes sent on the network. Returns 0 on error.
+ * @remarks dataLen must be > 0.
*/
uint32_t CASendLEMulticastData(void *data, uint32_t dataLen);
/**
* @brief Starts notification server on EDR adapters.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStartLENotifyServer();
/**
* @brief Send notification information.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri \
+ * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri
* and connectivity type) to which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
+ * @param data [IN] Data which required to be sent.
* @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
+ * @return The number of bytes sent on the network. Returns 0 on error.
+ * @remarks dataLen must be > 0.
*/
uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data,
uint32_t dataLen);
/**
- * @brief Get LE Connectivity network information
+ * @brief Get LE Connectivity network information
* @param info [OUT] Local connectivity information structures
* @param size [OUT] Number of local connectivity structures.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
/**
* @brief Read Synchronous API callback.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAReadLEData();
/**
* @brief Stopping the adapters and close socket connections
* LE Stops all GATT servers and close sockets.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAStopLE();
*/
void CATerminateLE();
+/**
+ * @brief This function will receive the data from the GattServer and add the data to
+ * the Server receiver queue.
+ * @param remoteAddress [IN] Remote address of the device from where data is received.
+ * @param serviceUUID [IN] Uuid of the OIC service running on the remote device
+ * @param data [IN] Actual data recevied from the remote device.
+ * @param dataLength [IN] Length of the data received from the remote device.
+ * @param sentLength [IN] Length of the data sent from the remote device.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID,
void *data, uint32_t dataLength, uint32_t *sentLength);
+/**
+ * @brief This function will receive the data from the GattClient and add the data into the
+ * Client receiver queue.
+ * @param remoteAddress [IN] Remote address of the device from where data is received.
+ * @param serviceUUID [IN] Uuid of the OIC service running on the remote device
+ * @param data [IN] Actual data recevied from the remote device.
+ * @param dataLength [IN] Length of the data received from the remote device.
+ * @param sentLength [IN] Length of the data sent from the remote device.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID,
void *data, uint32_t dataLength, uint32_t *sentLength);
+/**
+ * @brief This function is used to set the NetworkPacket received callback to CA layer from
+ * adapter layer.
+ * @param callback [IN] callback handle sent from the upper layer.
+ * @return NONE
+ */
void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback);
+/**
+ * @brief This function will push the data from CA layer to the Sender processor queue.
+ *
+ * @param remoteEndpoint [IN] Remote endpoint information of the server.
+ * @param data [IN] Data to be transmitted from LE.
+ * @param dataLen [IN] length of the Data being transmitted.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
void *data, uint32_t dataLen);
+/**
+ * @brief This function will push the data from CA layer to the Sender processor queue.
+ *
+ * @param remoteEndpoint [IN] Remote endpoint information of the server.
+ * @param data [IN] Data to be transmitted from LE.
+ * @param dataLen [IN] length of the Data being transmitted.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
- void *data, uint32_t dataLen);
+ void *data, uint32_t dataLen);
+/**
+ * @brief This function will be associated with the sender queue for GattClient.This function will
+ * fragment the data to the MTU of the transport and send the data in fragments to the
+ * adapters. The function will be blocked untill all data is sent out from the adapter.
+ *
+ * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
+ * and Data.
+ *
+ * @return NONE
+ */
void CABLEClientSendDataThread(void *threadData);
+/**
+ * @brief This function will be associated with the receiver queue of GattClient. This function
+ * will defragment the data received and will send the data UP to the CA layer only after
+ * it collects all the data from the adapter layer. Adapter Header will provide the length
+ * of the data sent from the server.
+ *
+ * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
+ * and Data.
+ * @return NONE
+ */
void CABLEClientDataReceiverHandler(void *threadData);
+/**
+ * @brief This function will terminate all queues created for GattServer and GattClient. All
+ * four queues will be be terminated with this function invocations.
+ * @return NONE
+ */
void CATerminateBleQueues();
+/**
+ * @brief This function will initalize the Receiver queue for GattClient. This will initlialize
+ * the queue to process the function CABLEClientDataReceiverHandler() when ever the task
+ * is added to this queue.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitBleClientReceiverQueue();
+/**
+ * @brief This function will initalize the Receiver queue for GattServer. This will initlialize
+ * the queue to process the function CABLEServerDataReceiverHandler() when ever the task
+ * is added to this queue.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ *
+ */
CAResult_t CAInitBleServerReceiverQueue();
+/**
+ * @brief This function is used to Initalize both GattServer and GattClient queues. All four
+ * queues will be initialized with this function invocations.
+ * @return NONE
+ */
void CAInitBleQueues();
-void CATerminateBleQueues();
-
+/**
+ * @brief This function will initalize the Receiver and Sender queues for GattServer. This
+ * function will inturn call the functions CAInitBleServerReceiverQueue() and
+ * CAInitBleServerSenderQueue() to initialize the queues.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitBleServerQueues();
+/**
+ * @brief This function will initalize the Receiver and Sender queues for GattClient. This
+ * function will inturn call the functions CAInitBleClientReceiverQueue() and
+ * CAInitBleClientSenderQueue() to initialize the queues.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ *
+ */
CAResult_t CAInitBleClientQueues();
+/**
+ * @brief This function will initalize the Receiver queue for GattServer. This will initlialize
+ * the queue to process the function CABLEServerSendDataThread() when ever the task is
+ * added to this queue.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitBleServerSenderQueue();
+/**
+ * @brief This function will initalize the Receiver queue for GattClient. This will initlialize
+ * the queue to process the function CABLEClientSendDataThread() when ever the task is
+ * added to this queue.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitBleClientSenderQueue();
-
-
/**
- * @fn CABLEDataReceiverHandler
- * @brief This function handles data from recv message queue.
+ * @brief This function will be associated with the receiver queue of GattServer. This function
+ * will defragment the data received and will send the data UP to the CA layer only after
+ * it collects all the data from the adapter layer. Adapter Header will provide the
+ * length of the data sent from the server.
+ *
+ * @param context [IN] Data pushed to the queue which contains the info about RemoteEndpoint
+ * and Data.
+ *
+ * @return NONE
*/
void CABLEServerDataReceiverHandler(void *context);
/**
- * @fn CABLESendDataThread
- * @brief This function handles data from sender message queue.
+ * @brief This function will be associated with the sender queue for GattServer.This function will
+ * fragment the data to the MTU of the transport and send the data in fragments to the
+ * adapters. The function will be blocked untill all data is sent out from the adapter.
+ *
+ * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
+ * and Data.
+ *
+ * @return NONE
*/
void CABLEServerSendDataThread(void *threadData);
/**
-* @fn CACreateBLEData
-* @brief This function will create the Data required to send it in the queue.
-*
-* @param[in] remoteEndpoint Remote endpoint information of the server.
-* @param[in] data Data to be transmitted from LE.
-* @param[in] length of the Data being transmitted.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief This function will create the Data required to send it in the queue.
+ *
+ * @param remoteEndpoint [IN] Remote endpoint information of the server.
+ * @param data [IN] Data to be transmitted from LE.
+ * @param dataLength [IN] length of the Data being transmitted.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CABLEData *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
uint32_t dataLength);
/**
-* @fn CAFreeBLEData
-* @brief Used to free the BLE information stored in the sender/receiver queues.
-*
-* @param[in] bleData Structure contains the information of a particular data segment.
-*
-* @return none.
-*/
+ * @brief Used to free the BLE information stored in the sender/receiver queues.
+ * @param bleData [IN] Structure contains the information of a particular data segment.
+ * @return NONE
+ */
void CAFreeBLEData(CABLEData *bleData);
+/**
+ * @brief This will be used to intimate device status changes to the LE adapter layer
+ * @param adapter_state [IN] State of the adapter
+ * @return NONE
+ */
+typedef void (*CALEDeviceStateChangedCallback)(CAAdapterState_t adapter_state);
+
+/**
+ * @brief This will be used to intimate network packet recieved from GATTClient to adapter layer.
+ * @param remoteAddress [IN] Remote endpoint Address
+ * @param serviceUUID [IN] Service UUID
+ * @param data [IN] Data received
+ * @param dataLength [IN] Length of the data received
+ * @param sentLength [IN] Length of the data sent
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+typedef CAResult_t (*CABLEClientDataReceivedCallback)(const char *remoteAddress,
+ const char *serviceUUID, void *data, uint32_t dataLength, uint32_t *sentLength);
+
+/**
+ * @brief This will be used to intimate network packet recieved from GATTServer to adapter layer.
+ * @param remoteAddress [IN] Remote endpoint Address
+ * @param serviceUUID [IN] Service UUID
+ * @param data [IN] Data received
+ * @param dataLength [IN] Length of the data received
+ * @param sentLength [IN] Length of the data sent
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+typedef CAResult_t (*CABLEServerDataReceivedCallback)(const char *remoteAddress,
+ const char *serviceUUID, void *data, uint32_t dataLength, uint32_t *sentLength);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
/**
* BT Common Method : JNI
*/
-jstring CANativeGetLocalDeviceAddress(JNIEnv *env);
-
-jobjectArray CANativeGetBondedDevices(JNIEnv *env);
-
-jint CANativeGetBTStateOnInfo(JNIEnv *env);
-
-jboolean CANativeIsEnableBTAdapter(JNIEnv *env);
-
-jstring CANativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice);
-
jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt);
jstring CANativeGetRemoteAddress(JNIEnv *env, jobject bluetoothSocketObj);
void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt);
+void CANativeLEDisconnectAll(JNIEnv *env);
+
void CANativeLEDiscoverServices(JNIEnv *env, jobject bluetoothGatt);
jboolean CANativeLESendData(JNIEnv *env, jobject bluetoothGatt, jobject gattCharacteristic);
void CANativeRemoveAllGattObjsList(JNIEnv *env);
-void CANativeLEDisconnectAll(JNIEnv *env);
-
-void CANativeRemoveGattObj(JNIEnv *env, jstring address);
+void CANativeRemoveGattObj(JNIEnv *env, jobject gatt);
void CAReorderingGattList(uint32_t index);
#include <stdbool.h>
#include "cacommon.h"
-
+#include "caleadapter.h"
#ifdef __cplusplus
extern "C"
#endif
/**
- * @ENUM TRANSFER_TYPE
+ * @enum TRANSFER_TYPE
* @brief Provide info about different mode of data transfer
- *
- * This enum is used to differentiate between unicast and multicast data transfer.
+ * This enum is used to differentiate between unicast and multicast data transfer.
*/
typedef enum
{
MULTICAST, /**< When this enum is selected, data will be updated to all OIC servers. */
- UNICAST /**< When this enum is selected, data will be updated to desired OIC Server. */
+ UNICAST /**< When this enum is selected, data will be updated to desired OIC Server. */
} TRANSFER_TYPE;
+
/**
-* @fn CAStartBleGattServer
-* @brief Used to start Gatt Server thread for service creation and advertise ble service.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Initialize the LE adapter layer. This will be invoked from the CA layer.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAInitializeLEAdapter();
+
+/**
+ * @brief Used to get the current state of the LE adapter.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_ADAPTER_NOT_ENABLED adapter not enabled
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAGetLEAdapterState();
+
+/**
+ * @brief Used to initialize the network monitor layer of the LE adapter. Mutex variables required
+ * to operate in this layer and other paramters can be initialized in this function.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAInitializeLENwkMonitor();
+
+/**
+ * @brief Used to terminate the network monitor layer of the LE adapter. The variables intialized
+ * in CAInitializeLEAdapterController() must be cleared in this function.
+ * @return NONE
+ */
+void CATerminateLENwkMonitor();
+
+/**
+ * @brief This function is used to set the callback for the Device state changes in the adapter.
+ *
+ * @param callback [IN] Callback to notify the Device state change to the CA Layer
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback);
+
+/**
+ * @brief Used to initilaze all the mutex variables required to operate the LE network monitor
+ * layer.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAInitLENwkMonitorMutexVaraibles();
+
+/**
+ * @brief Used to terminate all the mutex variables required to operate the LE network monitor
+ * layer.
+ * @return NONE
+ */
+void CATerminateLENwkMonitorMutexVaraibles();
+
+/**
+ * @brief Provides the BD address of the local adapter.
+ * @param local_address [IN] pointer to the location where bd address needs to be stored.
+ *
+ * @return NONE
+ */
+void CAGetLEAddress(char **local_address);
+
+/**
+ * @brief Used to start Gatt Server thread for service creation and advertise ble service.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAStartBleGattServer();
/**
-* @fn CAStopBleGattServer
-* @brief Used to terminate BLE Gatt Service.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Used to stop BLE Gatt Service.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAStopBleGattServer();
/**
-* @fn CASetBLEReqRespServerCallback
-* @brief used to store upper layer callback locally which will be used to send the data
-* to application
-* @param[in] CANetworkPacketReceivedCallback - upper layer callback function
-* to pass the data to CA layer.
-* @return void
-*/
+ * @brief Used to stop Gatt Server thread and remove service registration, stop advertising.
+ * @return NONE
+ */
+void CATerminateBleGattServer();
+
+/**
+ * @brief Used to store upper layer callback locally which will be used to send the data to
+ * application
+ * @param callback [IN] Callback function to pass the data to CA layer.
+ * @return NONE
+ */
void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback);
/**
-* @fn CAUpdateCharacteristicsInGattServer
-* @brief Used to update characteristics(Read/Write) value that we want to send to particular client.
-* Both unicast and multicast will use the same api. In mulicast, we will be sending in loop to all clients.
-*
-* @param[in] charValue - data that we want to send to client(unicast)/clients(multicast)
-* @param[in] charValueLen - length of the data.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
-CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue,
- const uint32_t charValueLen);
+ * @brief Used to update characteristics(Read/Write) value that we want to send to particular
+ * client. Both unicast and multicast will use the same api. In mulicast, we will be
+ * sending in loop to all clients.
+ *
+ * @param charValue [IN] Data that we want to send to client(unicast)/clients(multicast)
+ * @param charValueLen [IN] Length of the data.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, const uint32_t charValueLen);
/**
-* @fn CAStartBLEGattClient
-* @brief Used to start CAStartBleGattClientThread for initializing Gatt Client
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Used to start CAStartBleGattClientThread for initializing Gatt Client
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAStartBLEGattClient();
/**
-* @fn CAStopBLEGattClient
-* @brief Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient function.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient
+ * function.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
void CAStopBLEGattClient();
/**
-* @fn CATerminateBLEGattClient
-* @brief Used to unset all the callbacks and stop service discovery
-*
-* @return void
-*/
+ * @brief Used to unset all the callbacks and stop service discovery
+ * @return NONE
+ */
void CATerminateBLEGattClient();
/**
-* @fn CAUpdateCharacteristicsToGattServer
-* @brief Sets the value of characteristic and update the value to GATTServer(unicast).
-*
-* @param[in] remoteAddress The address of the remote device
-* @param[in] data The value of characteristic (byte array)
-* @param[in] dataLen The length of value
-* @param[in] TRANSFER_TYPE (UNICAST/MULTICAST)
-* @param[in] position The unique index of each ble server. Used for multicast feature.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Sets the value of characteristic and update the value to GATTServer(unicast).
+ *
+ * @param remoteAddress [IN] The address of the remote device
+ * @param data [IN] The value of characteristic (byte array)
+ * @param dataLen [IN] The length of value
+ * @param type [IN] Type of the transfer(#TRANSFER_TYPE)
+ * @param position [IN] The unique index of each ble server. Used for multicast feature.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data,
- const int32_t dataLen, TRANSFER_TYPE type, const int32_t position);
+ const int32_t dataLen, TRANSFER_TYPE type,
+ const int32_t position);
/**
- * @fn CAUpdateCharacteristicsToAllGattServers
- * @brief Sets the value of characteristic and update the value to All registered GATTServer -> Multicast
+ * @brief Sets the value of characteristic and update the value to all registered
+ * GATTServer -> Multicast
+ * @param data [IN] The value of characteristic (byte array)
+ * @param dataLen [IN] The length of value
*
- * @param[in] data The value of characteristic (byte array)
- * @param[in] dataLen The length of value
- *
- * @return 0 on success otherwise a positive error value.
- * @retval CA_STATUS_OK Successful
- * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval CA_STATUS_FAILED Operation failed
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
*/
-CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data,
- const int32_t dataLen);
+CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, const int32_t dataLen);
/**
- * @fn CASetBLEReqRespClientCallback
- * @brief used to store upper layer callback locally which will be used to send the data to application
- *
- * @param[in] CANetworkPacketReceivedCallback - upper layer callback function to pass the data to CA layer.
+ * @brief Used to store upper layer callback locally which will be used to send the data to
+ * application
+ * @param callback [IN] Callback function to pass the data to CA layer.
*
* @return void
*/
void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback);
+/**
+ * @brief Used to Set the gThreadPool handle which is required for spawning new thread.
+ *
+ * @param handle [IN] Thread pool handle which is given by above layer for using thread
+ * creation task.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+void CASetBleServerThreadPoolHandle(u_thread_pool_t handle);
+
+/**
+* @brief Used to Set the gThreadPool handle which is required for spawning new thread.
+* @param handle [IN] Thread pool handle which is given by above layer for using thread creation
+* task.
+* @return NONE
+*/
+void CASetBleClientThreadPoolHandle(u_thread_pool_t handle);
+
+/**
+ * @brief Used to unset the callback of adapter connection state change.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAUnSetLEAdapterStateChangedCb();
#ifdef __cplusplus
}
#endif
#include <stdbool.h>
#include "cacommon.h"
-
+#include "caleadapter_singlethread.h"
#ifdef __cplusplus
extern "C"
#endif
/**
- * @ENUM TRANSFER_TYPE
- * @brief Provide info about different mode of data transfer
- *
- * This enum is used to differentiate between unicast and multicast data transfer.
+ * @enum TRANSFER_TYPE
+ * @brief Provide information about different mode of data transfer
+ * This enum is used to differentiate between unicast and multicast data transfer.
*/
typedef enum
{
MULTICAST, /**< When this enum is selected, data will be updated to all OIC servers. */
- UNICAST /**< When this enum is selected, data will be updated to desired OIC Server. */
+ UNICAST /**< When this enum is selected, data will be updated to desired OIC Server. */
} TRANSFER_TYPE;
+
/**
-* @fn CAStartBleGattServer
-* @brief Used to start Gatt Server thread for service creation and advertise ble service.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Used to get the current state of the LE adapter.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_ADAPTER_NOT_ENABLED adapter not enabled
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAGetLEAdapterState();
+
+/**
+ * @brief Used to initialize the network monitor layer of the LE adapter.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CALEInitializeNetworkMonitor();
+
+/**
+ * @brief Used to terminate the network monitor layer of the LE adapter.
+ * @return NONE
+ */
+void CALETerminateNetworkMonitor();
+
+/**
+ * @brief This function is used to set the callback for the Device state changes in the adapter.
+ *
+ * @param callback [IN] Callback to notify the Device state change to the CA Layer
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback);
+
+/**
+ * @brief Provides the BD address of the local adapter.
+ * @param local_address [IN] pointer to the location where bd address needs to be stored.
+ *
+ * @return NONE
+ */
+void CAGetLEAddress(char **local_address);
+
+/**
+ * @brief Used to start Gatt Server thread for service creation and advertise ble service.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAStartBleGattServer();
/**
-* @fn CAStopBleGattServer
-* @brief Used to terminate BLE Gatt Service.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Used to stop BLE Gatt Service.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAStopBleGattServer();
/**
-* @fn CASetBLEReqRespServerCallback
-* @brief used to store upper layer callback locally which will be used to send the data
-* to application
-* @param[in] CANetworkPacketReceivedCallback - upper layer callback function
-* to pass the data to CA layer.
-* @return void
-*/
+ * @brief Used to store upper layer callback locally which will be used to send the data to
+ * application
+ * @param callback [IN] Callback function to pass the data to CA layer.
+ * @return NONE
+ */
void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback);
/**
-* @fn CAUpdateCharacteristicsInGattServer
-* @brief Used to update characteristics(Read/Write) value that we want to send to particular client.
-* Both unicast and multicast will use the same api. In mulicast, we will be sending in loop to all clients.
-*
-* @param[in] charValue - data that we want to send to client(unicast)/clients(multicast)
-* @param[in] charValueLen - length of the data.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
-CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, const uint32_t charValueLen);
+ * @brief Used to update characteristics(Read/Write) value that we want to send to particular
+ * client. Both unicast and multicast will use the same api. In mulicast, we will be
+ * sending in loop to all clients.
+ *
+ * @param charValue [IN] Data that we want to send to client(unicast)/clients(multicast)
+ * @param charValueLen [IN] Length of the data.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue,
+ const uint32_t charValueLen);
/**
-* @fn CAStartBLEGattClient
-* @brief Used to start CAStartBleGattClientThread for initializing Gatt Client
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Used to start CAStartBleGattClientThread for initializing Gatt Client
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAStartBLEGattClient();
/**
-* @fn CAStopBLEGattClient
-* @brief Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient function.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient
+ * function.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
void CAStopBLEGattClient();
/**
-* @fn CATerminateBLEGattClient
-* @brief Used to unset all the callbacks and stop service discovery
-*
-* @return void
-*/
+ * @brief Used to unset all the callbacks and stop service discovery
+ * @return NONE
+ */
void CATerminateBLEGattClient();
/**
-* @fn CAUpdateCharacteristicsToGattServer
-* @brief Sets the value of characteristic and update the value to GATTServer(unicast).
-*
-* @param[in] remoteAddress The address of the remote device
-* @param[in] data The value of characteristic (byte array)
-* @param[in] dataLen The length of value
-* @param[in] TRANSFER_TYPE (UNICAST/MULTICAST)
-* @param[in] position The unique index of each ble server. Used for multicast feature.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
+ * @brief Sets the value of characteristic and update the value to GATTServer(unicast).
+ *
+ * @param remoteAddress [IN] The address of the remote device
+ * @param data [IN] The value of characteristic (byte array)
+ * @param dataLen [IN] The length of value
+ * @param type [IN] Type of the transfer(#TRANSFER_TYPE)
+ * @param position [IN] The unique index of each ble server. Used for multicast feature.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data,
- const int32_t dataLen, TRANSFER_TYPE type, const int32_t position);
+ const int32_t dataLen, TRANSFER_TYPE type,
+ const int32_t position);
/**
- * @fn CAUpdateCharacteristicsToAllGattServers
- * @brief Sets the value of characteristic and update the value to All registered GATTServer -> Multicast
- *
- * @param[in] data The value of characteristic (byte array)
- * @param[in] dataLen The length of value
+ * @brief Sets the value of characteristic and update the value to all registered
+ * GATTServer -> Multicast
+ * @param data [IN] The value of characteristic (byte array)
+ * @param dataLen [IN] The length of value
*
- * @return 0 on success otherwise a positive error value.
- * @retval CA_STATUS_OK Successful
- * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval CA_STATUS_FAILED Operation failed
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
*/
-CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, const int32_t dataLen);
+CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data,
+ const int32_t dataLen);
/**
- * @fn CASetBLEReqRespClientCallback
- * @brief used to store upper layer callback locally which will be used to send the data to application
- *
- * @param[in] CANetworkPacketReceivedCallback - upper layer callback function to pass the data to CA layer.
+ * @brief Used to store upper layer callback locally which will be used to send the data to
+ * application
+ * @param callback [IN] Callback function to pass the data to CA layer.
*
* @return void
*/
void CALeServerCreateJniInterfaceObject();
-void LEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback);
+void CANativeLEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback);
-void LEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback);
+void CANativeLEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback);
-jobject CALEServerOpenGattServer(JNIEnv *env);
+jobject CANativeLEServerOpenGattServer(JNIEnv *env);
-jobject CALEServerCreateGattService(JNIEnv *env);
+jobject CANativeLEServerCreateGattService(JNIEnv *env);
-jboolean CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
+jboolean CANativeLEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
jobject bluetoothGattService);
jboolean CALEStartGattServer(JNIEnv *env, jobject gattServerCallback);
jboolean CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jstring data);
-jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData);
+jobject CANativeLEServerSetResponseData(JNIEnv *env, jbyteArray responseData);
-jboolean CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData);
+jboolean CANativeLEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData);
-jboolean CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
+jboolean CANativeLEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
jint offset, jbyteArray value);
-jboolean CALEServerConnect(JNIEnv *env, jobject bluetoothDevice);
+jboolean CANativeLEServerConnect(JNIEnv *env, jobject bluetoothDevice);
-void CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice);
+void CANativeLEServerDisconnect(JNIEnv *env, jobject bluetoothDevice);
/* BLE Server Utils */
void CALEServerCreateCachedDeviceList();
void CALEServerRemoveDevice(JNIEnv *env, jstring address);
-//void CALEServerReorderinglist(uint32_t index);
+void CALEServerReorderinglist(uint32_t index);
#ifdef __cplusplus
} /* extern "C" */
jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid);
-jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice);
+jstring CALEGetLocalDeviceAddress(JNIEnv *env);
+
+jobjectArray CALEGetBondedDevices(JNIEnv *env);
+
+jint CALEGetBTStateOnInfo(JNIEnv *env);
-jstring CALEGetLocalDeviceAddress(JNIEnv* env);
+jboolean CALEIsEnableBTAdapter(JNIEnv *env);
+
+jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice);
#ifdef __cplusplus
} /* extern "C" */
# Note for Arduino: The CC flag is set to the C++ compiler since Arduino build
# includes Time.h header file which has C++ style definitions.
ifeq ($(PLATFORM),arduinomega)
- include $(ROOT_DIR)/local.properties
- include $(ROOT_DIR)/$(PLATFORM).properties
+ include $(ROOT_DIR)/arduino/local.properties
+ include $(ROOT_DIR)/arduino/$(PLATFORM).properties
CC=$(ARDUINO_TOOLS_DIR)/avr-gcc
else ifeq ($(PLATFORM),arduinodue)
include $(ROOT_DIR)/local.properties
<application
android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
+#include <string.h>
#include <../../../../api/cainterface.h>
#include <../../../../api/cacommon.h>
void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo);
void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo);
+void send_response(const CARemoteEndpoint_t* endpoint, CAToken_t request_token);
void get_resource_uri(char *URI, char *resourceURI, int length);
int get_secure_information(CAPayload_t payLoad);
CAResult_t get_network_type(int selectedNetwork);
+void callback(char *subject, char *receicedData);
CAConnectivityType_t gSelectedNwType;
static CAToken_t gLastRequestToken = NULL;
static const char *gNormalInfoData = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
"\"if\":[\"oc.mi.def\"],\"obs\":1}}]}";
-static CADtlsPskCredsBlob_t *pskCredsBlob = NULL;
+static jobject gResponseListenerObject = NULL;
+extern JavaVM *g_jvm;
+// init
+JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj, jobject listener){
+ LOGI("setNativeResponseListener");
+ gResponseListenerObject = (*env)->NewGlobalRef(env, obj);
+}
+
+#ifdef __WITH_DTLS__
+static OCDtlsPskCredsBlob *pskCredsBlob = NULL;
void clearDtlsCredentialInfo()
{
if (pskCredsBlob)
{
// Initialize sensitive data to zeroes before freeing.
- memset(pskCredsBlob->creds, 0, sizeof(CADtlsPskCreds_t)*(pskCredsBlob->num));
+ memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCredsBlob)*(pskCredsBlob->num));
free(pskCredsBlob->creds);
- memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t));
+ memset(pskCredsBlob, 0, sizeof(OCDtlsPskCredsBlob));
free(pskCredsBlob);
pskCredsBlob = NULL;
}
}
// Internal API. Invoked by OC stack to retrieve credentials from this module
-void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
+void CAGetDtlsPskCredentials(OCDtlsPskCredsBlob **credInfo)
{
printf("CAGetDtlsPskCredentials IN\n");
int32_t SetCredentials()
{
printf("SetCredentials IN\n");
- pskCredsBlob = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t));
+ pskCredsBlob = (OCDtlsPskCredsBlob *)malloc(sizeof(OCDtlsPskCredsBlob));
- memset(pskCredsBlob, 0x0, sizeof(CADtlsPskCredsBlob_t));
+ memset(pskCredsBlob, 0x0, sizeof(OCDtlsPskCredsBlob));
memcpy(pskCredsBlob->rsIdentity, IDENTITY, DTLS_PSK_ID_LEN);
pskCredsBlob->num = 1;
- pskCredsBlob->creds = (CADtlsPskCreds_t *)malloc(sizeof(CADtlsPskCreds_t) *(pskCredsBlob->num));
+ pskCredsBlob->creds = (OCDtlsPskCredsBlob *)malloc(sizeof(OCDtlsPskCredsBlob) *(pskCredsBlob->num));
memcpy(pskCredsBlob->creds[0].clientIdentity, IDENTITY, DTLS_PSK_ID_LEN);
memcpy(pskCredsBlob->creds[0].rsClientPsk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
printf("SetCredentials OUT\n");
return 1;
}
-
+#endif
JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMInitialize
(JNIEnv *env, jobject obj, jobject context)
CALEClientJNISetContext(env, context);
CALENetworkMonitorJNISetContext(env, context);
+ CAResult_t res;
+
+#ifdef __WITH_DTLS__
if (SetCredentials() == 0)
{
printf("SetCredentials failed\n");
}
+ res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
+ if(res != CA_STATUS_OK)
+ {
+ printf("Set credential handler fail\n");
+ }
+#endif
+
if(CA_STATUS_OK != CAInitialize())
{
LOGI("Could not Initialize");
{
LOGI("RMRegisterHandler");
- if (CA_STATUS_OK != CARegisterHandler(request_handler, response_handler))
- {
- LOGI("Could not register handler");
- }
+ CARegisterHandler(request_handler, response_handler);
}
JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMFindResource(JNIEnv *env, jobject obj,
LOGI("generated token %s\n", (token != NULL) ? token : "");
- if(CA_STATUS_OK != CAFindResource(strUri, token))
+ if(CA_STATUS_OK != CAFindResource((const CAURI_t)strUri, token))
{
LOGI("Could not find resource");
}
}
JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj,
- jstring uri, jint selectedNetwork, jint isSecured, jint msgType)
+ jstring uri, jstring payload, jint selectedNetwork, jint isSecured, jint msgType)
{
const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
LOGI("RMSendRequest - %s", strUri);
//create remote endpoint
CARemoteEndpoint_t* endpoint = NULL;
- if(CA_STATUS_OK != CACreateRemoteEndpoint(strUri, gSelectedNwType, &endpoint))
+ if(CA_STATUS_OK != CACreateRemoteEndpoint((const CAURI_t)strUri, gSelectedNwType, &endpoint))
{
LOGI("Could not create remote end point");
CADestroyRemoteEndpoint(endpoint);
char resourceURI[15] = {0};
- get_resource_uri(strUri, resourceURI, 14);
+ get_resource_uri((const CAURI_t)strUri, resourceURI, 14);
CAInfo_t requestData;
memset(&requestData, 0, sizeof(CAInfo_t));
requestData.token = token;
-
+ const char* strPayload = (*env)->GetStringUTFChars(env, payload, NULL);
if (isSecured == 1)
{
int length = strlen(gSecureInfoData) + strlen(resourceURI) + 1;
}
else
{
- int length = strlen(gNormalInfoData) + strlen(resourceURI) + 1;
+ int length = strlen(strPayload) + strlen(resourceURI) + 1;
requestData.payload = (CAPayload_t) malloc(length);
- sprintf(requestData.payload, gNormalInfoData, resourceURI);
+ sprintf(requestData.payload, strPayload, resourceURI);
}
requestData.type = messageType;
}
}
-JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env,
- jobject obj, jstring uri, jint selectedNetwork)
+JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendResponse(JNIEnv *env,
+ jobject obj, jstring uri, jstring payload, jint selectedNetwork, jint isSecured)
{
- jint isSecured = 0;
+ LOGI("RMSendResponse");
const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
LOGI("RMSendResponse - %s", strUri);
res = get_network_type(selectedNetwork);
if (res != CA_STATUS_OK)
{
- LOGI("Not supported network type");
+ LOGI("Not supported network type");
return;
}
//create remote endpoint
CARemoteEndpoint_t* endpoint = NULL;
- if(CA_STATUS_OK != CACreateRemoteEndpoint(strUri, gSelectedNwType, &endpoint))
+ if(CA_STATUS_OK != CACreateRemoteEndpoint((const CAURI_t)strUri, gSelectedNwType, &endpoint))
{
LOGI("Could not create remote end point");
CADestroyRemoteEndpoint(endpoint);
char resourceURI[15] = {0};
- get_resource_uri(strUri, resourceURI, 14);
+ get_resource_uri((const CAURI_t)strUri, resourceURI, 14);
CAInfo_t responseData;
memset(&responseData, 0, sizeof(CAInfo_t));
responseData.token = token;
-
+ const char* strPayload = (*env)->GetStringUTFChars(env, payload, NULL);
if (isSecured == 1)
{
int length = strlen(gSecureInfoData) + strlen(resourceURI) + 1;
}
else
{
- int length = strlen(gNormalInfoData) + strlen(resourceURI) + 1;
+ int length = strlen(strPayload) + strlen(resourceURI) + 1;
responseData.payload = (CAPayload_t) malloc(length);
- sprintf(responseData.payload, gNormalInfoData, resourceURI);
+ sprintf(responseData.payload, strPayload, resourceURI);
}
responseData.type = messageType;
{
CADestroyRemoteEndpoint(endpoint);
}
+
+}
+
+JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMAdvertiseResource(JNIEnv *env,
+ jobject obj, jstring uri, jint selectedNetwork)
+{
+ LOGI("RMAdvertiseResource");
+
+ const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
+
+ int optionNum = 2;
+
+ CAHeaderOption_t *headerOpt;
+ headerOpt = (CAHeaderOption_t*) malloc(sizeof(CAHeaderOption_t) * optionNum);
+ if (NULL == headerOpt)
+ {
+ printf("Memory allocation failed!\n");
+ return;
+ }
+ memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum);
+
+ char* tmpOptionData1 = "Hello";
+ headerOpt[0].optionID = 3000;
+ memcpy(headerOpt[0].optionData, tmpOptionData1, strlen(tmpOptionData1));
+ headerOpt[0].optionLength = (uint16_t) strlen(tmpOptionData1);
+
+ char* tmpOptionData2 = "World";
+ headerOpt[1].optionID = 3001;
+ memcpy(headerOpt[1].optionData, tmpOptionData2, strlen(tmpOptionData2));
+ headerOpt[1].optionLength = (uint16_t) strlen(tmpOptionData2);
+
+ // create token
+ CAToken_t token = NULL;
+ CAResult_t res = CAGenerateToken(&token);
+ if (res != CA_STATUS_OK)
+ {
+ LOGI("token generate error!");
+ token = NULL;
+ }
+
+ CAAdvertiseResource((const CAURI_t)strUri, token, headerOpt, (uint8_t) optionNum);
+
+ free(headerOpt);
+}
+
+JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env,
+ jobject obj, jstring uri, jstring payload, jint selectedNetwork, jint isSecured)
+{
+ const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
+ LOGI("RMSendNotification - %s", strUri);
+
+ CAResult_t res;
+
+ LOGI("selectedNetwork - %d", selectedNetwork);
+
+ res = get_network_type(selectedNetwork);
+ if (res != CA_STATUS_OK)
+ {
+ LOGI("Not supported network type");
+ return;
+ }
+
+ //create remote endpoint
+ CARemoteEndpoint_t* endpoint = NULL;
+
+ if(CA_STATUS_OK != CACreateRemoteEndpoint((const CAURI_t)strUri, gSelectedNwType, &endpoint))
+ {
+ LOGI("Could not create remote end point");
+ CADestroyRemoteEndpoint(endpoint);
+ return;
+ }
+
+ CAMessageType_t messageType = CA_MSG_NONCONFIRM;
+
+ // create token
+ CAToken_t token = NULL;
+ res = CAGenerateToken(&token);
+ if (res != CA_STATUS_OK)
+ {
+ LOGI("token generate error!");
+ token = NULL;
+ }
+
+ char resourceURI[15] = {0};
+
+ get_resource_uri((const CAURI_t)strUri, resourceURI, 14);
+
+ CAInfo_t responseData;
+ memset(&responseData, 0, sizeof(CAInfo_t));
+ responseData.token = token;
+
+ const char* strPayload = (*env)->GetStringUTFChars(env, payload, NULL);
+ if (isSecured == 1)
+ {
+ int length = strlen(gSecureInfoData) + strlen(resourceURI) + 1;
+ responseData.payload = (CAPayload_t) malloc(length);
+ sprintf(responseData.payload, gSecureInfoData, resourceURI, gLocalSecurePort);
+ }
+ else
+ {
+ int length = strlen(strPayload) + strlen(resourceURI) + 1;
+ responseData.payload = (CAPayload_t) malloc(length);
+ sprintf(responseData.payload, strPayload, resourceURI);
+ }
+
+ responseData.type = messageType;
+
+ CAResponseInfo_t responseInfo;
+ memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
+ responseInfo.result = CA_SUCCESS;
+ responseInfo.info = responseData;
+
+ // send request
+ if(CA_STATUS_OK != CASendNotification(endpoint, &responseInfo))
+ {
+ LOGI("Could not send notification");
+ }
+
+ LOGI("Send Notification");
+
+ // destroy token
+ if (token != NULL)
+ {
+ CADestroyToken(token);
+ }
+
+ // destroy remote endpoint
+ if (endpoint != NULL)
+ {
+ CADestroyRemoteEndpoint(endpoint);
+ }
}
JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
LOGI("##########received request from remote device #############\n");
LOGI("Uri: %s\n", object->resourceUri);
- LOGI("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
- object->addressInfo.IP.port, object->isSecured);
+ LOGI("Remote Address: %s\n", object->addressInfo.IP.ipAddress);
LOGI("Data: %s\n", requestInfo->info.payload);
+ if (NULL != gResponseListenerObject)
+ {
+ callback("received request from remote device", "#######");
+ callback("Uri: ", object->resourceUri);
+
+ callback("Remote Address: ", (char *) object->addressInfo.IP.ipAddress);
+
+ if(requestInfo->info.payload)
+ {
+ callback("Data: ", requestInfo->info.payload);
+ }
+ }
+
if (gLastRequestToken != NULL && requestInfo->info.token != NULL
&& (strcmp((char *)gLastRequestToken, requestInfo->info.token) == 0))
{
LOGI("ID : %d\n", requestInfo->info.options[i].optionID);
LOGI("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
requestInfo->info.options[i].optionData);
+
+ if (NULL != gResponseListenerObject)
+ {
+ char tmpbuf[30];
+ sprintf(tmpbuf, "%d", i + 1);
+ callback("Option: ", tmpbuf);
+
+ sprintf(tmpbuf, "%d", requestInfo->info.options[i].optionID);
+ callback("ID: ", tmpbuf);
+
+ sprintf(tmpbuf, "Data:[%d]", requestInfo->info.options[i].optionLength);
+ callback("tmpbuf: ", requestInfo->info.options[i].optionData);
+ }
}
}
printf("############################################################\n");
gReceived = 1;
+ // response
+// send_response(object, (requestInfo != NULL) ? requestInfo->info.token : "");
+
}
void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo)
LOGI("##########Received response from remote device #############\n");
LOGI("Uri: %s\n", object->resourceUri);
- LOGI("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
- object->addressInfo.IP.port, object->isSecured);
- LOGI("response result : %d\n", responseInfo->result);
+ LOGI("Remote Address: %s\n", object->addressInfo.IP.ipAddress);
+ LOGI("response result: %d\n", responseInfo->result);
LOGI("Data: %s\n", responseInfo->info.payload);
+ if (NULL != gResponseListenerObject)
+ {
+ callback("received response from remote device", "#######");
+ callback("Uri: ", object->resourceUri);
+
+ callback("Remote Address: ", (char *)object->addressInfo.IP.ipAddress);
+
+ if(responseInfo->info.payload)
+ {
+ callback("Data: ", responseInfo->info.payload);
+ }
+ }
+
if (responseInfo->info.options)
{
uint32_t len = responseInfo->info.numOptions;
LOGI("ID : %d\n", responseInfo->info.options[i].optionID);
LOGI("Data[%d]: %s\n", responseInfo->info.options[i].optionLength,
responseInfo->info.options[i].optionData);
+
+ if (NULL != gResponseListenerObject)
+ {
+ char tmpbuf[30];
+ sprintf(tmpbuf, "%d", i + 1);
+ callback("Option: ", tmpbuf);
+
+ sprintf(tmpbuf, "%d", responseInfo->info.options[i].optionID);
+ callback("ID: ", tmpbuf);
+
+ sprintf(tmpbuf, "Data:[%d]", responseInfo->info.options[i].optionLength);
+ callback("tmpbuf: ", responseInfo->info.options[i].optionData);
+ }
}
}
LOGI("############################################################\n");
}
}
+void send_response(const CARemoteEndpoint_t* endpoint, CAToken_t request_token)
+{
+ LOGI("send_response");
+
+ CAInfo_t responseData;
+ memset(&responseData, 0, sizeof(CAInfo_t));
+ responseData.token = request_token;
+ responseData.payload = "response payload";
+
+ CAResponseInfo_t responseInfo;
+ memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
+ responseInfo.result = 203;
+ responseInfo.info = responseData;
+
+ // send request
+ CASendResponse(endpoint, &responseInfo);
+}
+
void get_resource_uri(char *URI, char *resourceURI, int length)
{
char *startPos = URI;
return CA_NOT_SUPPORTED;
}
+
+void callback(char *subject, char *receicedData)
+{
+ JNIEnv* env = NULL;
+ int status = (*g_jvm)->GetEnv(g_jvm, (void **) &env, JNI_VERSION_1_6);
+ int res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+ jclass cls = (*env)->GetObjectClass(env, gResponseListenerObject);
+ jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived", "(Ljava/lang/String;Ljava/lang/String;)V");
+
+ jstring jsubject = (*env)->NewStringUTF(env, (char*)subject);
+ jstring jreceivedData = (*env)->NewStringUTF(env, (char*)receicedData);
+ (*env)->CallVoidMethod(env, gResponseListenerObject, mid, jsubject, jreceivedData);
+}
* Method: RMInitialize
* Signature: (Landroid/content/Context;)I
*/
+JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_setNativeResponseListener
+ (JNIEnv *, jobject, jobject);
+
JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMInitialize
(JNIEnv *, jobject, jobject);
/*
* Class: com_iotivity_service_RMInterface
* Method: RMSendRequest
- * Signature: (Ljava/lang/String;)V
+ * Signature: (Ljava/lang/String;III)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendRequest
- (JNIEnv *, jobject, jstring, jint, jint, jint);
+ (JNIEnv *, jobject, jstring, jstring, jint, jint, jint);
+
+/*
+ * Class: com_iotivity_service_RMInterface
+ * Method: RMSendResponse
+ * Signature: (Ljava/lang/String;III)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendResponse
+ (JNIEnv *, jobject, jstring, jstring, jint, jint);
+
+/*
+ * Class: com_iotivity_service_RMInterface
+ * Method: RMAdvertiseResource
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMAdvertiseResource
+ (JNIEnv *, jobject, jstring, jint);
/*
* Class: com_iotivity_service_RMInterface
* Method: RMSendNotification
- * Signature: (Ljava/lang/String;)V
+ * Signature: (Ljava/lang/String;I)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendNotification
- (JNIEnv *, jobject, jstring, jint);
+ (JNIEnv *, jobject, jstring, jstring, jint, jint);
/*
* Class: com_iotivity_service_RMInterface
</RelativeLayout>
<RelativeLayout
- android:id="@+id/layout_find"
+ android:id="@+id/layout_find_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/layout_mode" >
+
+ <TextView
+ android:id="@+id/tv_find"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="[Find Resource]"
+ />
+
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/layout_find"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/layout_find_title" >
<Button
android:id="@+id/btn_find_resource"
</RelativeLayout>
<RelativeLayout
- android:id="@+id/layout_notify"
+ android:id="@+id/layout_Response_Noti_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/layout_mode" >
+
+ <TextView
+ android:id="@+id/tv_Response_Noti"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="[Send Response / Send Notification]"
+ />
+
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/layout_request_setting_for_server"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/layout_Response_Noti_title" >
+
+ <Button
+ android:id="@+id/btn_Request_setting_for_server"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text="@string/request_setting" />
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/layout_notify"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/layout_request_setting_for_server" >
+
+ <EditText
+ android:id="@+id/et_notification"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text="@string/notification" />
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/layout_payload_server_ed"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/layout_notify" >
+
+ <EditText
+ android:id="@+id/et_payload_data_for_server"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:text="@string/payload_data_server" />
+
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/layout_server_bt"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/layout_payload_server_ed" >
+
<Button
android:id="@+id/btn_notify"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="@string/notify" />
+
+ <Button
+ android:id="@+id/btn_sendresponse"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_toLeftOf="@id/btn_notify"
+ android:text="@string/sendresponse" />
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/layout_advertise_title"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/layout_server_bt" >
+
+ <TextView
+ android:id="@+id/tv_advertise"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="[Advertise Resource]"
+ />
+
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/layout_advertise_resource"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/layout_advertise_title" >
+ <Button
+ android:id="@+id/btn_advertise"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text="@string/advertise" />
+
<EditText
- android:id="@+id/et_notification"
+ android:id="@+id/et_uri_advertise"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toLeftOf="@id/btn_notify"
- android:text="@string/notification" />
+ android:layout_toLeftOf="@id/btn_advertise"
+ android:text="@string/uri" />
</RelativeLayout>
- <RelativeLayout
- android:id="@+id/layout_request_setting"
+ <RelativeLayout
+ android:id="@+id/layout_request_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/layout_find" >
-
+
+ <TextView
+ android:id="@+id/tv_request"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="[Send Request]"
+ />
+
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/layout_request_setting_for_client"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/layout_request_title" >
+
<Button
- android:id="@+id/btn_Request_setting"
+ android:id="@+id/btn_Request_setting_for_client"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="@+id/layout_request"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/layout_request_setting" >
+ android:layout_below="@id/layout_request_setting_for_client" >
<Button
android:id="@+id/btn_Request"
android:layout_toLeftOf="@id/btn_Request"
android:text="@string/req_data" />
</RelativeLayout>
-
+
<RelativeLayout
- android:id="@+id/layout_response"
+ android:id="@+id/layout_payload_client_ed"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/layout_notify" >
-
- <Button
- android:id="@+id/btn_Response"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:text="@string/response" />
-
+ android:layout_below="@id/layout_request" >
+
<EditText
- android:id="@+id/et_resp_data"
+ android:id="@+id/et_payload_data"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
- android:layout_toLeftOf="@id/btn_Response"
- android:text="@string/resp_data" />
+ android:text="@string/payload_data_client" />
+
</RelativeLayout>
<RelativeLayout
+ android:id="@+id/layout_handle_title"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/layout_advertise_resource" >
+
+ <TextView
+ android:id="@+id/tv_handle"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="[Handle Reqeust/Response data]"
+ />
+
+ </RelativeLayout>
+
+ <RelativeLayout
android:id="@+id/layout_receive"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/layout_request" >
+ android:layout_below="@id/layout_handle_title" >
<Button
android:id="@+id/btn_receive"
android:layout_height="wrap_content" />
</ScrollView>
-</RelativeLayout>
+</RelativeLayout>
\ No newline at end of file
<resources>
<string name="app_name">sample_service</string>
<string name="find">Find</string>
- <string name="notify">send</string>
+ <string name="sendresponse">Send Response</string>
+ <string name="notify">Send Notification</string>
+ <string name="advertise">Advertise</string>
<string name="request_setting">Request Setting</string>
<string name="request">Request</string>
<string name="response">Response</string>
- <string name="uri">a/light</string>
+ <string name="uri">/a/light</string>
<string name="notification">coap://D8:07:62:33:CE:11/a/bulb</string>
<string name="req_data">coap://FC:88:0D:47:0C:0F/b/light</string>
<string name="resp_data">resourceUri/response</string>
<string name="receive">Receive</string>
<string name="received">Received Message</string>
<string name="action_settings">Settings</string>
-</resources>
+ <string name="payload_data_client">PayloadData</string>
+ <string name="payload_data_server">PayloadData</string>
+
+</resources>
\ No newline at end of file
--- /dev/null
+
+package com.iotivity.service;
+
+import android.os.Handler;
+import android.widget.TextView;
+
+public final class DLog {
+
+ private final static String MAIN_TAG = "Sample_Service";
+
+ private static TextView mLogView = null;
+
+ private static Handler mHandler = null;
+
+ public static void setTextView(Handler handler, TextView logView) {
+ mHandler = handler;
+ mLogView = logView;
+ }
+
+ private static void addLogText(final String msg) {
+
+ mHandler.post(new Runnable() {
+
+ @Override
+ public void run() {
+
+ if (mLogView == null)
+ return;
+
+ StringBuilder builder = new StringBuilder(mLogView.getText());
+ // add front
+ builder.append(msg + "\n");
+
+ mLogView.setText(builder.toString());
+ }
+
+ });
+
+ }
+
+ public static final void v(String className, String msg) {
+ android.util.Log.v(MAIN_TAG, className + "." + msg);
+
+ if (mLogView != null) {
+ addLogText(msg);
+ }
+ }
+
+ public static final void d(String className, String msg) {
+ android.util.Log.d(MAIN_TAG, className + "." + msg);
+
+ if (mLogView != null) {
+ addLogText(msg);
+ }
+ }
+
+ public static final void i(String className, String msg) {
+ android.util.Log.i(MAIN_TAG, className + "." + msg);
+
+ if (mLogView != null) {
+ addLogText(msg);
+ }
+ }
+
+ public static final void w(String className, String msg) {
+ android.util.Log.w(MAIN_TAG, className + "." + msg);
+
+ if (mLogView != null) {
+ addLogText(msg);
+ }
+ }
+
+ public static final void w(String className, String msg, Exception ex) {
+ android.util.Log.w(MAIN_TAG, className + "." + msg + ":" + ex.getMessage());
+
+ if (mLogView != null) {
+ addLogText(msg);
+ }
+ }
+
+ public static final void w(String className, String msg, Error e) {
+ android.util.Log.w(MAIN_TAG, className + "." + msg + ":" + e.getMessage());
+
+ if (mLogView != null) {
+ addLogText(msg);
+ }
+ }
+
+}
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
+import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
static RMInterface RM = new RMInterface();
+ private final static String TAG = "MainActivity";
+
private final CharSequence[] mCheckBoxItems = { Network.WIFI.name(),
- Network.LE.name() };
+ Network.EDR.name(), Network.LE.name() };
private final CharSequence[] mDTLSCheckBoxItems = { DTLS.SECURED.name(),
DTLS.UNSECURED.name() };
};
private enum Network {
- WIFI, LE
+ WIFI, EDR, LE
};
private enum DTLS {
private ArrayList<Integer> mSelectedItems = new ArrayList<Integer>();
- private ArrayList<Integer> mSRSelectedItems = new ArrayList<Integer>();
-
- private boolean mCheckedItems[] = { false, false };
-
private RelativeLayout mFindResourceLayout = null;
private RelativeLayout mSendNotificationLayout = null;
private RelativeLayout mSendRequestLayout = null;
-
+
private RelativeLayout mSendRequestSettingLayout = null;
- private RelativeLayout mSendResponseLayout = null;
+ private RelativeLayout mSendResponseNotiSettingLayout = null;
private RelativeLayout mReceiveLayout = null;
+ private RelativeLayout mFindTitleLayout = null;
+
+ private RelativeLayout mRequestTitleLayout = null;
+
+ private RelativeLayout mResponseNotificationTitleLayout = null;
+
+ private RelativeLayout mAdvertiseTitleLayout = null;
+
+ private RelativeLayout mHandleTitleLayout = null;
+
+ private RelativeLayout mPayLoadClientEditLayout = null;
+
+ private RelativeLayout mPayLoadServerEditLayout = null;
+
+ private RelativeLayout mAdvertiseResourceLayout = null;
+
+ private RelativeLayout mServerButtonLayout = null;
+
private TextView mMode_tv = null;
private TextView mNetwork_tv = null;
private EditText mReqData_ed = null;
- private EditText mRespData_ed = null;
+ private EditText mPayload_ed = null;
private Button mFind_btn = null;
private Button mNotify_btn = null;
+ private Button mAdvertiseResource_btn = null;
+
private Button mReqeust_btn = null;
-
+
private Button mReqeust_setting_btn = null;
+ private Button mResponse_Notify_setting_btn = null;
+
private Button mResponse_btn = null;
private Button mRecv_btn = null;
+ private Handler mLogHandler = null;
+
/**
* Defined ConnectivityType in cacommon.c
*
* 3)
*/
private int CA_WIFI = (1 << 1);
+ private int CA_EDR = (1 << 2);
private int CA_LE = (1 << 3);
private int isSecured = 0;
private int msgType = 0;
+ private int selectedItem = 0;
int selectedNetwork = 0;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ RM.setResponseListener(this);
+
+ mLogHandler = new Handler();
+ TextView logView = (TextView) findViewById(R.id.tv_result);
+ DLog.setTextView(mLogHandler, logView);
+
// Initialize UI
+ // common
+ mReceiveLayout = (RelativeLayout) findViewById(R.id.layout_receive);
+
+ // client
+ mSendRequestLayout = (RelativeLayout) findViewById(R.id.layout_request);
+ mSendRequestSettingLayout = (RelativeLayout) findViewById(R.id.layout_request_setting_for_client);
mFindResourceLayout = (RelativeLayout) findViewById(R.id.layout_find);
+ mFindTitleLayout = (RelativeLayout) findViewById(R.id.layout_find_title);
+ mRequestTitleLayout = (RelativeLayout) findViewById(R.id.layout_request_title);
+ mHandleTitleLayout = (RelativeLayout) findViewById(R.id.layout_handle_title);
+ mPayLoadClientEditLayout = (RelativeLayout) findViewById(R.id.layout_payload_client_ed);
+
+ // server
mSendNotificationLayout = (RelativeLayout) findViewById(R.id.layout_notify);
- mSendRequestLayout = (RelativeLayout) findViewById(R.id.layout_request);
- mSendRequestSettingLayout = (RelativeLayout) findViewById(R.id.layout_request_setting);
- mSendResponseLayout = (RelativeLayout) findViewById(R.id.layout_response);
- mReceiveLayout = (RelativeLayout) findViewById(R.id.layout_receive);
+ mPayLoadServerEditLayout = (RelativeLayout) findViewById(R.id.layout_payload_server_ed);
+ mSendResponseNotiSettingLayout = (RelativeLayout) findViewById(R.id.layout_request_setting_for_server);
+ mServerButtonLayout = (RelativeLayout) findViewById(R.id.layout_server_bt);
+ mResponseNotificationTitleLayout = (RelativeLayout) findViewById(R.id.layout_Response_Noti_title);
+ mAdvertiseTitleLayout = (RelativeLayout) findViewById(R.id.layout_advertise_title);
+ mAdvertiseResourceLayout = (RelativeLayout) findViewById(R.id.layout_advertise_resource);
mMode_tv = (TextView) findViewById(R.id.tv_mode);
mNetwork_tv = (TextView) findViewById(R.id.tv_network);
mUri_ed = (EditText) findViewById(R.id.et_uri);
mNotification_ed = (EditText) findViewById(R.id.et_notification);
mReqData_ed = (EditText) findViewById(R.id.et_req_data);
- mRespData_ed = (EditText) findViewById(R.id.et_resp_data);
+ mPayload_ed = (EditText) findViewById(R.id.et_payload_data_for_server);
mFind_btn = (Button) findViewById(R.id.btn_find_resource);
+ mResponse_btn = (Button) findViewById(R.id.btn_sendresponse);
mNotify_btn = (Button) findViewById(R.id.btn_notify);
+ mAdvertiseResource_btn = (Button) findViewById(R.id.btn_advertise);
mReqeust_btn = (Button) findViewById(R.id.btn_Request);
- mReqeust_setting_btn = (Button) findViewById(R.id.btn_Request_setting);
- mResponse_btn = (Button) findViewById(R.id.btn_Response);
+ mReqeust_setting_btn = (Button) findViewById(R.id.btn_Request_setting_for_client);
+ mResponse_Notify_setting_btn = (Button) findViewById(R.id.btn_Request_setting_for_server);
mRecv_btn = (Button) findViewById(R.id.btn_receive);
mFind_btn.setOnClickListener(mFindResourceHandler);
+ mResponse_btn.setOnClickListener(mSendResponseHandler);
mNotify_btn.setOnClickListener(mNotifyHandler);
+ mAdvertiseResource_btn.setOnClickListener(mAdvertiseResourceHandler);
mReqeust_btn.setOnClickListener(mSendRequestHandler);
mReqeust_setting_btn.setOnClickListener(mSendRequestSettingHandler);
- mResponse_btn.setOnClickListener(mSendResponseHandler);
+ mResponse_Notify_setting_btn
+ .setOnClickListener(mSendResponseNotiSettingHandler);
mRecv_btn.setOnClickListener(mResponseHandler);
showSelectModeView();
mSendNotificationLayout.setVisibility(View.INVISIBLE);
mSendRequestLayout.setVisibility(View.INVISIBLE);
mSendRequestSettingLayout.setVisibility(View.INVISIBLE);
- mSendResponseLayout.setVisibility(View.INVISIBLE);
mReceiveLayout.setVisibility(View.INVISIBLE);
+ mFindTitleLayout.setVisibility(View.INVISIBLE);
+ mRequestTitleLayout.setVisibility(View.INVISIBLE);
+ mHandleTitleLayout.setVisibility(View.INVISIBLE);
+ mPayLoadClientEditLayout.setVisibility(View.INVISIBLE);
+ mPayLoadServerEditLayout.setVisibility(View.INVISIBLE);
+ mServerButtonLayout.setVisibility(View.INVISIBLE);
+ mResponseNotificationTitleLayout.setVisibility(View.INVISIBLE);
+ mAdvertiseTitleLayout.setVisibility(View.INVISIBLE);
+ mAdvertiseResourceLayout.setVisibility(View.INVISIBLE);
+ mSendResponseNotiSettingLayout.setVisibility(View.INVISIBLE);
mMode_tv.setText("Select Mode (Server or Client)");
}
mSendNotificationLayout.setVisibility(View.VISIBLE);
mSendRequestLayout.setVisibility(View.INVISIBLE);
mSendRequestSettingLayout.setVisibility(View.INVISIBLE);
- mSendResponseLayout.setVisibility(View.INVISIBLE);
mReceiveLayout.setVisibility(View.VISIBLE);
+ mFindTitleLayout.setVisibility(View.INVISIBLE);
+ mRequestTitleLayout.setVisibility(View.INVISIBLE);
+ mHandleTitleLayout.setVisibility(View.VISIBLE);
+ mPayLoadClientEditLayout.setVisibility(View.INVISIBLE);
+
+ mPayLoadServerEditLayout.setVisibility(View.VISIBLE);
+ mServerButtonLayout.setVisibility(View.VISIBLE);
+
+ mResponseNotificationTitleLayout.setVisibility(View.VISIBLE);
+ mAdvertiseTitleLayout.setVisibility(View.VISIBLE);
+ mAdvertiseResourceLayout.setVisibility(View.VISIBLE);
+
+ mSendResponseNotiSettingLayout.setVisibility(View.VISIBLE);
+
mNetwork_tv.setText("");
} else if (mCurrentMode == Mode.CLIENT) {
mSendNotificationLayout.setVisibility(View.INVISIBLE);
mSendRequestLayout.setVisibility(View.VISIBLE);
mSendRequestSettingLayout.setVisibility(View.VISIBLE);
- mSendResponseLayout.setVisibility(View.INVISIBLE);
mReceiveLayout.setVisibility(View.VISIBLE);
+ mFindTitleLayout.setVisibility(View.VISIBLE);
+ mRequestTitleLayout.setVisibility(View.VISIBLE);
+ mHandleTitleLayout.setVisibility(View.VISIBLE);
+ mPayLoadClientEditLayout.setVisibility(View.VISIBLE);
+
+ mPayLoadServerEditLayout.setVisibility(View.INVISIBLE);
+ mServerButtonLayout.setVisibility(View.INVISIBLE);
+
+ mResponseNotificationTitleLayout.setVisibility(View.INVISIBLE);
+ mAdvertiseTitleLayout.setVisibility(View.INVISIBLE);
+ mAdvertiseResourceLayout.setVisibility(View.INVISIBLE);
+
+ mSendResponseNotiSettingLayout.setVisibility(View.INVISIBLE);
+
mNetwork_tv.setText("");
}
}
// Terminate Connectivity Abstraction
RM.RMTerminate();
+ android.os.Process.killProcess(android.os.Process.myPid());
}
@Override
RM.RMStartListeningServer();
- if (mCurrentMode == Mode.UNKNOWN || mSelectedItems.size() == 0) {
+ if (mSelectedItems.size() == 0) {
mCurrentMode = Mode.SERVER;
mMode_tv.setText("MODE: " + mCurrentMode.toString());
showNetworkView();
RM.RMStartDiscoveryServer();
- if (mCurrentMode == Mode.UNKNOWN || mSelectedItems.size() == 0) {
+ if (mSelectedItems.size() == 0) {
mCurrentMode = Mode.CLIENT;
mMode_tv.setText("MODE: " + mCurrentMode.toString());
showNetworkView();
@Override
public void onClick(View v) {
+ DLog.v(TAG, "FindResource click");
RM.RMFindResource(mUri_ed.getText().toString());
}
};
+ private OnClickListener mSendResponseHandler = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+
+ DLog.v(TAG, "SendResponse click");
+ RM.RMSendResponse(mNotification_ed.getText().toString(),
+ mPayload_ed.getText().toString(), selectedNetwork,
+ isSecured);
+ }
+ };
+
private OnClickListener mNotifyHandler = new OnClickListener() {
@Override
public void onClick(View v) {
- RM.RMSendNotification(mNotification_ed.getText().toString(), selectedNetwork);
+ DLog.v(TAG, "SendNotification click");
+ RM.RMSendNotification(mNotification_ed.getText().toString(),
+ mPayload_ed.getText().toString(), selectedNetwork,
+ isSecured);
+ }
+ };
+
+ private OnClickListener mAdvertiseResourceHandler = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ DLog.v(TAG, "AdvertiseResource click");
+ RM.RMAdvertiseResource(mNotification_ed.getText().toString(),
+ selectedNetwork);
}
};
@Override
public void onClick(View v) {
- RM.RMSendRequest(mReqData_ed.getText().toString(), selectedNetwork, isSecured, msgType);
-
+ DLog.v(TAG, "SendRequest click");
+ RM.RMSendRequest(mReqData_ed.getText().toString(), mPayload_ed
+ .getText().toString(), selectedNetwork, isSecured, msgType);
}
};
-
+
private OnClickListener mSendRequestSettingHandler = new OnClickListener() {
@Override
}
};
- private OnClickListener mSendResponseHandler = new OnClickListener() {
+ private OnClickListener mSendResponseNotiSettingHandler = new OnClickListener() {
@Override
public void onClick(View v) {
- //RM.RMSendResponse(mRespData_ed.getText().toString(), selectedNetwork);
-
+ checkMsgSecured("Select DTLS Type");
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle(title)
- .setMultiChoiceItems(mCheckBoxItems, mCheckedItems,
+ .setMultiChoiceItems(mCheckBoxItems, null,
new DialogInterface.OnMultiChoiceClickListener() {
@Override
if (mSelectedItems.get(i) == Network.WIFI.ordinal()) {
interestedNetwork |= CA_WIFI;
-
+ } else if (mSelectedItems.get(i) == Network.EDR
+ .ordinal()) {
+ interestedNetwork |= CA_EDR;
} else if (mSelectedItems.get(i) == Network.LE
.ordinal()) {
interestedNetwork |= CA_LE;
RM.RMSelectNetwork(interestedNetwork);
selectedNetwork = interestedNetwork;
-
- if (interestedNetwork != 0
- && mCurrentMode != Mode.UNKNOWN) {
- showModeView();
- }
}
}).show();
+
+ mSelectedItems.clear();
}
private void checkMsgSecured(String title) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
+
builder.setTitle(title)
- .setMultiChoiceItems(mDTLSCheckBoxItems, mCheckedItems,
- new DialogInterface.OnMultiChoiceClickListener() {
+ .setSingleChoiceItems(mDTLSCheckBoxItems, -1,
+ new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
- int which, boolean isChecked) {
-
- if (isChecked) {
-
- mSRSelectedItems.add(which);
-
- } else if (mSRSelectedItems.contains(which)) {
-
- mSRSelectedItems.remove(Integer
- .valueOf(which));
- }
+ int which) {
+ selectedItem = which;
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- for (int i = 0; i < mSRSelectedItems.size(); i++) {
+ if (selectedItem == DTLS.SECURED.ordinal()) {
+ isSecured = 1;
+ DLog.v(TAG, "Send secured message");
- if (mSRSelectedItems.get(i) == DTLS.SECURED
- .ordinal()) {
- isSecured = 1;
+ mPayLoadClientEditLayout
+ .setVisibility(View.INVISIBLE);
- } else if (mSRSelectedItems.get(i) == DTLS.UNSECURED
- .ordinal()) {
- isSecured = 0;
+ mPayLoadServerEditLayout
+ .setVisibility(View.INVISIBLE);
+
+ } else if (selectedItem == DTLS.UNSECURED.ordinal()) {
+ isSecured = 0;
+ DLog.v(TAG, "Send unsecured message");
+
+ if (mCurrentMode == Mode.SERVER) {
+ mPayLoadServerEditLayout
+ .setVisibility(View.VISIBLE);
+ } else if (mCurrentMode == Mode.CLIENT) {
+ mPayLoadClientEditLayout
+ .setVisibility(View.VISIBLE);
}
}
}
- }).show();
- mSRSelectedItems.clear();
+ }).show();
}
private void checkMsgType(String title) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle(title)
- .setMultiChoiceItems(mMsgTyleCheckBoxItems, mCheckedItems,
- new DialogInterface.OnMultiChoiceClickListener() {
+ .setSingleChoiceItems(mMsgTyleCheckBoxItems, -1,
+ new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
- int which, boolean isChecked) {
-
- if (isChecked) {
-
- mSRSelectedItems.add(which);
-
- } else if (mSRSelectedItems.contains(which)) {
-
- mSRSelectedItems.remove(Integer
- .valueOf(which));
- }
+ int which) {
+ selectedItem = which;
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- for (int i = 0; i < mSRSelectedItems.size(); i++) {
-
- if (mSRSelectedItems.get(i) == MsgType.CON
- .ordinal()) {
- msgType = 0;
+ if (selectedItem == MsgType.CON.ordinal()) {
+ msgType = 0;
+ DLog.v(TAG, "Message Type is CON");
- } else if (mSRSelectedItems.get(i) == MsgType.NON
- .ordinal()) {
- msgType = 1;
- }
+ } else if (selectedItem == MsgType.NON.ordinal()) {
+ msgType = 1;
+ DLog.v(TAG, "Message Type is NON");
}
-
+
}
}).show();
+ }
+
+ public void OnResponseReceived(String subject, String receivedData) {
+ String callbackData = subject + receivedData;
+ DLog.v(TAG, callbackData);
- mSRSelectedItems.clear();
}
-}
+}
\ No newline at end of file
System.loadLibrary("CAInterface");
}
+ private com.iotivity.service.MainActivity mResponseListener = null;
+
+ public native void setNativeResponseListener(Object listener);
+
public native void RMInitialize(Context context);
public native void RMTerminate();
public native void RMFindResource(String uri);
- public native void RMSendRequest(String requestUri, int selectedNetwork, int isSecured, int msgType);
+ public native void RMSendRequest(String uri, String payload, int selectedNetwork, int isSecured, int msgType);
- public native void RMSendNotification(String notification, int selectedNetwork);
+ public native void RMSendResponse(String uri, String payload, int selectedNetwork, int isSecured);
+
+ public native void RMAdvertiseResource(String advertiseResource, int selectedNetwork);
+
+ public native void RMSendNotification(String uri, String payload, int selectedNetwork, int isSecured);
public native void RMSelectNetwork(int interestedNetwork);
public native void RMHandleRequestResponse();
-
-}
+
+ public void setResponseListener(com.iotivity.service.MainActivity listener) {
+ mResponseListener = listener;
+ setNativeResponseListener(this);
+ }
+
+ private void OnResponseReceived(String subject, String receivedData) {
+
+ if (null != mResponseListener) {
+ mResponseListener.OnResponseReceived(subject, receivedData);
+ }
+ }
+
+}
\ No newline at end of file
#CFLAGS=-std=c99
#CFLAGS=$(INC_DIRS) -std=c99 -DWITH_POSIX -g
CFLAGS=$(INC_DIRS) -DWITH_POSIX -D__TIZEN__ $(ADAPTER_MACRO)
-#COMPILEFLAG = `pkg-config --cflags --libs com.samsung.oicca com.samsung.oicca-devel`
-COMPILEFLAG = `pkg-config --cflags --libs com.samsung.oicca capi-network-wifi gobject-2.0 glib-2.0 dlog capi-network-bluetooth`
+COMPILEFLAG = `pkg-config --cflags --libs com.oic.ca capi-network-wifi gobject-2.0 glib-2.0 dlog capi-network-bluetooth`
OBJECTS := interfacesample.o casample.o
-Compiling Interface APIs:
-=========================
-1) Get the latest interface APIs code.
-2) Copy the oic-resource code to linux machine.
-3) Change the ROOT_DIR in interface APIs makefile such that it points to oic-resource/csdk in local linux environment.
-4) Do "make" inside the interface APIs folder.
-
Compiling Sample App FOR TIZEN:
===============================
-1) Get the oic-resource code(Changes done for Logging by SRI-B) from SRI-B and build it in Tizen GBS
-2) Get the latest interface APIs code from repo and build it in Tizen GBS
- To Build in Tizen GBS Platform, Use this command "sh gbsbuild.sh" to build for all the transports.
- Specify option WITH_WIFI, WITH_BT or WITH_BLE if you want to build specific transport. Example: sh gbsbuild.sh WITH_WIFI (it will build interface sample only for WIFI transport)
-3) For Verification, Build Sample Console App and execute in Tizen Device
+In "connectivity/samples/tizen" folder, execute following
+
+1) To build Tizen sample for all transports use the command :-
+ "sh gbsbuild.sh".
+
+2) To build for a specific transport specify options (WITH_WIFI/WITH_BT/WITH_BLE).
+ Example:
+ sh gbsbuild.sh WITH_WIFI (to build sample application only for Wi-Fi Transport.)
+ sh gbsbuild.sh WITH_BT (to build sample application only for BT Transport.)
+ sh gbsbuild.sh WITH_BLE (to build sample application only for BLE Transport.)
+
Procedure to Execute Sample App:
=================================
- 1) Copy the generated rpm(com.samsung.interfacesample-0.1-1.armv7l.rpm) to Tizen Device (say /opt/usr/media/xxx/)
+ 1) Copy the generated rpm(com.oic.ca.sample-0.1-1.armv7l.rpm) to Tizen Device (say /opt/usr/media/xxx/)
2) sdb shell,
3) su
4) cd /opt/usr/media/xxx/
5) change-booting-mode.sh --update
- 6) Install interfacesample(console app). It contains Interface API libs and OIC-CORE Libs
- i) rpm -Uvh com.samsung.interfacesample-0.1-1.armv7l.rpm --force --nodeps
+ 6) Install casample(console app). It contains Interface API libs and OIC-CORE Libs
+ i) rpm -Uvh com.oic.ca.sample-0.1-1.armv7l.rpm --force --nodeps
7) Execute smack_reload.sh
- 8) rpm will be installed in /usr/apps/ Execute the sample app by below commands
- i) cd /usr/apps/com.samsung.interfacesample/bin
- ii) ./sample
\ No newline at end of file
+ 8) rpm will be installed in "/usr/apps/"
+ Execute the sample app by below commands
+ i) cd /usr/apps/com.oic.ca.sample/bin
+ ii) ./ca_sample (for CA Sample)
+ iii) ./internal/interface_sample (for adapter interface sample).
+
+Install Dependent RPMS(Only for BLE Adapter Testing)
+====================================================
+
+ 1) Flash the system image present in connectivity/lib/tizen/ble/image/ folder on SM Z910F Tizen v2.3
+ 2) In su(super user) mode, Install Bluetooth related rpms Present in connectivity/lib/tizen/ble/rpms on
+ Tizen v2.3 mobile device (Currently only SM Z910F Device is supported)
+ 3) Install the Sample as given above in "Procedure to Execute Sample App" [ Till Step 6 ]
+ 4) Open another sdb shell, in su (super user) mode follow the below steps:
+ (i) cd /var/lib/bluetooth
+ (ii) Turn off Bluetooth in the device
+ (iii) rm -rf *
+ (iv) Run the command ./usr/lib/bluetooth/bluetoothd -ndE &. for OIC Server device and
+ run the command ./usr/lib/bluetooth/bluetoothd -nd &. for OIC Client device.
+ (v) Turn on the Bluetooth.
+ 5) Run the sample as given in Step 8 of "Procedure to Execute Sample App"
+
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include "cacommon.h"
#include "cainterface.h"
static GMainLoop *mainloop;
-static GIOChannel *channel;
-static guint g_test_io_watch_id;
-static GError *g_err_Sample;
pthread_t thread;
#define MAX_BUF_LEN 1024
#define MAX_OPT_LEN 16
+#define TRUE 1
+#define FALSE 0
+
+/**
+ * @def RS_IDENTITY
+ * @brief
+ */
+#define IDENTITY ("1111111111111111")
+/* @def RS_CLIENT_PSK
+ * @brief
+ */
+#define RS_CLIENT_PSK ("AAAAAAAAAAAAAAAA")
+
+
+int gReceived;
+CABool_t gLocalUnicastPort;
+CABool_t gLocalSecurePort;
+CAConnectivityType_t gSelectedNwType = CA_ETHERNET;
+const char* gMessageType[] = {"CON", "NON", "ACK", "RESET"};
char get_menu();
void process();
+CAResult_t get_network_type();
-void initialize();
+CAResult_t initialize();
void start_listening_server();
void start_discovery_server();
void find_resource();
void send_request();
+void send_request_all();
void send_response();
void advertise_resource();
void send_notification();
void select_network();
void unselect_network();
void handle_request_response();
+void find_fixed_resource();
+void get_network_info();
void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token);
-void terminate();
-CAConnectivityType_t get_network_type();
+void get_resource_uri(char *URI, char *resourceURI, int length);
+int get_secure_information(CAPayload_t payLoad);
+
+static CAToken_t gLastRequestToken = NULL;
+static const char *gSecureInfoData = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
+ "\"if\":[\"oc.mi.def\"],\"obs\":1,\"sec\":1,\"port\":%d}}]}";
+static const char *gNormalInfoData = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
+ "\"if\":[\"oc.mi.def\"],\"obs\":1}}]}";
+
+#ifdef __WITH_DTLS__
+static OCDtlsPskCredsBlob *pskCredsBlob = NULL;
+void clearDtlsCredentialInfo()
+{
+ printf("clearDtlsCredentialInfo IN\n");
+ if (pskCredsBlob)
+ {
+ // Initialize sensitive data to zeroes before freeing.
+ memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCreds) * (pskCredsBlob->num));
+ free(pskCredsBlob->creds);
+
+ memset(pskCredsBlob, 0, sizeof(OCDtlsPskCredsBlob));
+ free(pskCredsBlob);
+ pskCredsBlob = NULL;
+ }
+ printf("clearDtlsCredentialInfo OUT\n");
+}
+
+// Internal API. Invoked by OC stack to retrieve credentials from this module
+void CAGetDtlsPskCredentials(OCDtlsPskCredsBlob **credInfo)
+{
+ printf("CAGetDtlsPskCredentials IN\n");
+
+ *credInfo = pskCredsBlob;
+
+ printf("CAGetDtlsPskCredentials OUT\n");
+}
+
+int32_t SetCredentials()
+{
+ printf("SetCredentials IN\n");
+ pskCredsBlob = (OCDtlsPskCredsBlob *)malloc(sizeof(OCDtlsPskCredsBlob));
+
+ memset(pskCredsBlob, 0x0, sizeof(OCDtlsPskCredsBlob));
+ memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN);
+
+ pskCredsBlob->num = 1;
+ pskCredsBlob->creds = (OCDtlsPskCreds *)malloc(sizeof(OCDtlsPskCreds) * (pskCredsBlob->num));
+ memcpy(pskCredsBlob->creds[0].id, IDENTITY, DTLS_PSK_ID_LEN);
+ memcpy(pskCredsBlob->creds[0].psk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
+
+ printf("SetCredentials OUT\n");
+ return 1;
+}
+#endif
void pthread_func()
{
g_main_loop_run(mainloop);
int main()
{
+ system("clear");
- printf("=============================================\n");
+ printf("\n=============================================\n");
printf("\t\tsample main\n");
printf("=============================================\n");
+ CAResult_t res;
+ /*
+ * Read DTLS PSK credentials from persistent storage and
+ * set in the OC stack.
+ */
+#ifdef __WITH_DTLS__
+ if (SetCredentials() == 0)
+ {
+ printf("SetCredentials failed\n");
+ return 0;
+ }
+
+ res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
+ if(res != CA_STATUS_OK)
+ {
+ printf("Set credential handler fail\n");
+ return 0;
+ }
+#endif
+ res = initialize();
+ if (res != CA_STATUS_OK)
+ {
+ printf("CAInitialize fail\n");
+ return 0;
+ }
+
+#if 0
+ // network enable
+ // default
+ printf("select default network(WIFI)\n");
+ res = CASelectNetwork(CA_WIFI);
+ if (res != CA_STATUS_OK)
+ {
+ printf("CASelectNetwork fail\n");
+ return 0;
+ }
+#endif
+
+ // set handler.
+ CARegisterHandler(request_handler, response_handler);
+
process();
+ CATerminate();
+#ifdef __WITH_DTLS__
+ clearDtlsCredentialInfo();
+#endif
return 0;
}
switch (menu)
{
+ case 'm': // menu
+ case 'M':
+ continue;
case 'Q': // quits the sample program
printf("quit..!!\n");
g_main_loop_quit(mainloop);
return;
- case 'I': // Initialize interface
- initialize();
- break;
-
+ case 's': // start server
case 'S': // start server
start_listening_server();
break;
- case 'C': // start client
+ case 't': // send request
+ case 'T':
+ send_request_all();
+ break;
+
+ case 'c': // start client
+ case 'D':
start_discovery_server();
break;
advertise_resource();
break;
+ case 'b': // send notification
+ case 'B':
+ send_notification();
+ break;
case 'N': // select network
select_network();
break;
case 'H': // handle request response
handle_request_response();
break;
+ case 'y':
+ case 'Y':
+ while (1)
+ {
+ gReceived = 0;
+ find_fixed_resource();
+ while (gReceived == 0)
+ {
+ sleep(1);
+ handle_request_response();
+
+ }
+ }
+ break;
+ case 'z':
+ case 'Z':
+ start_listening_server();
+ while (1)
+ {
+ sleep(1);
+ handle_request_response();
+ }
+ break;
- case 'T': // Terminate interface
- terminate();
+ case 'g': // get network information
+ case 'G':
+ get_network_info();
break;
default:
}
-void initialize()
+CAResult_t initialize()
{
mainloop = g_main_loop_new(NULL, FALSE);
pthread_create (&thread, NULL, (void *) &pthread_func, NULL);
- CAInitialize();
-
- // network enable
- // default
- printf("select default network(WIFI)\n");
- CASelectNetwork(CA_WIFI);
+ CAResult_t res = CAInitialize();
+ if (res != CA_STATUS_OK)
+ {
+ printf("CAInitialize fail\n");
+ return CA_STATUS_FAILED;
+ }
- // set handler.
- CARegisterHandler(request_handler, response_handler);
+ return CA_STATUS_OK;
}
void start_listening_server()
{
printf("start listening server!!\n");
- CAStartListeningServer();
+ CAResult_t res = CAStartListeningServer();
+ if (res != CA_STATUS_OK)
+ {
+ printf("start listening server fail\n");
+ }
+ else
+ {
+ printf("start listening server success\n");
+ }
}
void start_discovery_server()
{
- printf("start discovery server at client!!\n");
+ printf("start discovery client!!\n");
- CAStartDiscoveryServer();
+ CAResult_t res = CAStartDiscoveryServer();
+ if (res != CA_STATUS_OK)
+ {
+ printf("start discovery client fail\n");
+ }
+ else
+ {
+ printf("start discovery client success\n");
+ }
}
+void find_fixed_resource()
+{
+ char buf[MAX_BUF_LEN] =
+ { 0, };
+ strcpy(buf, "/a/light");
+
+ // create token
+ CAToken_t token = NULL;
+ CAResult_t res = CAGenerateToken(&token);
+ if (res != CA_STATUS_OK)
+ {
+ printf("token generate error!!");
+ token = NULL;
+ }
+
+ printf("generated token %s\n", (token != NULL) ? token : "");
+
+ res = CAFindResource(buf, token);
+ if (res != CA_STATUS_OK)
+ {
+ printf("find resource error!!\n");
+ }
+ else
+ {
+ printf("find resource to %s URI\n", buf);
+ }
+
+ // delete token
+ /*
+ if (token != NULL)
+ {
+ CADestroyToken(token);
+ }
+ */
+
+ printf("=============================================\n");
+}
void find_resource()
{
char buf[MAX_BUF_LEN];
memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
printf("\n=============================================\n");
- printf("ex) a/light\n");
+ printf("ex) /a/light\n");
printf("reference uri : ");
gets(buf);
printf("generated token %s\n", (token != NULL) ? token : "");
res = CAFindResource(buf, token);
-
if (res != CA_STATUS_OK)
{
- printf("find resource error:%d !!\n", res);
+ printf("find resource error!!\n");
}
else
{
- printf("find resource for %s URI\n", buf);
+ printf("find resource to %s URI\n", buf);
+
+ gLastRequestToken = token;
}
+ // delete token
+ /*
+ if (token != NULL)
+ {
+ CADestroyToken(token);
+ }
+ */
+
printf("=============================================\n");
}
void send_request()
{
+ char secureRequest[2] = {0};
+ CAResult_t res;
+
+ res = get_network_type();
+ if (res != CA_STATUS_OK)
+ {
+ return;
+ }
+
+ printf("Do you want to send secure request ?.... enter (0/1): ");
+ gets(secureRequest);
+ if ('1' == secureRequest[0])
+ {
+ printf("Enter the URI like below....\n");
+ printf("coaps://10.11.12.13:4545/resource_uri ( for IP secure)\n");
+ }
+ else
+ {
+ printf("Enter the URI like below....\n");
+ printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
+ printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
+ }
+
+ char uri[MAX_BUF_LEN] = {'\0'};
+ gets(uri);
+
+ // create remote endpoint
+ CARemoteEndpoint_t *endpoint = NULL;
+ if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, gSelectedNwType, &endpoint)
+ || !endpoint)
+ {
+ printf("Failed to create remote endpoint!\n");
+ CADestroyRemoteEndpoint(endpoint);
+ return;
+ }
+
+ //endpoint->connectivityType = gSelectedNwType;
+
char buf[MAX_BUF_LEN];
+ memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+ printf("\n=============================================\n");
+ printf("0:CON, 1:NON\n");
+ printf("select message type : ");
+
+ gets(buf);
+
+ CAMessageType_t msgType = (buf[0] == '0' || buf[0] == '1') ? buf[0] - '0' : 0;
+
+ // create token
+ CAToken_t token = NULL;
+ if (CA_STATUS_OK != CAGenerateToken(&token))
+ {
+ printf("token generate error!!\n");
+ token = NULL;
+ }
+
+ printf("generated token %s\n", (token != NULL) ? token : "");
+
+ // extract relative resourceuri from give uri
+ char resourceURI[15] = {0};
+ printf("URI : %s\n", uri);
+ get_resource_uri(uri, resourceURI, 14);
+
+ // create request data
+ CAInfo_t requestData;
+ memset(&requestData, 0, sizeof(CAInfo_t));
+ requestData.token = token;
+ if ('1' == secureRequest[0])
+ {
+ int length = strlen(gSecureInfoData) + strlen(resourceURI) + 1;
+ requestData.payload = (CAPayload_t) malloc(length);
+ sprintf(requestData.payload, gSecureInfoData, resourceURI, gLocalSecurePort);
+ }
+ else
+ {
+ int length = strlen(gNormalInfoData) + strlen(resourceURI) + 1;
+ requestData.payload = (CAPayload_t) malloc(length);
+ sprintf(requestData.payload, gNormalInfoData, resourceURI);
+ }
+ requestData.type = msgType;
+
+ CARequestInfo_t requestInfo;
+ memset(&requestInfo, 0, sizeof(CARequestInfo_t));
+ requestInfo.method = CA_GET;
+ requestInfo.info = requestData;
+
+ // send request
+ CASendRequest(endpoint, &requestInfo);
+
+ if (token != NULL)
+ {
+ CADestroyToken(token);
+ }
+
+ // destroy remote endpoint
+ CADestroyRemoteEndpoint(endpoint);
+ printf("=============================================\n");
+}
+
+void send_request_all()
+{
+ char buf[MAX_BUF_LEN];
memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
- CAConnectivityType_t selectedNetwork;
- selectedNetwork = get_network_type();
+ CAResult_t res;
+
+ res = get_network_type();
+ if (res != CA_STATUS_OK)
+ {
+ return;
+ }
printf("\n=============================================\n");
printf("10.11.12.13:4545/resource_uri ( for IP )\n");
// create remote endpoint
CARemoteEndpoint_t *endpoint = NULL;
- CAResult_t res = CACreateRemoteEndpoint(buf,selectedNetwork, &endpoint);
+ res = CACreateRemoteEndpoint(buf, gSelectedNwType, &endpoint);
if (res != CA_STATUS_OK)
{
- printf("create remote endpoint error!!");
+ printf("create remote endpoint error!!\n");
CADestroyRemoteEndpoint(endpoint);
return;
}
+
+ CAGroupEndpoint_t *group = NULL;
+ group = (CAGroupEndpoint_t *)malloc(sizeof(CAGroupEndpoint_t));
+ group->connectivityType = endpoint->connectivityType;
+ group->resourceUri = endpoint->resourceUri;
+
+
// create token
CAToken_t token = NULL;
res = CAGenerateToken(&token);
if (res != CA_STATUS_OK)
{
- printf("token generate error!!");
+ printf("token generate error!!\n");
token = NULL;
}
memset(&requestData, 0, sizeof(CAInfo_t));
requestData.token = token;
requestData.payload = "Temp Json Payload";
-
+ requestData.type = CA_MSG_NONCONFIRM;
CARequestInfo_t requestInfo;
memset(&requestInfo, 0, sizeof(CARequestInfo_t));
requestInfo.method = CA_GET;
requestInfo.info = requestData;
// send request
- CASendRequest(endpoint, &requestInfo);
+ // CASendRequest(endpoint, &requestInfo);
+ CASendRequestToAll(group, &requestInfo);
if (token != NULL)
{
}
// destroy remote endpoint
- if (endpoint != NULL)
- {
- CADestroyRemoteEndpoint(endpoint);
- }
+ CADestroyRemoteEndpoint(endpoint);
+
+ free(group);
printf("=============================================\n");
}
printf("Option Num : ");
scanf("%d", &optionNum);
CAHeaderOption_t *headerOpt;
-
- if (optionNum > 0)
+ headerOpt = (CAHeaderOption_t *) malloc(sizeof(CAHeaderOption_t) * optionNum);
+ if (NULL == headerOpt)
{
- headerOpt = (CAHeaderOption_t *) malloc(sizeof(CAHeaderOption_t) * optionNum);
- if (NULL == headerOpt)
- {
- printf("memory allocation failed!\n");
- return;
- }
- memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum);
+ printf("Memory allocation failed!\n");
+ return;
}
+ memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum);
int i;
for (i = 0 ; i < optionNum ; i++)
memset(optionData, 0, sizeof(char) * MAX_OPT_LEN);
printf("[%d] Option Data : ", i + 1);
scanf("%s", optionData);
- memcpy(headerOpt[i].optionData, optionData, MAX_OPT_LEN);
+ memcpy(headerOpt[i].optionData, optionData, strlen(optionData));
printf("[%d] inputed option : ID : %d, data : %s\n", i + 1, optionID, optionData );
headerOpt[i].optionLength = (uint16_t)strlen(optionData);
}
+void send_notification()
+{
+ char buf[MAX_BUF_LEN];
+ memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+ CAResult_t res;
+
+ res = get_network_type();
+ if (res != CA_STATUS_OK)
+ {
+ return;
+ }
+
+ printf("\n=============================================\n");
+ printf("10.11.12.13:4545/resource_uri ( for IP )\n");
+ printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
+ printf("uri : ");
+
+ gets(buf);
+
+ // create remote endpoint
+ CARemoteEndpoint_t *endpoint = NULL;
+ res = CACreateRemoteEndpoint(buf, gSelectedNwType, &endpoint);
+
+ if (res != CA_STATUS_OK)
+ {
+ printf("create remote endpoint error!!\n");
+ CADestroyRemoteEndpoint(endpoint);
+ return;
+ }
+
+ CAInfo_t respondeData;
+ memset(&respondeData, 0, sizeof(CAInfo_t));
+ respondeData.token = "client token";
+ respondeData.payload = "Temp Notification Data";
+
+ CAResponseInfo_t responseInfo;
+ memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
+ responseInfo.result = CA_SUCCESS;
+ responseInfo.info = respondeData;
+
+ // send request
+ res = CASendNotification(endpoint, &responseInfo);
+ if (res != CA_STATUS_OK)
+ {
+ printf("send notification error\n");
+ }
+ else
+ {
+ printf("send notification success\n");
+ }
+
+ // destroy remote endpoint
+ if (endpoint != NULL)
+ {
+ CADestroyRemoteEndpoint(endpoint);
+ }
+
+ printf("\n=============================================\n");
+}
void select_network()
{
char buf[MAX_BUF_LEN];
int number = buf[0] - '0';
- number = (number < 0 || number > 3) ? 1 : number;
+ number = (number < 0 || number > 3) ? 0 : number;
- CASelectNetwork(1 << number);
+ CAResult_t res = CASelectNetwork(1 << number);
+ if (res != CA_STATUS_OK)
+ {
+ printf("select network error\n");
+ gSelectedNwType = 1 << number;
+ }
+ else
+ {
+ printf("select network success\n");
+ }
printf("=============================================\n");
}
number = (number < 0 || number > 3) ? 1 : number;
- CAUnSelectNetwork(1 << number);
- printf("Terminating...\n");
- CATerminate();
- //pthread_join(thread, NULL);
+ CAResult_t res = CAUnSelectNetwork(1 << number);
+ if (res != CA_STATUS_OK)
+ {
+ printf("unselect network error\n");
+ }
+ else
+ {
+ printf("unselect network success\n");
+ }
printf("=============================================\n");
}
printf("\n=============================================\n");
printf("\t\tMenu\n");
- printf("\ti : Initialize\n");
printf("\ts : start server\n");
- printf("\tc : start client\n");
+ printf("\tD : start client\n");
printf("\tf : find resource\n");
printf("\tr : send request\n");
+ printf("\tt : send request to all\n");
printf("\ta : advertise resource\n");
+ printf("\tb : send notification\n");
printf("\tn : select network\n");
printf("\tx : unselect network\n");
+ printf("\tg : get network information\n");
printf("\th : handle request response\n");
- printf("\tt : terminate\n");
+ printf("\ty : run static client\n");
+ printf("\tz : run static server\n");
printf("\tq : quit\n");
printf("=============================================\n");
printf("select : ");
void handle_request_response()
{
printf("handle_request_response\n");
- CAHandleRequestResponse();
+
+ CAResult_t res = CAHandleRequestResponse();
+ if (res != CA_STATUS_OK)
+ {
+ printf("handle request error\n");
+ }
+ else
+ {
+ printf("handle request success\n");
+ }
+}
+
+void get_network_info()
+{
+ int index;
+
+ CALocalConnectivity_t *tempInfo;
+ uint32_t tempSize = 0;
+
+ tempInfo = (CALocalConnectivity_t *) malloc(sizeof(CALocalConnectivity_t));
+
+ CAGetNetworkInformation(&tempInfo, &tempSize);
+ if (!tempSize)
+ {
+ printf("network not connected\n");
+ return;
+ }
+
+ printf("################## Network Information #######################\n");
+ printf("network info total size is %d\n\n", tempSize);
+ for (index = 0; index < tempSize; index++)
+ {
+ if (tempInfo == NULL)
+ {
+ break;
+ }
+
+ printf("Type: %d\n", tempInfo->type);
+ printf("Address: %s\n", tempInfo->addressInfo.IP.ipAddress);
+ printf("Port: %d\n", tempInfo->addressInfo.IP.port);
+ printf("Secured: %d\n\n", tempInfo->isSecured);
+
+ if (CA_TRUE == tempInfo->isSecured)
+ {
+ gLocalSecurePort = tempInfo->addressInfo.IP.port;
+ }
+ else
+ {
+ gLocalUnicastPort = tempInfo->addressInfo.IP.port;
+ }
+
+ tempInfo++;
+ }
+
+ //free(tempInfo);
+ printf("##############################################################");
}
void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
{
+ if (!object)
+ {
+ printf("Remote endpoint is NULL!");
+ return;
+ }
- printf("[CALLBACK] request_handler, uri : %s, data : %s\n",
- (object != NULL) ? object->resourceUri : "",
- (requestInfo != NULL) ? requestInfo->info.payload : "");
+ if (!requestInfo)
+ {
+ printf("Request info is NULL!");
+ return;
+ }
- printf("[CALLBACK] request_handler, address : %s\n",
- (object != NULL) ? object->addressInfo.IP.ipAddress : "");
+ printf("##########received request from remote device #############\n");
+ printf("Uri: %s\n", object->resourceUri);
+ printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
+ object->addressInfo.IP.port, object->isSecured);
+
+ printf("Data: %s\n", requestInfo->info.payload);
+ printf("Message type: %s\n", gMessageType[requestInfo->info.type]);
+ if (gLastRequestToken != NULL && requestInfo->info.token != NULL
+ && (strcmp((char *)gLastRequestToken, requestInfo->info.token) == 0))
+ {
+ printf("token is same. received request of it's own. skip.. \n");
+ return;
+ }
if (requestInfo->info.options)
{
- uint32_t len = requestInfo->info.numOptions;
+ uint32_t len = requestInfo->info.numOptions;
uint32_t i;
- for (i = 0 ; i < len ; i++)
+ for (i = 0; i < len; i++)
{
- printf("[CALLBACK] request_handler, option ID : %d\n", requestInfo->info.options[i].optionID);
- printf("[CALLBACK] request_handler, options data length : %d\n",
- requestInfo->info.options[i].optionLength);
- printf("[CALLBACK] request_handler, options data : %s\n", requestInfo->info.options[i].optionData );
+ printf("Option %d\n", i + 1);
+ printf("ID : %d\n", requestInfo->info.options[i].optionID);
+ printf("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
+ requestInfo->info.options[i].optionData);
+ }
+ }
+ printf("############################################################\n");
+
+ //Check if this has secure communication information
+ if (requestInfo->info.payload)
+ {
+ int securePort = get_secure_information(requestInfo->info.payload);
+ if (0 < securePort) //Set the remote endpoint secure details and send response
+ {
+ printf("This is secure resource...\n");
+ char *uri = NULL;
+ int length = 0;
+
+ length = 8; //length of "coaps://"
+ length += strlen(object->addressInfo.IP.ipAddress) + 5; // length of "ipaddress:port"
+ length += strlen(object->resourceUri) + 1;
+
+ uri = calloc(1, sizeof(char) * length);
+ if (!uri)
+ {
+ printf("Failed to create new uri\n");
+ return;
+ }
+ sprintf(uri, "coaps://%s:%d/%s", object->addressInfo.IP.ipAddress,
+ securePort, object->resourceUri);
+
+ CARemoteEndpoint_t *endpoint = NULL;
+ if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, object->connectivityType, &endpoint))
+ {
+ printf("Failed to create duplicate of remote endpoint!\n");
+ return;
+ }
+ //endpoint->connectivityType = object->connectivityType;
+ endpoint->isSecured = CA_TRUE;
+ object = endpoint;
+
+ free(uri);
}
}
printf("send response with URI\n");
- send_response(object, (requestInfo != NULL) ? requestInfo->info.token : "");
+ send_response(object, &requestInfo->info);
+ gReceived = 1;
}
void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo)
{
-
- printf("[CALLBACK] response_handler, uri : %s, data : %s\n",
- (object != NULL) ? object->resourceUri : "",
- (responseInfo != NULL) ? responseInfo->info.payload : "");
-
- printf("[CALLBACK] response_handler, address : %s\n",
- (object != NULL) ? object->addressInfo.IP.ipAddress : "");
-
+ printf("##########Received response from remote device #############\n");
+ printf("Uri: %s\n", object->resourceUri);
+ printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
+ object->addressInfo.IP.port, object->isSecured);
+ printf("response result : %d\n", responseInfo->result);
+ printf("Data: %s\n", responseInfo->info.payload);
+ printf("Message type: %s\n", gMessageType[responseInfo->info.type]);
if (responseInfo->info.options)
{
- uint32_t len = responseInfo->info.numOptions;
+ uint32_t len = responseInfo->info.numOptions;
uint32_t i;
- for (i = 0 ; i < len ; i++)
+ for (i = 0; i < len; i++)
{
- printf("[CALLBACK] response_handler, option ID : %d\n", responseInfo->info.options[i].optionID);
- printf("[CALLBACK] response_handler, options data length : %d\n",
- responseInfo->info.options[i].optionLength);
- printf("[CALLBACK] response_handler, options data : %s\n",
- responseInfo->info.options[i].optionData );
+ printf("Option %d\n", i + 1);
+ printf("ID : %d\n", responseInfo->info.options[i].optionID);
+ printf("Data[%d]: %s\n", responseInfo->info.options[i].optionLength,
+ responseInfo->info.options[i].optionData);
}
}
+ printf("############################################################\n");
+ gReceived = 1;
- //printf("send request with URI\n");
- //send_request_tmp(object, (responseInfo != NULL) ? responseInfo->info.token : "");
+ //Check if this has secure communication information
+ if (responseInfo->info.payload)
+ {
+ int securePort = get_secure_information(responseInfo->info.payload);
+ if (0 < securePort) //Set the remote endpoint secure details and send response
+ {
+ printf("This is secure resource...\n");
+ }
+ }
}
-void send_response(CARemoteEndpoint_t *endpoint, CAToken_t request_token)
+void send_response(CARemoteEndpoint_t *endpoint, CAInfo_t *info)
{
-
- printf("\n=============================================\n");
+ printf("entering send_response\n");
CAInfo_t responseData;
- //responseData = (CAInfo*) malloc(sizeof(CAInfo));
memset(&responseData, 0, sizeof(CAInfo_t));
- responseData.token = request_token;
+ responseData.type =
+ (info != NULL) ?
+ ((info->type == CA_MSG_CONFIRM) ? CA_MSG_ACKNOWLEDGE : CA_MSG_NONCONFIRM) :
+ CA_MSG_NONCONFIRM;
+ responseData.messageId = (info != NULL) ? info->messageId : 0;
+ responseData.token = (info != NULL) ? info->token : "";
responseData.payload = "response payload";
CAResponseInfo_t responseInfo;
- //responseInfo = (CAResponseInfo*) malloc(sizeof(CAResponseInfo));
memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
responseInfo.result = 203;
responseInfo.info = responseData;
+ if (CA_TRUE == endpoint->isSecured)
+ printf("Sending response on secure communication\n");
+ else
+ printf("Sending response on non-secure communication\n");
+
// send request (connectivityType from remoteEndpoint of request Info)
- CASendResponse(endpoint, &responseInfo);
+ CAResult_t res = CASendResponse(endpoint, &responseInfo);
+ if (res != CA_STATUS_OK)
+{
+ printf("send response error\n");
+ }
+ else
+ {
+ printf("send response success\n");
+ }
printf("=============================================\n");
-
}
void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token)
// send request
endpoint->connectivityType = CA_WIFI;
- CASendRequest(endpoint, &requestInfo);
+
+ CAResult_t res = CASendRequest(endpoint, &requestInfo);
+ if (res != CA_STATUS_OK)
+ {
+ printf("send request error\n");
+ }
+ else
+ {
+ printf("send request success\n");
+ }
printf("=============================================\n");
}
-void terminate()
+int get_secure_information(CAPayload_t payLoad)
{
- unselect_network();
+ printf("entering get_secure_information\n");
+
+ if (!payLoad)
+ {
+ printf("Payload is NULL\n");
+ return -1;
+ }
+
+ char *subString = NULL;
+ if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
+ {
+ printf("This is not secure resource\n");
+ return -1;
+ }
+
+ if (NULL == (subString = strstr(payLoad, "\"port\":")))
+ {
+ printf("This secure resource does not have port information\n");
+ return -1;
+ }
+
+ char *startPos = strstr(subString, ":");
+ if (!startPos)
+ {
+ printf("Parsing failed !\n");
+ return -1;
+ }
+
+ char *endPos = strstr(startPos, "}");
+ if (!endPos)
+ {
+ printf("Parsing failed !\n");
+ return -1;
+ }
+
+ char portStr[4] = {0};
+ memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
+
+ printf("secured port is: %s\n", portStr);
+ return atoi(portStr);
}
-CAConnectivityType_t get_network_type()
+void get_resource_uri(char *URI, char *resourceURI, int length)
+{
+ char *startPos = URI;
+ char *temp = NULL;
+ if (NULL != (temp = strstr(URI, "://")))
+ {
+ startPos = strchr(temp + 3, '/');
+ if (!startPos)
+ {
+ printf("Resource URI is missing\n");
+ return;
+ }
+ }
+
+ char *endPos = strchr(startPos, '?');
+ if (!endPos)
+ {
+ endPos = URI + strlen(URI);
+ }
+ endPos -= 1;
+
+ if (endPos - startPos <= length)
+ memcpy(resourceURI, startPos + 1, endPos - startPos);
+
+ printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
+}
+
+CAResult_t get_network_type()
{
char buf[MAX_BUF_LEN];
number = (number < 0 || number > 3) ? 0 : 1 << number;
+ if (!(number & 0xf))
+ {
+ return CA_NOT_SUPPORTED;
+ }
if (number & CA_ETHERNET)
{
- return CA_ETHERNET;
+ gSelectedNwType = CA_ETHERNET;
+ return CA_STATUS_OK;
}
if (number & CA_WIFI)
{
- return CA_WIFI;
+ gSelectedNwType = CA_WIFI;
+ return CA_STATUS_OK;
}
if (number & CA_EDR)
{
- return CA_EDR;
+ gSelectedNwType = CA_EDR;
+ return CA_STATUS_OK;
}
if (number & CA_LE)
{
- return CA_LE;
+ gSelectedNwType = CA_LE;
+ return CA_STATUS_OK;
}
printf("\n=============================================\n");
+ return CA_STATUS_OK;
}
<manifest>
<define>
- <domain name="interfacesample" />
+ <domain name="casample" />
<permit>
<smack permit="system::use_internet" type="rwx"/>
</permit>
</request>
</define>
<assign>
- <filesystem path="/opt/apps/com.samsung.interfacesample/bin/sample" exec_label="sample" />
+ <filesystem path="/opt/apps/com.oic.ca.sample/bin/sample" exec_label="sample" />
</assign>
<request>
- <domain name="interfacesample" />
+ <domain name="casample" />
</request>
</manifest>
#interfacesample device::video r
#interfacesample device::camera r
#interfacesample system::crash wx
-interfacesample system::use_internet rw
+casample system::use_internet rw
# db
#interfacesample libaccounts-svc::db rw
#interfacesample ail::db rw
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" package="com.oic.ca.sample" version="0.1.12" install-location="internal-only">
+ <label>casample</label>
+ <author email="oic" href="www.iotivity.org">OIC</author>
+ <description>casample</description>
+ <ui-application appid="com.oic.ca.sample" exec="/usr/apps/com.oic.ca.sample/bin/sample" nodisplay="false" multiple="false" type="capp" taskmanage="true">
+ <icon>com.oic.ca.sample.png</icon>
+ <label>casample</label>
+ <label xml:lang="en-us">casample</label>
+ <label xml:lang="nl-nl">casample</label>
+ </ui-application>
+ <privileges>
+ <privilege>http://tizen.org/privilege/socket</privilege>
+ </privileges>
+
+</manifest>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns="http://tizen.org/ns/packages" package="com.samsung.interfacesample" version="0.1.12" install-location="internal-only">
- <label>interfacesample</label>
- <author email="oic" href="www.iotivity.org">OIC</author>
- <description>interfacesample</description>
- <ui-application appid="com.samsung.interfacesample" exec="/usr/apps/com.samsung.interfacesample/bin/sample" nodisplay="false" multiple="false" type="capp" taskmanage="true">
- <icon>com.samsung.interfacesample.png</icon>
- <label>interfacesample</label>
- <label xml:lang="en-us">interfacesample</label>
- <label xml:lang="nl-nl">interfacesample</label>
- </ui-application>
- <privileges>
- <privilege>http://tizen.org/privilege/socket</privilege>
- </privileges>
-
-</manifest>
--- /dev/null
+%define PREFIX /usr/apps/com.oic.ca.sample
+%define ROOTDIR %{_builddir}/%{name}-%{version}
+
+Name: com.oic.ca.sample
+Version: 0.1
+Release: 1
+Summary: Tizen adapter interfacesample application
+URL: http://slp-source.sec.samsung.net
+Source: %{name}-%{version}.tar.gz
+License: Apache License, Version 2.0
+Group: OIC/Application
+#BuildRequires: cmake
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: boost-devel
+BuildRequires: boost-thread
+BuildRequires: boost-system
+BuildRequires: boost-filesystem
+#BuildRequires: oic-core
+BuildRequires: pkgconfig(capi-network-wifi)
+BuildRequires: pkgconfig(capi-network-bluetooth)
+BuildRequires: scons
+BuildRequires: com.oic.ca
+#BuildRequires: com.samsung.oicca-devel
+
+%description
+SLP interfacesample application
+
+%prep
+%setup -q
+
+%build
+
+scons TARGET_OS=tizen -c
+scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT}
+
+#make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+# remove later
+#%make_install
+mkdir -p %{buildroot}/usr/share/license
+mkdir -p %{buildroot}/usr/share/license
+mkdir -p %{buildroot}/usr/share/packages
+mkdir -p %{buildroot}/etc/smack/accesses2.d
+mkdir -p %{buildroot}/usr/apps/com.oic.ca.sample/bin/
+mkdir -p %{buildroot}/usr/apps/com.oic.ca.sample/bin/internal
+mkdir -p %{buildroot}/usr/lib
+
+cp -rf %{ROOTDIR}/com.oic.ca.sample.xml %{buildroot}/usr/share/packages
+cp -rf %{ROOTDIR}/com.oic.ca.sample.rule %{buildroot}/etc/smack/accesses2.d
+cp -rf %{ROOTDIR}/scons/interface_sample %{buildroot}/usr/apps/com.oic.ca.sample/bin/internal
+cp -rf %{ROOTDIR}/scons/ca_sample %{buildroot}/usr/apps/com.oic.ca.sample/bin/
+
+%files
+%manifest com.oic.ca.sample.manifest
+/etc/smack/accesses2.d/com.oic.ca.sample.rule
+%defattr(-,root,root,-)
+%attr(-,inhouse,inhouse)
+/usr/apps/com.oic.ca.sample/bin/internal/interface_sample
+/usr/apps/com.oic.ca.sample/bin/ca_sample
+#%{_libdir}/lib*.a*
+/usr/share/packages/com.oic.ca.sample.xml
+#/opt/share/process-info/cmsample.ini
+#/usr/share/license/%{name}
+++ /dev/null
-%define PREFIX /usr/apps/com.samsung.interfacesample
-%define ROOTDIR %{_builddir}/%{name}-%{version}
-
-Name: com.samsung.interfacesample
-Version: 0.1
-Release: 1
-Summary: Tizen interfacesample application
-URL: http://slp-source.sec.samsung.net
-Source: %{name}-%{version}.tar.gz
-License: SAMSUNG
-Group: Samsung/Application
-#BuildRequires: cmake
-BuildRequires: pkgconfig(dlog)
-BuildRequires: pkgconfig(glib-2.0)
-BuildRequires: boost-devel
-BuildRequires: boost-thread
-BuildRequires: boost-system
-BuildRequires: boost-filesystem
-#BuildRequires: oic-core
-BuildRequires: pkgconfig(capi-network-wifi)
-BuildRequires: pkgconfig(capi-network-bluetooth)
-BuildRequires: com.samsung.oicca
-#BuildRequires: com.samsung.oicca-devel
-
-%description
-SLP interfacesample application
-
-%prep
-%setup -q
-
-%build
-
-make clean
-make PLATFORM=linux
-
-#make %{?jobs:-j%jobs}
-
-%install
-rm -rf %{buildroot}
-# remove later
-#%make_install
-mkdir -p %{buildroot}/usr/share/license
-mkdir -p %{buildroot}/usr/share/license
-mkdir -p %{buildroot}/usr/share/packages
-mkdir -p %{buildroot}/etc/smack/accesses2.d
-mkdir -p %{buildroot}/usr/apps/com.samsung.interfacesample/bin/
-mkdir -p %{buildroot}/usr/lib
-#cp -rf LICENSE %{buildroot}/usr/share/license/%{name}
-cp -rf %{ROOTDIR}/com.samsung.interfacesample.xml %{buildroot}/usr/share/packages
-cp -rf %{ROOTDIR}/com.samsung.interfacesample.rule %{buildroot}/etc/smack/accesses2.d
-cp -rf %{ROOTDIR}/interface_sample %{buildroot}/usr/apps/com.samsung.interfacesample/bin/
-cp -rf %{ROOTDIR}/ca_sample %{buildroot}/usr/apps/com.samsung.interfacesample/bin/
-#cp -rf %{ROOTDIR}/liboicinterface.a %{buildroot}/usr/lib
-
-%files
-%manifest com.samsung.interfacesample.manifest
-/etc/smack/accesses2.d/com.samsung.interfacesample.rule
-%defattr(-,root,root,-)
-%attr(-,inhouse,inhouse)
-/usr/apps/com.samsung.interfacesample/bin/interface_sample
-/usr/apps/com.samsung.interfacesample/bin/ca_sample
-#%{_libdir}/lib*.a*
-/usr/share/packages/com.samsung.interfacesample.xml
-#/opt/share/process-info/cmsample.ini
-#/usr/share/license/%{name}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <jni.h>
+
+#include "caedrcore.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "uthreadpool.h" /* for thread pool */
+#include "umutex.h"
+#include "uarraylist.h"
+#include "caadapterutils.h"
+
+//#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 STATE_CONNECTED = 1;
+static const uint32_t STATE_DISCONNECTED = 0;
+
+static const uint32_t MAX_PDU_BUFFER = 1400;
+
+static u_arraylist_t *gdeviceStateList = NULL;
+static u_arraylist_t *gdeviceObjectList = NULL;
+
+static CAPacketReceiveCallback gPacketReceiveCallback = NULL;
+static u_thread_pool_t gThreadPoolHandle = NULL;
+
+static JavaVM *g_jvm;
+static jobject gContext;
+
+static jbyteArray gSendBuffer;
+
+/**
+ * @var gMutexSocketListManager
+ * @brief Mutex to synchronize socket list update
+ */
+static u_mutex gMutexSocketListManager;
+
+// server socket instance
+static jobject gServerSocketObject = NULL;
+
+/**
+ * @var gMutexUnicastServer
+ * @brief Mutex to synchronize unicast server
+ */
+static u_mutex gMutexUnicastServer = NULL;
+
+/**
+ * @var gStopUnicast
+ * @brief Flag to control the Receive Unicast Data Thread
+ */
+static bool gStopUnicast = FALSE;
+
+/**
+ * @var gMutexMulticastServer
+ * @brief Mutex to synchronize secure multicast server
+ */
+static u_mutex gMutexMulticastServer = NULL;
+
+/**
+ * @var gStopMulticast
+ * @brief Flag to control the Receive Multicast Data Thread
+ */
+static bool gStopMulticast = FALSE;
+
+/**
+ * @var gStopAccept
+ * @brief Flag to control the Accept Thread
+ */
+static bool gStopAccept = FALSE;
+
+typedef struct send_data {
+ char* address;
+ char* data;
+ uint32_t id;
+} data_t;
+
+/**
+ @brief Thread context information for unicast, multicast and secured unicast server
+ */
+typedef struct
+{
+ bool *stopFlag;
+ CAAdapterServerType_t type;
+} CAAdapterReceiveThreadContext_t;
+
+typedef struct
+{
+ bool *stopFlag;
+} CAAdapterAcceptThreadContext_t;
+
+
+static void CAReceiveHandler(void *data)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ // Input validation
+ VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
+
+ jboolean isAttached = FALSE;
+ JNIEnv* env;
+ jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+ res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+ return;
+ }
+ isAttached = TRUE;
+ }
+
+ 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 = CAEDRGetSocketListLength();
+ for(idx = 0 ; idx > length ; idx++)
+ {
+ CAEDRNativeReadData(env, idx, ctx->type);
+ }
+ }
+
+ if(isAttached)
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+
+ if(ctx)
+ OICFree(ctx);
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+static void CAAcceptHandler(void *data)
+{
+ int status;
+
+ OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
+
+ jboolean isAttached = FALSE;
+ JNIEnv* env;
+ jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+ res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+ return;
+ }
+ isAttached = TRUE;
+ }
+
+ jobject jni_obj_BTSeverSocket = CAEDRNativeListen(env);
+ if(!jni_obj_BTSeverSocket) {
+ OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread: jni_obj_BTSeverSocket is null");
+
+ if(isAttached)
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+
+ return;
+ }
+
+ CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *)data;
+
+ while (TRUE != *(ctx->stopFlag))
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
+ CAEDRNativeAccept(env, jni_obj_BTSeverSocket);
+ }
+
+ if(isAttached)
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+
+ if(ctx)
+ OICFree(ctx);
+
+ OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
+
+ return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//FIXME getting context
+void CAEDRClientJNISetContext(JNIEnv *env, jobject context)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRClientJNISetContext");
+
+ if(context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "context is null");
+ return;
+ }
+
+ gContext = (*env)->NewGlobalRef(env, context);
+}
+
+void CAEDRCreateJniInterfaceObject()
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRCreateJniInterfaceObject");
+
+// jboolean isAttached = FALSE;
+// JNIEnv* env;
+// jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+// if(res != JNI_OK)
+// {
+// OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+// res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+//
+// if(res != JNI_OK)
+// {
+// OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+// return;
+// }
+// isAttached = TRUE;
+// }
+//
+// jclass LeJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CAEDRInterface");
+// if (!LeJniInterface)
+// {
+// OIC_LOG_V(DEBUG, TAG, "Could not get CAEDRInterface class");
+// return;
+// }
+//
+// jmethodID LeInterfaceConstructorMethod =
+// (*env)->GetMethodID(env, LeJniInterface, "<init>", "(Landroid/content/Context;)V");
+// if (!LeInterfaceConstructorMethod)
+// {
+// OIC_LOG_V(DEBUG, TAG, "Could not get CAEDRInterface constructor method");
+// return;
+// }
+//
+// (*env)->NewObject(env, LeJniInterface, LeInterfaceConstructorMethod, gContext);
+// OIC_LOG_V(DEBUG, TAG, "Create CAEDRInterface instance");
+//
+// if(isAttached)
+// (*g_jvm)->DetachCurrentThread(g_jvm);
+}
+
+static void CAEDRDestroyMutex()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ if (gMutexUnicastServer)
+ {
+ u_mutex_free(gMutexUnicastServer);
+ gMutexUnicastServer = NULL;
+ }
+
+#ifdef __WITH_DTLS__
+
+#endif
+
+ if (gMutexMulticastServer)
+ {
+ u_mutex_free(gMutexMulticastServer);
+ gMutexMulticastServer = NULL;
+ }
+
+ if(gMutexSocketListManager)
+ {
+ u_mutex_free(gMutexSocketListManager);
+ gMutexSocketListManager = NULL;
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+static CAResult_t CAEDRCreateMutex()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ gMutexUnicastServer = u_mutex_new();
+ if (!gMutexUnicastServer)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to created mutex!");
+ return CA_STATUS_FAILED;
+ }
+
+#ifdef __WITH_DTLS__
+
+#endif
+
+ gMutexMulticastServer = u_mutex_new();
+ if (!gMutexMulticastServer)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to created mutex!");
+
+ CAEDRDestroyMutex();
+ return CA_STATUS_FAILED;
+ }
+
+ gMutexSocketListManager = u_mutex_new();
+ if (!gMutexSocketListManager)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to created mutex!");
+
+ CAEDRDestroyMutex();
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAEDRInitialize(u_thread_pool_t handle)
+{
+ OIC_LOG(DEBUG, TAG, "CAEDRInitialize");
+
+ gThreadPoolHandle = handle;
+
+ // init mutex
+ CAEDRCreateMutex();
+
+ jboolean isAttached = FALSE;
+ JNIEnv* env;
+ jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+ res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+ return;
+ }
+ isAttached = TRUE;
+ }
+
+ CAEDRNativeCreateDeviceStateList();
+ CAEDRNativeCreateDeviceSocketList();
+
+ if(isAttached)
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+
+// CAEDRCreateJniInterfaceObject(); /* create java CAEDRInterface instance*/
+
+ CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
+ OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
+ if (!ctx)
+ {
+ OIC_LOG(ERROR, TAG, "Out of memory!");
+ return;
+ }
+
+ ctx->stopFlag = &gStopAccept;
+ if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, CAAcceptHandler, (void *)ctx))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to create read thread!");
+ OICFree((void *)ctx);
+ return;
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CAEDRTerminate()
+{
+ OIC_LOG(DEBUG, TAG, "CAEDRTerminate");
+
+ jboolean isAttached = FALSE;
+ JNIEnv* env;
+ jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+ res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+ return;
+ }
+ isAttached = TRUE;
+ }
+
+ gStopAccept = TRUE;
+ gStopMulticast = TRUE;
+ gStopUnicast = TRUE;
+
+ if(isAttached)
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+
+ // delete mutex
+ CAEDRDestroyMutex();
+
+ if(gContext)
+ {
+ (*env)->DeleteGlobalRef(env, gContext);
+ }
+ CAEDRNativeRemoveAllDeviceState();
+ CAEDRNativeRemoveAllDeviceSocket(env);
+}
+
+void CAEDRCoreJniInit(JNIEnv *env, JavaVM* jvm)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEdrClientJniInit");
+ g_jvm = jvm;
+}
+
+int32_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessage(%s, %s)", address, data);
+
+ CAEDRSendUnicastMessageImpl(address, data, dataLen);
+ return 0;
+}
+
+int32_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRSendMulticastMessage(%s)", data);
+
+ jboolean isAttached = FALSE;
+ JNIEnv* env;
+ jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+ res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+ return 0;
+ }
+ isAttached = TRUE;
+ }
+
+ CAEDRSendMulticastMessageImpl(env, data, dataLen);
+
+ if(isAttached)
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+
+ return 1;
+}
+
+int32_t CAEDRStartUnicastServer(const char* address, bool isSecured)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRStartUnicastServer(%s)", address);
+
+ u_mutex_lock(gMutexUnicastServer);
+
+ /**
+ * 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!");
+ u_mutex_unlock(gMutexUnicastServer);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ // FIXME
+ isSecured = FALSE;
+ ctx->stopFlag = &gStopUnicast;
+ ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
+ if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, CAReceiveHandler, (void *)ctx))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to create read thread!");
+ u_mutex_unlock(gMutexUnicastServer);
+ OICFree((void *)ctx);
+ return CA_STATUS_FAILED;
+ }
+ u_mutex_unlock(gMutexUnicastServer);
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+int32_t CAEDRStartMulticastServer(bool isSecured)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRStartMulticastServer");
+
+ u_mutex_lock(gMutexMulticastServer);
+
+ /**
+ * 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!");
+ u_mutex_unlock(gMutexMulticastServer);
+
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ ctx->stopFlag = &gStopMulticast;
+ ctx->type = CA_MULTICAST_SERVER;
+
+ gStopMulticast = FALSE;
+ if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, CAReceiveHandler, (void *)ctx))
+ {
+ OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
+
+ gStopMulticast = TRUE;
+ u_mutex_unlock(gMutexMulticastServer);
+
+ return CA_STATUS_FAILED;
+ }
+ u_mutex_unlock(gMutexMulticastServer);
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+int32_t CAEDRStopUnicastServer(int32_t serverID)
+{
+ OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
+
+ u_mutex_lock(gMutexUnicastServer);
+ gStopUnicast = TRUE;
+ u_mutex_unlock(gMutexUnicastServer);
+
+ return 0;
+}
+
+int32_t CAEDRStopMulticastServer(int32_t serverID)
+{
+ OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
+
+ u_mutex_lock(gMutexMulticastServer);
+ gStopMulticast = true;
+ u_mutex_unlock(gMutexMulticastServer);
+
+ OIC_LOG_V(INFO, TAG, "Multicast server stopped");
+
+ return 0;
+}
+
+void CAEDRSetCallback(CAPacketReceiveCallback callback)
+{
+ gPacketReceiveCallback = callback;
+}
+
+CAResult_t CAEDRGetInterfaceInfo(char **address)
+{
+ CAEDRGetLocalAddress(address);
+ return CA_STATUS_OK;
+}
+
+void CAEDRGetLocalAddress(char** address)
+{
+ jboolean isAttached = FALSE;
+ JNIEnv* env;
+ jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+ res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+ return;
+ }
+ isAttached = TRUE;
+ }
+
+ jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
+ if(jni_address)
+ {
+ const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
+ *address = (char*)OICMalloc(strlen(localAddress) + 1);
+ if (*address == NULL)
+ {
+ return;
+ }
+ memcpy(*address, localAddress, strlen(localAddress));
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
+ if(isAttached)
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+}
+
+int32_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 = FALSE;
+ JNIEnv* env;
+ jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+ res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+ if(res != JNI_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+ return 0;
+ }
+ isAttached = TRUE;
+ }
+
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] set byteArray for data");
+ if(gSendBuffer)
+ {
+ (*env)->DeleteGlobalRef(env, gSendBuffer);
+ }
+ jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+ (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*)data);
+ gSendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
+
+ // get bonded device list
+ jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
+ if(!jni_arrayPairedDevices)
+ {
+ OIC_LOG_V(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
+ return 0;
+ }
+ // Get information from array of devices
+ jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
+ jsize 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)
+ {
+ const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
+ OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
+ (*env)->ReleaseStringUTFChars(env, j_str_name, name);
+ }
+
+ 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);
+
+ // find address
+ if(!strcmp(remoteAddress, address))
+ {
+ CAEDRNativeSendData(env, remoteAddress, data, i);
+ }
+ }
+
+ if(isAttached)
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+
+ return 1;
+}
+
+int32_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
+{
+ OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
+
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] set byteArray for data");
+ if(gSendBuffer)
+ {
+ (*env)->DeleteGlobalRef(env, gSendBuffer);
+ }
+ jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+ (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*)data);
+ gSendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
+
+ // get bonded device list
+ jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
+ if(!jni_arrayPairedDevices)
+ {
+ OIC_LOG_V(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
+ return 0;
+ }
+ // Get information from array of devices
+ jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
+ jsize 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)
+ {
+ const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
+ OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
+ (*env)->ReleaseStringUTFChars(env, j_str_name, name);
+ }
+
+ 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);
+
+ // find address
+ CAEDRNativeSendData(env, remoteAddress, data, i);
+ }
+
+ return 1;
+}
+
+/**
+ * EDR Method
+ */
+void CAEDRNativeSendData(JNIEnv *env, const char* address, const char* data, uint32_t id)
+{
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData logic start");
+
+ if(STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
+ {
+ // connect before send data
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] connect before send data");
+
+ if(NULL == address)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] remote address is empty");
+ return;
+ }
+ else
+ {
+ CAEDRNativeConnect(env, address, id);
+ }
+ }
+
+ if(STATE_CONNECTED == CAEDRIsConnectedDevice(address))
+ {
+ if(!((*env)->ExceptionCheck(env)))
+ {
+ jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
+ if(!jni_cid_BTsocket)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_cid_BTsocket is null");
+ return;
+ }
+
+ jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, "getOutputStream", "()Ljava/io/OutputStream;");
+ if(!jni_mid_getOutputStream)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_mid_getOutputStream is null");
+ return;
+ }
+ OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream..%d", id);
+
+ jobject jni_socket = CAEDRNativeGetDeviceSocket(id);
+ if(!jni_socket)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_socket is not available");
+ return;
+ }
+
+ jobject jni_obj_outputStream = (*env)->CallObjectMethod(env, jni_socket, jni_mid_getOutputStream);
+ if(!jni_obj_outputStream)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_obj_outputStream is null");
+ return;
+ }
+
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: ready outputStream..");
+
+ jclass jni_cid_OutputStream = (*env)->FindClass(env, "java/io/OutputStream");
+ if(!jni_cid_OutputStream)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_cid_OutputStream is null");
+ return;
+ }
+
+ jmethodID jni_mid_write = (*env)->GetMethodID(env, jni_cid_OutputStream, "write", "([BII)V");
+ if(!jni_mid_write)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_mid_write is null");
+ return;
+ }
+
+// jbyte buf[BUFSIZE] = "aaaaaaaaaaassssssssssa";
+
+ jbyteArray jbuf;
+// size_t nread = 20;
+ int length = strlen(data);
+ jbuf = (*env)->NewByteArray(env, length);
+ (*env)->SetByteArrayRegion(env, jbuf, 0, length, (jbyte*)data);
+
+ (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write, jbuf, (jint)0, (jint)length);
+
+ if((*env)->ExceptionCheck(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Error!!!");
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ return;
+ }
+
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Success");
+ }
+ else
+ {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: error!!");
+ return;
+ }
+
+ // close socket after data was sent
+ CAEDRNativeSocketClose(env, address, id);
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: BT connection is not completed!!");
+ }
+}
+
+int CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
+{
+ if(!((*env)->ExceptionCheck(env)))
+ {
+ // check whether this socket object is connected or not.
+ jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
+ if(!jni_obj_socket)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_socket is not available");
+ return -1;
+ }
+
+ jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
+ const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
+ if(STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: it is not connected yet..");
+ return -1;
+ }
+
+ // 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;");
+ OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d", id);
+
+ jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket, jni_mid_getInputStream);
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
+
+ jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
+ jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
+
+ jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
+ jlong nread;
+ while ((nread = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read, jbuf, (jint)0, MAX_PDU_BUFFER)) != -1)
+ {
+ if((*env)->ExceptionCheck(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: read Error!!!");
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ return -1;
+ }
+
+ jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
+ OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s", buf);
+ if (buf == NULL)
+ {
+ return -1;
+ }
+
+ switch (type)
+ {
+ case CA_UNICAST_SERVER:
+ case CA_MULTICAST_SERVER:
+ // Notify data to upper layer
+ if (gPacketReceiveCallback)
+ {
+// gPacketReceiveCallback(srcIPAddress, srcPort, recvBuffer, recvLen, false);
+ }
+ break;
+#ifdef __WITH_DTLS__
+ case CA_SECURED_UNICAST_SERVER:
+ break;
+#endif //__WITH_DTLS__
+ default:
+ // Should never occur
+ OIC_LOG_V(DEBUG, TAG, "Invalid server type");
+ return -1;
+ }
+
+ (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
+ break;
+ }
+ }
+ else
+ {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: env error!!");
+ return -1;
+ }
+
+ return 0;
+}
+
+jobject CAEDRNativeListen(JNIEnv *env)
+{
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
+
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+ if(!jni_cid_BTAdapter)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
+ return NULL;
+ }
+ // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
+ // setting UUID
+ jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
+ if(!jni_cid_uuid)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
+ return NULL;
+ }
+
+// jstring uuid = (*env)->NewStringUTF(env, "0000111f-0000-1000-8000-00805f9b8033");
+ jstring jni_uuid = (*env)->NewStringUTF(env, "00000000-0000-0000-0000-0000cdab0000");
+ jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid);
+ if(!jni_obj_uuid)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
+ return NULL;
+ }
+
+ // create socket
+ jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
+ jobject jni_obj_BTSeverSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen, jni_name, jni_obj_uuid);
+ if(!jni_obj_BTSeverSocket)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_obj_BTSeverSocket is null");
+ return NULL;
+ }
+
+ gServerSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTSeverSocket);
+
+ return jni_obj_BTSeverSocket;
+}
+
+void CAEDRNativeAccept(JNIEnv *env, jobject severSocketObject)
+{
+ if(severSocketObject != NULL)
+ {
+ jclass jni_cid_BTServerSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothServerSocket");
+ if(!jni_cid_BTServerSocket)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
+ return;
+ }
+
+ jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept", "()Landroid/bluetooth/BluetoothSocket;");
+ if(!jni_mid_accept)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
+ return;
+ }
+
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
+
+ jobject jni_obj_BTSocket = NULL;
+ jni_obj_BTSocket = (*env)->CallObjectMethod(env, severSocketObject, jni_mid_accept);
+ if(!jni_obj_BTSocket)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
+ return;
+ }
+
+ // get remote address
+ jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
+
+ 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);
+ CAEDRNativeAddDeviceSocketToList(env, jni_socket);
+
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
+
+ // update state
+ CAEDRUpdateDeviceState(STATE_CONNECTED, address);
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: severSocket is close previously");
+ }
+}
+
+void CAEDRNativeConnect(JNIEnv *env, const char* address, uint32_t id)
+{
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect..");
+
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+ if(!jni_cid_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTAdapter is null");
+ return;
+ }
+
+ // get BTadpater
+ 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;
+ }
+
+ 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;
+ }
+
+ // 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)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_getRemoteDevice is null");
+ return;
+ }
+
+ //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)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_remoteBTDevice is null");
+ return;
+ }
+
+ // get create Rfcomm Socket method ID
+ jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
+ if(!jni_cid_BluetoothDevice)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BluetoothDevice is null");
+ return;
+ }
+
+ 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;
+ }
+
+ // createInsecureRfcommSocketToServiceRecord / createRfcommSocketToServiceRecord
+ // setting UUID
+ jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
+ if(!jni_cid_uuid)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_uuid is null");
+ return;
+ }
+
+ 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;
+ }
+
+ jstring jni_uuid = (*env)->NewStringUTF(env, "00000000-0000-0000-0000-0000cdab0000");
+ jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid);
+ if(!jni_obj_uuid)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_uuid is null");
+ return;
+ }
+ // create socket
+ 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;
+ }
+
+ // connect
+ jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
+ if(!jni_cid_BTSocket)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTSocket is null");
+ return;
+ }
+
+ jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_BTSocket, "connect", "()V");
+ if(!jni_mid_connect)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_connect is null");
+ return;
+ }
+
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: initiating connection...");
+ (*env)->CallVoidMethod(env, jni_obj_BTSocket, jni_mid_connect);
+
+ if((*env)->ExceptionCheck(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: Connect is Failed!!!");
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ return;
+ }
+
+ // set socket to list
+ jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
+ CAEDRNativeAddDeviceSocketToList(env, jni_socket);
+
+ // update state
+ CAEDRUpdateDeviceState(STATE_CONNECTED, address);
+
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: connected");
+}
+
+void CAEDRNativeSocketClose(JNIEnv *env, const char* address, uint32_t id)
+{
+
+ jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
+ if(!jni_cid_BTSocket)
+ {
+ OIC_LOG(DEBUG, 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(DEBUG, TAG, "[EDR][Native] close: jni_mid_close is null");
+ return;
+ }
+
+ jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
+ if(!jni_obj_socket)
+ {
+ OIC_LOG(DEBUG, 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
+ CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
+
+ // update state
+ CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
+
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
+}
+
+/**
+ * BT common
+ */
+
+// get address from bluetooth socket
+jstring CAEDRNativeGetAddressFromDeviceSocket(JNIEnv *env, jobject bluetoothSocketObj)
+{
+ jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
+ if(!jni_cid_BTSocket)
+ {
+ OIC_LOG_V(DEBUG, 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)
+ {
+ OIC_LOG_V(DEBUG, 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)
+ {
+ OIC_LOG_V(DEBUG, TAG, "[EDR] getRemoteAddress: jni_obj_remoteBTDevice is null");
+ return NULL;
+ }
+
+ jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
+ jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress", "()Ljava/lang/String;");
+
+ jstring j_str_address = (*env)->CallObjectMethod(env, jni_obj_remoteBTDevice, j_mid_getAddress);
+ if(j_str_address)
+ {
+ const char * address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
+ OIC_LOG_V(DEBUG, TAG, "[EDR] getRemoteAddress: ~~ remote device address is %s", address);
+// (*env)->ReleaseStringUTFChars(env, j_str_address, address);
+ } else {
+ return NULL;
+ }
+ return j_str_address;
+}
+
+jstring CAEDRNativeGetLocalDeviceAddress(JNIEnv* env)
+{
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+ if(!jni_cid_BTAdapter)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] getAddress: jni_str_address is null");
+ return NULL;
+ }
+
+ return jni_str_address;
+}
+
+jobjectArray CAEDRNativeGetBondedDevices(JNIEnv *env)
+{
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+ if(!jni_cid_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] getBondedDevices: jni_cid_BTAdapter is null");
+ return NULL;
+ }
+
+ jmethodID jni_mid_getDefaultAdapter =
+ (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+
+ jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+ if(!jni_obj_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] getBondedDevices: bluetooth adapter is null");
+ return NULL;
+ }
+
+ // 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)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] getBondedDevices: jni_obj_setPairedDevices is null");
+ return NULL;
+ }
+
+ // Convert the set to an object array
+ // object[] array = Set<BluetoothDevice>.toArray();
+ jclass jni_cid_Set = (*env)->FindClass(env, "java/util/Set");
+ jmethodID jni_mid_toArray = (*env)->GetMethodID(env, jni_cid_Set, "toArray", "()[Ljava/lang/Object;");
+
+ if(!jni_mid_toArray)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] getBondedDevices: jni_arrayPairedDevices is null");
+ return NULL;
+ }
+
+ return jni_arrayPairedDevices;
+}
+
+jint CAEDRNativeGetBTStateOnInfo(JNIEnv *env)
+{
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+ if(!jni_cid_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] getBTStateOnInfo: jni_cid_BTAdapter is null");
+ return -1;
+ }
+
+ 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");
+ return -1;
+ }
+ 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);
+
+ return jni_int_val;
+}
+
+jboolean CAEDRNativeIsEnableBTAdapter(JNIEnv *env)
+{
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+ if(!jni_cid_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_cid_BTAdapter: jni_cid_BTAdapter is null");
+ return FALSE;
+ }
+
+ jmethodID jni_mid_getDefaultAdapter =
+ (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+ if(!jni_mid_getDefaultAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_mid_getDefaultAdapter is null");
+ return FALSE;
+ }
+
+ jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+ if(!jni_obj_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_obj_BTAdapter is null");
+ return FALSE;
+ }
+
+ // isEnable()
+ jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled",
+ "()Z");
+ if(!jni_mid_isEnable)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_mid_isEnable is null");
+ return FALSE;
+ }
+
+ jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
+ OIC_LOG_V(DEBUG, TAG, "[EDR][Native] adapter state is %d", jni_isEnable);
+
+ return jni_isEnable;
+}
+
+jstring CAEDRNativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
+{
+ jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
+ if(!jni_cid_device_list)
+ {
+ OIC_LOG(DEBUG, 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)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_mid_getAddress is null");
+ return NULL;
+ }
+
+ jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice, jni_mid_getAddress);
+ if(!jni_address)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_address is null");
+ return NULL;
+ }
+ return jni_address;
+}
+
+/**
+ * BT State List
+ */
+void CAEDRNativeCreateDeviceStateList()
+{
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceStateList");
+
+ // create new object array
+ if (gdeviceStateList == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Create device list");
+
+ gdeviceStateList = u_arraylist_create();
+ }
+}
+
+void CAEDRUpdateDeviceState(uint32_t state, const char* address)
+{
+ state_t *newstate = (state_t*) OICMalloc( sizeof(state_t) );
+ memset(newstate->address, 0, strlen(newstate->address));
+ strcpy(newstate->address, address);
+ newstate->state = state;
+
+ CAEDRNativeAddDeviceStateToList(newstate);
+}
+
+void CAEDRNativeAddDeviceStateToList(state_t* state)
+{
+ if(!state)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] device is null");
+ return;
+ }
+
+ if(!gdeviceStateList)
+ {
+ OIC_LOG(DEBUG, 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(gdeviceStateList, state); // update new state
+ OIC_LOG_V(DEBUG, TAG, "Set State to Connected State List");
+ }
+}
+
+jboolean CAEDRNativeIsDeviceInList(const char* remoteAddress){
+
+ jint index;
+ for (index = 0; index < u_arraylist_length(gdeviceStateList); index++)
+ {
+ state_t* state = (state_t*) u_arraylist_get(gdeviceStateList, index);
+ if(!state)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
+ return TRUE;
+ }
+
+ if(!strcmp(remoteAddress, state->address))
+ {
+ OIC_LOG_V(DEBUG, TAG, "the device is already set");
+ return TRUE;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "there are no the device in list.");
+ return FALSE;
+}
+
+void CAEDRNativeRemoveAllDeviceState()
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRNativeRemoveAllDevices");
+
+ if(!gdeviceStateList)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] gdeviceStateList is null");
+ return;
+ }
+
+ jint index;
+ for (index = 0; index < u_arraylist_length(gdeviceStateList); index++)
+ {
+ state_t* state = (state_t*) u_arraylist_get(gdeviceStateList, index);
+ if(!state)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
+ continue;
+ }
+ OICFree(state);
+ }
+
+ OICFree(gdeviceStateList);
+ gdeviceStateList = NULL;
+ return;
+}
+
+void CAEDRNativeRemoveDevice(const char* remoteAddress)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRNativeRemoveDevice");
+
+ if(!gdeviceStateList)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] gdeviceStateList is null");
+ return;
+ }
+
+ jint index;
+ for (index = 0; index < u_arraylist_length(gdeviceStateList); index++)
+ {
+ state_t* state = (state_t*) u_arraylist_get(gdeviceStateList, 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);
+
+ CAEDRReorderingDeviceList(index);
+ break;
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object");
+ return;
+}
+
+jboolean CAEDRIsConnectedDevice(const char* remoteAddress)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRNativeRemoveDevice");
+
+ if(!gdeviceStateList)
+ {
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] gdeviceStateList is null");
+ return FALSE;
+ }
+
+ jint index;
+ for (index = 0; index < u_arraylist_length(gdeviceStateList); index++)
+ {
+ state_t* state = (state_t*) u_arraylist_get(gdeviceStateList, 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] check whether it is connected or not");
+
+ return state->state;
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object");
+ return FALSE;
+}
+
+void CAEDRReorderingDeviceList(uint32_t index)
+{
+ if (index >= gdeviceStateList->length)
+ {
+ return;
+ }
+
+ if (index < gdeviceStateList->length - 1)
+ {
+ memmove(&gdeviceStateList->data[index], &gdeviceStateList->data[index + 1],
+ (gdeviceStateList->length - index - 1) * sizeof(void *));
+ }
+
+ gdeviceStateList->size--;
+ gdeviceStateList->length--;
+}
+
+/**
+ * Device Socket Object List
+ */
+void CAEDRNativeCreateDeviceSocketList()
+{
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] CAEDRNativeCreateDeviceSocketList");
+
+ // create new object array
+ if (gdeviceObjectList == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Create Device object list");
+
+ gdeviceObjectList = u_arraylist_create();
+ }
+}
+
+void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket)
+{
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeAddDeviceobjToList");
+
+ if(!deviceSocket)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] Device is null");
+ return;
+ }
+
+ if(!gdeviceObjectList)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
+ return;
+ }
+
+ jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket);
+ if(!jni_remoteAddress)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
+ return;
+ }
+
+ u_mutex_lock(gMutexSocketListManager);
+
+ const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+
+ if(!CAEDRNativeIsDeviceSocketInList(env, remoteAddress))
+ {
+ jobject gDeviceSocker = (*env)->NewGlobalRef(env, deviceSocket);
+ u_arraylist_add(gdeviceObjectList, gDeviceSocker);
+ OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
+ }
+
+ u_mutex_unlock(gMutexSocketListManager);
+}
+
+jboolean CAEDRNativeIsDeviceSocketInList(JNIEnv *env, const char* remoteAddress)
+{
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeIsDeviceObjInList");
+
+ jint index;
+ for (index = 0; index < u_arraylist_length(gdeviceObjectList); index++)
+ {
+
+ jobject jarrayObj = (jobject) u_arraylist_get(gdeviceObjectList, index);
+ if(!jarrayObj)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+ return TRUE;
+ }
+
+ jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
+ if(!jni_setAddress)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
+ return TRUE;
+ }
+
+ const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+
+ if(!strcmp(remoteAddress, setAddress))
+ {
+ OIC_LOG_V(DEBUG, TAG, "the device is already set");
+ return TRUE;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "there are no the Device obejct in list. we can add");
+ return FALSE;
+}
+
+void CAEDRNativeRemoveAllDeviceSocket(JNIEnv *env)
+{
+ OIC_LOG_V(DEBUG, TAG, "CANativeRemoveAllDeviceObjsList");
+
+ if(!gdeviceObjectList)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
+ return;
+ }
+
+ jint index;
+ for (index = 0; index < u_arraylist_length(gdeviceObjectList); index++)
+ {
+ jobject jarrayObj = (jobject) u_arraylist_get(gdeviceObjectList, index);
+ if(!jarrayObj)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+ return;
+ }
+ (*env)->DeleteGlobalRef(env, jarrayObj);
+ }
+
+ OICFree(gdeviceObjectList);
+ gdeviceObjectList = NULL;
+ return;
+}
+
+void CAEDRNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRNativeRemoveDeviceSocket");
+
+ if(!gdeviceObjectList)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
+ return;
+ }
+
+ u_mutex_lock(gMutexSocketListManager);
+
+ jint index;
+ for (index = 0; index < u_arraylist_length(gdeviceObjectList); index++)
+ {
+ jobject jarrayObj = (jobject) u_arraylist_get(gdeviceObjectList, index);
+ if(!jarrayObj)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+ continue;
+ }
+
+ jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
+ if(!jni_setAddress)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][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, "[BLE][Native] jni_remoteAddress is null");
+ continue;
+ }
+ const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+
+ if(!strcmp(setAddress, remoteAddress))
+ {
+ OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
+ (*env)->DeleteGlobalRef(env, jarrayObj);
+
+ CAEDRReorderingDeviceSocketList(index);
+ break;
+ }
+ }
+ u_mutex_unlock(gMutexSocketListManager);
+
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
+ return;
+}
+
+jobject CAEDRNativeGetDeviceSocket(uint32_t idx)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEDRNativeGetDeviceSocket");
+
+ if(idx < 0)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] index is not available");
+ return NULL;
+ }
+
+ if(!gdeviceObjectList)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
+ return NULL;
+ }
+
+ jobject jarrayObj = (jobject) u_arraylist_get(gdeviceObjectList, idx);
+ if(!jarrayObj)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is not available");
+ return NULL;
+ }
+ return jarrayObj;
+}
+
+uint32_t CAEDRGetSocketListLength()
+{
+ if(!gdeviceObjectList)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
+ return 0;
+ }
+
+ uint32_t length = u_arraylist_length(gdeviceObjectList);
+
+ return length;
+}
+
+void CAEDRReorderingDeviceSocketList(uint32_t index)
+{
+ if (index >= gdeviceObjectList->length)
+ {
+ return;
+ }
+
+ if (index < gdeviceObjectList->length - 1)
+ {
+ memmove(&gdeviceObjectList->data[index], &gdeviceObjectList->data[index + 1],
+ (gdeviceObjectList->length - index - 1) * sizeof(void *));
+ }
+
+ gdeviceObjectList->size--;
+ gdeviceObjectList->length--;
+}
--- /dev/null
+/******************************************************************
+ *
+ * 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 caedradapter.c
+ * @brief This file contains the APIs for EDR adapter.
+ */
+
+#include "caedradapter.h"
+
+#include "caedrinterface.h"
+#include "caadapterutils.h"
+#include "logger.h"
+#include "camsgparser.h"
+#include "caqueueingthread.h"
+
+/**
+ * @var EDR_ADAPTER_TAG
+ * @brief Logging tag for module name.
+ */
+#define EDR_ADAPTER_TAG "CA_EDR_ADAPTER"
+
+/**
+ * @var gEDRThreadPool
+ * @brief Reference to threadpool.
+ */
+static u_thread_pool_t gEDRThreadPool = NULL;
+
+/**
+ * @var gSendQueueHandle
+ * @brief Queue handle for Send Data
+ */
+static CAQueueingThread_t *gSendQueueHandle = NULL;
+
+/**
+ * @var gRecvQueueHandle
+ * @brief Queue handle for Receive Data
+ */
+static CAQueueingThread_t *gRecvQueueHandle = NULL;
+
+/**
+ * @var isHeaderAvailable
+ * @brief to differentiate btw header and data packet.
+ */
+static CABool_t isHeaderAvailable = CA_FALSE;
+
+/**
+ * @var gAdapterState
+ * @brief Storing Adapter state information
+ */
+static CABool_t gAdapterState = CA_TRUE;
+
+/**
+ * @var gNetworkPacketReceivedCallback
+ * @brief Maintains the callback to be notified on receival of network packets from other
+ * Bluetooth devices.
+ */
+static CANetworkPacketReceivedCallback gNetworkPacketReceivedCallback = NULL;
+
+/**
+ * @var gNetworkChangeCallback
+ * @brief Maintains the callback to be notified on local bluetooth adapter status change.
+ */
+static CANetworkChangeCallback gNetworkChangeCallback = NULL;
+
+/**
+ * @var gLocalConnectivity
+ * @brief Information of local Bluetooth adapter.
+ */
+static CALocalConnectivity_t *gLocalConnectivity = NULL;
+
+/**
+ * @var gServerId
+ * @brief Storing RfcommserverUUID
+ */
+static int32_t gServerId = -1;
+
+/**
+ * @var gServerState
+ * @brief Storing Rfcommserver state information
+ */
+static CABool_t gServerState = CA_FALSE;
+
+static CAResult_t CAStartServer(void);
+static CAResult_t CAEDRInitializeQueueHandlers(void);
+CAResult_t CAEDRInitializeSendHandler(void);
+CAResult_t CAEDRInitializeReceiveHandler(void);
+void CAAdapterTerminateQueues(void);
+void CAAdapterDataSendHandler(void *context);
+void CAAdapterDataReceiverHandler(void *context);
+CAResult_t CAAdapterStopQueue();
+void CAAdapterRecvData(const char *remoteAddress, void *data,
+ uint32_t dataLength, uint32_t *sentLength);
+void CAEDRNotifyNetworkStatus(CANetworkStatus_t status);
+void CAEDROnNetworkStatusChanged(void *context);
+CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength);
+CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CALocalConnectivity_t *connectivity,
+ CANetworkStatus_t status);
+CAResult_t CAEDRClientSendData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength);
+/**
+ * @fn CACreateEDRData
+ * @brief Helper function to create CAEDRData
+ */
+static CAEDRData *CACreateEDRData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength);
+
+/**
+ * @fn CAFreeEDRData
+ * @brief Free the Created EDR data
+ */
+static void CAFreeEDRData(CAEDRData *edrData);
+
+/**
+ * @fn CAEDRFreeNetworkEvent
+ * @brief Free the memory associated with @event.
+ */
+void CAEDRFreeNetworkEvent(CAEDRNetworkEvent *event);
+
+CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
+ CANetworkPacketReceivedCallback packetReceivedCallback,
+ CANetworkChangeCallback networkStateChangeCallback,
+ u_thread_pool_t handle)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Input validation
+ VERIFY_NON_NULL(registerCallback, EDR_ADAPTER_TAG, "register callback is NULL");
+ VERIFY_NON_NULL(packetReceivedCallback, EDR_ADAPTER_TAG, "data receive callback is NULL");
+ VERIFY_NON_NULL(networkStateChangeCallback, EDR_ADAPTER_TAG,
+ "network state change callback is NULL");
+ VERIFY_NON_NULL(handle, EDR_ADAPTER_TAG, "Thread pool hanlde is NULL");
+
+ // Register the callbacks
+
+ gEDRThreadPool = handle;
+ gNetworkPacketReceivedCallback = packetReceivedCallback;
+ gNetworkChangeCallback = networkStateChangeCallback;
+
+ // Initialize EDR Network Monitor
+ CAResult_t err = CAEDRInitializeNetworkMonitor();
+ if (CA_STATUS_OK != err)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "EDR N/w Monitor Initialize failed!, error number [%d]",
+ err);
+ return err;
+ }
+
+ CAEDRSetNetworkChangeCallback(CAEDRNotifyNetworkStatus);
+ CAEDRSetPacketReceivedCallback(CAAdapterRecvData);
+ CAEDRInitializeClient();
+
+ CAConnectivityHandler_t handler;
+ handler.startAdapter = CAStartEDR;
+ handler.startListenServer = CAStartEDRListeningServer;
+ handler.startDiscoverServer = CAStartEDRDiscoveryServer;
+ handler.sendData = CASendEDRUnicastData;
+ handler.sendDataToAll = CASendEDRMulticastData;
+ handler.GetnetInfo = CAGetEDRInterfaceInformation;
+ handler.readData = CAReadEDRData;
+ handler.stopAdapter = CAStopEDR;
+ handler.terminate = CATerminateEDR;
+ registerCallback(handler, CA_EDR);
+
+ // Initialize Send/Receive data message queues
+ if (CA_STATUS_OK != CAEDRInitializeQueueHandlers())
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "CAAdapterInitializeQueues API failed");
+ CATerminateEDR();
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAStartEDR(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ //Start Monitoring EDR Network
+ CAResult_t ret = CAEDRStartNetworkMonitor();
+ if(CA_STATUS_OK != ret)
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to Start n/w monitor");
+ }
+
+ // Get Bluetooth adapter state
+ CABool_t adapterState = CA_FALSE;
+ if (CA_STATUS_OK != CAEDRGetAdapterEnableState(&adapterState))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get adapter enable state");
+ return CA_STATUS_FAILED;
+ }
+
+ if (CA_FALSE == adapterState)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Bluetooth adapter is disabled!");
+ gAdapterState = CA_FALSE;
+ return CA_STATUS_OK;
+ }
+
+ if (CA_STATUS_OK != (ret = CAEDRClientSetCallbacks()))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Start Network Monitor failed!, error number [%d] ",
+ ret);
+ }
+
+ if (CA_STATUS_OK != (ret = CAAdapterStartQueue()))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "CAAdapterStartQueue failed!, error number [%d] ",
+ ret);
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return ret;
+}
+
+CAResult_t CAStartEDRListeningServer(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ return CAStartServer();
+}
+
+CAResult_t CAStartEDRDiscoveryServer(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ return CAStartServer();
+}
+
+uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ CAResult_t err = CA_STATUS_OK;
+
+ // Input validation
+ VERIFY_NON_NULL_RET(remoteEndpoint, EDR_ADAPTER_TAG, "Remote endpoint is null", 0);
+ VERIFY_NON_NULL_RET(data, EDR_ADAPTER_TAG, "Data is null", 0);
+
+ if (0 == strlen(remoteEndpoint->addressInfo.BT.btMacAddress))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: EDR Address is empty!");
+ return 0;
+ }
+
+ if (0 == dataLength)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: data length is zero!");
+ return 0;
+ }
+
+ uint32_t sentLength = 0;
+ const char *serviceUUID = OIC_EDR_SERVICE_ID;
+ const char *address = remoteEndpoint->addressInfo.BT.btMacAddress;
+ if (CA_STATUS_OK != (err = CAAdapterSendData(address, serviceUUID, data,
+ dataLength, &sentLength)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Send unicast data failed!, error num [%d]", err);
+ return 0;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return sentLength;
+}
+
+uint32_t CASendEDRMulticastData(void *data, uint32_t dataLength)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ CAResult_t err = CA_STATUS_OK;
+
+ // Input validation
+ VERIFY_NON_NULL_RET(data, EDR_ADAPTER_TAG, "Data is null", 0);
+
+ if (0 == dataLength)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: data length is zero!");
+ return 0;
+ }
+
+ uint32_t sentLen = 0;
+ const char *serviceUUID = OIC_EDR_SERVICE_ID;
+ if (CA_STATUS_OK != (err = CAAdapterSendData(NULL, serviceUUID, data, dataLength,
+ &sentLen)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Send multicast data failed!, error num [%d]",
+ err);
+ return 0;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return sentLen;
+}
+
+
+CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(info, EDR_ADAPTER_TAG, "LocalConnectivity info is null");
+
+ CAResult_t err = CA_STATUS_OK;
+ *size = 0;
+ if (CA_STATUS_OK != (err = CAEDRGetInterfaceInformation(info)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
+ "Failed to get local interface information!, error num [%d]", err);
+ return err;
+ }
+
+ *size = 1;
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return err;
+}
+
+CAResult_t CAReadEDRData(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ return CAEDRManagerReadData();
+}
+
+CAResult_t CAStopEDR(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Stop RFComm server if it is running
+ if (-1 != gServerId)
+ {
+ CAEDRServerStop(gServerId);
+ gServerId = -1;
+ }
+
+ // Stop network monitor
+ CAEDRStopNetworkMonitor();
+
+ // Stop the adapter
+ CAEDRClientUnsetCallbacks();
+
+ // Disconnect all the client connections
+ CAEDRClientDisconnectAll();
+
+ // Stop Send and receive Queue
+ CAAdapterStopQueue();
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CATerminateEDR(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Terminate EDR Network Monitor
+ CAEDRTerminateNetworkMonitor();
+
+ // Terminate BT Client
+ CAEDRTerminateClient();
+
+ // Terminate Send/Receive data messages queues
+ CAAdapterTerminateQueues();
+
+ gNetworkPacketReceivedCallback = NULL;
+ gNetworkChangeCallback = NULL;
+
+ // Terminate thread pool
+ gEDRThreadPool = NULL;
+
+ // Free LocalConnectivity information
+ CAAdapterFreeLocalEndpoint(gLocalConnectivity);
+ gLocalConnectivity = NULL;
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+CAResult_t CAStartServer(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ CAResult_t err = CA_STATUS_OK;
+
+ if (CA_FALSE == gAdapterState)
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Bluetooth adapter is disabled!");
+ // Setting gServerState for starting Rfcommserver when adapter starts
+ gServerState = TRUE;
+ return CA_STATUS_OK;
+ }
+
+ if (-1 < gServerId)
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Server is already in running state.");
+ return CA_STATUS_OK;
+ }
+
+ if (CA_STATUS_OK != (err = CAEDRServerStart(OIC_EDR_SERVICE_ID, &gServerId)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to start RFCOMM server!, error num [%d]",
+ err);
+ return err;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return err;
+}
+
+CAResult_t CAEDRInitializeQueueHandlers(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ if (CA_STATUS_OK == CAEDRInitializeSendHandler()
+ && CA_STATUS_OK == CAEDRInitializeReceiveHandler())
+ {
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Queue is initialized!");
+ return CA_STATUS_OK;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_FAILED;
+}
+
+CAResult_t CAEDRInitializeSendHandler(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+ // Check if the message queue is already initialized
+ if (gSendQueueHandle)
+ {
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Already queue is initialized!");
+ return CA_STATUS_OK;
+ }
+
+ gSendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
+ if (!gSendQueueHandle)
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Memory allocation failed!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAQueueingThreadInitialize(gSendQueueHandle, gEDRThreadPool,
+ CAAdapterDataSendHandler, NULL))
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to Initialize send queue thread");
+ return CA_STATUS_FAILED;
+ }
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRInitializeReceiveHandler(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+ // Check if the message queue is already initialized
+ if (gRecvQueueHandle)
+ {
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Already queue is initialized!");
+ return CA_STATUS_OK;
+ }
+
+ gRecvQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
+ if (!gRecvQueueHandle)
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Memory allocation failed!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAQueueingThreadInitialize(gRecvQueueHandle, gEDRThreadPool,
+ CAAdapterDataReceiverHandler, NULL))
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to Initialize send queue thread");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAAdapterTerminateQueues(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ if (gSendQueueHandle)
+ {
+ CAQueueingThreadDestroy(gSendQueueHandle);
+ gSendQueueHandle = NULL;
+ }
+ if (gRecvQueueHandle)
+ {
+ CAQueueingThreadDestroy(gRecvQueueHandle);
+ gRecvQueueHandle = NULL;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CAAdapterDataSendHandler(void *context)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ CAEDRData *message = (CAEDRData *) context;
+ if (message == NULL)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get message!");
+ return;
+ }
+ const char *remoteAddress = NULL;
+ const char *serviceUUID = NULL;
+ uint32_t sentLength = 0;
+
+ remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
+ serviceUUID = message->remoteEndpoint->resourceUri;
+
+ char *dataSegment = NULL;
+ int32_t datalen = message->dataLen;
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "checking for fragmentation and the dataLen is %d",
+ datalen);
+
+
+ char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+ VERIFY_NON_NULL_VOID(header, EDR_ADAPTER_TAG, "Malloc failed");
+
+ dataSegment = (char *) OICMalloc(sizeof(char) * message->dataLen + CA_HEADER_LENGTH);
+ if (NULL == dataSegment)
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Malloc failed");
+ OICFree(header);
+ return;
+ }
+
+ memset(header, 0x0, sizeof(char) * CA_HEADER_LENGTH );
+ memset(dataSegment, 0x0, sizeof(char) * message->dataLen );
+
+ CAResult_t result = CAGenerateHeader(header, message->dataLen);
+ if (CA_STATUS_OK != result )
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Generate header failed");
+ OICFree(header);
+ OICFree(dataSegment);
+ return ;
+ }
+
+ memcpy(dataSegment, header, CA_HEADER_LENGTH);
+ OICFree(header);
+ int32_t length = 0;
+ if (CA_SUPPORTED_BLE_MTU_SIZE >= message->dataLen)
+ {
+ length = message->dataLen + CA_HEADER_LENGTH;
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "length [%d]", length);
+ memcpy(dataSegment + CA_HEADER_LENGTH, message->data, message->dataLen);
+ }
+ else
+ {
+ length = CA_SUPPORTED_BLE_MTU_SIZE;
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "length [%d]", length);
+ memcpy(dataSegment + CA_HEADER_LENGTH, message->data,
+ CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH);
+ }
+
+ int32_t iter = message->dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
+ int32_t index = 0;
+ if (CA_STATUS_OK != CAEDRClientSendData(remoteAddress, serviceUUID,
+ dataSegment, length, &sentLength))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "CAEDRClientSendData API failed");
+ OICFree(dataSegment);
+ return;
+ }
+ OICFree(dataSegment);
+
+ for (index = 1; index < iter; index++)
+ {
+ // Send the remaining header.
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Sending the chunk number [%d]", index);
+
+ if (CA_STATUS_OK != CAEDRClientSendData(remoteAddress, serviceUUID,
+ message->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH),
+ CA_SUPPORTED_BLE_MTU_SIZE, &sentLength))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "CAEDRClientSendData API failed");
+ return;
+ }
+ }
+
+ if (message->dataLen / CA_SUPPORTED_BLE_MTU_SIZE)
+ {
+ // send the last segment of the data (Ex: 22 bytes of 622 bytes of data when MTU is 200)
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Sending the last chunk");
+ if (CA_STATUS_OK != CAEDRClientSendData(remoteAddress, serviceUUID,
+ message->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+ message->dataLen % CA_SUPPORTED_BLE_MTU_SIZE + CA_HEADER_LENGTH, &sentLength))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "CAEDRClientSendData API failed");
+ return;
+ }
+ }
+
+ // Free message
+ CAFreeEDRData(message);
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+CAResult_t CAEDRClientSendData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength)
+{
+ // Send the first segment with the header.
+ if (strlen(remoteAddress)) //Unicast data
+ {
+ if (CA_STATUS_OK != CAEDRClientSendUnicastData(remoteAddress, serviceUUID,
+ data, dataLength, sentLength))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send unicast data !");
+ return CA_STATUS_FAILED;
+ }
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "sending multicast data");
+ if (CA_STATUS_OK != CAEDRClientSendMulticastData(serviceUUID, data,
+ dataLength, sentLength))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send multicast data !");
+ return CA_STATUS_FAILED;
+ }
+ }
+ return CA_STATUS_OK;
+}
+void CAAdapterDataReceiverHandler(void *context)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+
+ CAEDRData *message = (CAEDRData *) context;
+ if (message == NULL)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get message!");
+ return;
+ }
+ const char *remoteAddress = NULL;
+ const char *serviceUUID = NULL;
+ static uint32_t recvDataLen = 0;
+ static uint32_t totalDataLen = 0;
+ static char *defragData = NULL;
+ static CARemoteEndpoint_t *remoteEndpoint = NULL;
+
+ if (!isHeaderAvailable)
+ {
+ char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+
+ if (NULL == header)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Out of memory (header)!");
+ return;
+ }
+ memcpy(header, (char *)message->data, CA_HEADER_LENGTH);
+ totalDataLen = CAParseHeader(header);
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Total data to be accumulated [%d] bytes",
+ totalDataLen);
+ defragData = NULL;
+ if (totalDataLen == 0)
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, " totalDataLen is zero");
+ OICFree(header);
+ return;
+ }
+ defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
+ OICFree(header);
+
+ remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
+ serviceUUID = message->remoteEndpoint->resourceUri;
+
+ remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+ serviceUUID);
+
+ memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
+ message->dataLen - CA_HEADER_LENGTH);
+ recvDataLen += message->dataLen - CA_HEADER_LENGTH;
+ isHeaderAvailable = CA_TRUE;
+ }
+ else
+ {
+ memcpy(defragData + recvDataLen, message->data, message->dataLen);
+ recvDataLen += message->dataLen ;
+ }
+ CAFreeEDRData(message);
+ if (totalDataLen == recvDataLen)
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Sending data up !");
+ gNetworkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
+ recvDataLen = 0;
+ totalDataLen = 0;
+ remoteEndpoint = NULL;
+ isHeaderAvailable = CA_FALSE;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+CAResult_t CAAdapterStartQueue()
+{
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
+ // Start send queue thread
+ if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to Start Send Data Thread");
+ CAEDRClientUnsetCallbacks();
+ //Disconnect all the client connections
+ CAEDRClientDisconnectAll();
+ return CA_STATUS_FAILED;
+ }
+
+ // Start receive queue thread
+ if (CA_STATUS_OK != CAQueueingThreadStart(gRecvQueueHandle))
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to Start Receive Data Thread");
+ CAEDRClientUnsetCallbacks();
+ //Disconnect all the client connections
+ CAEDRClientDisconnectAll();
+ return CA_STATUS_FAILED;
+ }
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAAdapterStopQueue()
+{
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
+ //Stop send queue thread
+ CAQueueingThreadStop(gSendQueueHandle);
+
+ //Stop receive queue thread
+ CAQueueingThreadStop(gRecvQueueHandle);
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAAdapterRecvData(const char *remoteAddress, void *data,
+ uint32_t dataLength, uint32_t *sentLength)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ if (CA_FALSE == gAdapterState)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Bluetooth adapter is disabled!");
+ *sentLength = 0;
+ return;
+ }
+
+ char *serviceUUID = OIC_EDR_SERVICE_ID;
+
+ // Input validation
+ VERIFY_NON_NULL_VOID(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null");
+ VERIFY_NON_NULL_VOID(data, EDR_ADAPTER_TAG, "Data is null");
+ VERIFY_NON_NULL_VOID(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
+
+ // Create remote endpoint
+ CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+ serviceUUID);
+ if (NULL == remoteEndpoint)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to create remote endpoint !");
+ return;
+ }
+
+ // Add message to data queue
+ CAEDRData *edrData = CACreateEDRData(remoteEndpoint, data, dataLength);
+ CAQueueingThreadAddData(gRecvQueueHandle, edrData, sizeof(CARemoteEndpoint_t));
+ *sentLength = dataLength;
+
+ // Free remote endpoint
+ CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return;
+}
+
+CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ if (CA_FALSE == gAdapterState)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Bluetooth adapter is disabled!");
+ *sentLength = 0;
+ return CA_STATUS_OK;
+ }
+ // Input validation
+ VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null");
+ VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
+ VERIFY_NON_NULL(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
+
+ // Create remote endpoint
+ CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+ serviceUUID);
+ if (NULL == remoteEndpoint)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to create remote endpoint !");
+ return CA_STATUS_FAILED;
+ }
+
+ // Add message to data queue
+ CAEDRData *edrData = CACreateEDRData(remoteEndpoint, data, dataLength);
+ CAQueueingThreadAddData(gSendQueueHandle, edrData, sizeof(CARemoteEndpoint_t));
+ *sentLength = dataLength;
+
+ // Free remote endpoint
+ CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAEDRNotifyNetworkStatus(CANetworkStatus_t status)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Create localconnectivity
+ if (NULL == gLocalConnectivity)
+ {
+ CAEDRGetInterfaceInformation(&gLocalConnectivity);
+ }
+
+ if(CA_INTERFACE_UP == status)
+ {
+ if(CA_FALSE == gAdapterState)
+ {
+ // Get Bluetooth adapter state
+ CABool_t adapterState = CA_FALSE;
+ if (CA_STATUS_OK != CAEDRGetAdapterEnableState(&adapterState))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get adapter enable state");
+ return;
+ }
+
+ if (CA_FALSE== adapterState)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Bluetooth adapter is disabled!");
+ gAdapterState = CA_FALSE;
+ return;
+ }
+ CAEDRClientSetCallbacks();
+ gAdapterState = CA_TRUE;
+ CAAdapterStartQueue();
+ // starting RFCommServer
+ if(CA_TRUE == gServerState)
+ {
+ CAStartServer();
+ gServerState = CA_FALSE;
+ }
+ }
+ }
+ else
+ {
+ gAdapterState = CA_FALSE;
+ }
+
+ // Notity to upper layer
+ if (gNetworkChangeCallback && gLocalConnectivity && gEDRThreadPool)
+ {
+ // Add notification task to thread pool
+ CAEDRNetworkEvent *event = CAEDRCreateNetworkEvent(gLocalConnectivity, status);
+ if (NULL != event)
+ {
+ if (CA_STATUS_OK != u_thread_pool_add_task(gEDRThreadPool, CAEDROnNetworkStatusChanged,
+ event))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to create threadpool!");
+ return;
+ }
+ }
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CAEDROnNetworkStatusChanged(void *context)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ if (NULL == context)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "context is NULL!");
+ return;
+ }
+
+ CAEDRNetworkEvent *networkEvent = (CAEDRNetworkEvent *) context;
+
+ // Notity to upper layer
+ if (gNetworkChangeCallback)
+ {
+ gNetworkChangeCallback(networkEvent->info, networkEvent->status);
+ }
+
+ // Free the created Network event
+ CAEDRFreeNetworkEvent(networkEvent);
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CALocalConnectivity_t *connectivity,
+ CANetworkStatus_t status)
+{
+ VERIFY_NON_NULL_RET(connectivity, EDR_ADAPTER_TAG, "connectivity is NULL", NULL);
+
+ // Create CAEDRNetworkEvent
+ CAEDRNetworkEvent *event = (CAEDRNetworkEvent *) OICMalloc(sizeof(CAEDRNetworkEvent));
+ if (NULL == event)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to allocate memory to network event!");
+ return NULL;
+ }
+
+ // Create duplicate of Local connectivity
+ event->info = CAAdapterCopyLocalEndpoint(connectivity);
+ event->status = status;
+ return event;
+}
+
+void CAEDRFreeNetworkEvent(CAEDRNetworkEvent *event)
+{
+ if (event)
+ {
+ CAAdapterFreeLocalEndpoint(event->info);
+ OICFree(event);
+ }
+}
+
+CAEDRData *CACreateEDRData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength)
+{
+ CAEDRData *edrData = (CAEDRData *) OICMalloc(sizeof(CAEDRData));
+ if (!edrData)
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Memory allocation failed!");
+ return NULL;
+ }
+
+ edrData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
+ edrData->data = (void *)OICMalloc(dataLength);
+ if (NULL == edrData->data)
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Memory allocation failed!");
+ CAFreeEDRData(edrData);
+ return NULL;
+ }
+ memcpy(edrData->data, data, dataLength);
+ edrData->dataLen = dataLength;
+
+ return edrData;
+}
+
+void CAFreeEDRData(CAEDRData *edrData)
+{
+ if (!edrData)
+ return;
+
+ CAAdapterFreeRemoteEndpoint(edrData->remoteEndpoint);
+ OICFree(edrData->data);
+ OICFree(edrData);
+}
+
+++ /dev/null
-/******************************************************************
- *
- * 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 cabtclient.c
- * @brief This file provides the APIs to establish RFCOMM connection with remote bluetooth device
- */
-
-#include "cabtclient.h"
-#include "caadapterutils.h"
-#include "cabtutils.h"
-#include "logger.h"
-
-CAResult_t CABTClientConnect(const char *remoteAddress, const char *serviceUUID)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- bt_error_e err = BT_ERROR_NONE;
- int32_t addressLen = 0;
-
- VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null");
- VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "Service UUID is null");
-
- addressLen = strlen(remoteAddress);
- if (0 == addressLen || CA_MACADDR_SIZE - 1 != addressLen)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Invalid remote address");
- return CA_STATUS_INVALID_PARAM;
- }
-
- if (0 == strlen(serviceUUID))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Empty service uuid");
- return CA_STATUS_INVALID_PARAM;
- }
-
- if (BT_ERROR_NONE != (err = bt_socket_connect_rfcomm(remoteAddress, serviceUUID)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG,
- "Failed to connect!, address [%s] error num [%x]",
- remoteAddress, err);
- return CA_STATUS_FAILED;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTClientDisconnect(const int32_t clientID)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- //Input validation
- if (0 > clientID)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: negative client id");
- return CA_STATUS_INVALID_PARAM;
- }
-
- bt_error_e err = BT_ERROR_NONE;
- if (BT_ERROR_NONE != (err = bt_socket_disconnect_rfcomm(clientID)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed close rfcomm client socket!, error num [%x]",
- err);
- return CA_STATUS_FAILED;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
+++ /dev/null
-/******************************************************************
- *
- * 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 cabtclient.h
- * @brief This file provides the APIs to establish RFCOMM connection with remote bluetooth device.
- */
-
-#ifndef __CA_BT_CLIENT_H_
-#define __CA_BT_CLIENT_H_
-
-#include <string.h>
-#include <bluetooth.h>
-
-#include "cacommon.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @fn CABTClientConnect
- * @brief Establishes RFCOMM connection with remote bluetooth device
- *
- * @param[in] remoteAddress The address of remote bluetooth device to which connection needs to be
- * established.
- * @param[in] serviceUUID The UUID of service to which RFCOMM connection needs to established.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- *
- */
-CAResult_t CABTClientConnect(const char *remoteAddress, const char *serviceUUID);
-
-/**
- * @fn CABTClientDisconnect
- * @brief Disconnect RFCOMM client socket connection
- *
- * @param[in] clientID The RFCOMM client socket file descriptor
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- *
- */
-CAResult_t CABTClientDisconnect(const int32_t clientID);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif //__CA_BT_CLIENT_H_
\ No newline at end of file
+++ /dev/null
-/******************************************************************
- *
- * 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 cabtdevicelist.c
- * @brief This file provides APIs to access the discovered bluetooth device list
- */
-
-#include "cabtdevicelist.h"
-#include "caadapterutils.h"
-#include "cabtutils.h"
-#include "logger.h"
-
-
-/**
- * @fn CACreateBTDevice
- * @brief Creates #BTDevice for specified remote address and uuid.
- *
- */
-static CAResult_t CACreateBTDevice(const char *deviceAddress, const char *uuid, BTDevice **device);
-
-
-/**
- * @fn CADestroyBTDevice
- * @brief Free all the memory associated with specified device.
- *
- */
-static void CADestroyBTDevice(BTDevice *device);
-
-
-/**
- * @fn CADestroyBTData
- * @brief Free all the memory associated with specified data.
- *
- */
-static void CADestroyBTData(BTData *data);
-
-
-CAResult_t CACreateAndAddToDeviceList(BTDeviceList **deviceList, const char *deviceAddress,
- const char *uuid, BTDevice **device)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(deviceList, BLUETOOTH_ADAPTER_TAG, "Device list is null");
- VERIFY_NON_NULL(deviceAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null");
- VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null");
-
- if (CA_STATUS_OK != CACreateBTDevice(deviceAddress, uuid, device) || NULL == *device)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid or Not bonded device!");
- return CA_STATUS_FAILED;
- }
-
- if (CA_STATUS_OK != CAAddBTDeviceToList(deviceList, *device))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add in list!");
-
- //Remove created BTDevice
- CADestroyBTDevice(*device);
- *device = NULL;
-
- return CA_STATUS_FAILED;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CACreateBTDevice(const char *deviceAddress, const char *uuid, BTDevice **device)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(deviceAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null");
- VERIFY_NON_NULL(uuid, BLUETOOTH_ADAPTER_TAG, "uuid is null");
- VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null");
-
- *device = (BTDevice *) OICMalloc(sizeof(BTDevice));
- if (NULL == *device)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Out of memory (device)!");
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- //Copy bluetooth address
- if (strlen(deviceAddress))
- {
- (*device)->remoteAddress = strndup(deviceAddress, strlen(deviceAddress));
- if (NULL == (*device)->remoteAddress)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Out of memory (remote address)!");
-
- OICFree(*device);
- *device = NULL;
- return CA_MEMORY_ALLOC_FAILED;
- }
- }
-
- //Copy OIC service uuid
- if (strlen(uuid))
- {
- (*device)->serviceUUID = strndup(uuid, strlen(uuid));
- if (NULL == (*device)->serviceUUID)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG,
- "[createBTDevice] Out of memory (service uuid)!");
-
- OICFree((*device)->remoteAddress);
- OICFree(*device);
- *device = NULL;
- return CA_MEMORY_ALLOC_FAILED;
- }
- }
-
- (*device)->socketFD = -1;
- (*device)->pendingDataList = NULL;
- (*device)->serviceSearched = 0;
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAAddBTDeviceToList(BTDeviceList **deviceList, BTDevice *device)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(deviceList, BLUETOOTH_ADAPTER_TAG, "Device list is null");
- VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null");
-
- BTDeviceList *node = (BTDeviceList *) OICMalloc(sizeof(BTDeviceList));
- if (NULL == node)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Out of memory (device list)!");
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- node->device = device;
- node->next = NULL;
-
- if (NULL == *deviceList) //Empty list
- {
- *deviceList = node;
- }
- else //Add at front end
- {
- node->next = *deviceList;
- *deviceList = node;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAGetBTDevice(BTDeviceList *deviceList, const char *deviceAddress, BTDevice **device)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(deviceList, BLUETOOTH_ADAPTER_TAG, "Device list is null");
- VERIFY_NON_NULL(deviceAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null");
- VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null");
-
- BTDeviceList *curNode = deviceList;
- *device = NULL;
- while (curNode != NULL)
- {
- if (!strcasecmp(curNode->device->remoteAddress, deviceAddress))
- {
- *device = curNode->device;
- return CA_STATUS_OK;
- }
-
- curNode = curNode->next;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT [Device not found!]");
- return CA_STATUS_FAILED;
-}
-
-CAResult_t CAGetBTDeviceBySocketId(BTDeviceList *deviceList, int32_t socketID, BTDevice **device)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(deviceList, BLUETOOTH_ADAPTER_TAG, "Device list is null");
- VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null");
- BTDeviceList *curNode = deviceList;
- *device = NULL;
- while (curNode != NULL)
- {
- if (curNode->device->socketFD == socketID)
- {
- *device = curNode->device;
- return CA_STATUS_OK;
- }
-
- curNode = curNode->next;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_FAILED;
-}
-
-CAResult_t CARemoveBTDeviceFromList(BTDeviceList **deviceList, const char *deviceAddress)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(deviceList, BLUETOOTH_ADAPTER_TAG, "Device list is null");
- VERIFY_NON_NULL(deviceAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null");
-
- BTDeviceList *curNode = NULL;
- BTDeviceList *prevNode = NULL;
-
- curNode = *deviceList;
- while (curNode != NULL)
- {
- if (!strcasecmp(curNode->device->remoteAddress, deviceAddress))
- {
- if (curNode == *deviceList)
- {
- *deviceList = curNode->next;
-
- curNode->next = NULL;
- CADestroyBTDeviceList(&curNode);
- return CA_STATUS_OK;
- }
- else
- {
- prevNode->next = curNode->next;
-
- curNode->next = NULL;
- CADestroyBTDeviceList(&curNode);
- return CA_STATUS_OK;
- }
- }
- else
- {
- prevNode = curNode;
- curNode = curNode->next;
- }
- }
-
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Device not in the list !");
- return CA_STATUS_FAILED;
-}
-
-void CADestroyBTDeviceList(BTDeviceList **deviceList)
-{
- while (*deviceList)
- {
- BTDeviceList *curNode = *deviceList;
- *deviceList = (*deviceList)->next;
-
- CADestroyBTDevice(curNode->device);
- OICFree(curNode);
- }
-}
-
-void CADestroyBTDevice(BTDevice *device)
-{
- if (device)
- {
- OICFree(device->remoteAddress);
- OICFree(device->serviceUUID);
- CADestroyBTDataList(&device->pendingDataList);
- OICFree(device);
- }
-}
-
-CAResult_t CAAddBTDataToList(BTDataList **dataList, void *data, uint32_t dataLength)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(dataList, BLUETOOTH_ADAPTER_TAG, "Data list is null");
- VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null");
-
- if (0 == dataLength)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: data length is zero!");
- return CA_STATUS_INVALID_PARAM;
- }
-
- BTDataList *pending_data = (BTDataList *) OICMalloc(sizeof(BTDataList));
- if (NULL == pending_data)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "OICMalloc failed (data list)!");
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- pending_data->data = (BTData *) OICMalloc(sizeof(BTData));
- if (NULL == pending_data->data)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "OICMalloc failed (data node)!");
-
- OICFree(pending_data);
- return CA_MEMORY_ALLOC_FAILED;
- }
- pending_data->next = NULL;
-
- pending_data->data->data = (void *) OICMalloc(dataLength); //data
- if (NULL == pending_data->data->data)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "OICMalloc failed (data)!");
-
- OICFree(pending_data->data);
- OICFree(pending_data);
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- memcpy(pending_data->data->data, data, dataLength);
- pending_data->data->dataLength = dataLength;
-
- if (NULL == *dataList) //Empty list
- {
- *dataList = pending_data;
- }
- else //Add at rear end
- {
- BTDataList *curNode = *dataList;
- while (curNode->next != NULL)
- {
- curNode = curNode->next;
- }
-
- curNode->next = pending_data;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CARemoveBTDataFromList(BTDataList **dataList)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(dataList, BLUETOOTH_ADAPTER_TAG, "Data list is null");
-
- if (*dataList)
- {
- BTDataList *curNode = *dataList;
- *dataList = (*dataList)->next;
-
- //Delete the first node
- CADestroyBTData(curNode->data);
- OICFree(curNode);
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CADestroyBTDataList(BTDataList **dataList)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- while (*dataList)
- {
- BTDataList *curNode = *dataList;
- *dataList = (*dataList)->next;
-
- CADestroyBTData(curNode->data);
- OICFree(curNode);
- }
-
- *dataList = NULL;
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-void CADestroyBTData(BTData *data)
-{
- if (data)
- {
- OICFree(data->data);
- OICFree(data);
- }
-}
-
+++ /dev/null
-/******************************************************************
- *
- * 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 cabtdevicelist.h
- * @brief This file provides APIs to manage discovered bluetooth device list.
- */
-
-#ifndef __CA_BT_DEVICE_LIST_H_
-#define __CA_BT_DEVICE_LIST_H_
-
-#include "cacommon.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @struct BTData
- * @brief Structure to maintain the data needs to send to peer Bluetooth device.
- */
-typedef struct
-{
- void *data; /**< Data to be send to peer Bluetooth device. */
- uint32_t dataLength; /**< Length of the data. */
-} BTData;
-
-/**
- * @struct BTDataList
- * @brief Structure to maintain list of data needs to send to peer Bluetooth device.
- */
-typedef struct _BTDataList
-{
- BTData *data; /**< Data to be send to peer Bluetooth device. */
- struct _BTDataList *next;/**< Reference to next data in list. */
-} BTDataList;
-
-/**
- * @struct BTDevice
- * @brief Structure to maintain information of peer Bluetooth device.
- */
-typedef struct
-{
- char *remoteAddress; /**< Address of peer Bluetooth device. */
- char *serviceUUID; /**< OIC service UUID running in peer Bluetooth device. */
- int32_t socketFD; /**< RfComm connection socket FD. */
- BTDataList *pendingDataList;/**< List of data needs to send to peer Bluetooth device. */
- uint32_t serviceSearched; /**< Flag to indicate the status of service search. */
-} BTDevice;
-
-/**
- * @struct BTDeviceList
- * @brief Structure to maintain list of peer Bluetooth device information.
- */
-typedef struct _BTDeviceList
-{
- BTDevice *device; /**< Bluetooth device information. */
- struct _BTDeviceList *next; /**< Reference to next device information. */
-} BTDeviceList;
-
-/**
- * @fn CACreateAndAddToDeviceList
- * @brief Creates #BTDevice for specified remote address and uuid and to device list.
- *
- * @param[in][out] deviceList Device list which created device add to.
- * @param[in] deviceAddress Bluetooth device address.
- * @param[in] uuid service uuid.
- * @param[in] device created #BTDevice.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
- * @retval #CA_STATUS_FAILED Failed to create device and add to list
- *
- */
-CAResult_t CACreateAndAddToDeviceList(BTDeviceList **deviceList, const char *deviceAddress,
- const char *uuid, BTDevice **device);
-
-/**
- * @fn CAAddBTDeviceToList
- * @brief Insert device to specified list.
- *
- * @param[in][out] deviceList Device list to which specifed @device to be added.
- * @param[in] device Device to be added to list.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
- * @retval #CA_MEMORY_ALLOC_FAILED Memory allocation failed
- *
- */
-CAResult_t CAAddBTDeviceToList(BTDeviceList **deviceList, BTDevice *device);
-
-/**
- * @fn CAGetBTDevice
- * @brief Get the device from list which matches specified device address.
- *
- * @param[in] deviceList Device list to search for the device.
- * @param[in] deviceAddress Device address used for matching.
- * @param[out] device #BTDevice which has matching device address.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
- * @retval #CA_STATUS_FAILED Device is not found in the list
- *
- */
-CAResult_t CAGetBTDevice(BTDeviceList *deviceList, const char *deviceAddress, BTDevice **device);
-
-/**
- * @fn CAGetBTDeviceBySocketId
- * @brief Get the device from list which matches specified RFCOMM socket id.
- *
- * @param[in] deviceList Device list to search for the device.
- * @param[in] socketID RFCOMM socket id.
- * @param[out] device #BTDevice which has matching RFCOMM socket id .
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
- * @retval #CA_STATUS_FAILED Device is not found in the list
- *
- */
-CAResult_t CAGetBTDeviceBySocketId(BTDeviceList *deviceList, int32_t socketID, BTDevice **device);
-
-/**
- * @fn CARemoveBTDeviceFromList
- * @brief Remove and delete the device matching specified device address from list.
- *
- * @param[in][out] deviceList Device list to search for the device.
- * @param[in] deviceAddress Bluetooth device address.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
- * @retval #CA_STATUS_FAILED Device is not found in the list
- *
- */
-CAResult_t CARemoveBTDeviceFromList(BTDeviceList **deviceList, const char *deviceAddress);
-
-/**
- * @fn CADestroyBTDeviceList
- * @brief Destroy the specified device list. Removes and delete all the devices in the list.
- *
- * @param[in][out] deviceList Device list to be destroyed.
- *
- */
-void CADestroyBTDeviceList(BTDeviceList **deviceList);
-
-/**
- * @fn CAAddBTDataToList
- * @brief Insert data to specified list.
- *
- * @param[in][out] dataList Data list to which data will be add.
- * @param[in] data Data to be stored.
- * @param[in] data_len Length of the data.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
- * @retval #CA_MEMORY_ALLOC_FAILED Memory allocation failed
- *
- */
-CAResult_t CAAddBTDataToList(BTDataList **dataList, void *data, uint32_t dataLength);
-
-/**
- * @fn CARemoveBTDataFromList
- * @brief Remove and delete data from front end of list.
- *
- * @param[in][out] dataList Data list from which data will be removed.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
- *
- */
-CAResult_t CARemoveBTDataFromList(BTDataList **dataList);
-
-/**
- * @fn CADestroyBTDataList
- * @brief Destroy the specified data list. Removes and deletes all the data in the list.
- *
- * @param[in] dataList Data list to be destroyed.
- *
- */
-void CADestroyBTDataList(BTDataList **dataList);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif //__CA_BT_DEVICE_LIST_H_
-
+++ /dev/null
-/******************************************************************
- *
- * 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 cabtmanager.c
- * @brief This file provides the APIs to control Bluetooth transport
- */
-
-#include "cabtmanager.h"
-#include "cabtclient.h"
-#include "cabtserver.h"
-#include "cabtendpoint.h"
-#include "cabtdevicelist.h"
-#include "cabtutils.h"
-#include "caadapterutils.h"
-#include "caqueueingthread.h"
-#include "camsgparser.h"
-
-/**
- * @struct CABTNetworkEvent
- * @brief Structure to maintain the adapter information and its status.
- */
-typedef struct
-{
- CALocalConnectivity_t *info;
- CANetworkStatus_t status;
-} CABTNetworkEvent;
-
-/**
- * @struct CABTData
- * @brief Structure to maintain the information of data in message queue.
- */
-typedef struct
-{
- CARemoteEndpoint_t *remoteEndpoint;
- void *data;
- uint32_t dataLen;
-} CABTData;
-/**
- * @var gNetworkPacketReceivedCallback
- * @brief Maintains the callback to be notified on receival of network packets from other
- * Bluetooth devices.
- */
-static CANetworkPacketReceivedCallback gNetworkPacketReceivedCallback = NULL;
-
-/**
- * @var gNetworkChangeCallback
- * @brief Maintains the callback to be notified on local bluetooth adapter status change.
- */
-static CANetworkChangeCallback gNetworkChangeCallback = NULL;
-
-/**
- * @var gBTDeviceListMutex
- * @brief Mutex to synchronize the access to Bluetooth device information list.
- */
-static u_mutex gBTDeviceListMutex = NULL;
-
-/**
- * @var gBTDeviceList
- * @brief Peer Bluetooth device information list.
- */
-static BTDeviceList *gBTDeviceList = NULL;
-
-/**
- * @var gLocalConnectivity
- * @brief Information of local Bluetooth adapter.
- */
-static CALocalConnectivity_t *gLocalConnectivity = NULL;
-
-/**
- * @var gBTThreadPool
- * @brief Reference to threadpool.
- */
-static u_thread_pool_t gBTThreadPool = NULL;
-
-/**
- * @var isHeaderAvailable
- * @brief to differentiate btw header and data packet.
- */
-static CABool_t isHeaderAvailable = false;
-
-/**
- * @var gSendQueueHandle
- * @brief Queue handle for Send Data
- */
-static CAQueueingThread_t *gSendQueueHandle = NULL;
-
-/**
- * @var gRecvQueueHandle
- * @brief Queue handle for Receive Data
- */
-static CAQueueingThread_t *gRecvQueueHandle = NULL;
-
-/**
- * @var gAdapterState
- * @brief Storing Adapter state information
- */
-static CABool_t gAdapterState = TRUE;
-
-/**
- * @var gServerId
- * @brief Storing RfcommserverUUID
- */
-static int32_t gServerId = -1;
-
-/**
- * @var gServerState
- * @brief Storing Rfcommserver state information
- */
-static CABool_t gServerState = FALSE;
-
-/**
- * @fn CABTAdapterStateChangeCallback
- * @brief This callback is registered to receive bluetooth adapter state changes.
- */
-static void CABTAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState,
- void *userData);
-
-/**
- * @fn CABTSocketConnectionStateCallback
- * @brief This callback is registered to receive bluetooth RFCOMM connection state changes.
- */
-static void CABTSocketConnectionStateCallback(int result,
- bt_socket_connection_state_e state,
- bt_socket_connection_s *connection, void *userData);
-
-/**
- * @fn CABTDataRecvCallback
- * @brief This callback is registered to recieve data on any open RFCOMM connection.
- */
-static void CABTDataRecvCallback(bt_socket_received_data_s *data, void *userData);
-
-/**
- * @fn CABTDeviceDiscoveryCallback
- * @brief This callback is registered to recieve all bluetooth nearby devices when device
- * scan is initiated.
- */
-static void CABTDeviceDiscoveryCallback(int result,
- bt_adapter_device_discovery_state_e state,
- bt_adapter_device_discovery_info_s *discoveryInfo,
- void *userData);
-
-/**
- * @fn CABTServiceSearchedCallback
- * @brief This callback is registered to recieve all the services remote bluetooth device supports
- * when service search initiated.
- */
-static void CABTServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo,
- void *userData);
-
-
-/**
- * @fn CABTManagerInitializeQueues
- * @brief This function creates and initialize message queues.
- */
-static CAResult_t CABTManagerInitializeQueues(void);
-
-/**
- * @fn CABTManagerInitializeSendHandler
- * @brief This function creates and initialize send message queue.
- */
-CAResult_t CABTManagerInitializeSendHandler(void);
-
-/**
- * @fn CABTManagerInitializeQueues
- * @brief This function creates and initialize receive message queue.
- */
-CAResult_t CABTManagerInitializeReceiveHandler(void);
-/**
- * @fn CABTManagerTerminateQueues
- * @brief This function terminates the send message queue.
- */
-static void CABTManagerTerminateQueues(void);
-
-/**
- * @fn CABTManagerInitializeMutex
- * @brief This function creates mutex.
- */
-static void CABTManagerInitializeMutex(void);
-
-/**
- * @fn CABTManagerTerminateMutex
- * @brief This function frees mutex.
- */
-static void CABTManagerTerminateMutex(void);
-
-/**
- * @fn CABTManagerDataSendHandler
- * @brief This function handles data from send message queue.
- */
-static void CABTManagerDataSendHandler(void *context);
-
-/**
- * @fn CABTManagerDataReceiverHandler
- * @brief This function handles data from recv message queue.
- */
-static void CABTManagerDataReceiverHandler(void *context);
-
-/**
- * @fn CABTManagerSendUnicastData
- * @brief This function sends data to specified remote bluetooth device.
- */
-static CAResult_t CABTManagerSendUnicastData(const char *remoteAddress, const char *serviceUUID,
- void *data, uint32_t dataLength, uint32_t *sentLength);
-
-/**
- * @fn CABTManagerSendMulticastData
- * @brief This function sends data to all bluetooth devices running OIC service.
- */
-static CAResult_t CABTManagerSendMulticastData(const char *serviceUUID, void *data,
- uint32_t dataLength, uint32_t *sentLength);
-
-/**
- * @fn CABTGetAdapterEnableState
- * @brief This function gets bluetooth adatper enable state.
- */
-static CAResult_t CABTGetAdapterEnableState(bool *state);
-
-/**
- * @fn CABTStartDeviceDiscovery
- * @brief This function starts device discovery.
- */
-static CAResult_t CABTStartDeviceDiscovery(void);
-
-/**
- * @fn CABTStopDeviceDiscovery
- * @brief This function stops device discovery.
- */
-static CAResult_t CABTStopDeviceDiscovery(void);
-
-/**
- * @fn CABTStartServiceSearch
- * @brief This function searches for OIC service for remote Bluetooth device.
- */
-static CAResult_t CABTStartServiceSearch(const char *remoteAddress);
-
-/**
- * @fn CABTStopServiceSearch
- * @brief This function stops any ongoing service sevice search.
- */
-static CAResult_t CABTStopServiceSearch(void);
-
-/**
- * @fn CABTNotifyNetworkStauts
- * @brief This function creates notification task for network adapter status and add it to thread pool.
- */
-static CAResult_t CABTNotifyNetworkStauts(CANetworkStatus_t status);
-
-/**
- * @fn CABTOnNetworkStautsChanged
- * @brief This is task callback function for notifying network adapter status to upper layer.
- */
-static void CABTOnNetworkStautsChanged(void *context);
-
-/**
- * @fn CABTCreateNetworkEvent
- * @brief Creates instance of CABTNetworkEvent.
- */
-static CABTNetworkEvent *CABTCreateNetworkEvent(CALocalConnectivity_t *connectivity,
- CANetworkStatus_t status);
-
-/**
- * @fn CABTFreeNetworkEvent
- * @brief Free the memory associated with @event.
- */
-static void CABTFreeNetworkEvent(CABTNetworkEvent *event);
-
-/**
- * @fn CABTManagerDisconnectAll
- * @brief Closes all the client connection to peer bluetooth devices.
- */
-static void CABTManagerDisconnectAll(void);
-
-/**
- * @fn CACreateBTData
- * @brief creating CABTData
- */
-static CABTData *CACreateBTData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLength);
-
-/**
- * @fn CABTManagerDisconnectAll
- * @brief freeing CABTData
- */
-static void CAFreeBTData(CABTData *btData);
-
-
-CAResult_t CABTManagerInitialize(u_thread_pool_t threadPool)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- int32_t err = BT_ERROR_NONE;
-
- //Initialize Bluetooth service
- if (BT_ERROR_NONE != (err = bt_initialize()))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth initialization failed!, error num [%x]",
- err);
- return CA_STATUS_FAILED;
- }
-
- //Create and initialize the mutex
- CABTManagerInitializeMutex();
-
- if (NULL == gBTThreadPool)
- {
- gBTThreadPool = threadPool;
- }
-
- //Initialize Send/Receive data message queues
- if (CA_STATUS_OK != CABTManagerInitializeQueues())
- {
- //Deinitialize the Bluetooth stack
- bt_deinitialize();
- return CA_STATUS_FAILED;
- }
-
- bt_adapter_set_state_changed_cb(CABTAdapterStateChangeCallback, NULL);
-
- //Notity to upper layer
- // CABTNotifyNetworkStauts(CA_INTERFACE_UP);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CABTManagerTerminate(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- gNetworkPacketReceivedCallback = NULL;
- gNetworkChangeCallback = NULL;
-
- //Stop the adpater
- CABTManagerStop();
-
- //Unset bluetooth adapter callbacks
- bt_adapter_unset_state_changed_cb();
-
- //Terminate Bluetooth service
- bt_deinitialize();
-
- //Terminate thread pool
- gBTThreadPool = NULL;
-
- //Free LocalConnectivity information
- CAAdapterFreeLocalEndpoint(gLocalConnectivity);
- gLocalConnectivity = NULL;
-
- //Free BTDevices list
- if (gBTDeviceListMutex)
- {
- u_mutex_lock(gBTDeviceListMutex);
- CADestroyBTDeviceList(&gBTDeviceList);
- u_mutex_unlock(gBTDeviceListMutex);
- }
-
- //Free the mutex
- CABTManagerTerminateMutex();
-
- //Terminate Send/Receive data messages queues
- CABTManagerTerminateQueues();
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-CAResult_t CABTManagerStart(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- //Get Bluetooth adapter state
- bool adapterState = false;
- if (CA_STATUS_OK != CABTGetAdapterEnableState(&adapterState))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get adatper enable state");
- return CA_STATUS_FAILED;
- }
-
- if (false == adapterState)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!");
- gAdapterState = FALSE;
- return CA_STATUS_OK;
- }
-
- //Register for discovery and rfcomm socket connection callbacks
- bt_adapter_set_device_discovery_state_changed_cb(CABTDeviceDiscoveryCallback, NULL);
- bt_device_set_service_searched_cb(CABTServiceSearchedCallback, NULL);
- bt_socket_set_connection_state_changed_cb(CABTSocketConnectionStateCallback, NULL);
- bt_socket_set_data_received_cb(CABTDataRecvCallback, NULL);
-
- //Start device discovery
- CABTStartDeviceDiscovery();
-
- // Start send queue thread
- if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
- {
- OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to Start Send Data Thread");
- CABTManagerStop();
- return CA_STATUS_FAILED;
- }
- // Start receive queue thread
- if (CA_STATUS_OK != CAQueueingThreadStart(gRecvQueueHandle))
- {
- OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to Start Receive Data Thread");
- CABTManagerStop();
- return CA_STATUS_FAILED;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CABTManagerStop(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- //Stop service search
- CABTStopServiceSearch();
-
- //Stop the device discovery process
- CABTStopDeviceDiscovery();
-
- //Stop send queue thread
- CAQueueingThreadStop(gSendQueueHandle);
-
- //Stop receive queue thread
- CAQueueingThreadStop(gRecvQueueHandle);
-
- //reset bluetooth adapter callbacks
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Resetting the callbacks");
- bt_adapter_unset_device_discovery_state_changed_cb();
- bt_device_unset_service_searched_cb();
- bt_socket_unset_connection_state_changed_cb();
- bt_socket_unset_data_received_cb();
-
- //Disconnect all the client connections
- CABTManagerDisconnectAll();
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-void CABTManagerSetPacketReceivedCallback(
- CANetworkPacketReceivedCallback packetReceivedCallback)
-{
- gNetworkPacketReceivedCallback = packetReceivedCallback;
-}
-
-void CABTManagerSetNetworkChangeCallback(
- CANetworkChangeCallback networkChangeCallback)
-{
- gNetworkChangeCallback = networkChangeCallback;
-}
-
-CAResult_t CABTManagerPushDataToReceiverQueue(const char *remoteAddress,
- const char *serviceUUID, void *data, uint32_t dataLength, uint32_t *sentLength)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (FALSE == gAdapterState)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!");
- *sentLength = 0;
- return CA_STATUS_OK;
- }
- //Input validation
- VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "service UUID is null");
- VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null");
- VERIFY_NON_NULL(sentLength, BLUETOOTH_ADAPTER_TAG, "Sent data length holder is null");
-
- //Add message to data queue
- CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
- serviceUUID);
- if (NULL == remoteEndpoint)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create remote endpoint !");
- return CA_STATUS_FAILED;
- }
-
- CABTData *btData = CACreateBTData(remoteEndpoint, data, dataLength);
- //Add message to data queue
-
- CAQueueingThreadAddData(gRecvQueueHandle, btData, sizeof(btData));
-
- *sentLength = dataLength;
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-CAResult_t CABTManagerSendData(const char *remoteAddress, const char *serviceUUID,
- void *data, uint32_t dataLength, uint32_t *sentLength)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (FALSE == gAdapterState)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!");
- *sentLength = 0;
- return CA_STATUS_OK;
- }
- //Input validation
- VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "service UUID is null");
- VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null");
- VERIFY_NON_NULL(sentLength, BLUETOOTH_ADAPTER_TAG, "Sent data length holder is null");
-
- CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
- serviceUUID);
- if (NULL == remoteEndpoint)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create remote endpoint !");
- return CA_STATUS_FAILED;
- }
-
- CABTData *btData = CACreateBTData(remoteEndpoint, data, dataLength);
- //Add message to data queue
-
- CAQueueingThreadAddData(gSendQueueHandle, btData, sizeof(btData));
-
- *sentLength = dataLength;
-
- //Signal message handler for processing data for sending
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTManagerStartServer(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (FALSE == gAdapterState)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!");
- //Setting gServerState for starting Rfcommserver when adapter starts
- gServerState = TRUE;
- return CA_STATUS_OK;
- }
-
- if (-1 < gServerId)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Server is already in running state.");
- return CA_STATUS_OK;
- }
- return CABTServerStart(OIC_BT_SERVICE_ID, &gServerId);
-}
-
-CAResult_t CABTManagerStopServer(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (-1 == gServerId)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "No Server is in running state.");
- return CA_STATUS_OK;
- }
-
- if (CA_STATUS_OK != CABTServerStop(gServerId))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to close server socket!");
- return CA_STATUS_FAILED;
- }
-
- gServerId = -1;
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTManagerGetInterface(CALocalConnectivity_t **info)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- int32_t err = BT_ERROR_NONE;
- char *localAddress = NULL;
-
- //Input validation
- VERIFY_NON_NULL(info, BLUETOOTH_ADAPTER_TAG, "LocalConnectivity info is null");
-
- //Get the bluetooth adapter local address
- if (BT_ERROR_NONE != (err = bt_adapter_get_address(&localAddress)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG,
- "Getting local adapter address failed!, error num [%x]",
- err);
- return CA_STATUS_FAILED;
- }
-
- //Create network info
- *info = CAAdapterCreateLocalEndpoint(CA_EDR, localAddress);
- if (NULL == *info)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create LocalConnectivity instance!");
-
- OICFree(localAddress);
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- OICFree(localAddress);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTManagerReadData(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_NOT_SUPPORTED;
-}
-
-CAResult_t CABTManagerInitializeQueues(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (CA_STATUS_OK == CABTManagerInitializeSendHandler()
- && CA_STATUS_OK == CABTManagerInitializeReceiveHandler())
- {
- OIC_LOG(DEBUG, BLUETOOTH_ADAPTER_TAG, "Queue is initialized!");
- return CA_STATUS_OK;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_FAILED;
-}
-
-CAResult_t CABTManagerInitializeSendHandler(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- // Check if the message queue is already initialized
- if (gSendQueueHandle)
- {
- OIC_LOG(DEBUG, BLUETOOTH_ADAPTER_TAG, "Already queue is initialized!");
- return CA_STATUS_OK;
- }
-
- gSendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
- if (!gSendQueueHandle)
- {
- OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Memory allocation failed!");
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- if (CA_STATUS_OK != CAQueueingThreadInitialize(gSendQueueHandle, gBTThreadPool,
- CABTManagerDataSendHandler))
- {
- OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to Initialize send queue thread");
- return CA_STATUS_FAILED;
- }
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTManagerInitializeReceiveHandler(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- // Check if the message queue is already initialized
- if (gRecvQueueHandle)
- {
- OIC_LOG(DEBUG, BLUETOOTH_ADAPTER_TAG, "Already queue is initialized!");
- return CA_STATUS_OK;
- }
-
- gRecvQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
- if (!gRecvQueueHandle)
- {
- OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Memory allocation failed!");
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- if (CA_STATUS_OK != CAQueueingThreadInitialize(gRecvQueueHandle, gBTThreadPool,
- CABTManagerDataReceiverHandler))
- {
- OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to Initialize send queue thread");
- return CA_STATUS_FAILED;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CABTManagerTerminateQueues(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (gSendQueueHandle)
- {
- CAQueueingThreadDestroy(gSendQueueHandle);
- gSendQueueHandle = NULL;
- }
- if (gRecvQueueHandle)
- {
- CAQueueingThreadDestroy(gRecvQueueHandle);
- gRecvQueueHandle = NULL;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-void CABTManagerInitializeMutex(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- u_mutex_init();
-
- if (!gBTDeviceListMutex)
- {
- gBTDeviceListMutex = u_mutex_new();
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-void CABTManagerTerminateMutex(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (gBTDeviceListMutex)
- {
- u_mutex_free(gBTDeviceListMutex);
- gBTDeviceListMutex = NULL;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-
-void CABTManagerDataReceiverHandler(void *context)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
-
- CABTData *message = (CABTData *) context;
- if (message == NULL)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get message!");
- return;
- }
- const char *remoteAddress = NULL;
- const char *serviceUUID = NULL;
- static uint32_t recvDataLen = 0;
- static uint32_t totalDataLen = 0;
- static char *defragData = NULL;
- static CARemoteEndpoint_t *remoteEndpoint = NULL;
-
- if (!isHeaderAvailable)
- {
- char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
-
- if (NULL == header)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Out of memory (header)!");
- return;
- }
- memcpy(header, (char *)message->data, CA_HEADER_LENGTH);
- totalDataLen = CAParseHeader(header);
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Total data to be accumulated [%d] bytes",
- totalDataLen);
- defragData = NULL;
- if (totalDataLen == 0)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, " totalDataLen is zero");
- OICFree(header);
- return;
- }
- defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
- OICFree(header);
-
- remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
- serviceUUID = message->remoteEndpoint->resourceUri;
-
- remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
- serviceUUID);
-
- memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
- message->dataLen - CA_HEADER_LENGTH);
- recvDataLen += message->dataLen - CA_HEADER_LENGTH;
- isHeaderAvailable = true;
- }
- else
- {
- memcpy(defragData + recvDataLen, message->data, message->dataLen);
- recvDataLen += message->dataLen ;
- }
- CAFreeBTData(message);
- if (totalDataLen == recvDataLen)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Sending data up !");
- gNetworkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
- recvDataLen = 0;
- totalDataLen = 0;
- remoteEndpoint = NULL;
- isHeaderAvailable = false;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-
-void CABTManagerDataSendHandler(void *context)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- CABTData *message = (CABTData *) context;
- if (message == NULL)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get message!");
- return;
- }
- const char *remoteAddress = NULL;
- const char *serviceUUID = NULL;
- uint32_t sentLength = 0;
- int32_t headerAdded = 0;
-
- remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
- serviceUUID = message->remoteEndpoint->resourceUri;
-
- char *dataSegment = NULL;
- uint32_t offset = 0, ret = 1;
- int32_t datalen = message->dataLen;
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "checking for fragmentation and the dataLen is %d",
- datalen);
- while ( 1)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "fragmenting the data DataLen [%d] Offset [%d]",
- datalen, offset);
- ret = CAFragmentData((char *)message->data, &dataSegment, datalen, offset);
- if (0 == ret)
- {
- break;
- }
- if (NULL == dataSegment)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to allocated memory fo dataSegment.");
- break;
- }
- if (strlen(remoteAddress)) //Unicast data
- {
- if (CA_STATUS_OK != CABTManagerSendUnicastData(remoteAddress, serviceUUID,
- dataSegment, ret, &sentLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send unicast data !");
- }
- }
- else
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "sending multicast data");
- if (CA_STATUS_OK != CABTManagerSendMulticastData(serviceUUID, dataSegment,
- ret, &sentLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send multicast data !");
- }
- }
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "freeing dataSegment");
-
- OICFree(dataSegment);
- dataSegment = NULL;
- offset += ret;
- if (headerAdded == 0)
- {
- datalen -= offset - CA_HEADER_LENGTH;
- offset = offset - CA_HEADER_LENGTH;
- headerAdded = 1;
- }
- else
- {
- datalen -= ret;
- }
-
- if (datalen < 0)
- {
- datalen += ret ;
- }
- if (datalen == message->dataLen)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "All data has been fragmented and sent");
- break;
- }
- }
- //Free message
- CAFreeBTData(message);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-CAResult_t CABTManagerSendUnicastData(const char *remoteAddress, const char *serviceUUID,
- void *data, uint32_t dataLength, uint32_t *sentLength)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- BTDevice *device = NULL;
-
- //Input validation
- VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null");
- VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "service UUID is null");
- VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null");
- VERIFY_NON_NULL(sentLength, BLUETOOTH_ADAPTER_TAG, "Sent data length holder is null");
-
- if (0 >= dataLength)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Negative data length!");
- return CA_STATUS_INVALID_PARAM;
- }
-
- //Check the connection existence with remote device
- u_mutex_lock(gBTDeviceListMutex);
- if (CA_STATUS_OK != CAGetBTDevice(gBTDeviceList, remoteAddress, &device))
- {
- //Create new device and add to list
- if (CA_STATUS_OK != CACreateAndAddToDeviceList(&gBTDeviceList, remoteAddress,
- OIC_BT_SERVICE_ID, &device))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed create device and add to list!");
-
- u_mutex_unlock(gBTDeviceListMutex);
- return CA_STATUS_FAILED;
- }
-
- //Start the OIC service search newly created device
- if (CA_STATUS_OK != CABTStartServiceSearch(remoteAddress))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to initiate service search!");
-
- //Remove device from list
- CARemoveBTDeviceFromList(&gBTDeviceList, remoteAddress);
-
- u_mutex_unlock(gBTDeviceListMutex);
- return CA_STATUS_FAILED;
- }
- }
- u_mutex_unlock(gBTDeviceListMutex);
-
- if (-1 == device->socketFD)
- {
- //Adding to pending list
- if (CA_STATUS_OK != CAAddBTDataToList(&device->pendingDataList, data,
- dataLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add data to pending list!");
-
- //Remove device from list
- CARemoveBTDeviceFromList(&gBTDeviceList, remoteAddress);
- return CA_STATUS_FAILED;
- }
-
- //Make a rfcomm connection with remote BT Device
- if (1 == device->serviceSearched &&
- CA_STATUS_OK != CABTClientConnect(remoteAddress, serviceUUID))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to make RFCOMM connection!");
-
- //Remove device from list
- CARemoveBTDeviceFromList(&gBTDeviceList, remoteAddress);
- return CA_STATUS_FAILED;
- }
- *sentLength = dataLength;
- }
- else
- {
- if (CA_STATUS_OK != CABTSendData(device->socketFD, data, dataLength, sentLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send data!");
- return CA_STATUS_FAILED;
- }
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTManagerSendMulticastData(const char *serviceUUID, void *data,
- uint32_t dataLength, uint32_t *sentLength)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- //Input validation
- VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "service UUID is null");
- VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null");
- VERIFY_NON_NULL(sentLength, BLUETOOTH_ADAPTER_TAG, "Sent data length holder is null");
-
- if (0 >= dataLength)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Negative data length!");
- return CA_STATUS_INVALID_PARAM;
- }
-
- *sentLength = dataLength;
-
- //Send the packet to all OIC devices
- u_mutex_lock(gBTDeviceListMutex);
- BTDeviceList *curList = gBTDeviceList;
- while (curList != NULL)
- {
- BTDevice *device = curList->device;
- curList = curList->next;
-
- if (!device)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "There is no device!");
- break;
- }
-
- if (-1 == device->socketFD)
- {
- //Check if the device service search is finished
- if (0 == device->serviceSearched)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Device services are still unknown!");
- continue;
- }
-
- //Adding to pendding list
- if (CA_STATUS_OK != CAAddBTDataToList(&device->pendingDataList, data,
- dataLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add data to pending list !");
- continue;
- }
-
- //Make a rfcomm connection with remote BT Device
- if (CA_STATUS_OK != CABTClientConnect(device->remoteAddress, device->serviceUUID))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to make RFCOMM connection !");
-
- //Remove the data which added to pending list
- CARemoveBTDataFromList(&device->pendingDataList);
- continue;
- }
- }
- else
- {
- if (CA_STATUS_OK != CABTSendData(device->socketFD, data, dataLength, sentLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send data to [%s] !",
- device->remoteAddress);
- }
- }
- }
- u_mutex_unlock(gBTDeviceListMutex);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTGetAdapterEnableState(bool *state)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- //Input validation
- VERIFY_NON_NULL(state, BLUETOOTH_ADAPTER_TAG, "state holder is NULL!");
-
- bt_error_e err = BT_ERROR_NONE;
- bt_adapter_state_e adapterState;
-
- //Get Bluetooth adapter state
- if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth get state failed!, error num [%x]",
- err);
-
- return CA_STATUS_FAILED;
- }
-
- *state = false;
- if (BT_ADAPTER_ENABLED == adapterState)
- {
- *state = true;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTStartDeviceDiscovery(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- bt_error_e err = BT_ERROR_NONE;
- bool isDiscoveryStarted = false;
-
- //Check the device discovery state
- if (BT_ERROR_NONE != (err = bt_adapter_is_discovering(&isDiscoveryStarted)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
- err);
- return CA_STATUS_FAILED;
- }
-
- //Start device discovery if its not started
- if (false == isDiscoveryStarted)
- {
- if (BT_ERROR_NONE != (err = bt_adapter_start_device_discovery()))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Device discovery failed!, error num [%x]",
- err);
- return CA_STATUS_FAILED;
- }
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTStopDeviceDiscovery(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- bt_error_e err = BT_ERROR_NONE;
- bool isDiscoveryStarted = false;
-
- //Check the device discovery state
- if (BT_ERROR_NONE != (err = bt_adapter_is_discovering(&isDiscoveryStarted)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
- err);
- return CA_STATUS_FAILED;
- }
-
- //stop the device discovery process
- if (true == isDiscoveryStarted)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Stopping the device search process");
- if (BT_ERROR_NONE != (err = bt_adapter_stop_device_discovery()))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to stop discovery!, error num [%x]",
- err);
- }
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTStartServiceSearch(const char *remoteAddress)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- bt_error_e err = BT_ERROR_NONE;
-
- //Input validation
- VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null");
- if (0 == strlen(remoteAddress))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Remote address is empty!");
- return CA_STATUS_INVALID_PARAM;
- }
-
- //Start searching for OIC service
- if (BT_ERROR_NONE != (err = bt_device_start_service_search(remoteAddress)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
- err);
- return CA_STATUS_FAILED;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CABTStopServiceSearch(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- bt_error_e err = BT_ERROR_NONE;
-
- //Stop ongoing service search
- if (BT_ERROR_NONE != (err = bt_device_cancel_service_search()))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
- err);
- return CA_STATUS_FAILED;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CABTAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState,
- void *userData)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (BT_ADAPTER_ENABLED == adapterState)
- {
- // checking for adapter state. If not started then start.
- if (FALSE == gAdapterState)
- {
- CABTManagerStart();
- gAdapterState = TRUE;
- //starting RFcommserver
- if (gServerState == TRUE)
- {
- CABTManagerStartServer();
- gServerState = FALSE;
- }
- }
- //Notity to upper layer
- CABTNotifyNetworkStauts(CA_INTERFACE_UP);
- }
- else if (BT_ADAPTER_DISABLED == adapterState)
- {
- //Notity to upper layer
- CABTNotifyNetworkStauts(CA_INTERFACE_DOWN);
- gAdapterState = FALSE;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-void CABTSocketConnectionStateCallback(int result, bt_socket_connection_state_e state,
- bt_socket_connection_s *connection, void *userData)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- BTDevice *device = NULL;
-
- if (BT_ERROR_NONE != result || NULL == connection)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid connection state!, error num [%x]",
- result);
- return;
- }
-
- switch (state)
- {
- case BT_SOCKET_CONNECTED:
- {
- u_mutex_lock(gBTDeviceListMutex);
- if (CA_STATUS_OK != CAGetBTDevice(gBTDeviceList, connection->remote_address,
- &device))
- {
- //Create the deviceinfo and add to list
- if (CA_STATUS_OK != CACreateAndAddToDeviceList(&gBTDeviceList,
- connection->remote_address, OIC_BT_SERVICE_ID, &device))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed add device to list!");
- u_mutex_unlock(gBTDeviceListMutex);
- return;
- }
-
- device->socketFD = connection->socket_fd;
- u_mutex_unlock(gBTDeviceListMutex);
- return;
- }
-
- device->socketFD = connection->socket_fd;
- while (device->pendingDataList)
- {
- uint32_t sentData = 0;
- BTData *btData = device->pendingDataList->data;
- if (CA_STATUS_OK != CABTSendData(device->socketFD, btData->data,
- btData->dataLength, &sentData))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send pending data [%s]",
- device->remoteAddress);
-
- //Remove all the data from pending list
- CADestroyBTDataList(&device->pendingDataList);
- break;
- }
-
- //Remove the data which send from pending list
- CARemoveBTDataFromList(&device->pendingDataList);
- }
- u_mutex_unlock(gBTDeviceListMutex);
- }
- break;
-
- case BT_SOCKET_DISCONNECTED:
- {
- u_mutex_lock(gBTDeviceListMutex);
- CARemoveBTDeviceFromList(&gBTDeviceList, connection->remote_address);
- u_mutex_unlock(gBTDeviceListMutex);
- }
- break;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-void CABTDataRecvCallback(bt_socket_received_data_s *data, void *userData)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- BTDevice *device = NULL;
-
- if (NULL == data || 0 >= data->data_size)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Data is null!");
- return;
- }
-
- if (NULL == gNetworkPacketReceivedCallback)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Callback is not registered!");
- return;
- }
-
- //Get BT device from list
- u_mutex_lock(gBTDeviceListMutex);
- if (CA_STATUS_OK != CAGetBTDeviceBySocketId(gBTDeviceList, data->socket_fd, &device))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Could not find the device!");
-
- u_mutex_unlock(gBTDeviceListMutex);
- return;
- }
- u_mutex_unlock(gBTDeviceListMutex);
-
- uint32_t sentLength = 0;
-
- CAResult_t res = CABTManagerPushDataToReceiverQueue(device->remoteAddress, OIC_BT_SERVICE_ID,
- data->data, (uint32_t)data->data_size, &sentLength);
-
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "CABTManagerPushDataToReceiverQueue done [%d]", res);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-void CABTDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e state,
- bt_adapter_device_discovery_info_s *discoveryInfo, void *userData)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- BTDevice *device = NULL;
-
- if (BT_ERROR_NONE != result)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Received bad state!, error num [%x]",
- result);
- return;
- }
-
- switch (state)
- {
- case BT_ADAPTER_DEVICE_DISCOVERY_STARTED:
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Discovery started!");
- }
- break;
-
- case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Discovery finished!");
- }
- break;
-
- case BT_ADAPTER_DEVICE_DISCOVERY_FOUND:
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Device discovered [%s]!",
- discoveryInfo->remote_name);
- if (true == CABTIsServiceSupported((const char **)discoveryInfo->service_uuid,
- discoveryInfo->service_count,
- OIC_BT_SERVICE_ID))
- {
- //Check if the deivce is already in the list
- u_mutex_lock(gBTDeviceListMutex);
- if (CA_STATUS_OK == CAGetBTDevice(gBTDeviceList, discoveryInfo->remote_address,
- &device))
- {
- device->serviceSearched = 1;
- u_mutex_unlock(gBTDeviceListMutex);
- return;
- }
-
- //Create the deviceinfo and add to list
- if (CA_STATUS_OK != CACreateAndAddToDeviceList(&gBTDeviceList,
- discoveryInfo->remote_address, OIC_BT_SERVICE_ID, &device))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add device to list!");
- u_mutex_unlock(gBTDeviceListMutex);
- return;
- }
-
- device->serviceSearched = 1;
- u_mutex_unlock(gBTDeviceListMutex);
- }
- else
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Device does not support OIC service!");
- }
- }
- break;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-void CABTServiceSearchedCallback(int32_t result, bt_device_sdp_info_s *sdpInfo, void *userData)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (NULL == sdpInfo)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "SDP info is null!");
- return;
- }
-
- u_mutex_lock(gBTDeviceListMutex);
-
- BTDevice *device = NULL;
- if (CA_STATUS_OK == CAGetBTDevice(gBTDeviceList, sdpInfo->remote_address, &device)
- && NULL != device)
- {
- if (1 == device->serviceSearched)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Service is already searched for this device!");
- u_mutex_unlock(gBTDeviceListMutex);
- return;
- }
-
- if (true == CABTIsServiceSupported((const char **)sdpInfo->service_uuid,
- sdpInfo->service_count, OIC_BT_SERVICE_ID))
- {
- device->serviceSearched = 1;
- if (CA_STATUS_OK != CABTClientConnect(sdpInfo->remote_address, OIC_BT_SERVICE_ID))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to make rfcomm connection!");
-
- //Remove the device from device list
- CARemoveBTDeviceFromList(&gBTDeviceList, sdpInfo->remote_address);
- }
- }
- else
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Device does not contain OIC service!");
-
- //Remove device from list as it does not support OIC service
- CARemoveBTDeviceFromList(&gBTDeviceList, sdpInfo->remote_address);
- }
- }
-
- u_mutex_unlock(gBTDeviceListMutex);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-CAResult_t CABTNotifyNetworkStauts(CANetworkStatus_t status)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- //Create localconnectivity
- if (NULL == gLocalConnectivity)
- {
- CABTManagerGetInterface(&gLocalConnectivity);
- }
-
- //Notity to upper layer
- if (gNetworkChangeCallback && gLocalConnectivity && gBTThreadPool)
- {
- //Add notification task to thread pool
- CABTNetworkEvent *event = CABTCreateNetworkEvent(gLocalConnectivity, status);
- if (NULL != event)
- {
- if (CA_STATUS_OK != u_thread_pool_add_task(gBTThreadPool, CABTOnNetworkStautsChanged,
- event))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create threadpool!");
- return CA_STATUS_FAILED;
- }
- }
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CABTOnNetworkStautsChanged(void *context)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (NULL == context)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "context is NULL!");
- return;
- }
-
- CABTNetworkEvent *networkEvent = (CABTNetworkEvent *) context;
-
- //Notity to upper layer
- if (gNetworkChangeCallback)
- {
- gNetworkChangeCallback(networkEvent->info, networkEvent->status);
- }
-
- //Free the created Network event
- CABTFreeNetworkEvent(networkEvent);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-CABTNetworkEvent *CABTCreateNetworkEvent(CALocalConnectivity_t *connectivity,
- CANetworkStatus_t status)
-{
- VERIFY_NON_NULL_RET(connectivity, BLUETOOTH_ADAPTER_TAG, "connectivity is NULL", NULL);
-
- //Create CABTNetworkEvent
- CABTNetworkEvent *event = (CABTNetworkEvent *) OICMalloc(sizeof(CABTNetworkEvent));
- if (NULL == event)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to allocate memory to network event!");
- return NULL;
- }
-
- //Create duplicate of Local connectivity
- event->info = CAAdapterCopyLocalEndpoint(connectivity);
- event->status = status;
- return event;
-}
-
-void CABTFreeNetworkEvent(CABTNetworkEvent *event)
-{
- if (event)
- {
- CAAdapterFreeLocalEndpoint(event->info);
- OICFree(event);
- }
-}
-
-void CABTManagerDisconnectAll(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- u_mutex_lock(gBTDeviceListMutex);
-
- BTDeviceList *cur = gBTDeviceList;
- while (cur != NULL)
- {
- BTDevice *device = cur->device;
- cur = cur->next;
-
- if (device && 0 <= device->socketFD)
- {
- if (CA_STATUS_OK != CABTClientDisconnect(device->socketFD))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to disconnect with client :%s",
- device->remoteAddress);
- }
-
- device->socketFD = -1;
- }
- }
-
- u_mutex_unlock(gBTDeviceListMutex);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-CABTData *CACreateBTData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLength)
-{
- CABTData *btData = (CABTData *) OICMalloc(sizeof(CABTData));
- if (!btData)
- {
- OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Memory allocation failed!");
- return NULL;
- }
-
- btData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
- btData->data = (void *)OICMalloc(dataLength);
- if (NULL == btData->data)
- {
- OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Memory allocation failed!");
- CAFreeBTData(btData);
- return NULL;
- }
- memcpy(btData->data, data, dataLength);
- btData->dataLen = dataLength;
-
- return btData;
-}
-
-void CAFreeBTData(CABTData *btData)
-{
- if (!btData)
- return;
-
- CAAdapterFreeRemoteEndpoint(btData->remoteEndpoint);
- OICFree(btData->data);
- OICFree(btData);
-}
+++ /dev/null
-/******************************************************************
- *
- * 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 cabtmanager.h
- * @brief This file provides the APIs to control Bluetooth transport
- */
-
-#ifndef __CA_BT_MANAGER_H_
-#define __CA_BT_MANAGER_H_
-
-#include <pthread.h>
-#include <string.h>
-#include <bluetooth.h>
-
-#include "caedradapter.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @fn CABTManagerInitialize
- * @brief Initializes bluetooth adapter.
- *
- * @param[in] threadPool Thread pool for handling asynchronous tasks.
- *
- * @return #CA_STATUS_OK or #CA_ADAPTER_NOT_ENABLED on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_ADAPTER_NOT_ENABLED Initialization is successful, but bluetooth adapter is
- * not enabled.
- * @retval #CA_STATUS_FAILED Operation failed
- *
- * @see CABTManagerTerminate()
- */
-CAResult_t CABTManagerInitialize(u_thread_pool_t threadPool);
-
-/**
- * @fn CABTManagerTerminate
- * @brief Deinitialize with bluetooth adapter.
- *
- * @pre CABTManagerIntialize() should be invoked before using this API.
- *
- * @see CABTManagerIntialize()
- *
- */
-void CABTManagerTerminate(void);
-
-/**
- * @fn CABTManagerStart
- * @brief Starts discovery for nearby OIC bluetooth devices.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_FAILED Operation failed
- *
- * @pre CABTManagerIntialize() should be invoked before using this API.
- *
- * @see CABTManagerIntialize()
- *
- */
-CAResult_t CABTManagerStart(void);
-
-/**
- * @fn CABTManagerStop
- * @brief Resetting callbacks with bluetooth framework and stop OIC device discovery.
- *
- * @pre CABTManagerStart() should be invoked before using this API.
- *
- * @see CABTManagerIntialize()
- * @see CABTManagerStart()
- *
- */
-void CABTManagerStop(void);
-
-/**
- * @fn CABTManagerSetPacketReceivedCallback
- * @brief Register callback for receiving packets from remote bluetooth device.
- *
- * @param[in] packetReceivedCallback Callback function to register for receiving network packets.
- *
- * @post CANetworkPacketReceivedCallback() will be called if any data received from peer
- * connected bluetooth device.
- *
- * @see CANetworkPacketReceivedCallback()
- *
- */
-void CABTManagerSetPacketReceivedCallback(CANetworkPacketReceivedCallback packetReceivedCallback);
-
-/**
- * @fn CABTManagerSetNetworkChangeCallback
- * @brief Register callback for receiving local bluetooth adapter state.
- *
- * @param[in] networkStateChangeCallback Callback function to register for receiving local bluetooth
- * adapter status.
- *
- * @post CANetworkChangeCallback() will be called if bluetooth adatper state changes.
- *
- * @see CANetworkChangeCallback()
- *
- */
-void CABTManagerSetNetworkChangeCallback(CANetworkChangeCallback networkStateChangeCallback);
-
-/**
- * @fn CABTManagerSendData
- * @brief Send unicast/multicast data to remote bluetooth device.
- *
- * @param[in] remoteAddress Address of remote bluetooth device to which data needs to be sent.
- * This will be NULL in case of sending multicast data.
- * @param[in] serviceUUID The UUID of service to which RFCOMM connection needs to established.
- * @param[in] data The data needs to be send to remote bluetooth device.
- * @param[in] dataLength Length of data.
- * @param[out] sentLength Length of data actually sent or added to pending list for sending.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- *
- */
-CAResult_t CABTManagerSendData(const char *remoteAddress, const char *serviceUUID,
- void *data, uint32_t dataLength, uint32_t *sentLength);
-
-/**
- * @fn CABTManagerStartServer
- * @brief Start RFCOMM server for given service UUID.
- *
- * @param[in] serviceUUID The UUID of service with which RFCOMM server needs to be started
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_SERVER_STARTED_ALREADY Service on the specified UUID is already running.
- * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- *
- */
-CAResult_t CABTManagerStartServer(void);
-
-/**
- * @fn CABTManagerStopServer
- * @brief Stop RFCOMM server
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_FAILED Operation failed
- *
- * @pre Server must be started with CABTManagerStartServer().
- *
- * @see CABTManagerStartServer()
- */
-CAResult_t CABTManagerStopServer(void);
-
-/**
- * @fn CABTManagerGetInterface
- * @brief Get the local bluetooth adapter information.
- *
- * @param[in] info Local bluetooth adapter information
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- *
- * @see #CALocalConnectivity_t
- *
- */
-CAResult_t CABTManagerGetInterface(CALocalConnectivity_t **info);
-
-/**
- * @fn CABTManagerReadData
- * @brief All received data will be notified to upper layer.
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_FAILED Operation failed
- *
- */
-CAResult_t CABTManagerReadData(void);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif //__CA_BT_MANAGER_H_
-
+++ /dev/null
-/******************************************************************
- *
- * 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 cabtserver.h
- * @brief This file provides the APIs to start and stop RFCOMM server.
- */
-
-#ifndef __CA_BT_SERVER_H_
-#define __CA_BT_SERVER_H_
-
-#include <string.h>
-#include <bluetooth.h>
-
-#include "cacommon.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @fn CABTServerStart
- * @brief Start RFCOMM server for given service UUID
- *
- * @param[in] serviceUUID The UUID of service with which RFCOMM server needs to be started.
- * @param[out] serverFD The RFCOMM server socket file descriptor.
- *
- * @return CA_STATUS_OK on success otherwise proper error code.
- * @retval CA_STATUS_OK Successful
- * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval CA_STATUS_FAILED Operation failed
- *
- */
-CAResult_t CABTServerStart(const char *serviceUUID, int32_t *serverFD);
-
-/**
- * @fn CABTServerStop
- * @brief Stop RFCOMM server
- *
- * @param[in] serverFD The RFCOMM server socket file descriptor which needs to be stopped.
- *
- * @return CA_STATUS_OK on success otherwise proper error code.
- * @retval CA_STATUS_OK Successful
- * @retval CA_STATUS_FAILED Operation failed
- *
- */
-CAResult_t CABTServerStop(const int32_t serverFD);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif //__CA_BT_SERVER_H_
\ No newline at end of file
+++ /dev/null
-/******************************************************************
- *
- * 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 caedradapter.c
- * @brief This file contains the APIs for EDR adapters to be implemented
- */
-
-#include "caedradapter.h"
-#include "cabtmanager.h"
-#include "cabtutils.h"
-#include "caadapterutils.h"
-#include "logger.h"
-
-static CAResult_t CAStartServer(void);
-
-CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback packetReceivedCallback,
- CANetworkChangeCallback networkStateChangeCallback,
- u_thread_pool_t handle)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- CAResult_t err = CA_STATUS_OK;
-
- //Input validation
- VERIFY_NON_NULL(registerCallback, BLUETOOTH_ADAPTER_TAG,
- "register callback is NULL");
- VERIFY_NON_NULL(packetReceivedCallback, BLUETOOTH_ADAPTER_TAG,
- "data receive callback is NULL");
- VERIFY_NON_NULL(networkStateChangeCallback, BLUETOOTH_ADAPTER_TAG,
- "network state change callback is NULL");
- VERIFY_NON_NULL(handle, BLUETOOTH_ADAPTER_TAG, "Thread pool hanlde is NULL");
-
- //Register the callbacks with BT Manager
- CABTManagerSetPacketReceivedCallback(packetReceivedCallback);
- CABTManagerSetNetworkChangeCallback(networkStateChangeCallback);
-
- //Initialize BT Manager
- err = CABTManagerInitialize(handle);
- if (CA_STATUS_OK != err && CA_ADAPTER_NOT_ENABLED != err)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "BT Manger initialize failed!, error number [%d]",
- err);
- return err;
- }
-
- CAConnectivityHandler_t handler;
- handler.startAdapter = CAStartEDR;
- handler.startListenServer = CAStartEDRListeningServer;
- handler.startDiscoverServer = CAStartEDRDiscoveryServer;
- handler.sendData = CASendEDRUnicastData;
- handler.sendDataToAll = CASendEDRMulticastData;
- handler.GetnetInfo = CAGetEDRInterfaceInformation;
- handler.readData = CAReadEDRData;
- handler.stopAdapter = CAStopEDR;
- handler.terminate = CATerminateEDR;
- registerCallback(handler, CA_EDR);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return err;
-}
-
-CAResult_t CAStartEDR(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- CAResult_t err = CA_STATUS_OK;
-
- if (CA_STATUS_OK != (err = CABTManagerStart()))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "BT Manger start failed!, error number [%d] ",
- err);
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return err;
-}
-
-CAResult_t CAStartEDRListeningServer(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- return CAStartServer();
-}
-
-CAResult_t CAStartEDRDiscoveryServer(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- return CAStartServer();
-}
-
-uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLength)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- CAResult_t err = CA_STATUS_OK;
-
- //Input validation
- VERIFY_NON_NULL_RET(remoteEndpoint, BLUETOOTH_ADAPTER_TAG, "Remote endpoint is null", 0);
- VERIFY_NON_NULL_RET(data, BLUETOOTH_ADAPTER_TAG, "Data is null", 0);
-
- if (0 == strlen(remoteEndpoint->addressInfo.BT.btMacAddress))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: BT Address is empty!");
- return 0;
- }
-
- if (0 == dataLength)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: data length is zero!");
- return 0;
- }
-
- uint32_t sentLength = 0;
- const char *serviceUUID = OIC_BT_SERVICE_ID;
- const char *address = remoteEndpoint->addressInfo.BT.btMacAddress;
- if (CA_STATUS_OK != (err = CABTManagerSendData(address, serviceUUID, data,
- dataLength, &sentLength)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Send unicast data failed!, error num [%d]", err);
- return 0;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return sentLength;
-}
-
-uint32_t CASendEDRMulticastData(void *data, uint32_t dataLength)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- CAResult_t err = CA_STATUS_OK;
-
- //Input validation
- VERIFY_NON_NULL_RET(data, BLUETOOTH_ADAPTER_TAG, "Data is null", 0);
-
- if (0 == dataLength)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: data length is zero!");
- return 0;
- }
-
- uint32_t sentLen = 0;
- const char *serviceUUID = OIC_BT_SERVICE_ID;
- if (CA_STATUS_OK != (err = CABTManagerSendData(NULL, serviceUUID, data, dataLength,
- &sentLen)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Send multicast data failed!, error num [%d]",
- err);
- return 0;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return sentLen;
-}
-
-
-CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(info, BLUETOOTH_ADAPTER_TAG, "LocalConnectivity info is null");
-
- CAResult_t err = CA_STATUS_OK;
- *size = 0;
- if (CA_STATUS_OK != (err = CABTManagerGetInterface(info)))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG,
- "Failed to get local interface information!, error num [%d]", err);
- return err;
- }
-
- *size = 1;
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return err;
-}
-
-CAResult_t CAReadEDRData(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- return CABTManagerReadData();
-}
-
-CAResult_t CAStopEDR(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- CABTManagerStopServer();
-
- //Stop the adapter
- CABTManagerStop();
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CATerminateEDR(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- //Terminate BT Manager
- CABTManagerTerminate();
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-}
-
-CAResult_t CAStartServer(void)
-{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- CAResult_t err = CA_STATUS_OK;
-
- if (CA_STATUS_OK != (err = CABTManagerStartServer()))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to start RFCOMM server!, error num [%d]",
- err);
- return err;
- }
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return err;
-}
--- /dev/null
+/******************************************************************
+ *
+ * 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 cabtclient.c
+ * @brief This file provides the APIs to establish RFCOMM connection with remote bluetooth device
+ */
+#include <string.h>
+#include <bluetooth.h>
+
+#include "caedrinterface.h"
+#include "umutex.h"
+#include "caedrendpoint.h"
+#include "caadapterutils.h"
+#include "caedrutils.h"
+#include "logger.h"
+#include "cacommon.h"
+#include "caedrdevicelist.h"
+
+/**
+ * @var gEDRDeviceListMutex
+ * @brief Mutex to synchronize the access to Bluetooth device information list.
+ */
+static u_mutex gEDRDeviceListMutex = NULL;
+
+/**
+ * @var gEDRDeviceList
+ * @brief Peer Bluetooth device information list.
+ */
+static EDRDeviceList *gEDRDeviceList = NULL;
+
+/**
+ * @var gEDRNetworkChangeCallback
+ * @brief Maintains the callback to be notified when data received from remote Bluetooth device
+ */
+static CAEDRDataReceivedCallback gEDRPacketReceivedCallback = NULL;
+
+/**
+ * @fn CAEDRManagerInitializeMutex
+ * @brief This function creates mutex.
+ */
+static void CAEDRManagerInitializeMutex(void);
+
+/**
+ * @fn CAEDRManagerTerminateMutex
+ * @brief This function frees mutex.
+ */
+static void CAEDRManagerTerminateMutex(void);
+
+/**
+ * @fn CAEDRDataRecvCallback
+ * @brief This callback is registered to recieve data on any open RFCOMM connection.
+ */
+static void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData);
+
+/**
+ * @brief This function starts device discovery.
+ * @return NONE
+ */
+static CAResult_t CAEDRStartDeviceDiscovery(void);
+
+/**
+ * @fn CAEDRStopServiceSearch
+ * @brief This function stops any ongoing service sevice search.
+ */
+static CAResult_t CAEDRStopServiceSearch(void);
+
+/**
+ * @fn CAEDRStopDeviceDiscovery
+ * @brief This function stops device discovery.
+ */
+static CAResult_t CAEDRStopDeviceDiscovery(void);
+
+/**
+ * @fn CAEDRStartServiceSearch
+ * @brief This function searches for OIC service for remote Bluetooth device.
+ */
+static CAResult_t CAEDRStartServiceSearch(const char *remoteAddress);
+
+/**
+ * @fn CAEDRDeviceDiscoveryCallback
+ * @brief This callback is registered to recieve all bluetooth nearby devices when device
+ * scan is initiated.
+ */
+static void CAEDRDeviceDiscoveryCallback(int result,
+ bt_adapter_device_discovery_state_e state,
+ bt_adapter_device_discovery_info_s *discoveryInfo,
+ void *userData);
+
+/**
+ * @fn CAEDRServiceSearchedCallback
+ * @brief This callback is registered to recieve all the services remote bluetooth device supports
+ * when service search initiated.
+ */
+static void CAEDRServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo,
+ void *userData);
+
+/**
+ * @fn CAEDRSocketConnectionStateCallback
+ * @brief This callback is registered to receive bluetooth RFCOMM connection state changes.
+ */
+static void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e state,
+ bt_socket_connection_s *connection, void *userData);
+
+/**
+ * @fn CAEDRClientConnect
+ * @brief Establishes RFCOMM connection with remote bluetooth device
+ */
+static CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID);
+
+/**
+ * @fn CAEDRClientDisconnect
+ * @brief Disconnect RFCOMM client socket connection
+ */
+static CAResult_t CAEDRClientDisconnect(const int32_t clientID);
+
+void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
+{
+ gEDRPacketReceivedCallback = packetReceivedCallback;
+}
+
+void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e state,
+ bt_socket_connection_s *connection, void *userData)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ EDRDevice *device = NULL;
+
+ if (BT_ERROR_NONE != result || NULL == connection)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid connection state!, error num [%x]",
+ result);
+ return;
+ }
+
+ switch (state)
+ {
+ case BT_SOCKET_CONNECTED:
+ {
+ u_mutex_lock(gEDRDeviceListMutex);
+ if (CA_STATUS_OK != CAGetEDRDevice(gEDRDeviceList, connection->remote_address,
+ &device))
+ {
+ // Create the deviceinfo and add to list
+ if (CA_STATUS_OK != CACreateAndAddToDeviceList(&gEDRDeviceList,
+ connection->remote_address, OIC_EDR_SERVICE_ID, &device))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed add device to list!");
+ u_mutex_unlock(gEDRDeviceListMutex);
+ return;
+ }
+
+ device->socketFD = connection->socket_fd;
+ u_mutex_unlock(gEDRDeviceListMutex);
+ return;
+ }
+
+ device->socketFD = connection->socket_fd;
+ while (device->pendingDataList)
+ {
+ uint32_t sentData = 0;
+ EDRData *edrData = device->pendingDataList->data;
+ if (CA_STATUS_OK != CAEDRSendData(device->socketFD, edrData->data,
+ edrData->dataLength, &sentData))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send pending data [%s]",
+ device->remoteAddress);
+
+ // Remove all the data from pending list
+ CADestroyEDRDataList(&device->pendingDataList);
+ break;
+ }
+
+ // Remove the data which send from pending list
+ CARemoveEDRDataFromList(&device->pendingDataList);
+ }
+ u_mutex_unlock(gEDRDeviceListMutex);
+ }
+ break;
+
+ case BT_SOCKET_DISCONNECTED:
+ {
+ u_mutex_lock(gEDRDeviceListMutex);
+ CARemoveEDRDeviceFromList(&gEDRDeviceList, connection->remote_address);
+ u_mutex_unlock(gEDRDeviceListMutex);
+ }
+ break;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+
+void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e state,
+ bt_adapter_device_discovery_info_s *discoveryInfo, void *userData)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ EDRDevice *device = NULL;
+
+ if (BT_ERROR_NONE != result)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Received bad state!, error num [%x]",
+ result);
+ return;
+ }
+
+ switch (state)
+ {
+ case BT_ADAPTER_DEVICE_DISCOVERY_STARTED:
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Discovery started!");
+ }
+ break;
+
+ case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Discovery finished!");
+ }
+ break;
+
+ case BT_ADAPTER_DEVICE_DISCOVERY_FOUND:
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Device discovered [%s]!",
+ discoveryInfo->remote_name);
+ if (CA_TRUE == CAEDRIsServiceSupported((const char **)discoveryInfo->service_uuid,
+ discoveryInfo->service_count,
+ OIC_EDR_SERVICE_ID))
+ {
+ // Check if the deivce is already in the list
+ u_mutex_lock(gEDRDeviceListMutex);
+ if (CA_STATUS_OK == CAGetEDRDevice(gEDRDeviceList, discoveryInfo->remote_address,
+ &device))
+ {
+ device->serviceSearched = 1;
+ u_mutex_unlock(gEDRDeviceListMutex);
+ return;
+ }
+
+ // Create the deviceinfo and add to list
+ if (CA_STATUS_OK != CACreateAndAddToDeviceList(&gEDRDeviceList,
+ discoveryInfo->remote_address, OIC_EDR_SERVICE_ID, &device))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to add device to list!");
+ u_mutex_unlock(gEDRDeviceListMutex);
+ return;
+ }
+
+ device->serviceSearched = 1;
+ u_mutex_unlock(gEDRDeviceListMutex);
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Device does not support OIC service!");
+ }
+ }
+ break;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CAEDRServiceSearchedCallback(int32_t result, bt_device_sdp_info_s *sdpInfo, void *userData)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ if (NULL == sdpInfo)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "SDP info is null!");
+ return;
+ }
+
+ u_mutex_lock(gEDRDeviceListMutex);
+
+ EDRDevice *device = NULL;
+ if (CA_STATUS_OK == CAGetEDRDevice(gEDRDeviceList, sdpInfo->remote_address, &device)
+ && NULL != device)
+ {
+ if (1 == device->serviceSearched)
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Service is already searched for this device!");
+ u_mutex_unlock(gEDRDeviceListMutex);
+ return;
+ }
+
+ if (CA_TRUE == CAEDRIsServiceSupported((const char **)sdpInfo->service_uuid,
+ sdpInfo->service_count, OIC_EDR_SERVICE_ID))
+ {
+ device->serviceSearched = 1;
+ if (CA_STATUS_OK != CAEDRClientConnect(sdpInfo->remote_address, OIC_EDR_SERVICE_ID))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to make rfcomm connection!");
+
+ // Remove the device from device list
+ CARemoveEDRDeviceFromList(&gEDRDeviceList, sdpInfo->remote_address);
+ }
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Device does not contain OIC service!");
+
+ // Remove device from list as it does not support OIC service
+ CARemoveEDRDeviceFromList(&gEDRDeviceList, sdpInfo->remote_address);
+ }
+ }
+
+ u_mutex_unlock(gEDRDeviceListMutex);
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+CAResult_t CAEDRStartDeviceDiscovery(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ bt_error_e err = BT_ERROR_NONE;
+ bool isDiscoveryStarted = false;
+
+ // Check the device discovery state
+ if (BT_ERROR_NONE != (err = bt_adapter_is_discovering(&isDiscoveryStarted)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+
+ //Start device discovery if its not started
+ if (false == isDiscoveryStarted)
+ {
+ if (BT_ERROR_NONE != (err = bt_adapter_start_device_discovery()))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Device discovery failed!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRStopServiceSearch(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ bt_error_e err = BT_ERROR_NONE;
+
+ // Stop ongoing service search
+ if (BT_ERROR_NONE != (err = bt_device_cancel_service_search()))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRStopDeviceDiscovery(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ bt_error_e err = BT_ERROR_NONE;
+ bool isDiscoveryStarted = false;
+
+ // Check the device discovery state
+ if (BT_ERROR_NONE != (err = bt_adapter_is_discovering(&isDiscoveryStarted)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+
+ //stop the device discovery process
+ if (true == isDiscoveryStarted)
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Stopping the device search process");
+ if (BT_ERROR_NONE != (err = bt_adapter_stop_device_discovery()))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to stop discovery!, error num [%x]",
+ err);
+ }
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRStartServiceSearch(const char *remoteAddress)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ bt_error_e err = BT_ERROR_NONE;
+
+ // Input validation
+ VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
+ if (0 == strlen(remoteAddress))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Remote address is empty!");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ // Start searching for OIC service
+ if (BT_ERROR_NONE != (err = bt_device_start_service_search(remoteAddress)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRClientSetCallbacks(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Register for discovery and rfcomm socket connection callbacks
+ bt_adapter_set_device_discovery_state_changed_cb(CAEDRDeviceDiscoveryCallback, NULL);
+ bt_device_set_service_searched_cb(CAEDRServiceSearchedCallback, NULL);
+ bt_socket_set_connection_state_changed_cb(CAEDRSocketConnectionStateCallback, NULL);
+ bt_socket_set_data_received_cb(CAEDRDataRecvCallback, NULL);
+
+ // Start device discovery
+ if( CA_STATUS_OK != CAEDRStartDeviceDiscovery())
+ {
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Failed to Start Device discovery");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+
+void CAEDRClientUnsetCallbacks(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Stop service search
+ CAEDRStopServiceSearch();
+
+ // Stop the device discovery process
+ CAEDRStopDeviceDiscovery();
+
+ // reset bluetooth adapter callbacks
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Resetting the callbacks");
+ bt_adapter_unset_device_discovery_state_changed_cb();
+ bt_device_unset_service_searched_cb();
+ bt_socket_unset_connection_state_changed_cb();
+ bt_socket_unset_data_received_cb();
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CAEDRManagerInitializeMutex(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ u_mutex_init();
+
+ if (!gEDRDeviceListMutex)
+ {
+ gEDRDeviceListMutex = u_mutex_new();
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CAEDRManagerTerminateMutex(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ if (gEDRDeviceListMutex)
+ {
+ u_mutex_free(gEDRDeviceListMutex);
+ gEDRDeviceListMutex = NULL;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CAEDRInitializeClient()
+{
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
+ CAEDRManagerInitializeMutex();
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CAEDRTerminateClient()
+{
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Free EDRDevices list
+ if (gEDRDeviceListMutex)
+ {
+ u_mutex_lock(gEDRDeviceListMutex);
+ CADestroyEDRDeviceList(&gEDRDeviceList);
+ u_mutex_unlock(gEDRDeviceListMutex);
+ }
+
+ // Free the mutex
+ CAEDRManagerTerminateMutex();
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CAEDRClientDisconnectAll(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ u_mutex_lock(gEDRDeviceListMutex);
+
+ EDRDeviceList *cur = gEDRDeviceList;
+ while (cur != NULL)
+ {
+ EDRDevice *device = cur->device;
+ cur = cur->next;
+
+ if (device && 0 <= device->socketFD)
+ {
+ if (CA_STATUS_OK != CAEDRClientDisconnect(device->socketFD))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to disconnect with client :%s",
+ device->remoteAddress);
+ }
+
+ device->socketFD = -1;
+ }
+ }
+
+ u_mutex_unlock(gEDRDeviceListMutex);
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+
+CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ EDRDevice *device = NULL;
+
+ // Input validation
+ VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
+ VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null");
+ VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
+ VERIFY_NON_NULL(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
+
+ if (0 >= dataLength)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: Negative data length!");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ // Check the connection existence with remote device
+ u_mutex_lock(gEDRDeviceListMutex);
+ if (CA_STATUS_OK != CAGetEDRDevice(gEDRDeviceList, remoteAddress, &device))
+ {
+ // Create new device and add to list
+ if (CA_STATUS_OK != CACreateAndAddToDeviceList(&gEDRDeviceList, remoteAddress,
+ OIC_EDR_SERVICE_ID, &device))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed create device and add to list!");
+
+ u_mutex_unlock(gEDRDeviceListMutex);
+ return CA_STATUS_FAILED;
+ }
+
+ // Start the OIC service search newly created device
+ if (CA_STATUS_OK != CAEDRStartServiceSearch(remoteAddress))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to initiate service search!");
+
+ // Remove device from list
+ CARemoveEDRDeviceFromList(&gEDRDeviceList, remoteAddress);
+
+ u_mutex_unlock(gEDRDeviceListMutex);
+ return CA_STATUS_FAILED;
+ }
+ }
+ u_mutex_unlock(gEDRDeviceListMutex);
+
+ if (-1 == device->socketFD)
+ {
+ // Adding to pending list
+ if (CA_STATUS_OK != CAAddEDRDataToList(&device->pendingDataList, data,
+ dataLength))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to add data to pending list!");
+
+ //Remove device from list
+ CARemoveEDRDeviceFromList(&gEDRDeviceList, remoteAddress);
+ return CA_STATUS_FAILED;
+ }
+
+ // Make a rfcomm connection with remote BT Device
+ if (1 == device->serviceSearched &&
+ CA_STATUS_OK != CAEDRClientConnect(remoteAddress, serviceUUID))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to make RFCOMM connection!");
+
+ //Remove device from list
+ CARemoveEDRDeviceFromList(&gEDRDeviceList, remoteAddress);
+ return CA_STATUS_FAILED;
+ }
+ *sentLength = dataLength;
+ }
+ else
+ {
+ if (CA_STATUS_OK != CAEDRSendData(device->socketFD, data, dataLength, sentLength))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send data!");
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, void *data,
+ uint32_t dataLength, uint32_t *sentLength)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Input validation
+ VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null");
+ VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
+ VERIFY_NON_NULL(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
+
+ if (0 >= dataLength)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: Negative data length!");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ *sentLength = dataLength;
+
+ // Send the packet to all OIC devices
+ u_mutex_lock(gEDRDeviceListMutex);
+ EDRDeviceList *curList = gEDRDeviceList;
+ while (curList != NULL)
+ {
+ EDRDevice *device = curList->device;
+ curList = curList->next;
+
+ if (!device)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "There is no device!");
+ break;
+ }
+
+ if (-1 == device->socketFD)
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN1");
+ // Check if the device service search is finished
+ if (0 == device->serviceSearched)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Device services are still unknown!");
+ continue;
+ }
+
+ // Adding to pendding list
+ if (CA_STATUS_OK != CAAddEDRDataToList(&device->pendingDataList, data,
+ dataLength))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to add data to pending list !");
+ continue;
+ }
+
+ // Make a rfcomm connection with remote BT Device
+ if (CA_STATUS_OK != CAEDRClientConnect(device->remoteAddress, device->serviceUUID))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to make RFCOMM connection !");
+
+ //Remove the data which added to pending list
+ CARemoveEDRDataFromList(&device->pendingDataList);
+ continue;
+ }
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN2");
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN3");
+ if (CA_STATUS_OK != CAEDRSendData(device->socketFD, data, dataLength, sentLength))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send data to [%s] !",
+ device->remoteAddress);
+ }
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN4");
+ }
+ }
+ u_mutex_unlock(gEDRDeviceListMutex);
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ bt_error_e err = BT_ERROR_NONE;
+ int32_t addressLen = 0;
+
+ VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
+ VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "Service UUID is null");
+
+ addressLen = strlen(remoteAddress);
+ if (0 == addressLen || CA_MACADDR_SIZE - 1 != addressLen)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: Invalid remote address");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ if (0 == strlen(serviceUUID))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: Empty service uuid");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ if (BT_ERROR_NONE != (err = bt_socket_connect_rfcomm(remoteAddress, serviceUUID)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
+ "Failed to connect!, address [%s] error num [%x]",
+ remoteAddress, err);
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRClientDisconnect(const int32_t clientID)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Input validation
+ if (0 > clientID)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: negative client id");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ bt_error_e err = BT_ERROR_NONE;
+ if (BT_ERROR_NONE != (err = bt_socket_disconnect_rfcomm(clientID)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed close rfcomm client socket!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ EDRDevice *device = NULL;
+
+ if (NULL == data || 0 >= data->data_size)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Data is null!");
+ return;
+ }
+
+ // Get EDR device from list
+ u_mutex_lock(gEDRDeviceListMutex);
+ if (CA_STATUS_OK != CAGetEDRDeviceBySocketId(gEDRDeviceList, data->socket_fd, &device))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Could not find the device!");
+
+ u_mutex_unlock(gEDRDeviceListMutex);
+ return;
+ }
+ u_mutex_unlock(gEDRDeviceListMutex);
+
+ uint32_t sentLength = 0;
+
+ gEDRPacketReceivedCallback(device->remoteAddress, data->data,
+ (uint32_t)data->data_size, &sentLength);
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
--- /dev/null
+/******************************************************************
+ *
+ * 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 cabtdevicelist.c
+ * @brief This file provides APIs to access the discovered bluetooth device list
+ */
+
+#include "caedrdevicelist.h"
+#include "caadapterutils.h"
+#include "caedrutils.h"
+#include "logger.h"
+
+
+/**
+ * @fn CACreateEDRDevice
+ * @brief Creates #EDRDevice for specified remote address and uuid.
+ *
+ */
+static CAResult_t CACreateEDRDevice(const char *deviceAddress, const char *uuid, EDRDevice **device);
+
+
+/**
+ * @fn CADestroyEDRDevice
+ * @brief Free all the memory associated with specified device.
+ *
+ */
+static void CADestroyEDRDevice(EDRDevice *device);
+
+
+/**
+ * @fn CADestroyEDRData
+ * @brief Free all the memory associated with specified data.
+ *
+ */
+static void CADestroyEDRData(EDRData *data);
+
+
+CAResult_t CACreateAndAddToDeviceList(EDRDeviceList **deviceList, const char *deviceAddress,
+ const char *uuid, EDRDevice **device)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(deviceList, EDR_ADAPTER_TAG, "Device list is null");
+ VERIFY_NON_NULL(deviceAddress, EDR_ADAPTER_TAG, "Remote address is null");
+ VERIFY_NON_NULL(device, EDR_ADAPTER_TAG, "Device is null");
+
+ if (CA_STATUS_OK != CACreateEDRDevice(deviceAddress, uuid, device) || NULL == *device)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid or Not bonded device!");
+ return CA_STATUS_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAAddEDRDeviceToList(deviceList, *device))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to add in list!");
+
+ //Remove created EDRDevice
+ CADestroyEDRDevice(*device);
+ *device = NULL;
+
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CACreateEDRDevice(const char *deviceAddress, const char *uuid, EDRDevice **device)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(deviceAddress, EDR_ADAPTER_TAG, "Remote address is null");
+ VERIFY_NON_NULL(uuid, EDR_ADAPTER_TAG, "uuid is null");
+ VERIFY_NON_NULL(device, EDR_ADAPTER_TAG, "Device is null");
+
+ *device = (EDRDevice *) OICMalloc(sizeof(EDRDevice));
+ if (NULL == *device)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Out of memory (device)!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ //Copy bluetooth address
+ if (strlen(deviceAddress))
+ {
+ (*device)->remoteAddress = strndup(deviceAddress, strlen(deviceAddress));
+ if (NULL == (*device)->remoteAddress)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Out of memory (remote address)!");
+
+ OICFree(*device);
+ *device = NULL;
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ }
+
+ //Copy OIC service uuid
+ if (strlen(uuid))
+ {
+ (*device)->serviceUUID = strndup(uuid, strlen(uuid));
+ if (NULL == (*device)->serviceUUID)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
+ "[createEDRDevice] Out of memory (service uuid)!");
+
+ OICFree((*device)->remoteAddress);
+ OICFree(*device);
+ *device = NULL;
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ }
+
+ (*device)->socketFD = -1;
+ (*device)->pendingDataList = NULL;
+ (*device)->serviceSearched = 0;
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAAddEDRDeviceToList(EDRDeviceList **deviceList, EDRDevice *device)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(deviceList, EDR_ADAPTER_TAG, "Device list is null");
+ VERIFY_NON_NULL(device, EDR_ADAPTER_TAG, "Device is null");
+
+ EDRDeviceList *node = (EDRDeviceList *) OICMalloc(sizeof(EDRDeviceList));
+ if (NULL == node)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Out of memory (device list)!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ node->device = device;
+ node->next = NULL;
+
+ if (NULL == *deviceList) //Empty list
+ {
+ *deviceList = node;
+ }
+ else //Add at front end
+ {
+ node->next = *deviceList;
+ *deviceList = node;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAGetEDRDevice(EDRDeviceList *deviceList, const char *deviceAddress, EDRDevice **device)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(deviceList, EDR_ADAPTER_TAG, "Device list is null");
+ VERIFY_NON_NULL(deviceAddress, EDR_ADAPTER_TAG, "Remote address is null");
+ VERIFY_NON_NULL(device, EDR_ADAPTER_TAG, "Device is null");
+
+ EDRDeviceList *curNode = deviceList;
+ *device = NULL;
+ while (curNode != NULL)
+ {
+ if (!strcasecmp(curNode->device->remoteAddress, deviceAddress))
+ {
+ *device = curNode->device;
+ return CA_STATUS_OK;
+ }
+
+ curNode = curNode->next;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT [Device not found!]");
+ return CA_STATUS_FAILED;
+}
+
+CAResult_t CAGetEDRDeviceBySocketId(EDRDeviceList *deviceList, int32_t socketID, EDRDevice **device)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(deviceList, EDR_ADAPTER_TAG, "Device list is null");
+ VERIFY_NON_NULL(device, EDR_ADAPTER_TAG, "Device is null");
+ EDRDeviceList *curNode = deviceList;
+ *device = NULL;
+ while (curNode != NULL)
+ {
+ if (curNode->device->socketFD == socketID)
+ {
+ *device = curNode->device;
+ return CA_STATUS_OK;
+ }
+
+ curNode = curNode->next;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_FAILED;
+}
+
+CAResult_t CARemoveEDRDeviceFromList(EDRDeviceList **deviceList, const char *deviceAddress)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(deviceList, EDR_ADAPTER_TAG, "Device list is null");
+ VERIFY_NON_NULL(deviceAddress, EDR_ADAPTER_TAG, "Remote address is null");
+
+ EDRDeviceList *curNode = NULL;
+ EDRDeviceList *prevNode = NULL;
+
+ curNode = *deviceList;
+ while (curNode != NULL)
+ {
+ if (!strcasecmp(curNode->device->remoteAddress, deviceAddress))
+ {
+ if (curNode == *deviceList)
+ {
+ *deviceList = curNode->next;
+
+ curNode->next = NULL;
+ CADestroyEDRDeviceList(&curNode);
+ return CA_STATUS_OK;
+ }
+ else
+ {
+ prevNode->next = curNode->next;
+
+ curNode->next = NULL;
+ CADestroyEDRDeviceList(&curNode);
+ return CA_STATUS_OK;
+ }
+ }
+ else
+ {
+ prevNode = curNode;
+ curNode = curNode->next;
+ }
+ }
+
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Device not in the list !");
+ return CA_STATUS_FAILED;
+}
+
+void CADestroyEDRDeviceList(EDRDeviceList **deviceList)
+{
+ while (*deviceList)
+ {
+ EDRDeviceList *curNode = *deviceList;
+ *deviceList = (*deviceList)->next;
+
+ CADestroyEDRDevice(curNode->device);
+ OICFree(curNode);
+ }
+}
+
+void CADestroyEDRDevice(EDRDevice *device)
+{
+ if (device)
+ {
+ OICFree(device->remoteAddress);
+ OICFree(device->serviceUUID);
+ CADestroyEDRDataList(&device->pendingDataList);
+ OICFree(device);
+ }
+}
+
+CAResult_t CAAddEDRDataToList(EDRDataList **dataList, void *data, uint32_t dataLength)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(dataList, EDR_ADAPTER_TAG, "Data list is null");
+ VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
+
+ if (0 == dataLength)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: data length is zero!");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ EDRDataList *pending_data = (EDRDataList *) OICMalloc(sizeof(EDRDataList));
+ if (NULL == pending_data)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "OICMalloc failed (data list)!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ pending_data->data = (EDRData *) OICMalloc(sizeof(EDRData));
+ if (NULL == pending_data->data)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "OICMalloc failed (data node)!");
+
+ OICFree(pending_data);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ pending_data->next = NULL;
+
+ pending_data->data->data = (void *) OICMalloc(dataLength); //data
+ if (NULL == pending_data->data->data)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "OICMalloc failed (data)!");
+
+ OICFree(pending_data->data);
+ OICFree(pending_data);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ memcpy(pending_data->data->data, data, dataLength);
+ pending_data->data->dataLength = dataLength;
+
+ if (NULL == *dataList) //Empty list
+ {
+ *dataList = pending_data;
+ }
+ else //Add at rear end
+ {
+ EDRDataList *curNode = *dataList;
+ while (curNode->next != NULL)
+ {
+ curNode = curNode->next;
+ }
+
+ curNode->next = pending_data;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARemoveEDRDataFromList(EDRDataList **dataList)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(dataList, EDR_ADAPTER_TAG, "Data list is null");
+
+ if (*dataList)
+ {
+ EDRDataList *curNode = *dataList;
+ *dataList = (*dataList)->next;
+
+ //Delete the first node
+ CADestroyEDRData(curNode->data);
+ OICFree(curNode);
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CADestroyEDRDataList(EDRDataList **dataList)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ while (*dataList)
+ {
+ EDRDataList *curNode = *dataList;
+ *dataList = (*dataList)->next;
+
+ CADestroyEDRData(curNode->data);
+ OICFree(curNode);
+ }
+
+ *dataList = NULL;
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CADestroyEDRData(EDRData *data)
+{
+ if (data)
+ {
+ OICFree(data->data);
+ OICFree(data);
+ }
+}
+
--- /dev/null
+/******************************************************************
+ *
+ * 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 cabtdevicelist.h
+ * @brief This file provides APIs to manage discovered bluetooth device list.
+ */
+
+#ifndef __CA_EDR_DEVICE_LIST_H_
+#define __CA_EDR_DEVICE_LIST_H_
+
+#include "cacommon.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @struct EDRData
+ * @brief Structure to maintain the data needs to send to peer Bluetooth device.
+ */
+typedef struct
+{
+ void *data; /**< Data to be sent to peer Bluetooth device. */
+ uint32_t dataLength; /**< Length of the data. */
+} EDRData;
+
+/**
+ * @struct EDRDataList
+ * @brief Structure to maintain list of data needs to send to peer Bluetooth device.
+ */
+typedef struct _EDRDataList
+{
+ EDRData *data; /**< Data to be sent to peer Bluetooth device. */
+ struct _EDRDataList *next;/**< Reference to next data in list. */
+} EDRDataList;
+
+/**
+ * @struct EDRDevice
+ * @brief Structure to maintain information of peer Bluetooth device.
+ */
+typedef struct
+{
+ char *remoteAddress; /**< Address of peer Bluetooth device. */
+ char *serviceUUID; /**< OIC service UUID running in peer Bluetooth device. */
+ int32_t socketFD; /**< RfComm connection socket FD. */
+ EDRDataList *pendingDataList;/**< List of data needs to send to peer Bluetooth device. */
+ uint32_t serviceSearched; /**< Flag to indicate the status of service search. */
+} EDRDevice;
+
+/**
+ * @struct EDRDeviceList
+ * @brief Structure to maintain list of peer Bluetooth device information.
+ */
+typedef struct _EDRDeviceList
+{
+ EDRDevice *device; /**< Bluetooth device information. */
+ struct _EDRDeviceList *next; /**< Reference to next device information. */
+} EDRDeviceList;
+
+/**
+ * @brief Creates #EDRDevice for specified remote address and uuid and to device list.
+ *
+ * @param deviceList [IN,OUT] Device list which created device add to.
+ * @param deviceAddress [IN] Bluetooth device address.
+ * @param uuid [IN] Service uuid.
+ * @param device [IN] Created #EDRDevice.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
+ * @retval #CA_STATUS_FAILED Failed to create device and add to list
+ */
+CAResult_t CACreateAndAddToDeviceList(EDRDeviceList **deviceList, const char *deviceAddress,
+ const char *uuid, EDRDevice **device);
+
+/**
+ * @brief Insert device to specified list.
+ *
+ * @param deviceList [IN,OUT] Device list to which specifed @device to be added.
+ * @param device [IN] Device to be added to list.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
+ * @retval #CA_MEMORY_ALLOC_FAILED Memory allocation failed
+ */
+CAResult_t CAAddEDRDeviceToList(EDRDeviceList **deviceList, EDRDevice *device);
+
+/**
+ * @brief Get the device from list which matches specified device address.
+ *
+ * @param deviceList [IN] Device list to search for the device.
+ * @param deviceAddress [IN] Device address used for matching.
+ * @param device [OUT] #EDRDevice which has matching device address.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
+ * @retval #CA_STATUS_FAILED Device is not found in the list
+ */
+CAResult_t CAGetEDRDevice(EDRDeviceList *deviceList, const char *deviceAddress, EDRDevice **device);
+
+/**
+ * @brief Get the device from list which matches specified RFCOMM socket id.
+ *
+ * @param deviceList [IN] Device list to search for the device.
+ * @param socketID [IN] RFCOMM socket id.
+ * @param device [OUT] #EDRDevice which has matching RFCOMM socket id .
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
+ * @retval #CA_STATUS_FAILED Device is not found in the list
+ */
+CAResult_t CAGetEDRDeviceBySocketId(EDRDeviceList *deviceList, int32_t socketID,
+ EDRDevice **device);
+
+/**
+ * @brief Remove and delete the device matching specified device address from list.
+ *
+ * @param deviceList [IN,OUT] Device list to search for the device.
+ * @param deviceAddress [IN] Bluetooth device address.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
+ * @retval #CA_STATUS_FAILED Device is not found in the list
+ */
+CAResult_t CARemoveEDRDeviceFromList(EDRDeviceList **deviceList, const char *deviceAddress);
+
+/**
+ * @brief Destroy the specified device list. Removes and delete all the devices in the list.
+ * @param deviceList [IN,OUT] Device list to be destroyed.
+ * @return NONE
+ */
+void CADestroyEDRDeviceList(EDRDeviceList **deviceList);
+
+/**
+ * @brief Insert data to specified list.
+ *
+ * @param dataList [IN,OUT] Data list to which data will be add.
+ * @param data [IN] Data to be stored.
+ * @param dataLength [IN] Length of the data.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
+ * @retval #CA_MEMORY_ALLOC_FAILED Memory allocation failed
+ */
+CAResult_t CAAddEDRDataToList(EDRDataList **dataList, void *data, uint32_t dataLength);
+
+/**
+ * @brief Remove and delete data from front end of list.
+ * @param dataList [IN,OUT] Data list from which data will be removed.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters
+ */
+CAResult_t CARemoveEDRDataFromList(EDRDataList **dataList);
+
+/**
+ * @brief Destroy the specified data list. Removes and deletes all the data in the list.
+ * @param dataList [IN] Data list to be destroyed.
+ * @return NONE
+ */
+void CADestroyEDRDataList(EDRDataList **dataList);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif //__CA_EDR_DEVICE_LIST_H_
+
* @brief This file provides the APIs to send data on established RFCOMM connections.
*/
-#include "cabtendpoint.h"
+#include "caedrendpoint.h"
#include "caadapterutils.h"
-#include "cabtutils.h"
+#include "caedrutils.h"
#include "logger.h"
-CAResult_t CABTSendData(const int32_t serverFD, const void *data, const uint32_t dataLength,
- uint32_t *sentDataLen)
+CAResult_t CAEDRSendData(const int32_t serverFD, const void *data, const uint32_t dataLength,
+ uint32_t *sentDataLen)
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
- VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null");
- VERIFY_NON_NULL(sentDataLen, BLUETOOTH_ADAPTER_TAG, "Sent data length holder is null");
+ VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
+ VERIFY_NON_NULL(sentDataLen, EDR_ADAPTER_TAG, "Sent data length holder is null");
if (0 > serverFD)
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Negative socket id");
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: Negative socket id");
return CA_STATUS_INVALID_PARAM;
}
dataLen = bt_socket_send_data(serverFD, (const char *)data, dataLength);
if (dataLen == -1)
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "sending data failed!, soketid [%d]", serverFD);
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "sending data failed!, soketid [%d]", serverFD);
*sentDataLen = 0;
return CA_STATUS_FAILED;
}
*sentDataLen = dataLen;
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
******************************************************************/
/**
- * @file cabtendpoint.h
+ * @file cabtendpoint.h
* @brief This file provides the APIs to send data on established RFCOMM connections.
*/
-#ifndef __CA_BT_ENDPOINT_H_
-#define __CA_BT_ENDPOINT_H_
+#ifndef __CA_EDR_ENDPOINT_H_
+#define __CA_EDR_ENDPOINT_H_
#include <bluetooth.h>
#endif
/**
- * @fn CABTSendData
* @brief Send data over RFCOMM connection.
*
- * @param[in] serverFD The RFCOMM connection socket file descriptor.
- * @param[in] data The data needs to be sent.
- * @param[in] dataLength The length of data.
- * @param[in] sentDataLength The length of data which actually sent successful.
- *
- * @return CA_STATUS_OK on success otherwise proper error code.
- * @retval CA_STATUS_OK Successful
- * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval CA_STATUS_FAILED Operation failed
+ * @param serverFD [IN] The RFCOMM connection socket file descriptor.
+ * @param data [IN] The data needs to be sent.
+ * @param dataLength [IN] The length of data.
+ * @param sentDataLength [IN] The length of data which actually sent successful.
*
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
*/
-CAResult_t CABTSendData(const int32_t serverFD, const void *data, const uint32_t dataLength,
+CAResult_t CAEDRSendData(const int32_t serverFD, const void *data, const uint32_t dataLength,
uint32_t *sentDataLength);
#ifdef __cplusplus
} /* extern "C" */
#endif
-#endif //__CA_BT_ENDPOINT_H_
+#endif //__CA_EDR_ENDPOINT_H_
--- /dev/null
+/******************************************************************
+ *
+ * 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 cabtnwmonitor.c
+ * @brief This file provides the APIs for EDR Network Monitor
+ */
+
+#include <string.h>
+#include <bluetooth.h>
+#include "caedrinterface.h"
+#include "caedrdevicelist.h"
+#include "caedrutils.h"
+#include "caadapterutils.h"
+#include "caqueueingthread.h"
+
+/**
+ * @var gEDRNetworkChangeCallback
+ * @brief Maintains the callback to be notified on local bluetooth adapter status change.
+ */
+static CAEDRNetworkStatusCallback gEDRNetworkChangeCallback = NULL;
+
+/**
+ * @fn CAEDRAdapterStateChangeCallback
+ * @brief This callback is registered to receive bluetooth adapter state changes.
+ */
+static void CAEDRAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState,
+ void *userData);
+
+CAResult_t CAEDRInitializeNetworkMonitor()
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Initialize Bluetooth service
+ int32_t err = bt_initialize();
+
+ if (BT_ERROR_NONE != err)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Bluetooth initialization failed!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAEDRTerminateNetworkMonitor(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ gEDRNetworkChangeCallback = NULL;
+
+ // Terminate Bluetooth service
+ bt_deinitialize();
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+CAResult_t CAEDRStartNetworkMonitor()
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ int32_t ret = bt_adapter_set_state_changed_cb(CAEDRAdapterStateChangeCallback, NULL);
+ if(BT_ERROR_NONE != ret)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "bt_adapter_set_state_changed_cb failed");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRStopNetworkMonitor()
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+ // Unset bluetooth adapter callbacks
+ int32_t ret = bt_adapter_unset_state_changed_cb();
+ if(BT_ERROR_NONE != ret)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "bt_adapter_set_state_changed_cb failed");
+ return CA_STATUS_FAILED;
+ }
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAEDRSetNetworkChangeCallback(
+ CAEDRNetworkStatusCallback networkChangeCallback)
+{
+ gEDRNetworkChangeCallback = networkChangeCallback;
+}
+
+CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ int32_t err = BT_ERROR_NONE;
+ char *localAddress = NULL;
+
+ // Input validation
+ VERIFY_NON_NULL(info, EDR_ADAPTER_TAG, "LocalConnectivity info is null");
+
+ // Get the bluetooth adapter local address
+ if (BT_ERROR_NONE != (err = bt_adapter_get_address(&localAddress)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
+ "Getting local adapter address failed!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+
+ // Create network info
+ *info = CAAdapterCreateLocalEndpoint(CA_EDR, localAddress);
+ if (NULL == *info)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to create LocalConnectivity instance!");
+
+ OICFree(localAddress);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ OICFree(localAddress);
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEDRGetAdapterEnableState(CABool_t *state)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ // Input validation
+ VERIFY_NON_NULL(state, EDR_ADAPTER_TAG, "state holder is NULL!");
+
+ bt_error_e err = BT_ERROR_NONE;
+ bt_adapter_state_e adapterState;
+
+ // Get Bluetooth adapter state
+ if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState)))
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Bluetooth get state failed!, error num [%x]",
+ err);
+
+ return CA_STATUS_FAILED;
+ }
+
+ *state = CA_FALSE;
+ if (BT_ADAPTER_ENABLED == adapterState)
+ {
+ *state = CA_TRUE;
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAEDRAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState,
+ void *userData)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ if (BT_ADAPTER_ENABLED == adapterState)
+ {
+ // Notity to upper layer
+ if (gEDRNetworkChangeCallback)
+ {
+ gEDRNetworkChangeCallback(CA_INTERFACE_UP);
+ }
+ }
+ else if (BT_ADAPTER_DISABLED == adapterState)
+ {
+ // Notity to upper layer
+ if (gEDRNetworkChangeCallback)
+ {
+ gEDRNetworkChangeCallback(CA_INTERFACE_DOWN);
+ }
+ }
+
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
\ No newline at end of file
* @brief This file provides the APIs to start and stop RFCOMM server.
*/
-#include "cabtserver.h"
+
+#include <string.h>
+#include <bluetooth.h>
+#include "caedrinterface.h"
+
#include "caadapterutils.h"
-#include "cabtutils.h"
+#include "caedrutils.h"
#include "logger.h"
+#include "umutex.h"
+#include "cacommon.h"
+#include "caedrdevicelist.h"
static int32_t gMaxPendingConnections = 10;
-CAResult_t CABTServerStart(const char *serviceUUID, int32_t *serverFD)
+CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD)
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
bt_error_e err = BT_ERROR_NONE;
bool isRunning = false;
int32_t socketFD;
- VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "Service UUID is null");
- VERIFY_NON_NULL(serverFD, BLUETOOTH_ADAPTER_TAG, "Server fd holder is null");
+ VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "Service UUID is null");
+ VERIFY_NON_NULL(serverFD, EDR_ADAPTER_TAG, "Server fd holder is null");
if (0 >= strlen(serviceUUID))
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Empty service uuid!");
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid input: Empty service uuid!");
return CA_STATUS_INVALID_PARAM;
}
if (BT_ERROR_NONE != bt_adapter_is_service_used(serviceUUID, &isRunning))
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG,
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG,
"Unable to find whether service is already running or not!");
return CA_STATUS_FAILED;
}
if (true == isRunning)
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Service is already running with this UUID!");
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Service is already running with this UUID!");
return CA_SERVER_STARTED_ALREADY;
}
- //Registers a rfcomm socket with a specific service_uuid .
+ // Registers a rfcomm socket with a specific service_uuid .
if (BT_ERROR_NONE != (err = bt_socket_create_rfcomm(serviceUUID, &socketFD)))
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create rfcomm socket!, error num [%x]",
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to create rfcomm socket!, error num [%x]",
err);
return CA_STATUS_FAILED;
}
- //Start listening and accepting
+ // Start listening and accepting
if (BT_ERROR_NONE != (err = bt_socket_listen_and_accept_rfcomm(socketFD,
gMaxPendingConnections)))
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed in listen rfcomm socket!, error num [%x]",
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed in listen rfcomm socket!, error num [%x]",
err);
bt_socket_destroy_rfcomm(socketFD);
*serverFD = socketFD;
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
-CAResult_t CABTServerStop(const int32_t serverFD)
+CAResult_t CAEDRServerStop(const int32_t serverFD)
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
bt_error_e err = BT_ERROR_NONE;
if (BT_ERROR_NONE != (err = bt_socket_destroy_rfcomm(serverFD)))
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed close server socket!, error num [%x]",
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed close server socket!, error num [%x]",
err);
return CA_STATUS_FAILED;
}
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
+CAResult_t CAEDRManagerReadData(void)
+{
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_NOT_SUPPORTED;
+}
* @brief This file provides helper functions for EDR adapter.
*/
-#include "cabtutils.h"
+#include "caedrutils.h"
#include "logger.h"
#include <bluetooth.h>
-bool CABTIsServiceSupported(const char **serviceUUID, const int32_t serviceCount,
- const char *matchService)
+CABool_t CAEDRIsServiceSupported(const char **serviceUUID, const int32_t serviceCount,
+ const char *matchService)
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "IN");
if (NULL == serviceUUID || 0 == serviceCount || NULL == matchService)
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Invalid input");
- return false;
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Invalid input");
+ return CA_FALSE;
}
for (int i = 0; i < serviceCount; i++)
{
if (!strcasecmp(serviceUUID[i], matchService))
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Service found !");
- return true;
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Service found !");
+ return CA_TRUE;
}
}
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return false;
+ OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
+ return CA_FALSE;
}
/**
* @file cabtutils.h
- * @brief This file provides helper functions for EDR adapter.
+ * @brief This file provides helper functions for EDR adapter.
*/
-#ifndef __CA_BT_UTILS_H_
-#define __CA_BT_UTILS_H_
+#ifndef __CA_EDR_UTILS_H_
+#define __CA_EDR_UTILS_H_
#include <stdbool.h>
#include <string.h>
#include "cacommon.h"
#include "oic_malloc.h"
-#ifndef BLUETOOTH_ADAPTER_TAG
-#define BLUETOOTH_ADAPTER_TAG "CA_BLUETOOTH"
-#endif //BLUETOOTH_ADAPTER_TAG
-
-#ifndef OIC_BT_SERVICE_ID
-#define OIC_BT_SERVICE_ID "12341234-1C25-481F-9DFB-59193D238280"
-#endif //OIC_BT_SERVICE_ID
+/**
+ * @var EDR_ADAPTER_TAG
+ * @brief Logging tag for module name.
+ */
+#ifndef EDR_ADAPTER_TAG
+#define EDR_ADAPTER_TAG "CA_EDR_ADAPTER"
+#endif //EDR_ADAPTER_TAG
#ifdef __cplusplus
extern "C"
#endif
/**
- * @fn CABTIsServiceSupported
* @brief Checks if the specified list of service UUIDs contains OIC service UUID.
*
- * @param[in] serviceUUID Array of service UUIDs
- * @param[in] serviceCount Size of the service UUIDs array.
- * @param[in] matchService Service UUID to be checked in the given array of service UUIDs
+ * @param serviceUUID [IN] Array of service UUIDs
+ * @param serviceCount [IN] Size of the service UUIDs array.
+ * @param matchService [IN] Service UUID to be checked in the given array of service UUIDs
*
- * @return true if match service UUID found otherwise false.
+ * @return CA_TRUE if match service UUID found otherwise CA_FALSE.
*
*/
-bool CABTIsServiceSupported(const char **serviceUUID, const int32_t serviceCount,
+CABool_t CAEDRIsServiceSupported(const char **serviceUUID, const int32_t serviceCount,
const char *matchService);
#ifdef __cplusplus
} /* extern "C" */
#endif
-#endif //__CA_BT_UTILS_H_
+#endif //__CA_EDR_UTILS_H_
if (endpoint == NULL)
{
OIC_LOG(DEBUG, TAG, "CALEPacketReceiveCallback, Memory allocation failed !");
- OICFree(address);
+ OICFree((char*)address);
return;
}
{
strcpy((char*) endpoint->addressInfo.BT.btMacAddress, address);
}
- OICFree(address);
+ OICFree((char*)address);
// set connectivity type
endpoint->connectivityType = CA_LE;
// call the callback
if (gLENetworkChangeCallback != NULL)
{
- CARemoteEndpoint_t* endpoint = NULL;
- endpoint = (CARemoteEndpoint_t*) OICMalloc(sizeof(CARemoteEndpoint_t));
-
- if (endpoint == NULL)
- {
- OIC_LOG(DEBUG, TAG, "CALENetworkStateChangedCallback, Memory allocation failed !");
- OICFree(address);
- return;
- }
-
- // set address
- memset((void*) endpoint->addressInfo.BT.btMacAddress, 0, CA_MACADDR_SIZE);
- if (CA_MACADDR_SIZE > strlen(address))
- {
- strcpy((char*) endpoint->addressInfo.BT.btMacAddress, address);
- }
- OICFree(address);
-
- // set connectivity type
- endpoint->connectivityType = CA_LE;
-
CANetworkStatus_t netStatus = CA_INTERFACE_DOWN;
if(status == 12)
{
netStatus = CA_INTERFACE_DOWN;
}
- gLENetworkChangeCallback(endpoint, netStatus);
+ CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_LE, address);
+ if (!localEndpoint)
+ {
+ OIC_LOG_V(ERROR, TAG, "Out of memory");
+ return;
+ }
+
+ gLENetworkChangeCallback(localEndpoint, netStatus);
+
+ CAAdapterFreeLocalEndpoint(localEndpoint);
+
}
}
#include "calecore.h"
#include "caleserver.h"
+#include "caleutils.h"
+#include "caedrcore.h"
+
#include "logger.h"
#include "oic_malloc.h"
#include "uthreadpool.h" /* for thread pool */
#include "com_iotivity_jar_CALeInterface.h"
//#define DEBUG_MODE
-#define TAG PCF("CA")
+#define TAG PCF("CA_LE_CLIENT")
static const char *METHODID_OBJECTNONPARAM = "()Landroid/bluetooth/BluetoothAdapter;";
static const char *METHODID_STRINGNONPARAM = "()Ljava/lang/String;";
static const uint32_t STATE_DISCONNECTED = 0;
static const uint32_t GATT_SUCCESS = 0;
-static JavaVM *g_jvm;
+static const uint32_t MAX_PDU_BUFFER = 1400;
+
+JavaVM *g_jvm;
static u_arraylist_t *gdeviceList = NULL;
static u_arraylist_t *gGattObjectList = NULL;
static CAPacketReceiveCallback gPacketReceiveCallback = NULL;
//JVM required for WifiCore to work with JNI interface
CAWiFiJniInit(jvm);
CALeServerJniInit(env, jvm);
+ CAEDRCoreJniInit(env, jvm);
return JNI_VERSION_1_6;
}
}
else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate) // le disconnected
{
+// CANativeLEStartScan();
+
if(gatt) {
- CANativeGattClose(env, gatt);
- CANativeRemoveGattObj(env, gatt);
+ //CANativeGattClose(env, gatt); // 20150105
+ //CANativeRemoveGattObj(env, gatt); // 20150105
}
}
else // other error
(JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data, jint status)
{
OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicReadCallback - status : %d", status);
-
- jboolean isCopy;
- char* readData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
-
- jstring jni_address = CANativeGetAddressFromGattObj(env, gatt);
- const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
-
- OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicReadCallback - read data : %s", readData);
-
- gPacketReceiveCallback(address, readData);
}
/*
OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
jboolean isCopy;
- char* writeData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
+ char* wroteData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
jstring jni_address = CANativeGetAddressFromGattObj(env, gatt);
const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
- OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", writeData);
+ OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
#ifdef DEBUG_MODE
CANativeSendFinsih(env, gatt);
#endif
- if(0 != status)
+ if(0 != status) // error case
{
CANativeSendFinsih(env, gatt);
}
{
OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
+ // get Byte Array and covert to char*
+ jint length = (*env)->GetArrayLength(env, data);
+
jboolean isCopy;
- char* NotificationData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
+ jbyte *jni_byte_responseData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
+
+ char responseData[MAX_PDU_BUFFER];
+ memset(responseData, 0, MAX_PDU_BUFFER);
+ strncpy(responseData, (char*)jni_byte_responseData, length);
+ responseData[length] = '\0';
+ (*env)->ReleaseByteArrayElements(env, data, (jbyte*)jni_byte_responseData, JNI_ABORT);
jstring jni_address = CANativeGetAddressFromGattObj(env, gatt);
const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
- OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data : %s", NotificationData);
+ OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %s, %d", responseData, length);
- gPacketReceiveCallback(address, NotificationData);
+ // callback
+ gPacketReceiveCallback(address, responseData);
+ // LE disconnect and finish BLE write routine
CANativeSendFinsih(env, gatt);
}
// delete mutex object
u_mutex_free(gThreadMutex);
gThreadMutex = NULL;
+ u_cond_signal(gThreadCond);
u_cond_free(gThreadCond);
}
isAttached = TRUE;
}
- jstring jni_address = CANativeGetLocalDeviceAddress(env);
+ jstring jni_address = CALEGetLocalDeviceAddress(env);
if(jni_address)
{
const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
return 0;
}
- jstring jni_setAddress = CANativeGetAddressFromBTDevice(env, jarrayObj);
+ jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
if(!jni_setAddress)
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
return 1;
}
-/**
- * BT common
- */
-jstring CANativeGetLocalDeviceAddress(JNIEnv* env)
-{
- jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
- if(!jni_cid_BTAdapter)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][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)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][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)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][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)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][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)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_str_address is null");
- return NULL;
- }
-
- return jni_str_address;
-}
-
-jobjectArray CANativeBondedDevices(JNIEnv *env)
-{
- jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
- if(!jni_cid_BTAdapter)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_cid_BTAdapter is null");
- return NULL;
- }
-
- jmethodID jni_mid_getDefaultAdapter =
- (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
-
- jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
- if(!jni_obj_BTAdapter)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: bluetooth adapter is null");
- return NULL;
- }
-
- // 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)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][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)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_obj_setPairedDevices is null");
- return NULL;
- }
-
- // Convert the set to an object array
- // object[] array = Set<BluetoothDevice>.toArray();
- jclass jni_cid_Set = (*env)->FindClass(env, "java/util/Set");
- jmethodID jni_mid_toArray = (*env)->GetMethodID(env, jni_cid_Set, "toArray", "()[Ljava/lang/Object;");
-
- if(!jni_mid_toArray)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][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)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_arrayPairedDevices is null");
- return NULL;
- }
-
- return jni_arrayPairedDevices;
-}
-
-jint CANativeGetBTStateOnInfo(JNIEnv *env)
-{
- jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
- if(!jni_cid_BTAdapter)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] getBTStateOnInfo: jni_cid_BTAdapter is null");
- return -1;
- }
-
- jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
- if (jni_fid_stateon == 0)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] get_field_state is 0");
- return -1;
- }
- jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
-
- OIC_LOG_V(DEBUG, TAG, "[BLE][Native] bluetooth STATE_ON state integer value : %d", jni_int_val);
-
- return jni_int_val;
-}
-
-jboolean CANativeIsEnableBTAdapter(JNIEnv *env)
-{
- jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
- if(!jni_cid_BTAdapter)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTAdapter: jni_cid_BTAdapter is null");
- return FALSE;
- }
-
- jmethodID jni_mid_getDefaultAdapter =
- (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
- if(!jni_mid_getDefaultAdapter)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getDefaultAdapter is null");
- return FALSE;
- }
-
- jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
- if(!jni_obj_BTAdapter)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_BTAdapter is null");
- return FALSE;
- }
-
- // isEnable()
- jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled",
- "()Z");
- if(!jni_mid_isEnable)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_isEnable is null");
- return FALSE;
- }
-
- jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
- OIC_LOG_V(DEBUG, TAG, "[BLE][Native] adapter state is %d", jni_isEnable);
-
- return jni_isEnable;
-}
-
-jstring CANativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
-{
- jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
- if(!jni_cid_device_list)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][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)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getAddress is null");
- return NULL;
- }
-
- jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice, jni_mid_getAddress);
- if(!jni_address)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_address is null");
- return NULL;
- }
- return jni_address;
-}
-
jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt)
{
if(!gatt)
return NULL;
}
- jstring jni_address = CANativeGetAddressFromBTDevice(env, jni_obj_device);
+ jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
if(!jni_address)
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_address is null");
void CANativeLEStartScanImpl(JNIEnv *env, jobject callback)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return;
// get default bt adapter class
OIC_LOG(DEBUG, TAG, "[BLE][Native] get default bt adapter class");
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return;
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStopScan");
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return;
int32_t CANativeLEConnect(JNIEnv *env, jobject bluetoothDevice, jobject context,
jboolean autoconnect, jobject callback)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return 0;
}
- jstring jni_address = CANativeGetAddressFromBTDevice(env, bluetoothDevice);
+ jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
const char * addr = (*env)->GetStringUTFChars(env, jni_address, NULL);
OIC_LOG_V(DEBUG, TAG, "[BLE][Native] request connectGatt to %s", addr);
void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return;
}
+void CANativeLEDisconnectAll(JNIEnv *env)
+{
+ OIC_LOG_V(DEBUG, TAG, "CANativeLEDisconnectAll");
+
+ if(!gGattObjectList)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
+ return;
+ }
+
+ jint index;
+ for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
+ {
+ jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
+ if(!jarrayObj)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+ return;
+ }
+ CANativeLEDisconnect(env, jarrayObj);
+ }
+
+ OICFree(gGattObjectList);
+ gGattObjectList = NULL;
+ return;
+}
+
void CANativeLEDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return;
jboolean CANativeLESendData(JNIEnv *env, jobject bluetoothGatt, jobject gattCharacteristic)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return FALSE;
void CANativeReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return;
jboolean CANativeSetCharacteristicNoti(JNIEnv *env, jobject bluetoothGatt, const char* uuid)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return FALSE;
jobject CANativeGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return NULL;
jobject CANativeCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return NULL;
jbyteArray CANativeGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
{
- if(!CANativeIsEnableBTAdapter(env))
+ if(!CALEIsEnableBTAdapter(env))
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
return NULL;
return;
}
- jstring jni_remoteAddress = CANativeGetAddressFromBTDevice(env, device);
+ jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
if(!jni_remoteAddress)
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
return TRUE;
}
- jstring jni_setAddress = CANativeGetAddressFromBTDevice(env, jarrayObj);
+ jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
if(!jni_setAddress)
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
return;
}
- jstring jni_setAddress = CANativeGetAddressFromBTDevice(env, jarrayObj);
+ jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
if(!jni_setAddress)
{
OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
return;
}
-void CANativeLEDisconnectAll(JNIEnv *env)
-{
- OIC_LOG_V(DEBUG, TAG, "CANativeLEDisconnectAll");
-
- if(!gGattObjectList)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
- return;
- }
-
- jint index;
- for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
- {
- jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
- if(!jarrayObj)
- {
- OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
- return;
- }
- CANativeLEDisconnect(env, jarrayObj);
- }
-
- OICFree(gGattObjectList);
- gGattObjectList = NULL;
- return;
-}
-
void CANativeRemoveGattObj(JNIEnv *env, jobject gatt)
{
OIC_LOG_V(DEBUG, TAG, "CANativeRemoveGattObj");
gGattObjectList->length--;
}
+/**
+ * Check Sent Count for remove gSendBuffer
+ */
void CANativeupdateSendCnt(JNIEnv *env)
{
// mutex lock
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
/* Service UUID */
-//static const char *OIC_GATT_SERVICE_UUID = "000018f3-0000-1000-8000-00805f9b34fb";
-//static const char *OIC_GATT_CHARACTERISTIC_RESPONSE_UUID = "00002af5-0000-1000-8000-00805f9b34fb"; //read
-//static const char *OIC_GATT_CHARACTERISTIC_REQUEST_UUID = "00002af6-0000-1000-8000-00805f9b34fb"; //write
-
static const char *OIC_GATT_SERVICE_UUID = "713d0000-503e-4c75-ba94-3148f18d941e";
static const char *OIC_GATT_CHARACTERISTIC_RESPONSE_UUID = "713d0002-503e-4c75-ba94-3148f18d941e"; //read
static const char *OIC_GATT_CHARACTERISTIC_REQUEST_UUID = "713d0003-503e-4c75-ba94-3148f18d941e"; //write
static u_thread_pool_t gThreadPoolHandle = NULL;
static jboolean gIsStartServer;
+static jboolean gIsSendingMulticastData;
//getting context
void CALEServerJNISetContext(JNIEnv *env, jobject context)
g_jvm = jvm;
}
-jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
+jobject CANativeLEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
{
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return NULL;
+ }
OIC_LOG_V(DEBUG, TAG, "CALEServerSetResponseData");
return jni_obj_bluetoothGattCharacteristic;
}
-jboolean CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
+jboolean CANativeLEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
{
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return JNI_FALSE;
+ }
+
OIC_LOG_V(DEBUG, TAG, "CALEServerSendResponseData");
jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
return jni_boolean_notifyCharacteristicChanged;
}
-jboolean CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
+jboolean CANativeLEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
jint offset, jbyteArray value)
{
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return JNI_FALSE;
+ }
+
OIC_LOG_V(DEBUG, TAG, "CALEServerSendResponse");
jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
return jni_boolean_sendResponse;
}
-void LEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
+void CANativeLEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
{
OIC_LOG_V(DEBUG, TAG, "LEServerStartAdvertise");
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return;
+ }
+
jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
"android/bluetooth/le/AdvertiseSettings$Builder");
OIC_LOG_V(DEBUG, TAG, "Advertising started!!");
}
-void LEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
+void CANativeLEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
{
OIC_LOG_V(DEBUG, TAG, "LEServerStopAdvertise");
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return;
+ }
+
jclass jni_cid_BTAdapter = (*env)->FindClass(env,
"android/bluetooth/BluetoothAdapter");
OIC_LOG_V(DEBUG, TAG, "CALEStartGattServer");
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return JNI_FALSE;
+ }
+
if(gIsStartServer)
OIC_LOG_V(DEBUG, TAG, "Gatt server already started");
gBluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
// open gatt server
- jobject bluetoothGattServer = CALEServerOpenGattServer(env);
+ jobject bluetoothGattServer = CANativeLEServerOpenGattServer(env);
+ if(!bluetoothGattServer)
+ {
+ OIC_LOG_V(DEBUG, TAG, "bluetoothGattServer is null");
+ return JNI_FALSE;
+ }
+
gBluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
// create gatt service
- jobject bluetoothGattService = CALEServerCreateGattService(env);
+ jobject bluetoothGattService = CANativeLEServerCreateGattService(env);
// add gatt service
- return CALEServerAddGattService(env, bluetoothGattServer, bluetoothGattService);
+ return CANativeLEServerAddGattService(env, gBluetoothGattServer, bluetoothGattService);
}
-jobject CALEServerOpenGattServer(JNIEnv *env)
+jobject CANativeLEServerOpenGattServer(JNIEnv *env)
{
OIC_LOG_V(DEBUG, TAG, "CALEServerOpenGattServer");
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return NULL;
+ }
+
jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
jclass jni_cid_bluetoothManager = (*env)->FindClass(env,
jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env,
jni_cid_context, jni_fid_bluetoothService);
+ if(!jni_obj_bluetoothService)
+ {
+ OIC_LOG_V(DEBUG, TAG, "jni_obj_bluetoothService is null");
+ return JNI_FALSE;
+ }
+
jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, gContext,
jni_mid_getSystemService, jni_obj_bluetoothService);
+ if(!jni_obj_bluetoothManager)
+ {
+ OIC_LOG_V(DEBUG, TAG, "jni_obj_bluetoothManager is null");
+ return JNI_FALSE;
+ }
jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env,
jni_obj_bluetoothManager, jni_mid_openGattServer, gContext,
gBluetoothGattServerCallback);
+ if(!jni_obj_bluetoothGattServer)
+ {
+ OIC_LOG_V(DEBUG, TAG, "jni_obj_bluetoothGattServer is null");
+ return JNI_FALSE;
+ }
return jni_obj_bluetoothGattServer;
}
-jobject CALEServerCreateGattService(JNIEnv *env)
+jobject CANativeLEServerCreateGattService(JNIEnv *env)
{
OIC_LOG_V(DEBUG, TAG, "CALEServerCreateGattService");
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return NULL;
+ }
+
jclass jni_cid_bluetoothGattService = (*env)->FindClass(env,
"android/bluetooth/BluetoothGattService");
return jni_bluetoothGattService;
}
-jboolean CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
+jboolean CANativeLEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
jobject bluetoothGattService)
{
OIC_LOG_V(DEBUG, TAG, "CALEServerAddGattService");
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return JNI_FALSE;
+ }
+
jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
"android/bluetooth/BluetoothGattServer");
return jni_boolean_addService;
}
-jboolean CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
+jboolean CANativeLEServerConnect(JNIEnv *env, jobject bluetoothDevice)
{
OIC_LOG_V(DEBUG, TAG, "CALEConnect");
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return JNI_FALSE;
+ }
+
jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
"android/bluetooth/BluetoothGattServer");
"(Landroid/bluetooth/BluetoothDevice;Z)Z");
jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env,
- gBluetoothGattServer, jni_mid_connect, bluetoothDevice, JNI_TRUE);
+ gBluetoothGattServer, jni_mid_connect, bluetoothDevice, JNI_FALSE);
if(jni_boolean_connect == JNI_FALSE) {
OIC_LOG_V(DEBUG, TAG, "Fail to connect");
return jni_boolean_connect;
}
-void CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
+void CANativeLEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
{
OIC_LOG_V(DEBUG, TAG, "CALEDisconnect");
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return;
+ }
+
jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
"android/bluetooth/BluetoothGattServer");
OIC_LOG_V(DEBUG, TAG, "CALESend");
- jobject responseChar = CALEServerSetResponseData(env, responseData);
+ if(!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+ return JNI_FALSE;
+ }
+
+ jobject responseChar = CANativeLEServerSetResponseData(env, responseData);
- jboolean result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
+ jboolean result = CANativeLEServerSendResponseData(env, bluetoothDevice, responseChar);
if(result == JNI_FALSE)
{
gThreadPoolHandle = handle;
+ gIsSendingMulticastData = FALSE;
+
CALEServerCreateCachedDeviceList();
}
}
// start advertise
- LEServerStartAdvertise(env, gLeAdvertiseCallback);
+ CANativeLEServerStartAdvertise(env, gLeAdvertiseCallback);
if(isAttached)
(*g_jvm)->DetachCurrentThread(g_jvm);
isAttached = TRUE;
}
- LEServerStopAdvertise(env, gLeAdvertiseCallback);
+ CANativeLEServerStopAdvertise(env, gLeAdvertiseCallback);
gIsStartServer = FALSE;
return -1;
}
- CALEServerConnect(env, jarrayObj);
+ gIsSendingMulticastData = TRUE;
+ CANativeLEServerConnect(env, jarrayObj);
sleep(1);
}
CALEServerAddDeviceToList(env, device);
}
+// // temp data
+// if(gIsSendingMulticastData)
+// {
+// OIC_LOG_V(DEBUG, TAG, "send data");
+//
+// const char* data = "HelloWorld~";
+// uint32_t dataLen = strlen(data);
+// jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
+// (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*)data);
+// CALEServerSend(env, device, jni_bytearr_data);
+// gIsSendingMulticastData = FALSE;
+// }
+
+
}
else if(newState == jni_int_state_disconnected)
{
{
OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Read Request Callback");
- CALEServerSendResponse(env, device, requestId, 0, offset, NULL);
+ CANativeLEServerSendResponse(env, device, requestId, 0, offset, NULL);
}
JNIEXPORT void JNICALL
{
OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Write Request Callback");
- CALEServerSendResponse(env, device, requestId, 0, offset, value);
+ CANativeLEServerSendResponse(env, device, requestId, 0, offset, value);
if(data == NULL)
{
return;
}
+ // get Byte Array and covert to char*
+ jint length = (*env)->GetArrayLength(env, data);
+
jboolean isCopy;
- char* requestData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
+ jbyte *jni_byte_requestData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
+
+ char* requestData = NULL;
+ requestData = (char*) OICMalloc (sizeof(char) * length);
+ memset(requestData, 0, sizeof(char) * length);
+ strncpy(requestData, (char*)jni_byte_requestData, length);
+ requestData[length] = '\0';
+ (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
jstring jni_address = CALEGetAddressFromBTDevice(env, device);
const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
{
OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerExecuteWriteCallback");
- CALEServerSendResponse(env, device, requestId, 0, 0, NULL);
+ CANativeLEServerSendResponse(env, device, requestId, 0, 0, NULL);
}
JNIEXPORT void JNICALL
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define METHODID_OBJECTNONPARAM "()Landroid/bluetooth/BluetoothAdapter;"
-//#define METHODID_INTNONPARAM "()I"
#define METHODID_STRINGNONPARAM "()Ljava/lang/String;"
-//#define METHODID_OBJECT_STRINGUUIDPARAM "(Ljava/lang/String;Ljava/util/UUID;)Ljava/lang/Object;"
-//#define METHODID_ONRESPONSE_PARAM "(Ljava/lang/String;)V"
#define CLASSPATH_BT_ADPATER "android/bluetooth/BluetoothAdapter"
-//#define CLASSPATH_BT_UUID "java/util/UUID"
jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
{
return jni_ParcelUuid;
}
-jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
+jstring CALEGetLocalDeviceAddress(JNIEnv* env)
{
- OIC_LOG(DEBUG, TAG, "CALEGetAddressFromBTDevice");
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+ if(!jni_cid_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_cid_BTAdapter is null");
+ return NULL;
+ }
- jclass jni_cid_device_list = (*env)->FindClass(env,
- "android/bluetooth/BluetoothDevice");
- jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_device_list,
- "getAddress", "()Ljava/lang/String;");
- jstring jni_address = (jstring)(*env)->CallObjectMethod(env,
- bluetoothDevice, jni_mid_getAddress);
- if (!jni_address)
+ jmethodID jni_mid_getDefaultAdapter =
+ (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+ if(!jni_mid_getDefaultAdapter)
{
- OIC_LOG(DEBUG, TAG, "jni_address is null");
- return 0;
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_mid_getDefaultAdapter is null");
+ return NULL;
}
- return jni_address;
+
+ jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTAdapter, "getAddress", METHODID_STRINGNONPARAM);
+ if(!jni_mid_getAddress)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][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)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][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)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_str_address is null");
+ return NULL;
+ }
+
+ return jni_str_address;
}
-jstring CALEGetLocalDeviceAddress(JNIEnv* env)
+jobjectArray CALEBondedDevices(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(DEBUG, TAG, "getAddress: jni_cid_BTAdapter is null");
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: 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);
+
+ jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+ if(!jni_obj_BTAdapter)
{
- OIC_LOG(DEBUG, TAG, "getAddress: jni_mid_getDefaultAdapter is null");
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: bluetooth adapter is null");
return NULL;
}
- jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTAdapter,
- "getAddress", METHODID_STRINGNONPARAM);
- if (!jni_mid_getAddress)
+ // 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)
{
- OIC_LOG(DEBUG, TAG, "getAddress: jni_mid_getAddress is null");
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_mid_getBondedDevicesr is null");
return NULL;
}
- jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env,
- jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
- if (!jni_obj_BTAdapter)
+ jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_getBondedDevices);
+ if(!jni_obj_setPairedDevices)
{
- OIC_LOG(DEBUG, TAG, "getAddress: jni_obj_BTAdapter is null");
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_obj_setPairedDevices is null");
return NULL;
}
- jstring jni_str_address = (jstring)(*env)->CallObjectMethod(env,
- jni_obj_BTAdapter, jni_mid_getAddress);
- if (!jni_str_address)
+ // Convert the set to an object array
+ // object[] array = Set<BluetoothDevice>.toArray();
+ jclass jni_cid_Set = (*env)->FindClass(env, "java/util/Set");
+ jmethodID jni_mid_toArray = (*env)->GetMethodID(env, jni_cid_Set, "toArray", "()[Ljava/lang/Object;");
+
+ if(!jni_mid_toArray)
{
- OIC_LOG(DEBUG, TAG, "getAddress: jni_str_address is null");
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_mid_toArray is null");
return NULL;
}
- return jni_str_address;
+ jobjectArray jni_arrayPairedDevices = (jobjectArray)((*env)->CallObjectMethod(env,
+ jni_obj_setPairedDevices, jni_mid_toArray));
+ if(!jni_arrayPairedDevices)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_arrayPairedDevices is null");
+ return NULL;
+ }
+
+ return jni_arrayPairedDevices;
+}
+
+jint CALEGetBTStateOnInfo(JNIEnv *env)
+{
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+ if(!jni_cid_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] getBTStateOnInfo: jni_cid_BTAdapter is null");
+ return -1;
+ }
+
+ jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
+ if (jni_fid_stateon == 0)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] get_field_state is 0");
+ return -1;
+ }
+ jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
+
+ OIC_LOG_V(DEBUG, TAG, "[BLE][Native] bluetooth STATE_ON state integer value : %d", jni_int_val);
+
+ return jni_int_val;
+}
+
+jboolean CALEIsEnableBTAdapter(JNIEnv *env)
+{
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+ if(!jni_cid_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTAdapter: jni_cid_BTAdapter is null");
+ return FALSE;
+ }
+
+ jmethodID jni_mid_getDefaultAdapter =
+ (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+ if(!jni_mid_getDefaultAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getDefaultAdapter is null");
+ return FALSE;
+ }
+
+ jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+ if(!jni_obj_BTAdapter)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_BTAdapter is null");
+ return FALSE;
+ }
+
+ // isEnable()
+ jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled",
+ "()Z");
+ if(!jni_mid_isEnable)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_isEnable is null");
+ return FALSE;
+ }
+
+ jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
+ OIC_LOG_V(DEBUG, TAG, "[BLE][Native] adapter state is %d", jni_isEnable);
+
+ return jni_isEnable;
+}
+
+jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
+{
+ jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
+ if(!jni_cid_device_list)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][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)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getAddress is null");
+ return NULL;
+ }
+
+ jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice, jni_mid_getAddress);
+ if(!jni_address)
+ {
+ OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_address is null");
+ return NULL;
+ }
+ return jni_address;
}
--- /dev/null
+/******************************************************************
+*
+* 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.
+*
+******************************************************************/
+
+//logger.h included first to avoid conflict with RBL library PROGMEM attribute
+#include "logger.h"
+
+#include "caleinterface_singlethread.h"
+
+#include <Arduino.h>
+#include <SPI.h>
+#include <boards.h>
+#include <RBL_nRF8001.h>
+
+#include "caleadapter_singlethread.h"
+#include "caadapterutils.h"
+
+/**
+ * @def TAG
+ * @brief Logging tag for module name
+ */
+#define TAG "LENW"
+
+/**
+ * @var gCALEDeviceStateChangedCallback
+ * @brief Maintains the callback to be notified on device state changed.
+ */
+static CALEDeviceStateChangedCallback gCALEDeviceStateChangedCallback = NULL;
+
+/**
+ * @var gLeAddress
+ * @brief Maintains the local BLE Shield Address
+ */
+static unsigned char *gLeAddress = NULL;
+
+CAResult_t CALEInitializeNetworkMonitor()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ memcpy(gLeAddress, 0, CA_MACADDR_SIZE);
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CALETerminateNetworkMonitor()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAGetLEAdapterState()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAGetLEAddress(char **leAddress)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ gLeAddress = ble_getAddress();
+ /**
+ * Below Allocated Memory will be freed by caller API
+ */
+ *leAddress = (char*)OICMalloc(CA_MACADDR_SIZE);
+ if (NULL == leAddress)
+ {
+ OIC_LOG(ERROR, TAG, "error");
+ return;
+ }
+ memset(*leAddress, 0, CA_MACADDR_SIZE);
+ memcpy(*leAddress, gLeAddress, CA_MACADDR_SIZE);
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return;
+}
+
+CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ gCALEDeviceStateChangedCallback = callback;
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAUnSetLEAdapterStateChangedCb()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ gCALEDeviceStateChangedCallback = NULL;
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
*
******************************************************************/
+
+//logger.h included first to avoid conflict with RBL library PROGMEM attribute
+#include "logger.h"
+
#include "cableserver.h"
#include <Arduino.h>
#include <SPI.h>
#include <boards.h>
#include <RBL_nRF8001.h>
-#include <services.h>
-#include <logger.h>
+#include "caleinterface_singlethread.h"
#include "oic_malloc.h"
#include "caadapterutils.h"
OIC_LOG(DEBUG, TAG, "IN");
// Set your BLE Shield name here, max. length 10
- ble_set_name("SAMSUNG");
+ ble_set_name(__OIC_DEVICE_NAME__);
OIC_LOG(DEBUG, TAG, "LEName Set");
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
+}
+
+CAResult_t CATerminateBle()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ ble_disconnect();
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
}
return CA_STATUS_OK;
}
-CAResult_t CAWriteBleData(unsigned char *data, uint8_t len)
+CAResult_t CAUpdateCharacteristicsInGattServer(const char *char_value,
+ const uint32_t value_length)
{
// Currently ble_write_bytes api returns void.
- ble_write_bytes(data, len);
+ ble_write_bytes((unsigned char *)char_value, (unsigned char)value_length);
return CA_STATUS_OK;
-}
\ No newline at end of file
+}
+
*
******************************************************************/
+/**
+ * @file cableserver.h
+ * @brief This file contains the APIs related to the GATT Server functionalities.
+ * Creation of the GattServer with the characteristics. Enabling the advertisement
+ * and updating the characteristics for the response and notifying the change of
+ * characteristcs for the request will be done here
+ */
+
#ifndef _BLE_ADAPTER_ARDUINO_H_
#define _BLE_ADAPTER_ARDUINO_H_
/**
* @brief API to initialize Arduino BLE module and advertise the service
- * @return - int
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAInitializeBle();
/**
- * @brief API to send received data to upper layer
- * @param[in] data - data received from BLE characteristics
- * @param[in] dataLen - received data Length
- * @param[in] senderAdrs - sender Address.
- * @param[in] senderPort - sender port
- * @return - Error Code
+ * @brief API to Terminate Arduino BLE module and advertise the service
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CATerminateBle();
+
+/**
+ * @brief Send the received data to Connectivity Abstraction layer.
+ * @param data [IN] Data received from BLE characteristics
+ * @param dataLen [IN] Received data Length
+ * @param senderAdrs [IN] Sender Address.
+ * @param senderPort [IN] Sender port
+ * @return #CA_STATUS_OK or Appropriate error code
*/
void CANotifyCallback(void *data, int32_t dataLen, char *senderAdrs, int32_t senderPort);
/**
- * @brief API to add new service in Gatt Server
- * @param[in] service_uuid - unique identifier for each service.
- * @return - Error Code
+ * @brief Adds a new service in Gatt Server
+ * @param service_uuid [IN] Unique identifier for each service.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CAAddNewBleServiceInGattServer(const char *service_uuid);
/**
- * @brief API to remove the added service from Ble Gatt server.
- * @param[in] svc_path - unique identifier for each service.
- * @return - Error Code
+ * @brief Remove the added service from Ble Gatt server.
+ * @param svc_path [IN] Unique identifier for each service.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CARemoveBleServiceFromGattServer(const char *svc_path);
/**
- * @brief API to remove all the services from Ble Gatt server.
- * @return - Error Code
+ * @brief Remove all the services from Ble Gatt server.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CARemoveAllBleServicesFromGattServer();
/**
- * @brief API to register service with GattService after adding the service.
- * @param[in] svc_path - unique identifier for each service.
- * @return - Error Code
+ * @brief Register service with GattService after adding the service.
+ * @param svc_path [IN] Unique identifier for each service.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CARegisterBleServicewithGattServer(const char *svc_path);
/**
- * @brief API to add new characteristics to the service
- * @param[in] svc_path service path to which this characteristic belongs to.
- * @param[in] char_uuid Gatt characteristic uuid.
- * @param[in] char_value Gatt characteristic value.
- * @param[in] value_len Caracteristic value length.
- * @param[in] char_flags Characteristic flags.
- * @param[in] flags_length Caracteristic flags length.
- * @param[out] char_path characteristic path registered on the interface.
- * @return - Error Code
+ * @brief Add new characteristics to the service
+ * @param svc_path [IN] Service path to which this characteristic belongs to.
+ * @param char_uuid [IN] Gatt characteristic uuid.
+ * @param char_value [IN] Gatt characteristic value.
+ * @param char_value_len [IN] Characteristic value length.
+ * @param read [IN] Boolean variable for checking whether read characteristics or
+ * write characteristics.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
-CAResult_t CAAddNewCharacteristicsToGattServer(const char *svc_path,
- const char *char_uuid,
- const char *char_value,
- int char_value_len,
- int read);
+CAResult_t CAAddNewCharacteristicsToGattServer(const char *svc_path, const char *char_uuid,
+ const char *char_value, int char_value_len,
+ int read);
/**
- * @brief API to remove the characteristics.
- * @param[in] char_path characteristic path registered on the interface and unique
- * identifier for added characteristics.
- * @return - Error Code
+ * @brief Remove the characteristics from BLE GATT server
+ * @param char_path [IN] characteristic path registered on the interface and unique
+ * identifier for added characteristics.
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CARemoveCharacteristicsFromGattServer(const char *char_path);
/**
* @brief API to check whether data is available in BLE shield
- * @return - unsigned char
+ * @return - Received buffer length
*/
unsigned char CAIsBleDataAvailable();
/**
* @brief API to check whether client is connected with BLE Shield
- * @return - unsigned char
+ * @return - Connection state
*/
unsigned char CAIsBleConnected();
/**
* @brief API to read data from BLE shield
- * @return - char
+ * @return - Data read
*/
char CAReadBleData();
/**
* @brief API to perform BLE events
- * @return - Error Code
+ * @return #CA_STATUS_OK or Appropriate error code
*/
CAResult_t CABleDoEvents();
-/**
- * @brief API used to send data to connected ble client
- *
- * @param[in] data - data to be sent
- * @param[in] len - data length
- *
- * @return Error Code
- */
-CAResult_t CAWriteBleData(unsigned char *data, uint8_t len);
-
#ifdef __cplusplus
} /* extern "C" */
#endif
******************************************************************/
#include "caleadapter.h"
-#ifdef __TIZEN__
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <ifaddrs.h>
-#include <unistd.h>
-#include <pthread.h>
-#endif //#ifdef __TIZEN__
#include <stdio.h>
#include <stdlib.h>
-#ifdef __TIZEN__
-#include "cableserver.h"
-#include "cableclient.h"
+#include "caleinterface.h"
#include "cacommon.h"
#include "umutex.h"
#include "caadapterutils.h"
-#else // __ARDUINO__
-#include "BLEAdapterArduino.h"
-#include "caadapterutils.h"
-#endif //#ifdef __TIZEN__
#include "caqueueingthread.h"
#include "camsgparser.h"
+/**
+ * @var CALEADAPTER_TAG
+ * @brief Logging tag for module name.
+ */
#define CALEADAPTER_TAG "CA_BLE_ADAPTER"
+/**
+ * @var gNetworkCallback
+ * @brief Callback to provide the status of the network change to CA layer.
+ */
static CANetworkChangeCallback gNetworkCallback = NULL;
+/**
+ * @var gLocalBLEAddress
+ * @brief bleAddress of the local adapter. Value will be initialized to zero, and will be updated later.
+ */
static char gLocalBLEAddress[16] = { 0, };
+/**
+ * @var gIsServer
+ * @brief Variable to differentiate btw GattServer and GattClient.
+ */
static CABool_t gIsServer = CA_FALSE;
+/**
+ * @var gBleIsServerMutex
+ * @brief Mutex to synchronize the task to be executed on the GattServer function calls.
+ */
static u_mutex gBleIsServerMutex = NULL;
+/**
+ * @var gBleNetworkCbMutex
+ * @brief Mutex to synchronize the callback to be called for the network changes.
+ */
static u_mutex gBleNetworkCbMutex = NULL;
+/**
+ * @var gBleLocalAddressMutex
+ * @brief Mutex to synchronize the updation of the local LE address of the adapter.
+ */
static u_mutex gBleLocalAddressMutex = NULL;
/**
*/
static u_mutex gBleServerReceiveDataMutex = NULL;
+/**
+ * @var gBleAdapterReqRespCbMutex
+ * @brief Mutex to synchronize the callback to be called for the adapterReqResponse.
+ */
static u_mutex gBleAdapterReqRespCbMutex = NULL;
+/**
+ * @var gNetworkPacketReceivedCallback
+ * @brief Callback to be called when the network packet recieved from either GattServer or GattClient.
+ */
static CANetworkPacketReceivedCallback gNetworkPacketReceivedCallback = NULL;
+
/**
* @ENUM CALeServerStatus
* @brief status of BLE Server Status
CA_DISCOVERY_SERVER
} CALeServerStatus;
+/**
+ * @var gLeServerStatus
+ * @brief structure to maintain the status of the server.
+ */
static CALeServerStatus gLeServerStatus = CA_SERVER_NOTSTARTED;
+/**
+* @fn CALERegisterNetworkNotifications
+* @brief This function is used to register network change notification callback.
+*
+* @param[in] netCallback CANetworkChangeCallback callback which will be set for the change in nwk.
+*
+* @return 0 for success.
+*
+*/
int32_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback);
+/**
+* @fn CASetBleAdapterThreadPoolHandle
+* @brief Used to Set the gThreadPool handle which is required for spawning new thread.
+*
+* @param[in] handle - Thread pool handle which is given by above layer for using thread creation task.
+*
+* @return void
+*
+*/
void CASetBleAdapterThreadPoolHandle(u_thread_pool_t handle);
-#ifdef __TIZEN__
-void CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state,
- void *user_data);
+/**
+* @fn CALEDeviceStateChangedCb
+* @brief This function is used to call the callback to the upper layer when the device state gets changed.
+*
+* @param[in] adapter_state New state of the adapter to be notified to the upper layer.
+*
+* @return None.
+*
+*/
+void CALEDeviceStateChangedCb( CAAdapterState_t adapter_state);
+
+/**
+* @fn CAInitBleAdapterMutex
+* @brief Used to initialize all required mutex variable for LE Adapter implementation.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*
+*/
CAResult_t CAInitBleAdapterMutex();
-CAResult_t CATermiateBleAdapterMutex();
-#endif //#ifdef __TIZEN__
+/**
+* @fn CATermiateBleAdapterMutex
+* @brief Used to terminate all required mutex variable for LE adapter implementation.
+*
+* @return void
+*
+*/
+void CATermiateBleAdapterMutex();
CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
CANetworkPacketReceivedCallback reqRespCallback,
return CA_STATUS_FAILED;
}
-#ifdef __TIZEN__
-
- bt_initialize();
+ result = CAInitializeLENwkMonitor();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "CAInitializeLENwkMonitor() failed");
+ return CA_STATUS_FAILED;
+ }
-#endif //#ifdef __TIZEN__
+ CAInitializeLEAdapter();
CASetBleServerThreadPoolHandle(handle);
CASetBleClientThreadPoolHandle(handle);
CAConnectivityHandler_t connHandler;
connHandler.startAdapter = NULL;
- connHandler.stopAdapter = NULL;
+ connHandler.stopAdapter = CAStopLE;
connHandler.startListenServer = CAStartLEListeningServer;
connHandler.startDiscoverServer = CAStartLEDiscoveryServer;
connHandler.sendData = CASendLEUnicastData;
return CA_STATUS_OK;
}
+CAResult_t CAStopLE()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ CAStopBleQueues();
+
+ u_mutex_lock(gBleIsServerMutex);
+ if (CA_TRUE == gIsServer)
+ {
+ CAStopBleGattServer();
+ }
+ else
+ {
+ CAStopBLEGattClient();
+ }
+ u_mutex_unlock(gBleIsServerMutex);
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+
+ return CA_STATUS_OK;
+}
+
void CATerminateLE()
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
CASetBLEReqRespServerCallback(NULL);
CASetBLEReqRespClientCallback(NULL);
CALERegisterNetworkNotifications(NULL);
+ CASetBLEReqRespAdapterCallback(NULL);
+ CATerminateLENwkMonitor();
u_mutex_lock(gBleIsServerMutex);
if (CA_TRUE == gIsServer)
{
- CAStopBleGattServer();
+ CATerminateBleGattServer();
}
else
{
- CAStopBLEGattClient();
+ CATerminateBLEGattClient();
}
u_mutex_unlock(gBleIsServerMutex);
CATerminateBleQueues();
+ CATermiateBleAdapterMutex();
+
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return;
}
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
- bt_error_e err = BT_ERROR_NONE;
- bt_adapter_state_e adapterState;
-
CAResult_t result = CAInitBleServerQueues();
if (CA_STATUS_OK != result)
{
return CA_STATUS_FAILED;
}
- //Get Bluetooth adapter state
- if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState)))
- {
- OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!, error num [%x]",
- err);
-
- return CA_STATUS_FAILED;
- }
-
- if (BT_ADAPTER_ENABLED != adapterState)
+ result = CAGetLEAdapterState();
+ if (CA_ADAPTER_NOT_ENABLED == result)
{
gLeServerStatus = CA_LISTENING_SERVER;
OIC_LOG(DEBUG, CALEADAPTER_TAG, "Listen Server will be started once BT Adapter is enabled");
return CA_STATUS_OK;
}
+ if (CA_STATUS_FAILED == result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!");
+ return CA_STATUS_FAILED;
+ }
+
CAStartBleGattServer();
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
- bt_error_e err = BT_ERROR_NONE;
- bt_adapter_state_e adapterState;
-
CAResult_t result = CAInitBleClientQueues();
if (CA_STATUS_OK != result)
{
return CA_STATUS_FAILED;
}
- //Get Bluetooth adapter state
- if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState)))
+ result = CAGetLEAdapterState();
+ if (CA_ADAPTER_NOT_ENABLED == result)
{
- OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!, error num [%x]",
- err);
-
- return CA_STATUS_FAILED;
+ gLeServerStatus = CA_DISCOVERY_SERVER;
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Listen Server will be started once BT Adapter is enabled");
+ return CA_STATUS_OK;
}
- if (BT_ADAPTER_ENABLED != adapterState)
+ if (CA_STATUS_FAILED == result)
{
- gLeServerStatus = CA_DISCOVERY_SERVER;
- OIC_LOG(DEBUG, CALEADAPTER_TAG, "Disc Server will be started once BT Adapter is enabled");
- return CA_STATUS_OK;
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!");
+ return CA_STATUS_FAILED;
}
CAStartBLEGattClient();
- OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
u_mutex_lock(gBleIsServerMutex);
gIsServer = CA_FALSE;
u_mutex_unlock(gBleIsServerMutex);
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-
return CA_STATUS_OK;
}
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-
return CA_STATUS_OK;
}
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-
return CA_STATUS_OK;
}
CAResult_t result = CA_STATUS_FAILED;
-#ifdef __TIZEN__
u_mutex_lock(gBleIsServerMutex);
if (CA_TRUE == gIsServer)
{
}
}
u_mutex_unlock(gBleIsServerMutex);
-#else
- char *tempPath = "temp_path";
- updateCharacteristicsInGattServer(tempPath, (char *) data, dataLen);
-#endif //#ifdef __TIZEN__
- OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return dataLen;
}
}
CAResult_t result = CA_STATUS_FAILED;
-#ifdef __TIZEN__
+
u_mutex_lock(gBleIsServerMutex);
if (CA_TRUE == gIsServer)
{
}
}
u_mutex_unlock(gBleIsServerMutex);
-#else
- char *tempPath = "temp_path";
- updateCharacteristicsInGattServer(tempPath, (char *) data, dataLen);
-#endif //#ifdef __TIZEN__
+
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return dataLen;
}
VERIFY_NON_NULL(info, NULL, "CALocalConnectivity info is null");
-#if __TIZEN__
-
char *local_address = NULL;
- bt_adapter_get_address(&local_address);
+ CAGetLEAddress(&local_address);
if (NULL == local_address)
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "Get local bt adapter address failed");
return CA_STATUS_FAILED;
}
-#endif //#if ARDUINODUE
*size = 0;
(*info) = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t));
if (NULL == (*info))
u_mutex_lock(gBleNetworkCbMutex);
gNetworkCallback = netCallback;
u_mutex_unlock(gBleNetworkCbMutex);
- int32_t ret = 0;
-#ifdef __TIZEN__
+
if (netCallback)
{
- ret = bt_adapter_set_state_changed_cb(CALEDeviceStateChangedCb, NULL);
- if (ret != 0)
+ CAResult_t res = CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCb);
+ if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!");
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLEAdapterStateChangedCb failed!");
}
}
else
{
- ret = bt_adapter_unset_state_changed_cb();
- if (ret != 0)
+ CAResult_t res = CAUnSetLEAdapterStateChangedCb();
+ if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!");
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLEAdapterStateChangedCb failed!");
}
}
-#endif //#ifdef __TIZEN__
+
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
-#ifdef __TIZEN__
-
-void CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state, void *user_data)
+void CALEDeviceStateChangedCb( CAAdapterState_t adapter_state)
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
u_mutex_unlock(gBleNetworkCbMutex);
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return;
}
CAResult_t CAInitBleAdapterMutex()
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
return CA_STATUS_OK;
}
-CAResult_t CATermiateBleAdapterMutex()
+
+void CATermiateBleAdapterMutex()
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
gBleAdapterReqRespCbMutex = NULL;
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
+ return;
}
void CAInitBleQueues()
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return;
-
}
CAResult_t CAInitBleServerQueues()
}
if (CA_STATUS_OK != CAQueueingThreadInitialize(gSendQueueHandle, gBleAdapterThreadPool,
- CABLEServerSendDataThread))
+ CABLEServerSendDataThread, NULL))
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
OICFree(gSendQueueHandle);
return CA_STATUS_FAILED;
}
-
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return CA_STATUS_OK;
-
}
CAResult_t CAInitBleClientSenderQueue()
}
if (CA_STATUS_OK != CAQueueingThreadInitialize(gBLEClientSendQueueHandle, gBleAdapterThreadPool,
- CABLEClientSendDataThread))
+ CABLEClientSendDataThread, NULL))
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
OICFree(gBLEClientSendQueueHandle);
}
if (CA_STATUS_OK != CAQueueingThreadInitialize(gCABleServerReceiverQueue, gBleAdapterThreadPool,
- CABLEServerDataReceiverHandler))
+ CABLEServerDataReceiverHandler, NULL))
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
OICFree(gCABleServerReceiverQueue);
}
if (CA_STATUS_OK != CAQueueingThreadInitialize(gCABleClientReceiverQueue, gBleAdapterThreadPool,
- CABLEClientDataReceiverHandler))
+ CABLEClientDataReceiverHandler, NULL))
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
OICFree(gBLEClientSendQueueHandle);
return CA_STATUS_FAILED;
}
}
- //gClientUp = CA_TRUE; //AMOGH
-
if (CA_STATUS_OK != CAQueueingThreadStart(gCABleClientReceiverQueue))
{
OIC_LOG_V(ERROR, CALEADAPTER_TAG, "u_thread_pool_add_task failed ");
return CA_STATUS_OK;
}
-void CATerminateBleQueues()
+void CAStopBleQueues()
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
if (NULL != gBLEClientSendQueueHandle)
{
CAQueueingThreadStop(gBLEClientSendQueueHandle);
- gBLEClientSendQueueHandle = NULL;
}
u_mutex_unlock(gBleClientSendDataMutex);
if (NULL != gCABleClientReceiverQueue)
{
CAQueueingThreadStop(gCABleClientReceiverQueue);
- gCABleClientReceiverQueue = NULL;
}
u_mutex_unlock(gBleClientReceiveDataMutex);
u_mutex_lock(gBleServerSendDataMutex);
- if (NULL != gBLEClientSendQueueHandle)
+ if (NULL != gSendQueueHandle)
{
- CAQueueingThreadStop(gBLEClientSendQueueHandle);
- gBLEClientSendQueueHandle = NULL;
+ CAQueueingThreadStop(gSendQueueHandle);
}
u_mutex_unlock(gBleServerSendDataMutex);
if (NULL != gCABleServerReceiverQueue)
{
CAQueueingThreadStop(gCABleServerReceiverQueue);
- gCABleServerReceiverQueue = NULL;
}
u_mutex_unlock(gBleServerReceiveDataMutex);
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
}
+void CATerminateBleQueues()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ CAQueueingThreadDestroy(gBLEClientSendQueueHandle);
+ OICFree(gBLEClientSendQueueHandle);
+ gBLEClientSendQueueHandle = NULL;
+
+
+ CAQueueingThreadDestroy(gCABleClientReceiverQueue);
+ OICFree(gCABleClientReceiverQueue);
+ gCABleClientReceiverQueue = NULL;
+
+
+ CAQueueingThreadDestroy(gSendQueueHandle);
+ OICFree(gSendQueueHandle);
+ gSendQueueHandle = NULL;
+
+
+ CAQueueingThreadDestroy(gCABleServerReceiverQueue);
+ OICFree(gCABleServerReceiverQueue);
+ gCABleServerReceiverQueue = NULL;
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+}
void CABLEServerDataReceiverHandler(void *threadData)
{
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN");
remoteAddress = bleData->remoteEndpoint->addressInfo.LE.leMacAddress;
serviceUUID = bleData->remoteEndpoint->resourceUri;
- remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+ remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
serviceUUID);
memcpy(defragData + recvDataLen, bleData->data + CA_HEADER_LENGTH,
{
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN");
- // CAAdapterMessage_t *message = NULL;
static const char *remoteAddress = NULL;
static const char *serviceUUID = NULL;
static uint32_t recvDataLen = 0;
remoteAddress = bleData->remoteEndpoint->addressInfo.LE.leMacAddress;
serviceUUID = bleData->remoteEndpoint->resourceUri;
- remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+ remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
serviceUUID);
memcpy(defragData , bleData->data + CA_HEADER_LENGTH,
OICFree(bleData->remoteEndpoint);
OICFree(bleData);
- u_mutex_unlock(gBleServerSendDataMutex); // AMOGH is this mutex required ?
+ u_mutex_unlock(gBleServerSendDataMutex); // TODO: this mutex required ?
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return;
char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed");
- char *dataSegment = (char *) OICMalloc(sizeof(char) * bleData->dataLen + CA_HEADER_LENGTH);
+ char *dataSegment = (char *) OICMalloc(sizeof(char) * bleData->dataLen + CA_HEADER_LENGTH + 1);
if (NULL == dataSegment)
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
}
memset(header, 0x0, sizeof(char) * CA_HEADER_LENGTH );
- memset(dataSegment, 0x0, sizeof(char) * bleData->dataLen );
+ memset(dataSegment, 0x0, sizeof(char) * bleData->dataLen + CA_HEADER_LENGTH + 1);
CAResult_t result = CAGenerateHeader(header, bleData->dataLen);
if (CA_STATUS_OK != result )
result = CAUpdateCharacteristicsToAllGattServers(dataSegment + (index * length),
length);
// Send the remaining header.
- for (index = 1; index <= iter; index++)
+ for (index = 1; index < iter; index++)
{
result = CAUpdateCharacteristicsToAllGattServers(
bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return;
-
}
CABLEData *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
if (!bleData)
{
OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
+ CAAdapterFreeRemoteEndpoint(remoteEndpoint);
return CA_MEMORY_ALLOC_FAILED;
}
if (!bleData)
{
OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
+ CAAdapterFreeRemoteEndpoint(remoteEndpoint);
return CA_MEMORY_ALLOC_FAILED;
}
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
}
-
-
-#endif //#ifdef OIC_TIZEN
static CANetworkChangeCallback networkCallback = NULL;
static bool gServerRunning = false;
-#define BLE_ADDRESS "DB:F7:EB:B5:0F:07"
#define TAG "LAD"
#define COAP_MAX_PDU_SIZE 320
static CANetworkPacketReceivedCallback gRespCallback;
static char *gCoapBuffer = NULL;
-static int32_t dataLen = 0;
-static uint16_t packetDataLen = 0;
+static uint32_t dataLen = 0;
+static uint32_t packetDataLen = 0;
/**
* @brief API to store the networkcallback passed from top layer, register BLE network notification
return CA_STATUS_INVALID_PARAM;
}
+ CAResult_t result = CALEInitializeNetworkMonitor();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, TAG, "error");
+ return CA_STATUS_FAILED;
+ }
+
gRespCallback = reqRespCallback;
LERegisterNetworkNotifications(netCallback);
CAConnectivityHandler_t connHandler;
CAResult_t CAReadLEData()
{
- CABleDoEvents();
- CACheckData();
+ if (true == gServerRunning)
+ {
+ CACheckData();
+ }
return CA_STATUS_OK;
}
gRespCallback = NULL;
LERegisterNetworkNotifications(NULL);
CAStopBleGattServer();
+ CALETerminateNetworkMonitor();
+ gServerRunning = false;
OIC_LOG(DEBUG, TAG, "OUT");
return;
}
CAResult_t CAStartLEListeningServer()
{
OIC_LOG(DEBUG, TAG, "IN");
- CAInitializeBle();
- CABleDoEvents();
- CACheckData();
+ uint32_t iter = 0;
+ CAResult_t result = CAInitializeBle();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, TAG, "error");
+ return CA_STATUS_FAILED;
+ }
+
+ /**
+ * Below for loop is to process the BLE Events received from BLE Shield.
+ * BLE Events includes BLE Shield Address Added as a patch to RBL Library.
+ */
+ for (iter = 0; iter < 20; iter++)
+ {
+ CACheckData();
+ }
+
+ gServerRunning = true;
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
{
OIC_LOG(DEBUG, TAG, "IN");
OIC_LOG(DEBUG, TAG, "OUT");
- return CA_STATUS_OK;
+ return 1;
}
-CAResult_t CAUpdateCharacteristicsInGattServer(const char *char_value,
- const uint32_t value_length)
+uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLen)
{
- // Only 1 characteristic will be used for sending data from server
OIC_LOG(DEBUG, TAG, "IN");
+ if (NULL == remoteEndpoint)
+ {
+ OIC_LOG(ERROR, TAG, "error");
+ return 0;
+ }
+
+ char *char_value = (char *)data;
+ if (NULL == char_value || dataLen == 0)
+ {
+ OIC_LOG(ERROR, TAG, "error");
+ return 0;
+ }
char header[CA_HEADER_LENGTH] = "";
memset(header, 0, sizeof(char) * CA_HEADER_LENGTH);
- CAResult_t result = CAGenerateHeader(header, value_length);
+ CAResult_t result = CAGenerateHeader(header, dataLen);
if (CA_STATUS_OK != result)
{
- return CA_STATUS_FAILED;
+ return 0;
}
int32_t index = 0;
if (!CAIsBleConnected())
{
OIC_LOG(DEBUG, TAG, "le not conn");
- return CA_STATUS_FAILED;
+ return 0;
}
- CAWriteBleData((unsigned char *)header, CA_HEADER_LENGTH);
- int32_t iter = value_length / CA_SUPPORTED_BLE_MTU_SIZE;
+ CAUpdateCharacteristicsInGattServer(header, CA_HEADER_LENGTH);
+ int32_t iter = dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
for (index = 0; index < iter; index++)
{
- CAWriteBleData((unsigned char *)(char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
- (unsigned char) CA_SUPPORTED_BLE_MTU_SIZE);
+ CAUpdateCharacteristicsInGattServer((char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
+ CA_SUPPORTED_BLE_MTU_SIZE);
CABleDoEvents();
}
- CAWriteBleData((unsigned char *)(char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
- (unsigned char) value_length % CA_SUPPORTED_BLE_MTU_SIZE);
+ CAUpdateCharacteristicsInGattServer((char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
+ dataLen % CA_SUPPORTED_BLE_MTU_SIZE);
CABleDoEvents();
OIC_LOG(DEBUG, TAG, "writebytes done");
OIC_LOG(DEBUG, TAG, "OUT");
- return CA_STATUS_OK;
+ // Arduino BLEWrite doesnot return value. So, Return the received DataLength
+ return dataLen;
}
-uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLen)
+uint32_t CASendLEMulticastData(void *data, uint32_t dataLen)
{
OIC_LOG(DEBUG, TAG, "IN");
- if (NULL == remoteEndpoint)
+ if (NULL == data || 0 == dataLen)
{
OIC_LOG(ERROR, TAG, "error");
- return CA_STATUS_INVALID_PARAM;
+ return 0;
}
- CAUpdateCharacteristicsInGattServer((char *)data, dataLen);
- OIC_LOG(DEBUG, TAG, "OUT");
- return CA_STATUS_OK;
-}
-uint32_t CASendLEMulticastData(void *data, uint32_t dataLen)
-{
- OIC_LOG(DEBUG, TAG, "IN");
- if (NULL == data || 0 == dataLen)
+ char *char_value = (char *)data;
+ if (NULL == char_value || dataLen == 0)
{
OIC_LOG(ERROR, TAG, "error");
- return CA_STATUS_INVALID_PARAM;
+ return 0;
+ }
+
+ char header[CA_HEADER_LENGTH] = "";
+ memset(header, 0, sizeof(char) * CA_HEADER_LENGTH);
+
+ CAResult_t result = CAGenerateHeader(header, dataLen);
+
+ if (CA_STATUS_OK != result)
+ {
+ return 0;
+ }
+
+ int32_t index = 0;
+
+ if (!CAIsBleConnected())
+ {
+ OIC_LOG(DEBUG, TAG, "le not conn");
+ return 0;
}
- CAUpdateCharacteristicsInGattServer((char *)data, dataLen);
+
+ CAUpdateCharacteristicsInGattServer(header, CA_HEADER_LENGTH);
+ int32_t iter = dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
+
+ for (index = 0; index < iter; index++)
+ {
+ CAUpdateCharacteristicsInGattServer((char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
+ CA_SUPPORTED_BLE_MTU_SIZE);
+ CABleDoEvents();
+ }
+
+ CAUpdateCharacteristicsInGattServer((char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
+ dataLen % CA_SUPPORTED_BLE_MTU_SIZE);
+ CABleDoEvents();
+ OIC_LOG(DEBUG, TAG, "writebytes done");
+
OIC_LOG(DEBUG, TAG, "OUT");
- return CA_STATUS_OK;
+ // Arduino BLEWrite doesnot return value. So, Return the received DataLength
+ return dataLen;
}
CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
return CA_STATUS_INVALID_PARAM;
}
+ char *leAddress = NULL;
+ CAGetLEAddress(&leAddress);
+ OIC_LOG_V(DEBUG, TAG, "leAddress = %s", leAddress);
+
/**
* Create local endpoint using util function
*/
- (*info) = CAAdapterCreateLocalEndpoint(CA_LE, BLE_ADDRESS);
+ (*info) = CAAdapterCreateLocalEndpoint(CA_LE, leAddress);
if (NULL == (*info))
{
OIC_LOG(DEBUG, TAG, "error");
}
(*size) = 1;
+ if (*leAddress)
+ {
+ OICFree(leAddress);
+ }
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
{
OIC_LOG(DEBUG, TAG, "IN");
// Done at time of setup i.e. in initializeBle api
- gServerRunning = true;
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
CAResult_t CAStopBleGattServer()
{
// Not Supported
+ CAResult_t result = CATerminateBle();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, TAG, "error");
+ return CA_STATUS_FAILED;
+ }
return CA_STATUS_OK;
}
void CACheckData()
{
- OIC_LOG(DEBUG, TAG, "IN");
CABleDoEvents();
if (CAIsBleDataAvailable())
static u_mutex gBleReqRespClientCbMutex = NULL;
/**
+ * @var gBleReqRespClientCbMutex
+ * @brief Mutex to synchronize access to the requestResponse callback to be called
+ * when the data needs to be sent from GATTClient.
+ */
+static u_mutex gBleClientConnectMutex = NULL;
+
+
+/**
* @var gBleClientStateMutex
* @brief Mutex to synchronize the calls to be done to the platform from GATTClient
* interfaces from different threads.
static u_mutex gBleClientStateMutex = NULL;
/**
+ * @var gBleServerBDAddressMutex
+ * @brief Mutex to synchronize the Server BD Address update on client side.
+ */
+static u_mutex gBleServerBDAddressMutex = NULL;
+
+/**
* @var gBleClientSendCondWait
* @brief Condition used for notifying handler the presence of data in send queue.
*/
char *address; /**< BD Address of */
} stGattServiceInfo_t;
-///TODO: gRemoteAddress is defined here temporarily.
-///TODO: It will be removed once UUID based service discovery Implemented in tizen BLE platform
/**
- * @struct gRemoteAddress
+ * @var gRemoteAddress
* @brief Remote address of Gatt Server
- *
*/
-static const char *gRemoteAddress = "E4:12:1D:99:F3:57";
-//static const char *gRemoteAddress = "DB:F7:EB:B5:0F:07";
-
-static u_arraylist_t *gNonOicDeviceList = NULL;
-
-static CABool_t gIsOicDeviceFound = CA_FALSE;
+static char *gRemoteAddress = NULL;
void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic,
unsigned char *value,
return;
}
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
+
+ u_mutex_lock(gBleServerBDAddressMutex);
gCABLEClientDataReceivedCallback(gRemoteAddress, OIC_BLE_SERVICE_ID,
data, strlen(data), &sentLength);
+ u_mutex_unlock(gBleServerBDAddressMutex);
u_mutex_unlock(gBleReqRespClientCbMutex);
memcpy(stTemp->desc, (uint8_t *)descriptor, total);
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "result [%d] format [%d] total [%d]", result, format, total);
+ OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "result[%d] format[%d] total[%d]", result, format, total);
OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "characteristic [%s]", (const char *) characteristic);
(void *) stTemp);
if (CA_STATUS_OK != retVal)
{
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", retVal);
+ OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+ "u_thread_pool_add_task failed with ret [%d]", retVal);
bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
OICFree(stTemp->address);
OICFree(stTemp);
VERIFY_NON_NULL_VOID(bleServiceInfo, TZ_BLE_CLIENT_TAG,
"bleServiceInfo is NULL");
- int32_t ret = CAVerifyOICService(bleServiceInfo->service_clone);
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
- "We dont need to interact with this generic BLE device since it deos not have OIC service");
- }
- else
- {
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
+ OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG ,
- " serviceInfo remote address [%s]", bleServiceInfo->bdAddress);
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG ,
+ " serviceInfo remote address [%s]", bleServiceInfo->bdAddress);
- stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICMalloc(sizeof(stGattServiceInfo_t));
+ stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICMalloc(sizeof(stGattServiceInfo_t));
- VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed");
+ VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed");
- bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), bleServiceInfo->service_clone);
+ bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), bleServiceInfo->service_clone);
- int32_t len = strlen(bleServiceInfo->bdAddress);
+ int32_t len = strlen(bleServiceInfo->bdAddress);
- stTemp->address = (char *)OICMalloc(sizeof(char) * len + 1);
- if (NULL == stTemp->address)
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! ");
- bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
- OICFree(stTemp);
- return;
- }
- memset(stTemp->address, 0x0, len + 1);
+ stTemp->address = (char *)OICMalloc(sizeof(char) * len + 1);
+ if (NULL == stTemp->address)
+ {
+ OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! ");
+ bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+ OICFree(stTemp);
+ return;
+ }
+ memset(stTemp->address, 0x0, len + 1);
- strncpy(stTemp->address, bleServiceInfo->bdAddress, len);
+ strncpy(stTemp->address, bleServiceInfo->bdAddress, len);
- u_mutex_lock(gBleClientThreadPoolMutex);
- if (NULL == gBleClientThreadPool)
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
- bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
- OICFree(stTemp->address);
- OICFree(stTemp);
- u_mutex_unlock(gBleClientThreadPoolMutex);
- return;
- }
+ u_mutex_lock(gBleClientThreadPoolMutex);
+ if (NULL == gBleClientThreadPool)
+ {
+ OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
+ bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+ OICFree(stTemp->address);
+ OICFree(stTemp);
+ u_mutex_unlock(gBleClientThreadPoolMutex);
+ return;
+ }
- CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool,
- (void *) CADiscoverCharThread, (void *) stTemp);
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
- "u_thread_pool_add_task failed with ret [%d]", ret);
- bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
- OICFree(stTemp->address);
- OICFree(stTemp);
- u_mutex_unlock(gBleClientThreadPoolMutex);
- return;
- }
+ CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool,
+ (void *) CADiscoverCharThread, (void *) stTemp);
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+ "u_thread_pool_add_task failed with ret [%d]", ret);
+ bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+ OICFree(stTemp->address);
+ OICFree(stTemp);
u_mutex_unlock(gBleClientThreadPoolMutex);
+ return;
}
+ u_mutex_unlock(gBleClientThreadPoolMutex);
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
"Callback: is_bonded - %d.", device_info->is_bonded);
}
bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, int32_t count,
- void *userData)
+ void *userData)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service,
index, count);
- CAResult_t result = CAVerifyOICService(service);
-
- if (CA_STATUS_OK != result)
- {
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "No need to process the service ");
-
- if ((index + 1) == count && CA_FALSE == gIsOicDeviceFound)
- {
- char *bdAddress = (char *)userData;
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "OIC service is not available in remote address [%s]",
- bdAddress);
- int32_t len = strlen(bdAddress);
-
- char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
- VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "malloc failed!", false);
- memset(addr, 0x0, len + 1);
- strncpy(addr, bdAddress, len);
-
- uint32_t listLen = u_arraylist_length(gNonOicDeviceList);
- int32_t indexValue = 0;
- CABool_t found = CA_FALSE;
- for (indexValue = 0; indexValue < listLen; indexValue++)
- {
- char *storedAddr = u_arraylist_get(gNonOicDeviceList, indexValue);
- if (NULL == storedAddr)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
- "storedAddr is NULL");
- OICFree(addr);
- return false;
- }
- if (strcmp(storedAddr, addr) == 0)
- {
- found = CA_TRUE;
- break;
- }
- }
- if (found == CA_FALSE)
- {
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Adding device [%s] to gNonOicDeviceList", addr);
- u_arraylist_add(gNonOicDeviceList, addr);
- }
+ CAResult_t result = CAVerifyOICServiceByServiceHandle(service);
- CAResult_t result = CABleGattDisConnect(bdAddress);
- if (CA_STATUS_OK != result)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
- "CABleGattDisConnect failed!");
- OICFree(addr);
- return false;
- }
- }
- }
- else
+ if (CA_STATUS_OK == result)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
- gIsOicDeviceFound = CA_TRUE;
+ //gIsOicDeviceFound = CA_TRUE;
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes \n");
return true;;
}
-void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const char *remoteAddress,
- void *userData)
+void CABleGattConnectionStateChangedCb(int32_t result, bool connected,
+ const char *remoteAddress, void *userData)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
{
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);
+
int32_t len = strlen(remoteAddress);
- char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
+ u_mutex_lock(gBleServerBDAddressMutex);
+
+ gRemoteAddress = OICStrdup(remoteAddress);
- VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
+ u_mutex_unlock(gBleServerBDAddressMutex);
- memset(addr, 0x0, len + 1);
+ VERIFY_NON_NULL_VOID(gRemoteAddress, TZ_BLE_CLIENT_TAG, "Malloc failed");
- strncpy(addr, remoteAddress, len);
+ char *addr = OICStrdup(remoteAddress);
u_mutex_lock(gBleClientThreadPoolMutex);
if (NULL == gBleClientThreadPool)
{
OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
OICFree(addr);
+
+ u_mutex_lock(gBleServerBDAddressMutex);
+ OICFree(gRemoteAddress);
+ u_mutex_unlock(gBleServerBDAddressMutex);
+
u_mutex_unlock(gBleClientThreadPoolMutex);
return;
}
{
OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
OICFree(addr);
+
+ u_mutex_lock(gBleServerBDAddressMutex);
+ OICFree(gRemoteAddress);
+ u_mutex_unlock(gBleServerBDAddressMutex);
+
u_mutex_unlock(gBleClientThreadPoolMutex);
return;
}
{
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
" LE Discovery state is [%s]",
- discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished" );
+ discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished");
}
else
{
CAPrintDiscoveryInformation(discoveryInfo);
- VERIFY_NON_NULL_VOID(discoveryInfo->remote_address, TZ_BLE_CLIENT_TAG,
- "discoveryInfo->remote_address is NULL");
- ///TODO: Below check is for filtering to make connection with our intended device(hardcoded one)
- ///TODO: Later it will be removed once Service UUID based implementation is done.
-
- if (NULL != gNonOicDeviceList)
+ int i = 0;
+ if (discoveryInfo->service_uuid == NULL)
{
- uint32_t listLen = u_arraylist_length(gNonOicDeviceList);
- int32_t index = 0;
- for (index = 0; index < listLen; index++)
+ OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "NO UUIDS from device");
+ }
+ else
+ {
+ for (i = discoveryInfo->service_count - 1; i > 0; i--)
{
- char *storedAddr = u_arraylist_get(gNonOicDeviceList, index);
- if (NULL == storedAddr)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
- "storedAddr is NULL");
- return ;
- }
- if (strcmp(storedAddr, discoveryInfo->remote_address) == 0)
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "uuid[%d]: [%s]",
+ i, discoveryInfo->service_uuid[i]);
+ CAResult_t res = CAVerifyOICServiceByUUID(discoveryInfo->service_uuid[i]);
+ if (CA_STATUS_OK == res)
{
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Discovered Device is NON OIC Device. Ignore.");
- return;
+
+ int32_t len = strlen(discoveryInfo->remote_address);
+
+ char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
+
+ VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
+
+ memset(addr, 0x0, len + 1);
+ strncpy(addr, discoveryInfo->remote_address, len);
+
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
+ "Trying to do Gatt connection to [%s] ", addr);
+
+ u_mutex_lock(gBleClientThreadPoolMutex);
+ if (NULL == gBleClientThreadPool)
+ {
+ OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
+ OICFree(addr);
+ u_mutex_unlock(gBleClientThreadPoolMutex);
+ return;
+ }
+
+ CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool,
+ (void *) CAGattConnectThread, (void *) addr);
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+ "u_thread_pool_add_task failed with ret [%d]", ret);
+ OICFree(addr);
+ u_mutex_unlock(gBleClientThreadPoolMutex);
+ return;
+ }
+ u_mutex_unlock(gBleClientThreadPoolMutex);
+ if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
+ {
+ bt_adapter_le_stop_device_discovery();
+ return;
+ }
+ break; // Found the OIC Service. No need to verify remaining services.
}
}
}
-
- int32_t len = strlen(discoveryInfo->remote_address);
-
- char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
-
- VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
-
- memset(addr, 0x0, len + 1);
- strncpy(addr, discoveryInfo->remote_address, len);
-
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
- "Trying to do Gatt connection to [%s] ", addr);
-
- u_mutex_lock(gBleClientThreadPoolMutex);
- if (NULL == gBleClientThreadPool)
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
- OICFree(addr);
- u_mutex_unlock(gBleClientThreadPoolMutex);
- return;
- }
-
- CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, (void *) CAGattConnectThread,
- (void *) addr);
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
- OICFree(addr);
- u_mutex_unlock(gBleClientThreadPoolMutex);
- return;
- }
- u_mutex_unlock(gBleClientThreadPoolMutex);
- if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
- {
- bt_adapter_le_stop_device_discovery();
- return;
- }
-
}
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
return;
}
+
void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discoveryInfo)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
" Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
discoveryInfo->adv_data_len, discoveryInfo->scan_data_len, discoveryInfo->rssi,
discoveryInfo->address_type);
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
+ " Number of services present in device [%s] is [%d]",
+ discoveryInfo->remote_address, discoveryInfo->service_count);
+
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
}
CATerminateGattClientMutexVariables();
return CA_STATUS_FAILED;
}
- gNonOicDeviceList = u_arraylist_create();
+
u_mutex_lock(gBleClientThreadPoolMutex);
if (NULL == gBleClientThreadPool)
{
gDataReceiverHandlerState = CA_FALSE;
}
- CATerminateBLEGattClient();
-
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
}
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
gClientUp = CA_FALSE;
- gIsOicDeviceFound = CA_FALSE;
u_mutex_lock(gBleClientStateMutex);
+ GMainContext *context_event_loop = NULL;
// Required for waking up the thread which is running in gmain loop
- GMainContext *context_event_loop = g_main_loop_get_context(g_event_loop);
-
+ if (NULL != g_event_loop)
+ {
+ context_event_loop = g_main_loop_get_context(g_event_loop);
+ }
if (context_event_loop)
{
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "g_event_loop context %x", context_event_loop);
g_main_context_wakeup(context_event_loop);
+
+ // Kill g main loops and kill threads.
+ g_main_loop_quit(g_event_loop);
}
else
{
OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_event_loop context is NULL");
}
- // Kill g main loops and kill threads
- g_main_loop_quit(g_event_loop);
+ u_mutex_lock(gBleServerBDAddressMutex);
+
+ OICFree(gRemoteAddress);
+
+ u_mutex_unlock(gBleServerBDAddressMutex);
CABleGattUnWatchCharacteristicChanges();
CABleGattStopDeviceDiscovery();
- CAClearNonOICDeviceList();
-
u_mutex_lock(gBleServiceListMutex);
CAFreeBLEServiceList(gBLEServiceList);
gBLEServiceList = NULL;
}
}
+ if (NULL == gBleClientConnectMutex)
+ {
+ gBleClientConnectMutex = u_mutex_new();
+ if (NULL == gBleClientConnectMutex)
+ {
+ OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
if (NULL == gBleClientSendCondWait)
{
gBleClientSendCondWait = u_cond_new();
}
}
+ if (NULL == gBleServerBDAddressMutex)
+ {
+ gBleServerBDAddressMutex = u_mutex_new();
+ if (NULL == gBleServerBDAddressMutex)
+ {
+ OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
return CA_STATUS_OK;
}
u_mutex_free(gBleReqRespClientCbMutex);
gBleReqRespClientCbMutex = NULL;
+ u_mutex_free(gBleClientConnectMutex);
+ gBleClientConnectMutex = NULL;
+
u_mutex_free(gBleClientThreadPoolMutex);
gBleClientThreadPoolMutex = NULL;
+ u_mutex_free(gBleServerBDAddressMutex);
+ gBleServerBDAddressMutex = NULL;
+
u_cond_free(gBleClientSendCondWait);
gBleClientSendCondWait = NULL;
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
}
-void CAClearNonOICDeviceList()
-{
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-
- if (NULL != gNonOicDeviceList)
- {
- uint32_t listLen = u_arraylist_length(gNonOicDeviceList);
- int32_t index = 0;
- for (index = 0; index < listLen; index++)
- {
- char *storedAddr = u_arraylist_remove(gNonOicDeviceList, index);
- free(storedAddr);
- }
- u_arraylist_free(gNonOicDeviceList);
- gNonOicDeviceList = NULL;
- }
-
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-}
-
CAResult_t CABleGattSetScanParameter()
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
- VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL", CA_STATUS_FAILED);
+ VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
+ "remote address is NULL", CA_STATUS_FAILED);
+
+ sleep(1);
+
+ u_mutex_lock(gBleClientConnectMutex);
int32_t ret = bt_gatt_connect(remoteAddress, true);
CABTGetErrorMsg(ret));
return CA_STATUS_FAILED;
}
+ u_mutex_unlock(gBleClientConnectMutex);
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
return CA_STATUS_OK;
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
- VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL", CA_STATUS_FAILED);
+ VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
+ "remote address is NULL", CA_STATUS_FAILED);
int32_t ret = bt_gatt_disconnect(remoteAddress);
(void *)addr); // addr memory will be free in callback.
if (BT_ERROR_NONE != ret)
{
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_foreach_primary_services Failed with ret value [%d] ",
- ret);
+ OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+ "bt_gatt_foreach_primary_services Failed with ret value [%d] ", ret);
OICFree(addr);
return CA_STATUS_FAILED;
}
return NULL;
}
-CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service, const char *remoteAddress)
+CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service,
+ const char *remoteAddress)
{
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
return NULL;
}
-CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescriptorInfo)
+CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescInfo)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
VERIFY_NON_NULL_RET(strUUID, TZ_BLE_CLIENT_TAG, "malloc failed", CA_STATUS_FAILED);
memset(strUUID, 0x0, sizeof(char) * 5);
- snprintf(strUUID, 4, "%x%x", stGattCharDescriptorInfo->desc[3], stGattCharDescriptorInfo->desc[2]);
- noti[0] = stGattCharDescriptorInfo->desc[0];
- noti[1] = stGattCharDescriptorInfo->desc[1];
+ snprintf(strUUID, 4, "%x%x", stGattCharDescInfo->desc[3], stGattCharDescInfo->desc[2]);
+ noti[0] = stGattCharDescInfo->desc[0];
+ noti[1] = stGattCharDescInfo->desc[1];
noti[2] = 0x01;
noti[3] = 0x00;
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x0 [%x]", stGattCharDescriptorInfo->desc[0]);
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x1 [%x]", stGattCharDescriptorInfo->desc[1]);
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x2 [%x]", stGattCharDescriptorInfo->desc[2]);
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x3 [%x]", stGattCharDescriptorInfo->desc[3]);
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x0 [%x]", stGattCharDescInfo->desc[0]);
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x1 [%x]", stGattCharDescInfo->desc[1]);
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x2 [%x]", stGattCharDescInfo->desc[2]);
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x3 [%x]", stGattCharDescInfo->desc[3]);
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG strUUID is [%s]",
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor");
int32_t ret = bt_gatt_set_characteristic_desc_value_request(
- stGattCharDescriptorInfo->characteristic,
+ stGattCharDescInfo->characteristic,
noti, 4, CABleGattCharacteristicWriteCb);
if (BT_ERROR_NONE != ret)
{
if (BT_ERROR_NONE != ret)
{
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_device_create_bond Failed with ret value [%d] ", ret);
+ OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+ "bt_device_create_bond Failed with ret value [%d] ", ret);
return CA_STATUS_FAILED;
}
else
return CA_STATUS_OK;
}
-CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data,
- const int32_t dataLen, TRANSFER_TYPE type, const int32_t position)
+CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
+ const char *data, const int32_t dataLen,
+ TRANSFER_TYPE type, const int32_t position)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
memset(value, 0x0, (dataLen + 1));
strncpy((char *)value, data, dataLen);
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen,
- bleServiceInfo->bdAddress);
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
+ "Updating the data of length [%d] to [%s] and size of data is [%d] ", dataLen,
+ bleServiceInfo->bdAddress, strlen(value));
int32_t result = bt_gatt_set_characteristic_value_request(bleServiceInfo->read_char, value,
dataLen,
OICFree(value);
return CA_STATUS_FAILED;
}
- OICFree(value);
+ // OICFree(value);
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
return CA_STATUS_OK;
}
-CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, const int32_t dataLen)
+CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data,
+ const int32_t dataLen)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
* limitations under the License.
*
******************************************************************/
+
+/**
+ * @file cableclient.h
+ * @brief This file contains the functionalities of GATT Client. Functionalities like LE device
+ * discovery, connecting to the LE device with OIC service, registering to the service and
+ * there characteristics, registering to the change in the charateristics, setting the
+ * value of the characteristcs for the request and response will be done here.
+ */
+
#ifndef _BLE_CLIENT_
#define _BLE_CLIENT_
#include "cacommon.h"
#include "caadapterutils.h"
-#include "cableclientutil.h"
+#include "cableutil.h"
#include "caadapterinterface.h"
#include "logger.h"
#include "uthreadpool.h"
/**
-* @fn CABleGattCharacteristicChangedCb
-* @brief This is the callback which will be called after the characteristic value changes happen.
-*
-* @param[in] characteristic The attribute handle of characteristic
-* @param[in] value Value of the characteristics of a service.
-* @param[in] valueLen length of data.
-* @param[in] userData The user data passed from the request function
-*
-* @return 0 on failure and 1 on success.
-*
-*/
+ * @brief This is the callback which will be called after the characteristic value changes happen.
+ *
+ * @param characteristic [IN] The attribute handle of characteristic
+ * @param value [IN] Value of the characteristics of a service.
+ * @param valueLen [IN] length of data.
+ * @param userData [IN] The user data passed from the request function
+ * @return NONE
+ */
void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic, unsigned char *value,
int32_t valueLen, void *userData);
/**
-* @fn CABleGattCharacteristicWriteCb
-* @brief This is the callback which will be called after the characteristics changed.
-*
-* @param[in] result result of write value
-* @param[in] userData user context
-*
-* @return void
-*
-*/
+ * @brief This is the callback which will be called after the characteristics changed.
+ *
+ * @param result [IN] result of write value
+ * @param userData [IN] user context
+ *
+ * @return NONE
+ */
void CABleGattCharacteristicWriteCb(int32_t result, void *userData);
/**
-* @fn CABleGattDescriptorDiscoveredCb
-* @brief This is the callback which will be called when descriptor of characteristics is found.
-*
-* @param[in] result The result of discovering
-* @param[in] format format of descriptor.
-* @param[in] total The total number of descriptor in a characteristic
-* @param[in] descriptor The attribute handle of descriptor
-* @param[in] characteristic The attribute handle of characteristic
-* @param[in] userData The user data passed from the request function
-*
-* @return void
-*
-*/
+ * @brief This is the callback which will be called when descriptor of characteristics is found.
+ *
+ * @param result [IN] The result of discovering
+ * @param format [IN] format of descriptor.
+ * @param total [IN] The total number of descriptor in a characteristic
+ * @param descriptor [IN] The attribute handle of descriptor
+ * @param characteristic [IN] The attribute handle of characteristic
+ * @param userData [IN] The user data passed from the request function
+ * @return NONE
+ */
void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32_t total,
- bt_gatt_attribute_h descriptor, bt_gatt_attribute_h characteristic, void *userData);
-
-/**
-* @fn CABleGattCharacteristicsDiscoveredCb
-* @brief This is the callback which will be called after the characteristics are discovered by
-* bt_gatt_discover_characteristics()
-*
-* @param[in] result The result of discovering
-* @param[in] inputIndex The index of characteristics in a service, starts from 0
-* @param[in] total The total number of characteristics in a service
-* @param[in] characteristic The attribute handle of characteristic
-* @param[in] userData The user data passed from the request function
-*
-* @return 0 on failure and 1 on success.
-*
-*/
+ bt_gatt_attribute_h descriptor,
+ bt_gatt_attribute_h characteristic, void *userData);
+
+/**
+ * @brief This is the callback which will be called after the characteristics are discovered by
+ * bt_gatt_discover_characteristics()
+ *
+ * @param result [IN] The result of discovering
+ * @param inputIndex [IN] The index of characteristics in a service, starts from 0
+ * @param total [IN] The total number of characteristics in a service
+ * @param characteristic [IN] The attribute handle of characteristic
+ * @param userData [IN] The user data passed from the request function
+ *
+ * @return 0 on failure and 1 on success.
+ */
bool CABleGattCharacteristicsDiscoveredCb(int32_t result, int32_t inputIndex, int32_t total,
- bt_gatt_attribute_h characteristic, void *userData);
+ bt_gatt_attribute_h characteristic, void *userData);
/**
-* @fn CABtGattBondCreatedCb
-* @brief This is the callback which will be called when bond created with remote device.
-*
-* @param[in] result The result of bond creation.
-* @param[in] device_info remote device information
-* @param[in] userData The user data passed from the request function
-*
-* @return void
-*
-*/
+ * @brief This is the callback which will be called when bond created with remote device.
+ *
+ * @param result [IN] The result of bond creation.
+ * @param device_info [IN] remote device information
+ * @param userData [IN] The user data passed from the request function
+ * @return NONE
+ */
void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *user_data);
/**
-* @fn CABleGattPrimaryServiceCb
-* @brief This is the callback which will be called when we get the primary services repeatedly.
-*
-* @param[in] service -The attribute handle of service. Unique identifier for service.
-* @param[in] index -The current index of the service
-* @param[in] count -Total number of services available in remote device
-* @param[in] userData - user data
-*
-* @return 0 on failure and 1 on success.
-*
-*/
+ * @brief This is the callback which will be called when we get the primary services repeatedly.
+ *
+ * @param service [IN] The attribute handle of service. Unique identifier for service.
+ * @param index [IN] The current index of the service
+ * @param count [IN] Total number of services available in remote device
+ * @param userData [IN] user data
+ *
+ * @return 0 on failure and 1 on success.
+ */
bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, int32_t count,
void *userData);
/**
-* @fn CABleGattConnectionStateChangedCb
-* @brief This is the callback which will be called whenever there is change in gatt connection
-* with server(Connected/Disconnected)
-*
-* @param[in] result The result of discovering
-* @param[in] connected State of connection
-* @param[in] remoteAddress Mac address of the remote device in which we made connection.
-* @param[in] userData The user data passed from the request function
-*
-* @return void
-*
-*/
+ * @brief This is the callback which will be called whenever there is change in gatt connection
+ * with server(Connected/Disconnected)
+ *
+ * @param result [IN] The result of discovering
+ * @param connected [IN] State of connection
+ * @param remoteAddress [IN] Mac address of the remote device in which we made connection.
+ * @param userData [IN] The user data passed from the request function
+ *
+ * @return NONE
+ */
void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const char *remoteAddress,
void *userData);
/**
-* @fn CABtAdapterLeDeviceDiscoveryStateChangedCb
-* @brief This is the callback which will be called when the device discovery state changes.
-*
-* @param[in] result The result of discovering
-* @param[in] discoveryState State of the discovery(FOUND/STARTED/ FINISHED)
-* @param[in] discoveryInfo Remote Device information.
-* @param[in] userData The user data passed from the request function
-*
-* @return void
-*
-*/
+ * @brief This is the callback which will be called when the device discovery state changes.
+ *
+ * @param result [IN] The result of discovering
+ * @param discoveryState [IN] State of the discovery(FOUND/STARTED/ FINISHED)
+ * @param discoveryInfo [IN] Remote Device information.
+ * @param userData [IN] The user data passed from the request function
+ *
+ * @return NONE
+ */
void CABtAdapterLeDeviceDiscoveryStateChangedCb(int32_t result,
bt_adapter_le_device_discovery_state_e discoveryState,
bt_adapter_le_device_discovery_info_s *discoveryInfo,
void *userData);
/**
-* @fn CAPrintDiscoveryInformation
-* @brief Used to print device information(Util method)
-*
-* @param[in] discoveryInfo Device information structure.
-*
-* @return void
-*
-*/
+ * @brief Used to print device information(Util method)
+ * @param discoveryInfo [IN] Device information structure.
+ * @return NONE
+ */
void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discoveryInfo);
/**
-* @fn CASetBleClientThreadPoolHandle
-* @brief Used to Set the gThreadPool handle which is required for spawning new thread.
-*
-* @param[in] handle - Thread pool handle which is given by above layer for using thread creation task.
-*
-* @return void
-*
-*/
-void CASetBleClientThreadPoolHandle(u_thread_pool_t handle);
-
-/**
-* @fn CAStartBleGattClientThread
-* @brief This is thread which will be used to initialize the Gatt Client and start device discovery.
-* 1. Set scan parameters 2.Setting neccessary callbacks for connection, characteristics changed and
-* discovery and bond creation.
-* 3. Start device discovery
-*
-* @param[in] data - Currently it will be NULL(no parameter)
-*
-* @return NULL on success or failure.
-*
-*/
+ * @brief This thread will be used to initialize the Gatt Client and start device discovery.
+ * 1. Set scan parameters
+ * 2. Setting neccessary callbacks for connection, characteristics changed and discovery
+ * and bond creation.
+ * 3. Start device discovery
+ *
+ * @param data [IN] Currently it will be NULL(no parameter)
+ *
+ * @return NONE
+ *
+ */
void *CAStartBleGattClientThread(void *data);
/**
-* @fn CAInitGattClientMutexVaraibles
-* @brief Used to initialize all required mutex variable for Gatt Client implementation.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to initialize all required mutex variable for Gatt Client implementation.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitGattClientMutexVaraibles();
/**
-* @fn CATerminateGattClientMutexVaraibles
-* @brief Used to terminate all required mutex variable for Gatt Client implementation.
-*
-* @return void
-*
-*/
+ * @brief Used to terminate all required mutex variable for Gatt Client implementation.
+ * @return NONE
+ */
void CATerminateGattClientMutexVariables();
/**
-* @fn CAClearNonOICDeviceList
-* @brief Used to clear NonOICDeviceList
-*
-* @return void
-*
-*/
+ * @brief Used to clear NonOICDeviceList
+ * @return NONE
+ */
void CAClearNonOICDeviceList();
/**
-* @fn CABleGattSetScanParameter
-* @brief Used to set scan parameter of starting discovery.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to set scan parameter of starting discovery.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGattSetScanParameter();
/**
-* @fn CABleGattSetCallbacks
-* @brief Used to register required callbacks to BLE platform(connection, discovery, bond and etc).
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to register required callbacks to BLE platform(connection, discovery, bond and etc).
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGattSetCallbacks();
/**
-* @fn CABleGattUnSetCallbacks
-* @brief Used to unset all the registerd callbacks to BLE platform
-*
-* @return void
-*
-*/
+ * @brief Used to unset all the registerd callbacks to BLE platform
+ * @return NONE
+ */
void CABleGattUnSetCallbacks();
/**
-* @fn CABleGattWatchCharacteristicChanges
-* @brief Used to watch all the changes happening in characteristics of the service.
-*
-* @param[in] service - The attribute handle of the service.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to watch all the changes happening in characteristics of the service.
+ *
+ * @param service [IN] The attribute handle of the service.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGattWatchCharacteristicChanges(bt_gatt_attribute_h service);
/**
-* @fn CABleGattUnWatchCharacteristicChanges
-* @brief Used to unwatch characteristics changes using bt_gatt_unwatch_characteristic_changes
-*
-* @return void
-*
-*/
+ * @brief Used to unwatch characteristics changes using bt_gatt_unwatch_characteristic_changes
+ * @return NONE
+ */
void CABleGattUnWatchCharacteristicChanges();
/**
-* @fn CABleGattStartDeviceDiscovery
-* @brief Used to start LE discovery for BLE devices
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to start LE discovery for BLE devices
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGattStartDeviceDiscovery();
/**
-* @fn CABleGattStopDeviceDiscovery
-* @brief Used to stop LE discovery for BLE devices
-*
-* @return void
-*
-*/
+ * @brief Used to stop LE discovery for BLE devices
+ * @return NONE
+ */
void CABleGattStopDeviceDiscovery();
/**
-* @fn CAGattConnectThread
-* @brief This is the thread which will be used for making gatt connection with remote devices
-*
-* @param[in] remoteAddress Mac address of remote device which wants to connect with.
-*
-* @return NULL on success or failure.
-*
-*/
+ * @brief This is the thread which will be used for making gatt connection with remote devices
+ * @param remoteAddress [IN] MAC address of remote device to connect
+ * @return NONE
+ */
void *CAGattConnectThread (void *remoteAddress);
/**
-* @fn CABleGattConnect
-* @brief Used to do connection with remote device
-*
-* @param[in] remoteAddress - Remote address inwhich we wants to connect with
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to do connection with remote device
+ *
+ * @param remoteAddress [IN] Remote address inwhich we wants to connect with
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGattConnect(const char *remoteAddress);
/**
-* @fn CABleGattDisConnect
-* @brief Used to do disconnection with remote device
-*
-* @param[in] remoteAddress - Remote address inwhich we wants to disconnect with
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to do disconnection with remote device
+ * @param remoteAddress [IN] Remote address inwhich we wants to disconnect with
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGattDisConnect(const char *remoteAddress);
/**
-* @fn CADiscoverBLEServicesThread
-* @brief This is thread which will be spawned for discovering ble services. Once called discover api,
-* then it will be terminated.
-*
-* @param[in] remoteAddress Mac address of the remote device in which we want to search services.
-*
-* @return NULL for success or failure.
-*
-*/
+ * @brief This is thread which will be spawned for discovering ble services. Once called discover
+ * api, then it will be terminated.
+ * @param remoteAddress [IN] Mac address of the remote device in which we want to search services.
+ * @return NONE
+ */
void *CADiscoverBLEServicesThread (void *remoteAddress);
/**
-* @fn CABleGattDiscoverServices
-* @brief Used to discover the services that is advertised by Gatt Server asynchrounously.
-*
-* @param[in] remoteAddress - mac address of remote device inwhich we want to discover the services.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to discover the services that is advertised by Gatt Server asynchrounously.
+ *
+ * @param remoteAddress [IN] MAC address of remote device in which we want to discover the services.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGattDiscoverServices(const char *remoteAddress);
/**
-* @fn CADiscoverCharThread
-* @brief This is the thread which will be used for finding characteristic of a service.
-*
-* @param[in] stServiceInfo Service Information which contains the remote address and service handle,
-* characteristic handle.
-*
-* @return NULL on success or failure.
-*
-*/
+ * @brief This is the thread which will be used for finding characteristic of a service.
+ *
+ * @param stServiceInfo [IN] Service Information which contains the remote address, service
+ * handle and characteristic handle.
+ * @return NONE
+ */
void *CADiscoverCharThread(void *stServiceInfo);
/**
-* @fn CABleGattDiscoverCharacteristics
-* @brief Used to discover characteristics of service using bt_gatt_discover_characteristics api.
-*
-* @param[in] service - The attribute handle for service.
-* @param[in] remoteAddress - Remote address inwhich we wants to discover characteristics of given service handle.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to discover characteristics of service using bt_gatt_discover_characteristics api.
+ *
+ * @param service [IN] The attribute handle for service.
+ * @param remoteAddress [IN] Remote address inwhich we wants to discover characteristics of
+ * given service handle.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service, const char *remoteAddress);
/**
-* @fn CADiscoverDescriptorThread
-* @brief This is the thread which will be used for finding descriptor of characteristic.
-*
-* @param[in] stServiceInfo Service Information which contains the remote address and service handle,
-* characteristic handle.
-*
-* @return NULL on success or failure.
-*
-*/
+ * @brief This is the thread which will be used for finding descriptor of characteristic.
+ *
+ * @param stServiceInfo [IN] Service Information which contains the remote address, service
+ * handle and characteristic handle.
+ * @return NONE
+ */
void *CADiscoverDescriptorThread(void *stServiceInfo);
/**
-* @fn CABleGattDiscoverDescriptor
-* @brief This is thread which will be used for calling CASetCharacteristicDescriptorValue api.
-*
-* @param[in] service - The attribute handle for characteristics.
-* @param[in] remoteAddress - Remote address inwhich we wants to discover descriptor of given char handle.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief This is thread which will be used for calling CASetCharacteristicDescriptorValue api.
+ *
+ * @param service [IN] The attribute handle for characteristics.
+ * @param remoteAddress [IN] Remote address inwhich we wants to discover descriptor of given
+ * char handle.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *remoteAddress);
/**
-* @fn CASetCharacteristicDescriptorValueThread
-* @brief This is thread which will be used for calling CASetCharacteristicDescriptorValue api.
-*
-* @param[in] stServiceInfo - Service Information which contains the remote address and service handle,
-* characteristic handle.
-*
-* @return NULL on sucess or failure.
-*
-*/
+ * @brief This is thread which will be used for calling CASetCharacteristicDescriptorValue api.
+ *
+ * @param stServiceInfo [IN] Service Information which contains the remote address, service
+ * handle and characteristic handle.
+ * @return NONE
+ */
void *CASetCharacteristicDescriptorValueThread(void *stServiceInfo);
/**
-* @fn CASetCharacteristicDescriptorValue
-* @brief Used to set characteristic descriptor value using bt_gatt_set_characteristic_desc_value_request api.
-*
-* @param[in] stGattCharDescriptor_t structure which contains char handle and descriptor handle.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to set characteristic descriptor value using
+ * bt_gatt_set_characteristic_desc_value_request api.
+ * @param stGattCharDescriptorInfo [IN] Structure which contains char handle and descriptor handle.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescriptorInfo);
/**
-* @fn CAGATTCreateBondThread
-* @brief This is the thread which will be used for creating bond with remote device.
-*
-* @param[in] stServiceInfo Service Information which contains the remote address and service handle,
-* characteristic handle.
-*
-* @return NULL on success or failure.
-*
-*/
+ * @brief This is the thread which will be used for creating bond with remote device.
+ *
+ * @param stServiceInfo [IN] Service Information which contains the remote address and service
+ * handle, characteristic handle.
+ * @return NONE
+ */
void *CAGATTCreateBondThread(void *stServiceInfo);
/**
-* @fn CABleGATTCreateBond
-* @brief Used to make LE bond with remote device(pairng the device) using bt_device_create_bond api.
-*
-* @param[in] remoteAddress - mac address of remote device which we want to bond with
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to make LE bond with remote device(pairng the device) using bt_device_create_bond
+ * api.
+ * @param remoteAddress [IN] MAC address of remote device with which we want to bond
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleGATTCreateBond(const char *remoteAddress);
/**
-* @fn CABleClientSenderQueueEnqueueMessage
-* @brief Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make signal
-* to the thread to process.
-*
-* @param[in] remoteEndpoint Remote device information
-* @param[in] data data which we wants to send to remote device
-* @param[in] dataLen Length of data.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make
+ * signal to the thread to process.
+ *
+ * @param remoteEndpoint [IN] Remote device information
+ * @param data [IN] Data to be sent to remote device
+ * @param dataLen [IN] Length of data.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleClientSenderQueueEnqueueMessage(const CARemoteEndpoint_t *remoteEndpoint,
- void *data, uint32_t dataLen);
+ void *data, uint32_t dataLen);
/**
-* @fn CABleClientSenderQueueProcessor
-* @brief This is the thread which will be used for processing sender queue.
-*
-* @return NULL on success or failure.
-*
-*/
+ * @brief This is the thread which will be used for processing sender queue.
+ *
+ * @return NONE
+ */
void *CABleClientSenderQueueProcessor();
/**
-* @fn CALEReadDataFromLEClient
-* @brief synchronous function for reading characteristic value.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Synchronous function for reading characteristic value.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CALEReadDataFromLEClient();
#endif //#ifndef _BLE_CLIENT_
+++ /dev/null
-/******************************************************************
-*
-* 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.
-*
-******************************************************************/
-#ifndef _BLE_CLIENT_UTIL
-#define _BLE_CLIENT_UTIL
-
-#include <bluetooth.h>
-
-#include "cacommon.h"
-#include "logger.h"
-
-
-/**
- * @struct BLEServiceInfo
- * @brief Info regarding the GATTServer
- *
- * This structure holds the infomation about the GATTServer
-* in the service and the characteristic level
- */
-typedef struct
-{
- bt_gatt_attribute_h service_clone; /**< gatt_attribute handler for the OIC service. */
- bt_gatt_attribute_h
- read_char; /**< gatt_attribute handler for the OIC read characteristic. Server will read. */
- bt_gatt_attribute_h
- write_char; /**< gatt_attribute handler for the OIC write characteristic. server will write */
- char *bdAddress; /**< BD address where OIC service is running. */
-} BLEServiceInfo;
-
-/**
- * @struct BLEServiceList
- * @brief List of the BLEServiceInfo structures.
- *
- * A list of BLEServiceInfo and gives the info about all the
- * the registered services from the client side.
- */
-typedef struct _BLEServiceList
-{
- BLEServiceInfo *serviceInfo; /**< BLEServiceInfo strucutre from an OIC Server */
- struct _BLEServiceList *next; /**< next pointer */
-} BLEServiceList;
-
-/**
- * @ENUM CHAR_TYPE
- * @brief different characteristics types.
- *
- * This ENUM provides information of different characteristics
- * which will be added to OIC service.
- */
-typedef enum
-{
- WRITE_CHAR, /**< write_char This will be used to get the unicast response */
- READ_CHAR, /**< read_char This will be used update value to OIC server */
- NOTIFY_CHAR /**< reserved char for the time being. */
-} CHAR_TYPE;
-
-/**
- * @ENUM CHAR_INDEX
- * @brief indexes for the characteristics defined..
- *
- * This ENUM provides index values for the characteristics
- * which will be added to OIC service.
- */
-typedef enum
-{
- READ_CHAR_INDEX = 1, /**< read_char index */
- WRITE_CHAR_INDEX = 2, /**< write_char index */
- NOTIFY_CHAR_INDEX = 3 /**< reserved char index for the time being. */
-} CHAR_INDEX;
-
-
-/**
- * @Structure stGattCharDescriptor_t
- * @brief Stores the information required to set the descriptor value of the Service.
- *
- */
-typedef struct gattCharDescriptor
-{
- bt_gatt_attribute_h characteristic;
- uint8_t *desc;
- int total;
-} stGattCharDescriptor_t;
-
-#define OIC_BLE_SERVICE_ID "713D0000-503E-4C75-BA94-3148F18D941E"
-///TODO: OIC_BLE_SERVICE_ID will be generated by invoking API in future.
-/**
-* @fn CAIncrementRegisteredServiceCount
-* @brief Used to increment the registered service count.
-*
-* @return void.
-*
-*/
-void CAIncrementRegisteredServiceCount();
-
-/**
-* @fn CADecrementRegisteredServiceCount
-* @brief Used to decrement the registered service count.
-*
-* @return void.
-*
-*/
-void CADecrementRegisteredServiceCount();
-
-/**
-* @fn CAResetRegisteredServiceCount
-* @brief Used to reset the registered service count.
-*
-* @return void.
-*
-*/
-void CAResetRegisteredServiceCount();
-
-/**
-* @fn CAGetRegisteredServiceCount
-* @brief Used to get the total registered service count.
-*
-* @return total registered service count.
-*
-*/
-int32_t CAGetRegisteredServiceCount();
-
-/**
-* @fn CACreateBLEServiceInfo
-* @brief Used to create BLEServiceInfo structure with server handler and BD address will be created.
-*
-* @param[in] bdAddress - BD address of the device where GATTServer is running.
-* @param[in] service - service attribute handler.
-* @param[in] bleServiceInfo - Pointer where serviceInfo structure needs to be stored.
-* Memory will be allocated here and needs to be cleared by user.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CACreateBLEServiceInfo(const char *bdAddress, bt_gatt_attribute_h service,
- BLEServiceInfo **bleServiceInfo);
-
-/**
-* @fn CAAppendBLECharInfo
-* @brief Used to append the characteristic info to the already created serviceInfo structure.
-*
-* @param[in] characteristic charecteristic attribute handler.
-* @param[in] type specifies whether its READ_CHAR or WRITE_CHAR
-* @param[in] bleServiceInfo Pointer where serviceInfo structure needs to be appended with char info.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CAAppendBLECharInfo(bt_gatt_attribute_h characteristic, CHAR_TYPE type,
- BLEServiceInfo *bleServiceInfo);
-
-/**
-* @fn CAAddBLEServiceInfoToList
-* @brief Used to add the ServiceInfo structure to the Service List.
-*
-* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client.
-* @param[in] bleServiceInfo Pointer where serviceInfo structure needs to be appended with char info.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CAAddBLEServiceInfoToList(BLEServiceList **serviceList, BLEServiceInfo *bleServiceInfo);
-
-/**
-* @fn CARemoveBLEServiceInfoToList
-* @brief Used to remove the ServiceInfo structure from the Service List.
-*
-* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client.
-* @param[in] bleServiceInfo Pointer where serviceInfo structure needs to be appended with char info.
-* @param[in] bdAddress BD address of the device where GATTServer is disconnected.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CARemoveBLEServiceInfoToList(BLEServiceList **serviceList,
- BLEServiceInfo *bleServiceInfo,
- const char *bdAddress);
-
-/**
-* @fn CAGetBLEServiceInfo
-* @brief Used to get the serviceInfo from the list.
-*
-* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client.
-* @param[in] bdAddress BD address of the device where GATTServer information is required.
-* @param[out] bleServiceInfo Pointer where serviceInfo structure needs to provide the service and char info.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CAGetBLEServiceInfo(BLEServiceList *serviceList, const char *bdAddress,
- BLEServiceInfo **bleServiceInfo);
-
-/**
-* @fn CAGetBLEServiceInfoByPosition
-* @brief Used to get the serviceInfo from the list by position.
-*
-* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client.
-* @param[in] position The service information of particular position in the list.
-* @param[out] bleServiceInfo Pointer where serviceInfo structure needs to provide the service and char info.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CAGetBLEServiceInfoByPosition(BLEServiceList *serviceList, int32_t position,
- BLEServiceInfo **bleServiceInfo);
-
-/**
-* @fn CAFreeBLEServiceList
-* @brief Used to get clear ble service list
-*
-* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client.
-*
-* @return void
-*
-*/
-void CAFreeBLEServiceList(BLEServiceList *serviceList);
-
-/**
-* @fn CAFreeBLEServiceInfo
-* @brief Used to get remove particular ble service info from list
-*
-* @param[in] serviceinfo Pointer to the structure which needs to be cleared.
-*
-* @return void
-*
-*/
-void CAFreeBLEServiceInfo(BLEServiceInfo *bleServiceInfo);
-
-/**
-* @fn CAVerifyOICService
-* @brief Used to check whether found handle is OIC service handle or not.
-*
-* @param[in] serviceHandle - Discovered service handle(unique identifier for service)
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CAVerifyOICService(bt_gatt_attribute_h serviceHandle);
-
-/**
-* @fn CABTGetErrorMsg
-* @brief Used to get the Error message.
-*
-* @param[in] err - Error code(bt_error_e)
-*
-* @return Error string corresponding to the BT error code.
-*
-*/
-const char *CABTGetErrorMsg(bt_error_e err);
-
-#endif //#ifndef _BLE_CLIENT_UTIL
--- /dev/null
+/******************************************************************
+*
+* 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 "caleinterface.h"
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include<arpa/inet.h>
+#include<sys/types.h>
+#include<sys/socket.h>
+#include<netinet/in.h>
+
+#include <bluetooth.h>
+#include <bluetooth_type.h>
+#include <bluetooth_product.h>
+
+
+#include "umutex.h"
+#include "caleadapter.h"
+#include "caadapterutils.h"
+
+/**
+ * @def TZ_LE_NWK_MONITOR_TAG
+ * @brief Logging tag for module name
+ */
+#define TZ_LE_NWK_MONITOR_TAG "TZ_BLE_ADAPTER_CONTROLLER"
+
+/**
+ * @var gCALEDeviceStateChangedCallback
+ * @brief Maintains the callback to be notified on device state changed.
+ */
+static CALEDeviceStateChangedCallback gCALEDeviceStateChangedCallback = NULL;
+
+/**
+ * @var gCALEDeviceStateChangedCbMutex
+ * @brief Mutex to synchronize access to the deviceStateChanged Callback when the state
+ * of the LE adapter gets change.
+ */
+static u_mutex gCALEDeviceStateChangedCbMutex = NULL;
+
+/**
+* @fn CALEAdapterStateChangedCb
+* @brief This is the callback which will be called when the adapter state gets changed.
+*
+* @param[in] result result of the query done to the platform.
+* @param[in] adapter_state State of the LE adapter.
+* @param[in] user_data Any user_data passed by the caller when querying for the state changed cb.
+*
+* @return None.
+*
+*/
+void CALEAdapterStateChangedCb(int32_t result, bt_adapter_state_e adapter_state, void *user_data);
+
+CAResult_t CAInitializeLENwkMonitor()
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+
+ CAResult_t res = CAInitLENwkMonitorMutexVaraibles();
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR, TZ_LE_NWK_MONITOR_TAG, "CAInitLENwkMonitorMutexVaraibles() failed");
+ return CA_STATUS_FAILED;
+ }
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+
+ return CA_STATUS_OK;
+
+}
+
+void CATerminateLENwkMonitorMutexVariables()
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+
+ u_mutex_free(gCALEDeviceStateChangedCbMutex);
+ gCALEDeviceStateChangedCbMutex = NULL;
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+ return;
+}
+
+void CATerminateLENwkMonitor()
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+
+ CATerminateLENwkMonitorMutexVariables();
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+
+ return ;
+
+}
+
+CAResult_t CAInitializeLEAdapter()
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+
+ CAResult_t res = bt_initialize();
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR, TZ_LE_NWK_MONITOR_TAG, "bt_initialize failed");
+ return CA_STATUS_FAILED;
+ }
+
+ int32_t ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0);
+ if (0 != ret)
+ {
+ OIC_LOG_V(ERROR, TZ_LE_NWK_MONITOR_TAG, "bt_adapter_set_visibility failed");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAGetLEAdapterState()
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+ bt_error_e err = BT_ERROR_NONE;
+ bt_adapter_state_e adapterState;
+
+ //Get Bluetooth adapter state
+ if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState)))
+ {
+ OIC_LOG_V(ERROR, TZ_LE_NWK_MONITOR_TAG, "Bluetooth get state failed!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+
+ if (BT_ADAPTER_ENABLED != adapterState)
+ {
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "BT Adapter is not enabled");
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAGetLEAddress(char **local_address)
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+
+ char *address = NULL;
+
+ bt_adapter_get_address(&address);
+
+ OIC_LOG_V(DEBUG, TZ_LE_NWK_MONITOR_TAG, "bd address[%s]", address);
+
+ *local_address = address;
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+ return ;
+}
+
+CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "Setting CALEDeviceStateChangedCallback");
+
+ u_mutex_lock(gCALEDeviceStateChangedCbMutex);
+ gCALEDeviceStateChangedCallback = callback;
+ u_mutex_unlock(gCALEDeviceStateChangedCbMutex);
+
+ int32_t ret = bt_adapter_set_state_changed_cb(CALEAdapterStateChangedCb, NULL);
+ if (0 != ret)
+ {
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "bt_adapter_set_state_changed_cb failed");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CALEAdapterStateChangedCb(int32_t result, bt_adapter_state_e adapter_state, void *user_data)
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+
+ u_mutex_lock(gCALEDeviceStateChangedCbMutex);
+
+ if ( BT_ADAPTER_DISABLED == adapter_state)
+ {
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "Adapter is disabled");
+ if (NULL == gCALEDeviceStateChangedCallback)
+ {
+ OIC_LOG(ERROR, TZ_LE_NWK_MONITOR_TAG, "gReqRespCallback is NULL!");
+ u_mutex_unlock(gCALEDeviceStateChangedCbMutex);
+ return;
+ }
+
+ gCALEDeviceStateChangedCallback(CA_ADAPTER_DISABLED);
+ u_mutex_unlock(gCALEDeviceStateChangedCbMutex);
+ return;
+ }
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "Adapter is Enabled");
+ gCALEDeviceStateChangedCallback(CA_ADAPTER_ENABLED);
+ u_mutex_unlock(gCALEDeviceStateChangedCbMutex);
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+ return;
+}
+
+
+CAResult_t CAUnSetLEAdapterStateChangedCb()
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+
+ int32_t ret = bt_adapter_unset_state_changed_cb();
+ if (ret != 0)
+ {
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "bt_adapter_set_state_changed_cb failed");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+ return CA_STATUS_OK;
+
+}
+
+CAResult_t CAInitLENwkMonitorMutexVaraibles()
+{
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "IN");
+ u_mutex_init();
+ if (NULL == gCALEDeviceStateChangedCbMutex)
+ {
+ gCALEDeviceStateChangedCbMutex = u_mutex_new();
+ if (NULL == gCALEDeviceStateChangedCbMutex)
+ {
+ OIC_LOG(ERROR, TZ_LE_NWK_MONITOR_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ OIC_LOG(DEBUG, TZ_LE_NWK_MONITOR_TAG, "OUT");
+ return CA_STATUS_OK;
+
+}
+
+
+
#include "caqueueingthread.h"
#include "caadapterutils.h"
#include "camsgparser.h"
-#include "cableclientutil.h"
+#include "cableutil.h"
/**
* @def TZ_BLE_SERVER_TAG
*/
#define TZ_BLE_SERVER_TAG "TZ_BLE_GATT_SERVER"
-/* TODO:: Currently keeping as single service. Later service path will be added in list for
- * supporting multiple services */
-
-#define CA_BLE_SERVICE_UUID "713d0000-503e-4c75-ba94-3148f18d941e"
+/**
+ * @def CA_BLE_SERVICE_UUID
+ * @brief UUID of OIC service. This UUID is common across all platoform for LE transport.
+ */
+#define CA_BLE_SERVICE_UUID "713D0000-503E-4C75-BA94-3148F18D941E"
-#define CA_BLE_READ_CHAR_UUID "00002af5-0000-1000-8000-00805f9b34fb"
+/**
+ * @def CA_BLE_READ_CHAR_UUID
+ * @brief UUID of read characteristic. This UUID is common across all platoform for LE transport.
+ */
+#define CA_BLE_READ_CHAR_UUID "713D0002-503E-4C75-BA94-3148F18D941E"
-#define CA_BLE_WRITE_CHAR_UUID "00002af6-0000-1000-8000-00805f9b34fb"
+/**
+ * @def CA_BLE_WRITE_CHAR_UUID
+ * @brief UUID of write characteristic. This UUID is common across all platoform for LE transport.
+ */
+#define CA_BLE_WRITE_CHAR_UUID "713D0003-503E-4C75-BA94-3148F18D941E"
/**
* @var gGattSvcPath
*/
static u_mutex gBleServiceMutex = NULL;
+ /**
+ * @var gBleClientBDAddressMutex
+ * @brief Mutex to synchronize the client BD Address update on server side.
+ */
+static u_mutex gBleClientBDAddressMutex = NULL;
+
+
/**
* @var gBleReqRespCbMutex
* @brief Mutex to synchronize access to the requestResponse callback to be called
* @brief Remote address of Gatt client
*
*/
-static const char *gRemoteClientAddress = "DB:F7:EB:B5:0F:07";
-///TODO: later this will be replaced with the platform apis.
+static char *gRemoteClientAddress = NULL;
/**
* @var g_event_loop
*/
static CABool_t gServerUp = CA_FALSE;
-CAResult_t CAStartBleGattServer()
+void CABleGattServerConnectionStateChangedCb(int32_t result, bool connected,
+ const char *remoteAddress, void *userData)
{
- ///TODO:: Check BT adapter is enabled or not ..if its not enabled, enable bt adapter.
+ OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
+
+ OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "CABleGattConnectionStateChangedCb result[%d]", result);
+
+ VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_SERVER_TAG, "remote address is NULL");
+
+ if (connected)
+ {
+ OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Connected to [%s]", remoteAddress);
+
+ u_mutex_lock(gBleClientBDAddressMutex);
+ gRemoteClientAddress = OICStrdup(remoteAddress);
+ u_mutex_unlock(gBleClientBDAddressMutex);
+
+ VERIFY_NON_NULL_VOID(gRemoteClientAddress, TZ_BLE_SERVER_TAG, "Malloc failed");
+ }
+ OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
+}
+CAResult_t CAStartBleGattServer()
+{
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
CAResult_t ret = CAInitGattServerMutexVaraibles();
return CA_SERVER_NOT_STARTED;
}
-
u_mutex_lock(gBleServerThreadPoolMutex);
if (NULL == gBleServerThreadPool)
{
}
CAResult_t ret = CAInitBleGattService();
-
if (CA_STATUS_OK != ret )
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_init_service failed");
char *serviceUUID = CA_BLE_SERVICE_UUID;
ret = CAAddNewBleServiceInGattServer(serviceUUID);
-
if (CA_STATUS_OK != ret )
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewBleServiceInGattServer failed");
}
char *charReadUUID = CA_BLE_READ_CHAR_UUID;
-
char charReadValue[4] = {33, 44, 55, 66};
ret = CAAddNewCharacteristicsToGattServer(gGattSvcPath, charReadUUID, charReadValue, 512 ,
0); // For Read Characteristics.
-
if (CA_STATUS_OK != ret )
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewCharacteristicsToGattServer failed");
}
char *charWriteUUID = CA_BLE_WRITE_CHAR_UUID;
-
char charWriteValue[4] = {33, 44, 55, 66};
}
ret = CARegisterBleServicewithGattServer(gGattSvcPath);
-
if (CA_STATUS_OK != ret )
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CARegisterBleServicewithGattServer failed");
return NULL;
}
- bt_adapter_le_create_advertiser(&hAdvertiser);
+ int32_t res = bt_gatt_set_connection_state_changed_cb(CABleGattServerConnectionStateChangedCb,
+ NULL);
+ if (BT_ERROR_NONE != res)
+ {
+ OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
+ "bt_gatt_set_connection_state_changed_cb Failed with return as [%s]",
+ CABTGetErrorMsg(res));
+ return NULL;
+ }
+ bt_adapter_le_create_advertiser(&hAdvertiser);
if (NULL == hAdvertiser)
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "hAdvertiser is NULL");
u_cond_signal(gReceiverDataCond);
}
- CATerminateBleGattServer();
-
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
-
return CA_STATUS_OK;
}
u_cond_signal(gBleServerSendCondWait);
u_mutex_lock(gBleServerStateMutex);
+ GMainContext *context_event_loop = NULL;
// Required for waking up the thread which is running in gmain loop
- GMainContext *context_event_loop = g_main_loop_get_context(g_event_loop);
-
+ if ( NULL != g_event_loop)
+ {
+ context_event_loop = g_main_loop_get_context(g_event_loop);
+ }
if (context_event_loop)
{
OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "g_event_loop context %x", context_event_loop);
g_main_context_wakeup(context_event_loop);
+
+ // Kill g main loops and kill threads
+ g_main_loop_quit(g_event_loop);
}
else
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "g_event_loop context is NULL");
}
- // Kill g main loops and kill threads
- g_main_loop_quit(g_event_loop);
-
int32_t ret = 0;
-
if (NULL != hAdvertiser )
{
ret = bt_adapter_le_stop_advertising(hAdvertiser);
- if (ret != 0)
+ if (0 != ret)
{
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_adapter_le_stop_advertising failed with ret [%d]", ret);
+ OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
+ "bt_adapter_le_stop_advertising failed with ret [%d]", ret);
}
ret = bt_adapter_le_destroy_advertiser(hAdvertiser);
- if (ret != 0)
+ if (0 != ret)
{
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_adapter_le_destroy_advertiser failed with ret [%d]", ret);
+ OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
+ "bt_adapter_le_destroy_advertiser failed with ret [%d]", ret);
}
hAdvertiser = NULL;
}
ret = CARemoveAllBleServicesFromGattServer();
- if (ret != 0)
+ if (0 != ret)
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "removeAllBleServicesFromGattServer failed");
}
ret = CADeInitBleGattService();
- if (ret != 0)
+ if (0 != ret)
{
OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_deinit_service failed with ret [%d]", ret);
}
+ u_mutex_lock(gBleClientBDAddressMutex);
+ OICFree(gRemoteClientAddress);
+ u_mutex_unlock(gBleClientBDAddressMutex);
// free service Path(unique identifier for ble service)
u_mutex_lock(gBleServiceMutex);
OICFree(gGattSvcPath);
return CA_STATUS_FAILED;
}
}
+
+ if (NULL == gBleClientBDAddressMutex)
+ {
+ gBleClientBDAddressMutex = u_mutex_new();
+ if (NULL == gBleClientBDAddressMutex)
+ {
+ OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
return CA_STATUS_OK;
}
void CATerminateGattServerMutexVaraibles()
u_mutex_free(gBleServerStateMutex);
gBleServerStateMutex = NULL;
+ u_mutex_free(gBleClientBDAddressMutex);
+ gBleClientBDAddressMutex = NULL;
+
gBleServerStateMutex = NULL;
u_mutex_free(gBleServiceMutex);
gBleServiceMutex = NULL;
{
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
int32_t ret = _bt_gatt_init_service();
-
- if (ret != 0)
+ if (0 != ret)
{
OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_deinit_service failed with ret [%d]", ret);
return CA_STATUS_FAILED;
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
int32_t ret = _bt_gatt_deinit_service();
- if (ret != 0)
+ if (0 != ret)
{
OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_deinit_service failed with ret [%d]", ret);
return CA_STATUS_FAILED;
char *svcPath = NULL;
int32_t ret = bt_gatt_add_service(serviceUUID, &svcPath);
-
- if (ret != 0)
+ if (0 != ret)
{
OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_add_service failed with ret [%d]", ret);
return CA_STATUS_FAILED;
if (NULL != svcPath)
{
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "AddNewBleServiceInGattServer ServicePath obtained is %s",
- svcPath);
+ OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
+ "AddNewBleServiceInGattServer ServicePath obtained is %s", svcPath);
u_mutex_lock(gBleServiceMutex);
}
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
-
return CA_STATUS_OK;
}
int32_t ret = bt_gatt_remove_service(svcPath);
- if (ret != 0)
+ if (0 != ret)
{
OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_remove_service failed [%d]", ret);
return CA_STATUS_FAILED;
}
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
-
return CA_STATUS_OK;
}
{
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
int32_t ret = bt_gatt_delete_services();
-
- if (ret != 0)
+ if (0 != ret)
{
OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_delete_services failed with ret [%d]", ret);
return CA_STATUS_FAILED;
}
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
-
return CA_STATUS_OK;
}
}
memset(data, 0x0, charValueLen + 1);
-
strncpy(data, (char *)charValue, charValueLen);
uint32_t sentLength = 0;
}
OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Sending data up !");
+ u_mutex_lock(gBleClientBDAddressMutex);
gCABLEServerDataReceivedCallback(gRemoteClientAddress, OIC_BLE_SERVICE_ID,
data, strlen(data), &sentLength);
+ u_mutex_unlock(gBleClientBDAddressMutex);
+
u_mutex_unlock(gBleReqRespCbMutex);
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
int32_t ret = bt_gatt_register_service(svcPath, CABleGattRemoteCharacteristicWriteCb, NULL);
- if (ret != 0)
+ if (0 != ret)
{
OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_register_service failed with ret [%d]", ret);
return CA_STATUS_FAILED;
}
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
-
return CA_STATUS_OK;
}
int32_t ret = bt_gatt_add_characteristic(charUUID, charValue, charValueLen, charFlags, flagLen,
svcPath, &charPath);
- if (ret != 0 || charPath == NULL)
+ if (0 != ret || NULL == charPath)
{
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_add_characteristic failed with ret [%d]", ret);
+ OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
+ "bt_gatt_add_characteristic failed with ret [%d]", ret);
return CA_STATUS_FAILED;
}
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "bt_gatt_add_characteristic charPath obtained: %s", charPath);
+ OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG,
+ "bt_gatt_add_characteristic charPath obtained: %s", charPath);
u_mutex_lock(gBleCharacteristicMutex);
- if (read == 0)
+ if (0 == read)
{
if (NULL != gGattReadCharPath)
{
u_mutex_unlock(gBleCharacteristicMutex);
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
-
return CA_STATUS_OK;
}
int32_t ret = bt_gatt_update_characteristic(gGattWriteCharPath, data, charValueLen);
if (0 != ret)
{
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_update_characteristic failed with return [%d]", ret);
+ OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
+ "bt_gatt_update_characteristic failed with return [%d]", ret);
OICFree(data);
data = NULL;
u_mutex_unlock(gBleCharacteristicMutex);
u_mutex_unlock(gBleCharacteristicMutex);
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "OUT");
-
return CA_STATUS_OK;
}
* limitations under the License.
*
******************************************************************/
+
+/**
+ * @file cableserver.h
+ * @brief This file contains the APIs related to the GATT Server functionalities.
+ * Creation of the GattServer with the characteristics. Enabling the advertisement and
+ * updating the characteristics for the response and notifying the change of characteristcs
+ * for the request will be done here. LE adapter will interact with this sub module.
+ */
+
#ifndef __TZ_BLE_SERVER_H_
#define __TZ_BLE_SERVER_H_
#include "caleinterface.h"
/**
-* @fn CAStartBleGattServerThread
-* @brief This is thread which will be used for creating ble service and advertise ble service.
-* 1. Create New OIC Service 2. Add two read & write characteristics to service.
-* 3. Register Service 4. Advertise service.
-*
-* @param[in] data - Currently it will be NULL.
-*
-* @return NULL on sucess or failure.
-*
-*/
+ * @brief This is thread which will be used for creating ble service and advertise ble service.
+ * 1. Create New OIC Service 2. Add two read & write characteristics to service.
+ * 3. Register Service 4. Advertise service.
+ *
+ * @param data [IN] Currently it will be NULL.
+ * @return NONE
+ */
void *CAStartBleGattServerThread(void *data);
/**
-* @fn CATerminateBleGattServer
-* @brief Used to stop Gatt Server thread and remove service registration, stop advertising.
-*
-* @return void
-*
-*/
-void CATerminateBleGattServer();
-
-/**
-* @fn CAInitBleGattService
-* @brief Used to initialize gatt service using _bt_gatt_init_service api.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to initialize gatt service using _bt_gatt_init_service api.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitBleGattService();
/**
-* @fn CADeInitBleGattService
-* @brief Used to de-initialize gatt service using _bt_gatt_deinit_service api.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to de-initialize gatt service using _bt_gatt_deinit_service api.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CADeInitBleGattService();
/**
-* @fn CAInitGattServerMutexVaraibles
-* @brief Used to initialize all required mutex varaibles for GATT server implementation.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to initialize all required mutex varaibles for GATT server implementation.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAInitGattServerMutexVaraibles();
/**
-* @fn CATerminateGattServerMutexVaraibles
-* @brief Used to terminate all required mutex varaibles for GATT server implementation.
-*
-* @return void
-*
-*/
+ * @brief Used to terminate all required mutex varaibles for GATT server implementation.
+ * @return NONE
+ */
void CATerminateGattServerMutexVaraibles();
/**
-* @fn CASetBleServerThreadPoolHandle
-* @brief Used to Set the gThreadPool handle which is required for spawning new thread.
-*
-* @param[in] handle - Thread pool handle which is given by above layer for using thread creation task.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-void CASetBleServerThreadPoolHandle(u_thread_pool_t handle);
-
-/**
-* @fn CAAddNewBleServiceInGattServer
-* @brief Used to add new OIC service in GATT server using bt_gatt_add_service api and
-* internally store service path(outparam) in global variable
-*
-* @param[in] serviceUUID - unique identifier for BLE OIC service.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to add new OIC service in GATT server using bt_gatt_add_service api and
+ * internally store service path(outparam) in global variable.
+ *
+ * @param serviceUUID [IN] unique identifier for BLE OIC service.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CAAddNewBleServiceInGattServer(const char *serviceUUID);
/**
-* @fn CARemoveBleServiceFromGattServer
-* @brief Used to remove already registered service from Gatt Server using bt_gatt_remove_service api.
-*
-* @param[in] svcPath - unique identifier for BLE OIC service which is outparam of bt_gatt_add_service api.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to remove already registered service from Gatt Server using
+ * bt_gatt_remove_service api.
+ * @param svcPath [IN] unique identifier for BLE OIC service which is outparam of
+ * bt_gatt_add_service api.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CARemoveBleServiceFromGattServer(const char *svcPath);
/**
-* @fn CARemoveAllBleServicesFromGattServer
-* @brief Used to remove all the registered service from Gatt Server using bt_gatt_delete_services api.
-*
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to remove all the registered service from Gatt Server using
+ * bt_gatt_delete_services api.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CARemoveAllBleServicesFromGattServer();
/**
-* @fn CARegisterBleServicewithGattServer
-* @brief Used to register the service in Gatt Server using bt_gatt_register_service api.
-*
-* @param[in] svcPath - unique identifier for BLE OIC service which is outparam of bt_gatt_add_service api.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to register the service in Gatt Server using bt_gatt_register_service api.
+ *
+ * @param svcPath [IN] unique identifier for BLE OIC service which is outparam of
+ * bt_gatt_add_service api.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CARegisterBleServicewithGattServer(const char *svcPath);
/**
-* @fn CAAddNewCharacteristicsToGattServer
-* @brief Used to add new characteristics(Read/Write) to the service in Gatt Server using bt_gatt_add_characteristic api.
-*
-* @param[in] svcPath service path to which this characteristic belongs to.
-* @param[in] charUUID - Gatt characteristic uuid.
-* @param[in] charValue -Gatt characteristic value.
-* @param[in] charValueLen - Caracteristic value length.
-* @param[in] read - boolean varaible for checking whether read characteristics or write characteristics.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to add new characteristics(Read/Write) to the service in Gatt Server using
+ * bt_gatt_add_characteristic api.
+ * @param svcPath [IN] Service path to which this characteristic belongs to.
+ * @param charUUID [IN] Gatt characteristic uuid.
+ * @param charValue [IN] Gatt characteristic value.
+ * @param charValueLen [IN] Characteristic value length.
+ * @param read [IN] Boolean variable for checking whether read characteristics or
+ * write characteristics.
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
CAResult_t CAAddNewCharacteristicsToGattServer(const char *svcPath, char *charUUID,
- char *charValue, int32_t charValueLen,
- int32_t read);
-
-/**
-* @fn CARemoveCharacteristicsFromGattServer
-* @brief Used to remove characteristics(Read/Write) from the service in Gatt Server.
-*
-* @param[in] charPath characteristic path registered on the interface and unique identifier for added characteristics.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ char *charValue, int32_t charValueLen,
+ int32_t read);
+
+/**
+ * @brief Used to remove characteristics(Read/Write) from the service in Gatt Server.
+ *
+ * @param charPath [IN] Characteristic path registered on the interface and unique identifier
+ * for added characteristics.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CARemoveCharacteristicsFromGattServer(const char *charPath);
/**
-* @fn CABleGattRemoteCharacteristicWriteCb
-* @brief This is the callback which will be called when client update one of the characteristics with data.
-*
-* @param[in] charPath - characteristic path registered on the interface and unique identifier for added characteristics.
-* @param[in] charValue - data which is send by client.
-* @param[in] charValueLen - length of the data.
-* @param[in] userData - user data
-*
-* @return void
-*
-*/
-void CABleGattRemoteCharacteristicWriteCb(char *charPath,
- unsigned char *charValue, int32_t charValueLen, void *userData);
-
-/**
-* @fn CALEReadDataFromLEServer
-* @brief synchronous function for reading characteristic value.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief This is the callback which will be called when client update one of the characteristics
+ * with data.
+ * @param charPath [IN] characteristic path registered on the interface and unique
+ * identifier for added characteristics.
+ * @param charValue [IN] data which is send by client.
+ * @param charValueLen [IN] length of the data.
+ * @param userData [IN] user data
+ *
+ * @return NONE
+ */
+void CABleGattRemoteCharacteristicWriteCb(char *charPath, unsigned char *charValue,
+ int32_t charValueLen, void *userData);
+
+/**
+ * @brief This is the callback which will be called whenever there is change in gatt connection
+ * with Client(Connected/Disconnected).
+ *
+ * @param result [IN] The result of discovering.
+ * @param connected [IN] State of connection.
+ * @param remoteAddress [IN] Mac address of the remote device in which we made connection.
+ * @param userData [IN] The user data passed from the request function.
+ *
+ * @return NONE
+ */
+void CABleGattServerConnectionStateChangedCb(int32_t result, bool connected,
+ const char *remoteAddress, void *userData);
+
+/**
+ * @brief Synchronous function for reading characteristic value.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CALEReadDataFromLEServer();
/**
-* @fn CABleServerSenderQueueEnqueueMessage
-* @brief Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make
-* signal to the thread to process.
-*
-* @param[in] remoteEndpoint Remote device information
-* @param[in] data data which we wants to send to remote device
-* @param[in] dataLen Length of data.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
+ * @brief Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make
+ * signal to the thread to process.
+ *
+ * @param remoteEndpoint [IN] Remote device information.
+ * @param data [IN] Data to be sent to remote device.
+ * @param dataLen [IN] Length of data.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
CAResult_t CABleServerSenderQueueEnqueueMessage(const CARemoteEndpoint_t *remoteEndpoint,
- void *data, uint32_t dataLen);
+ void *data, uint32_t dataLen);
/**
-* @fn CABleServerSenderQueueProcessor
-* @brief This is the thread which will be used for processing receiver queue.
-*
-* @return NULL on success or failure.
-*
-*/
+ * @brief This is the thread which will be used for processing receiver queue.
+ * @return NONE
+ */
void *CABleServerSenderQueueProcessor();
#endif //#ifndef __TZ_BLE_SERVER_H_
*
******************************************************************/
-#include "cableclientutil.h"
+#include "cableutil.h"
#include<stdio.h>
#include<stdlib.h>
}
-CAResult_t CAVerifyOICService(bt_gatt_attribute_h serviceHandle)
+CAResult_t CAVerifyOICServiceByUUID(const char* serviceUUID)
+{
+ OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
+
+ VERIFY_NON_NULL(serviceUUID, NULL, "Param serviceHandle is NULL");
+/*
+ int32_t ret = 0;
+ char *uuid = NULL;
+
+ ret = bt_gatt_get_service_uuid(serviceHandle, &uuid);
+
+ if (0 != ret)
+ {
+ OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "bt_gatt_get_service_uuid failed !");
+ return CA_STATUS_FAILED;
+ }
+*/
+ if (strcasecmp(serviceUUID, OIC_BLE_SERVICE_ID) != 0)
+ {
+ OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "It is not OIC service!");
+ return CA_STATUS_FAILED;
+ }
+ OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAVerifyOICServiceByServiceHandle(bt_gatt_attribute_h serviceHandle)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
--- /dev/null
+/******************************************************************
+*
+* 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 cableutil.h
+ * @brief This file contains the util function for LE adapter. This maintains the list of services
+ * an individual GATT Client connected to and operations on that list, such as getting the
+ * service info with BD address or with position etc. This is mainly useful for the
+ * multicast transmission of data where client needs to have the info of all the services
+ * to which it is connected.
+ */
+
+#ifndef _BLE_UTIL_H_
+#define _BLE_UTIL_H_
+
+#include <bluetooth.h>
+
+#include "cacommon.h"
+#include "logger.h"
+
+
+/**
+ * @struct BLEServiceInfo
+ * @brief Information regarding the GATTServer
+ *
+ * This structure holds the infomation about the GATTServer
+ * in the service and the characteristic level
+ */
+typedef struct
+{
+ bt_gatt_attribute_h service_clone; /**< gatt_attribute handler for the OIC service. */
+ bt_gatt_attribute_h
+ read_char; /**<gatt_attribute handler for OIC read characteristic. Server will read.*/
+ bt_gatt_attribute_h
+ write_char; /**<gatt_attribute handler for OIC write characteristic. server will write*/
+ char *bdAddress; /**< BD address where OIC service is running. */
+} BLEServiceInfo;
+
+/**
+ * @struct BLEServiceList
+ * @brief List of the BLEServiceInfo structures.
+ *
+ * A list of BLEServiceInfo and gives the info about all the
+ * the registered services from the client side.
+ */
+typedef struct _BLEServiceList
+{
+ BLEServiceInfo *serviceInfo; /**< BLEServiceInfo structure from an OIC Server */
+ struct _BLEServiceList *next; /**< Next reference to the List*/
+} BLEServiceList;
+
+/**
+ * @enum CHAR_TYPE
+ * @brief Different characteristics types.
+ *
+ * This provides information of different characteristics
+ * which will be added to OIC service.
+ */
+typedef enum
+{
+ WRITE_CHAR, /**< write_char This will be used to get the unicast response */
+ READ_CHAR, /**< read_char This will be used update value to OIC server */
+ NOTIFY_CHAR /**< Reserved char for the time being. */
+} CHAR_TYPE;
+
+/**
+ * @enum CHAR_INDEX
+ * @brief indexes for the characteristics defined..
+ *
+ * This provides index values for the characteristics
+ * which will be added to OIC service.
+ */
+typedef enum
+{
+ READ_CHAR_INDEX = 1, /**< read_char index */
+ WRITE_CHAR_INDEX = 2, /**< write_char index */
+ NOTIFY_CHAR_INDEX = 3 /**< Reserved char index for the time being. */
+} CHAR_INDEX;
+
+
+/**
+ * @struct stGattCharDescriptor_t
+ * @brief Stores the information required to set the descriptor value of the Service.
+ */
+typedef struct gattCharDescriptor
+{
+ bt_gatt_attribute_h characteristic; /**< The attribute handle of descriptor */
+ uint8_t *desc; /**< Descriptor handle of characteristic, in byte array*/
+ int total; /**< The total number of descriptor in a characteristic */
+} stGattCharDescriptor_t;
+
+#define OIC_BLE_SERVICE_ID "713D0000-503E-4C75-BA94-3148F18D941E"
+///TODO: OIC_BLE_SERVICE_ID will be generated by invoking API in future.
+
+/**
+ * @brief Used to increment the registered service count.
+ * @return NONE
+ */
+void CAIncrementRegisteredServiceCount();
+
+/**
+ * @brief Used to decrement the registered service count.
+ *
+ * @return NONE.
+ */
+void CADecrementRegisteredServiceCount();
+
+/**
+ * @brief Used to reset the registered service count.
+ * @return NONE
+ */
+void CAResetRegisteredServiceCount();
+
+/**
+ * @brief Used to get the total registered service count.
+ * @return Total registered service count.
+ */
+int32_t CAGetRegisteredServiceCount();
+
+/**
+ * @brief Used to create BLEServiceInfo structure with server handler and BD address will be
+ * created.
+ * @param bdAddress [IN] BD address of the device where GATTServer is running.
+ * @param service [IN] service attribute handler.
+ * @param bleServiceInfo [IN] Pointer where serviceInfo structure needs to be stored.
+ * Memory will be allocated here and needs to be cleared by caller.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CACreateBLEServiceInfo(const char *bdAddress, bt_gatt_attribute_h service,
+ BLEServiceInfo **bleServiceInfo);
+
+/**
+ * @brief Used to append the characteristic info to the already created serviceInfo structure.
+ *
+ * @param characteristic [IN] Charecteristic attribute handler.
+ * @param type [IN] Specifies whether its READ_CHAR or WRITE_CHAR
+ * @param bleServiceInfo [IN] Pointer where serviceInfo structure needs to be appended with
+ * char info.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAAppendBLECharInfo(bt_gatt_attribute_h characteristic, CHAR_TYPE type,
+ BLEServiceInfo *bleServiceInfo);
+
+/**
+ * @brief Used to add the ServiceInfo structure to the Service List.
+ *
+ * @param serviceList [IN] Pointer to the ble service list which holds the info of list of
+ * service registered from client.
+ * @param bleServiceInfo [IN] Pointer where serviceInfo structure needs to be appended with
+ * char info.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAAddBLEServiceInfoToList(BLEServiceList **serviceList, BLEServiceInfo *bleServiceInfo);
+
+/**
+ * @brief Used to remove the ServiceInfo structure from the Service List.
+ *
+ * @param serviceList [IN] Pointer to the ble service list which holds the info of list of
+ * service registered from client.
+ * @param bleServiceInfo [IN] Pointer where serviceInfo structure needs to be appended with
+ * char info.
+ * @param bdAddress [IN] BD address of the device where GATTServer is disconnected.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CARemoveBLEServiceInfoToList(BLEServiceList **serviceList,
+ BLEServiceInfo *bleServiceInfo,
+ const char *bdAddress);
+
+/**
+ * @brief Used to get the serviceInfo from the list.
+ *
+ * @param serviceList [IN] Pointer to the ble service list which holds the info of list
+ * of service registered from client.
+ * @param bdAddress [IN] BD address of the device where GATTServer information is required.
+ * @param bleServiceInfo [OUT] Pointer where serviceInfo structure needs to provide the service
+ * and char info.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAGetBLEServiceInfo(BLEServiceList *serviceList, const char *bdAddress,
+ BLEServiceInfo **bleServiceInfo);
+
+/**
+ * @brief Used to get the serviceInfo from the list by position.
+ *
+ * @param serviceList [IN] Pointer to the ble service list which holds the info of list
+ * of service registered from client.
+ * @param position [IN] The service information of particular position in the list.
+ * @param bleServiceInfo [OUT] Pointer where serviceInfo structure needs to provide the service
+ * and char info.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAGetBLEServiceInfoByPosition(BLEServiceList *serviceList, int32_t position,
+ BLEServiceInfo **bleServiceInfo);
+
+/**
+ * @brief Used to clear BLE service list
+ *
+ * @param serviceList [IN] Pointer to the ble service list which holds the info of list of
+ * service registered from client.
+ * @return NONE
+ */
+void CAFreeBLEServiceList(BLEServiceList *serviceList);
+
+/**
+ * @brief Used to get remove particular BLE service info from list
+ * @param serviceinfo [IN] Pointer to the structure which needs to be cleared.
+ *
+ * @return NONE
+ */
+void CAFreeBLEServiceInfo(BLEServiceInfo *bleServiceInfo);
+
+/**
+ * @brief Used to check whether found handle is OIC service handle or not.
+ *
+ * @param serviceHandle [IN] Discovered service handle(unique identifier for service)
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAVerifyOICServiceByServiceHandle(bt_gatt_attribute_h serviceHandle);
+
+/**
+ * @brief Used to check whether UUID of the discovered device is OIC service or not.
+ *
+ * @param serviceUUID [IN] Service UUID
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAVerifyOICServiceByUUID(const char* serviceUUID);
+
+/**
+ * @brief Used to get the Error message.
+ * @param err [IN] Error code(#bt_error_e)
+ * @return Error string corresponding to the BT error code.
+ */
+const char *CABTGetErrorMsg(bt_error_e err);
+
+#endif //#ifndef _BLE_UTIL_H_
\ No newline at end of file
return NULL;\r
}\r
\r
- coapUri = (char *) OICMalloc(length + coapHeaderLength + 1);\r
+ uint32_t uriLength = length + coapHeaderLength + 1;\r
+ coapUri = (char *) OICMalloc(uriLength);\r
+\r
if (coapUri == NULL)\r
{\r
OIC_LOG(DEBUG, TAG, "CAGeneratePdu, Memory allocation failed !");\r
return NULL;\r
}\r
- memset(coapUri, 0, length + coapHeaderLength + 1);\r
+ memset(coapUri, 0, uriLength);\r
\r
if (NULL != coapUri)\r
{\r
CAParseHeadOption(code, info, &optlist);\r
\r
OICFree(coapUri);\r
+ coapUri = NULL;\r
}\r
\r
if (NULL != info.payload) // payload is include in request / response\r
return NULL;\r
}\r
\r
+ // free option list\r
+ coap_delete_list(optlist);\r
+\r
// pdu print method : coap_show_pdu(pdu);\r
OIC_LOG(DEBUG, TAG, "CAGeneratePdu OUT");\r
return pdu;\r
coap_option *option;\r
coap_list_t *node;\r
\r
- option = coap_malloc(sizeof(coap_option) + length);\r
+ option = coap_malloc(sizeof(coap_option) + length + 1);\r
if (!option)\r
{\r
OIC_LOG(DEBUG, TAG, "Out of memory");\r
return NULL;\r
}\r
- memset(option, 0, sizeof(coap_option) + length);\r
+ memset(option, 0, sizeof(coap_option) + length + 1);\r
\r
COAP_OPTION_KEY(*option) = key;\r
COAP_OPTION_LENGTH(*option) = length;\r
if (pdu->hdr->token_length > 0)\r
{\r
OIC_LOG(DEBUG, TAG, "inside pdu->hdr->token_length");\r
- outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN);\r
+ outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN + 1);\r
if (outInfo->token == NULL)\r
{\r
OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo, Memory allocation failed !");\r
OICFree(outInfo->options);\r
return;\r
}\r
+ memset(outInfo->token, 0, CA_MAX_TOKEN_LEN + 1);\r
memcpy(outInfo->token, pdu->hdr->token, CA_MAX_TOKEN_LEN);\r
}\r
\r
#define CA_BUFSIZE 128
#define CA_COAP_MESSAGE_CON 0
-#include "util.h"
uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo,
char *outUri)
coap_free(option);
return NULL;
}
- coap_free(option);
+
OIC_LOG(DEBUG, TAG, "OUT");
return node;
}
if (pdu->hdr->token_length > 0)
{
OIC_LOG(DEBUG, TAG, "pdu->hdr->token_length>0");
- outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN);
+ outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN + 1);
if (outInfo->token == NULL)
{
OIC_LOG(DEBUG, TAG, "error");
OICFree(outInfo->options);
return;
}
+ memset(outInfo->token, 0, CA_MAX_TOKEN_LEN + 1);
memcpy(outInfo->token, pdu->hdr->token, CA_MAX_TOKEN_LEN);
}
gExceptionCallback(ctx->type);
}
OICFree(ctx);
+ ctx = NULL;
return;
}
// Should never occur
OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Invalid server type");
OICFree(ctx);
+ ctx = NULL;
return;
}
}
+ OICFree(ctx);
+ ctx = NULL;
+
OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
}
OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
// Input validation
- VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "Local address is NULL");
- VERIFY_NON_NULL(multicastAddress, ETHERNET_SERVER_TAG, "Multicast address is NULL");
+ VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "localAddress");
+ VERIFY_NON_NULL(multicastAddress, ETHERNET_SERVER_TAG, "port");
+ VERIFY_NON_NULL(serverFD, ETHERNET_SERVER_TAG, "server socket FD");
int16_t port = multicastPort;
if (0 >= port)
* @def WIFI_ETHERNET_ADAPTER_TAG
* @brief Logging tag for module name
*/
-#define WIFI_ADAPTER_TAG "WA"
+#define WIFI_ADAPTER_TAG "WAST"
/**
* @def CA_PORT