Implementation of following functionality
authorashok.channa <ashok.channa@samsung.com>
Tue, 16 Dec 2014 10:17:27 +0000 (19:17 +0900)
committerashok.channa <ashok.channa@samsung.com>
Tue, 16 Dec 2014 10:23:49 +0000 (19:23 +0900)
1) DTLS support for ETH and Tizen platform
2) Removing SUDO from make files
3) Optimization of WIFI , ETH adapters for all platforms
4) Adding single thread header files for consistency with source files.

Signed-off-by: ashok.channa <ashok.channa@samsung.com>
Change-Id: I8a92b0ef38b16818c740f3e95aad5ce1e65741a4

60 files changed:
resource/csdk/connectivity/build/Makefile
resource/csdk/connectivity/build/arduino/arduinomega.properties
resource/csdk/connectivity/build/arduino/build.sh
resource/csdk/connectivity/build/tizen/gbsbuild.sh
resource/csdk/connectivity/inc/caadapternetdtls.h
resource/csdk/connectivity/inc/caadapterutils.h
resource/csdk/connectivity/inc/caedradapter.h
resource/csdk/connectivity/inc/caedradapter_singlethread.h [new file with mode: 0644]
resource/csdk/connectivity/inc/caethernetadapter.h
resource/csdk/connectivity/inc/caethernetadapter_singlethread.h [new file with mode: 0644]
resource/csdk/connectivity/inc/caethernetinterface.h
resource/csdk/connectivity/inc/caethernetinterface_singlethread.h [new file with mode: 0644]
resource/csdk/connectivity/inc/caleadapter.h
resource/csdk/connectivity/inc/caleadapter_singlethread.h [new file with mode: 0644]
resource/csdk/connectivity/inc/caleinterface.h
resource/csdk/connectivity/inc/caleinterface_singlethread.h [new file with mode: 0644]
resource/csdk/connectivity/inc/camessagehandler_singlethread.h
resource/csdk/connectivity/inc/caprotocolmessage_singlethread.h [new file with mode: 0644]
resource/csdk/connectivity/inc/caretransmission_singlethread.h
resource/csdk/connectivity/inc/cawifiadapter.h
resource/csdk/connectivity/inc/cawifiadapter_singlethread.h [new file with mode: 0644]
resource/csdk/connectivity/inc/cawifiinterface.h
resource/csdk/connectivity/inc/cawifiinterface_singlethread.h [new file with mode: 0644]
resource/csdk/connectivity/samples/arduino/sample_main.cpp
resource/csdk/connectivity/samples/linux/sample.sh
resource/csdk/connectivity/samples/linux/sample_main.c
resource/csdk/connectivity/samples/tizen/README.txt
resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c [moved from resource/csdk/connectivity/src/caadapternetdtls.c with 71% similarity]
resource/csdk/connectivity/src/adapter_util/caadapterutils.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c
resource/csdk/connectivity/src/bt_le_adapter/arduino/caleadapter.cpp
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c
resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c
resource/csdk/connectivity/src/cainterfacecontroller.c
resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c
resource/csdk/connectivity/src/camessagehandler_singlethread.c
resource/csdk/connectivity/src/caprotocolmessage.c
resource/csdk/connectivity/src/caprotocolmessage_singlethread.c [new file with mode: 0644]
resource/csdk/connectivity/src/caqueueingthread.c
resource/csdk/connectivity/src/caretransmission_singlethread.cpp
resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.cpp
resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.h
resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetclient.cpp
resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetnwmonitor.cpp
resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetserver.cpp
resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c
resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter_singlethread.c
resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c
resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c
resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c
resource/csdk/connectivity/src/wifi_adapter/arduino/cawificlient.cpp
resource/csdk/connectivity/src/wifi_adapter/arduino/cawifinwmonitor.cpp
resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiserver.cpp
resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c
resource/csdk/connectivity/src/wifi_adapter/cawifiadapter_singlethread.c
resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c
resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c
resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c
resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c

index b57c9f6..261f50e 100644 (file)
@@ -36,19 +36,19 @@ VERSION_PATCH := 0
 ifeq ($(PLATFORM),tizen)
 $(info *******************tizen Build !!******************)
 all:
-       sudo sh tizen/gbsbuild.sh $(TRANSPORT)
+       sh tizen/gbsbuild.sh $(TRANSPORT)
 
 else ifeq ($(PLATFORM),arduinomega)
 $(info *********ArduinoMega Build!!**********)
 all:
-       sudo sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
-       sudo sh arduino/build.sh make $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
+       sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
+       sh arduino/build.sh make $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
 
 clean: 
-       sudo sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
+       sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
 
 install:
-       sudo sh arduino/build.sh install $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
+       sh arduino/build.sh install $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
        
 else
    $(info *********error**********)
index 329914a..3628952 100644 (file)
@@ -101,7 +101,7 @@ SPI_OBJ = SPI.cpp.o
 TIMED_OBJ = TimedAction.cpp.o
 LOGGER_OBJ = logger.cpp.o oic_logger.c.o oic_console_logger.c.o oic_malloc.c.o oic_string.c.o uarraylist.c.o
 UTIL_OBJ = caadapterutils.c.o camsgparser.c.o
-CACOMMON_OBJ = caconnectivitymanager_singlethread.c.o cainterfacecontroller_singlethread.c.o camessagehandler_singlethread.c.o canetworkconfigurator_singlethread.c.o caprotocolmessage.c.o \
+CACOMMON_OBJ = caconnectivitymanager_singlethread.c.o cainterfacecontroller_singlethread.c.o camessagehandler_singlethread.c.o canetworkconfigurator_singlethread.c.o caprotocolmessage_singlethread.c.o \
                           caremotehandler.c.o caretransmission_singlethread.cpp.o
 
 ifeq ($(TRANSPORT),ETHERNET)
index 04abff2..3aa2b31 100644 (file)
@@ -2,12 +2,12 @@
 if echo $1 | grep -q -i "make"
 then
 cd ../lib/libcoap-4.1.1/
-sudo make -f makefile_arduino.mak PLATFORM=$2 ARDUINO_DIR=$4
+make -f makefile_arduino.mak PLATFORM=$2 ARDUINO_DIR=$4
 cd ../../build/arduino
-sudo make PLATFORM=$2 TRANSPORT=$3 ARDUINO_DIR=$4 APP_NAME=$5
+make PLATFORM=$2 TRANSPORT=$3 ARDUINO_DIR=$4 APP_NAME=$5
 else
 cd ../lib/libcoap-4.1.1/
-sudo make $1 -f makefile_arduino.mak PLATFORM=$2 ARDUINO_DIR=$4
+make $1 -f makefile_arduino.mak PLATFORM=$2 ARDUINO_DIR=$4
 cd ../../build/arduino/
-sudo make $1 PLATFORM=$2 TRANSPORT=$3 ARDUINO_DIR=$4 APP_NAME=$5
+make $1 PLATFORM=$2 TRANSPORT=$3 ARDUINO_DIR=$4 APP_NAME=$5
 fi
\ No newline at end of file
index 718a9e3..c3394b1 100644 (file)
@@ -8,7 +8,7 @@ version=`echo $version|cut -d" " -f 1`
 
 name=cmsample
 
-sudo rm -rf $name-$version
+rm -rf $name-$version
 
 builddir=`pwd`
 sourcedir=`pwd`
@@ -94,8 +94,8 @@ rm -rf *dtls.*
 #build
 #cd $name-$version
 git init
-gbs build -A armv7l --include-all
+gbs build -A armv7l --include-all -B ~/GBS-ROOT-NEW
 
 rm -rf $sourcedir/tizen/tmp
 #cd $builddir
-#sudo rm -rf $name-$version
+#rm -rf $name-$version
index e327cda..b53e355 100644 (file)
 #include "umutex.h"
 #include "caadapterutils.h"
 
+#define MAX_SUPPORTED_ADAPTERS 2
+
+///TODO: once proper .h provided for this function, it will be removed
 extern void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo);
 
 typedef void (*CAPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
         const void *data, const uint32_t dataLength, const CABool_t isSecured);
 
+typedef uint32_t (*CAPacketSendCallback)(const char *ipAddress, const uint32_t port,
+        const void *data, const uint32_t dataLength);
+
+/**
+ * @struct stCAAdapterCallbacks_t
+ * @brief  Data structure for holding the send and recv callbacks.
+ */
+typedef struct CAAdapterCallbacks
+{
+    CAPacketReceivedCallback recvCallback;
+    CAPacketSendCallback sendCallback;
+}stCAAdapterCallbacks_t;
+
 /**
- *@struct stCADtlsContext_t
+ * @struct stCADtlsContext_t
  * @brief  Data structure for holding the tinyDTLS interface
  *              related info.
  */
@@ -39,14 +55,14 @@ typedef struct stCADtlsContext
 {
     u_arraylist_t  *cacheList;          /**< pdu's are cached until DTLS session is formed */
     struct dtls_context_t *dtlsContext;    /**< pointer to tinyDTLS context */
-    struct stPacketInfo
-            *packetInfo;          /**< used by callback during  decryption to hold address/length */
+    struct stPacketInfo *packetInfo;          /**< used by callback during
+                                                                    decryption to hold address/length */
     dtls_handler_t callbacks;           /**< pointer to callbacks needed by tinyDTLS */
-    CAPacketReceivedCallback gPacketReceivedCallback;
+    stCAAdapterCallbacks_t adapterCallbacks[MAX_SUPPORTED_ADAPTERS];
 } stCADtlsContext_t;
 
 /**
- *@struct stPacketInfo_t
+ * @struct stPacketInfo_t
  * @brief  Data structure for holding the decrypted data address
  *              and length provided by tinyDTLS callback interface.
  */
@@ -84,7 +100,7 @@ typedef struct
         struct sockaddr_in  sin;
         struct sockaddr_in6 sin6;
     } addr;
-    uint8_t ifindex;
+    uint8_t ifIndex;
 } stCADtlsAddrInfo_t;
 
 /**
@@ -92,14 +108,38 @@ typedef struct
  * @brief structure to holds the information of cachemessage and address info.
  *
  */
-typedef struct CACacheMessage_t
+typedef struct CACacheMessage
 {
     void *data;
     uint32_t dataLen;
     stCADtlsAddrInfo_t *destSession;
 } stCACacheMessage_t;
 
-void CADTLSSetPacketReceiveCallback(CAPacketReceivedCallback callback);
+/**
+ * @enum eDtlsAdapterType_t
+ * @brief adapter types
+ *
+ */
+typedef enum
+{
+    DTLS_ETHERNET = 0,
+    DTLS_WIFI
+} eDtlsAdapterType_t;
+
+/**
+ * @fn  CADTLSSetAdapterCallbacks
+ * @brief  Used set send and recv callbacks for different adapters(WIFI,EtherNet)
+ *
+ * @param[in]  recvCallback  packet received callback
+ * @param[in]  sendCallback  packet sent callback
+ * @param[in]  type  type of adapter
+ *
+ * @retval  void
+ *
+ */
+
+void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
+                                    CAPacketSendCallback sendCallback, eDtlsAdapterType_t type);
 
 /**
  * @fn  CAAdapterNetDtlsInit
@@ -150,7 +190,8 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
                                    const uint32_t port,
                                    const void *data,
                                    uint32_t dataLen,
-                                   uint8_t *cacheFlag);
+                                   uint8_t *cacheFlag,
+                                   eDtlsAdapterType_t type);
 
 /**
  * @fn  CAAdapterNetDtlsDecrypt
@@ -170,7 +211,8 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
 CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress,
                                    const uint32_t port,
                                    uint8_t *data,
-                                   uint32_t dataLen);
+                                   uint32_t dataLen,
+                                   eDtlsAdapterType_t type);
 
 #endif //_CA_ADAPTER_NET_DTLS_H
 
index 7a1ec28..4878a7f 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef _CA_ADAPTER_UTILS_H_
 #define _CA_ADAPTER_UTILS_H_
 
+#include <stdbool.h>
+
 #include "cacommon.h"
 #include "logger.h"
 #include "oic_malloc.h"
@@ -105,6 +107,12 @@ CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(
  */
 void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndPoint);
 
+/**
+ * @fn CAAdapterIsSameSubnet
+ * @brief Check if two ip address belong to same subnet
+ */
+bool CAAdapterIsSameSubnet(const char *ipAddress1, const char *ipAddress2,
+                           const char *netMask);
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 02328ac..558a544 100644 (file)
@@ -29,9 +29,7 @@
  **/
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#ifndef ARDUINO
 #include "uthreadpool.h" /* for thread pool */
-#endif  //ARDUINO
 
 #ifdef __cplusplus
 extern "C"
@@ -55,17 +53,10 @@ extern "C"
  * not enabled
  * @retval  #CA_STATUS_FAILED Operation failed
  */
-#ifdef ARDUINO
-CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
-                           CANetworkPacketReceivedCallback reqRespCallback,
-                           CANetworkChangeCallback netCallback);
-#else
 CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
                            CANetworkPacketReceivedCallback reqRespCallback,
                            CANetworkChangeCallback netCallback,
                            u_thread_pool_t handle);
-#endif //#ifdef ARDUINO
-
 
 /**
  * @fn  CAStartEDR
diff --git a/resource/csdk/connectivity/inc/caedradapter_singlethread.h b/resource/csdk/connectivity/inc/caedradapter_singlethread.h
new file mode 100644 (file)
index 0000000..ed1ba73
--- /dev/null
@@ -0,0 +1,176 @@
+/******************************************************************
+ *
+ * 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_singlethread.h
+ * @brief This file contains the APIs for EDR adapters to be implemented
+ */
+#ifndef __CA_EDRADAPTER_SINGLETHREAD_H_
+#define __CA_EDRADAPTER_SINGLETHREAD_H_
+
+/**
+ * BT Interface AP
+ **/
+#include "cacommon.h"
+#include "caadapterinterface.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#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.
+ * @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
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
+                           CANetworkPacketReceivedCallback reqRespCallback,
+                           CANetworkChangeCallback netCallback);
+
+/**
+ * @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.
+ * @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.
+ *
+ * @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
+ *
+ */
+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
+ *
+ */
+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.
+ *
+ */
+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.
+ *
+ */
+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
+ *
+ */
+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
+ *
+ */
+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
+ *
+ */
+CAResult_t CAStopEDR();
+
+/**
+ * @fn  CATerminateEDR
+ * @brief  Terminate the EDR connectivity adapter.
+ * Configuration information will be deleted from further use.
+ *
+ */
+void CATerminateEDR();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif  //__CA_EDRADAPTER_SINGLETHREAD_H_
index d4240fb..9ee9ecd 100644 (file)
@@ -27,9 +27,7 @@
 
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#ifndef ARDUINO
 #include "uthreadpool.h" /* for thread pool */
-#endif  //ARDUINO
 
 #ifdef __cplusplus
 extern "C"
@@ -44,14 +42,9 @@ extern "C"
  * @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)
  */
-#ifdef ARDUINO
-CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
-                                CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback);
-#else
 CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
                                 CANetworkPacketReceivedCallback networkPacketCallback,
                                 CANetworkChangeCallback netCallback, u_thread_pool_t handle);
-#endif
 
 /**
  * @brief Start Ethernet Interface adapter.
diff --git a/resource/csdk/connectivity/inc/caethernetadapter_singlethread.h b/resource/csdk/connectivity/inc/caethernetadapter_singlethread.h
new file mode 100644 (file)
index 0000000..5a59a0f
--- /dev/null
@@ -0,0 +1,123 @@
+/******************************************************************
+ *
+ * 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 caethernetadapter_singlethread.h
+ * @brief This file contains the APIs for Ethernet Adapter.
+ */
+#ifndef __CA_ETHERNET_ADAPTER_SINGLETHREAD_H__
+#define __CA_ETHERNET_ADAPTER_SINGLETHREAD_H__
+
+#include "cacommon.h"
+#include "caadapterinterface.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @brief API to initialize Ethernet Interface.
+ * @param registerCallback [IN] To register ETHERNET interfaces to Connectivity Abstraction Layer
+ * @param networkPacketCallback [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)
+ */
+CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
+                                CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback);
+
+/**
+ * @brief Start Ethernet Interface adapter.
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAStartEthernet();
+
+/**
+ * @brief Starting listening server for receiving multicast search requests
+ * Transport Specific Behavior:
+ * Ethernet Starts Multicast Server on  all available IPs and prefixed port number and
+ * as per OIC Specification.
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAStartEthernetListeningServer();
+
+/**
+ * @brief for starting discovery servers for receiving multicast advertisements
+ * Transport Specific Behavior:
+ * Ethernet Starts Start multicast server on all available IPs and prefixed port
+ * number as per OIC Specification
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAStartEthernetDiscoveryServer();
+
+/**
+ * @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.
+ */
+uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
+                                   uint32_t dataLen);
+
+/**
+ * @brief Sends Multicast data to the endpoint using the Ethernet 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.
+ */
+uint32_t CASendEthernetMulticastData(void *data, uint32_t dataLen);
+
+/**
+ * @brief Get Ethernet 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)
+ */
+CAResult_t CAGetEthernetInterfaceInformation(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)
+ */
+CAResult_t CAReadEthernetData();
+
+/**
+ * @brief Stopping the adapters and close socket connections
+ *   Ethernet Stops all multicast and unicast servers and close sockets.
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAStopEthernet();
+
+/**
+ * @brief Terminate the Ethernet connectivity adapter.
+ * Configuration information will be deleted from further use
+ */
+void CATerminateEthernet();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif  // #ifndef __CA_ETHERNET_ADAPTER_SINGLETHREAD_H__
index 7aa8c2c..0fe6e21 100644 (file)
  * @brief This file provides APIs ethernet client/server/network monitor modules
  */
 
-#ifndef _CA_ETHERNET_INTERFACE_
-#define _CA_ETHERNET_INTERFACE_
+#ifndef _CA_ETHERNET_INTERFACE_H_
+#define _CA_ETHERNET_INTERFACE_H_
 
 #include <stdbool.h>
 
 #include "cacommon.h"
-#ifndef ARDUINO
 #include "uthreadpool.h" /* for thread pool */
-#endif  //ARDUINO
 
 #ifdef __cplusplus
 extern "C"
@@ -62,7 +60,7 @@ typedef enum
  * @pre  Callback must be registered using CAEthernetSetPacketReceiveCallback()
  */
 typedef void (*CAEthernetPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
-              const void *data, const uint32_t dataLength);
+              const void *data, const uint32_t dataLength, const CABool_t isSecured);
 
 /**
  * @fn  CAEthernetExceptionCallback
@@ -86,21 +84,8 @@ typedef void (*CAEthernetExceptionCallback)(CAAdapterServerType_t type);
  * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
  * @retval  #CA_STATUS_FAILED Initialization failed
  */
-#ifndef ARDUINO
 CAResult_t CAEthernetInitializeServer(const u_thread_pool_t threadPool);
 
-#else
-/**
- * @fn  CAEthernetInitializeServer
- * @brief  API to initialize Ethernet server
- *
- * @return  #CA_STATUS_OK on success otherwise proper error code.
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Initialization failed
- */
-CAResult_t CAEthernetInitializeServer(void);
-#endif //ARDUINO
-
 /**
  * @fn  CAEthernetTerminateServer
  * @brief  API to terminate Ethernet server
@@ -125,27 +110,6 @@ void CAEthernetTerminateServer(void);
 CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
                                           const int16_t multicastPort, int32_t *serverFD);
 
-#ifdef ARDUINO
-/**
- * @fn  CAEthernetStartUnicastServer
- * @brief  API to start unicast server for specified local address and port
- *
- * @param[in]  localAddress  Local adapter address to which server to be binded.
- * @param[in][out]  port  Port number on which server to be running.
- * Port number on which server actually started will be returned.
- * @param[in]  forceStart  Indicate whether to start server forcesfully on specified port or not.
- * @param[in]  secured  true if the secure server to be started, otherwise false.
- * @param[out]  serverFD  Unicast server socket FD.
- *
- * @return  #CA_STATUS_OK on success otherwise proper error code.
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
-                                        const bool forceStart, int32_t *serverFD);
-#else
 /**
  * @fn  CAEthernetStartUnicastServer
  * @brief  API to start unicast server for specified local address and port
@@ -165,7 +129,6 @@ CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
  */
 CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
                                         const bool forceStart, const bool secured, int32_t *serverFD);
-#endif //ARDUINO
 
 /**
  * @fn  CAEthernetStopMulticastServer
@@ -197,27 +160,6 @@ CAResult_t CAEthernetStopUnicastServer();
  */
 CAResult_t CAEthernetStopSecureUnicastServer();
 
-#ifdef ARDUINO
-/**
- * @fn  CAEthernetGetUnicastServerInfo
- * @brief  API to get running unicast server information.
- * @remarks  @ipAddress must be freed using free().
- *
- * @param[in]  secure  true if the secure server information needed, otherwise false.
- * @param[in]  ipAddress  IP address on which server is binded and running.
- * @param[out]  port  Port number on which server is running
- * @param[out]  serverFD  Server socket fd.
- *
- * @return  #CA_STATUS_OK on success otherwise proper error code.
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-
-CAResult_t CAEthernetGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
-
-#else
-
 /**
  * @fn  CAEthernetGetUnicastServerInfo
  * @brief  API to get running unicast server information.
@@ -236,8 +178,6 @@ CAResult_t CAEthernetGetUnicastServerInfo(char **ipAddress, int16_t *port, int32
 CAResult_t CAEthernetGetUnicastServerInfo(const bool secure, char **ipAddress, int16_t *port,
                                           int32_t *serverFD);
 
-#endif // ARDUINO
-
 /**
  * @fn  CAEthernetSetPacketReceiveCallback
  * @brief  API to set callback for receiving data packets from peer devices.
@@ -250,14 +190,6 @@ CAResult_t CAEthernetGetUnicastServerInfo(const bool secure, char **ipAddress, i
  */
 void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback);
 
-#ifdef ARDUINO
-/**
- * @fn  CAEthernetReadData
- * @brief  API to pull data
- */
-void CAEthernetPullData();
-#endif // ARDUINO
-
 /**
  * @fn  CAEthernetSetExceptionCallback
  * @brief  API to set callback for receiving exception notifications.
@@ -288,6 +220,7 @@ void CAEthernetSetUnicastSocket(const int32_t socketFD);
  */
 void CAEthernetSetUnicastPort(const int32_t port);
 
+#ifdef __WITH_DTLS__
 /**
  * @fn  CAEthernetSetSecureUnicastSocket
  * @brief  API to set socket description for sending secured (encrypted) unicast UDP data
@@ -296,30 +229,8 @@ void CAEthernetSetUnicastPort(const int32_t port);
  *
  */
 void CAEthernetSetSecureUnicastSocket(const int32_t socketFD);
+#endif
 
-#ifdef ARDUINO
-/**
- * @fn  CAEthernetSendUnicastData
- * @brief  API to send unicast UDP data
- *
- * @param[in]  remoteAddress  IP address to which data needs to be send.
- * @param[in]  port  Port to which data needs to be send.
- * @param[in]  data  Data to be send.
- * @param[in]  dataLength  Length of data in bytes
- * @param[in]  isMulticast  whether data needs to be sent to multicast ip
- * @param[in]  isSecure  Indicate the whether data needs to be send on secure channel.
- * @isSecure will be ignored when @isMulticast is true.
- *
- * @return  #CA_STATUS_OK on success otherwise proper error code.
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-
-uint32_t CAEthernetSendData(const char *remoteAddress, const int16_t port,
-                            const char *buf, const uint32_t bufLen, bool isMulticast);
-
-#else
 /**
  * @fn  CAEthernetSendUnicastData
  * @brief  API to send unicast UDP data
@@ -341,8 +252,6 @@ uint32_t CAEthernetSendData(const char *remoteAddress, const uint32_t port,
                             const void *data, const uint32_t dataLength,
                             CABool_t isMulticast, CABool_t isSecure);
 
-#endif //ARDUINO
-
 /**
  * @fn  CAEthernetConnectionStateChangeCallback
  * @brief  Callback to be notified when ethernet adapter connection state changes.
@@ -366,20 +275,8 @@ typedef void (*CAEthernetConnectionStateChangeCallback)(const char *ipAddress,
  * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
  * @retval  #CA_STATUS_FAILED Initialization failed
  */
-#ifndef ARDUINO
-CAResult_t CAEthernetInitializeNetworkMonitor(const u_thread_pool_t threadPool);
 
-#else
-/**
- * @fn  CAEthernetInitializeServer
- * @brief  API to initialize Ethernet server
- *
- * @return  #CA_STATUS_OK on success otherwise proper error code.
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Initialization failed
- */
-CAResult_t CAEthernetInitializeNetworkMonitor(void);
-#endif //ARDUINO
+CAResult_t CAEthernetInitializeNetworkMonitor(const u_thread_pool_t threadPool);
 
 /**
  * @fn  CAEthernetTerminateNetworkMonitor
@@ -423,6 +320,20 @@ CAResult_t CAEthernetStopNetworkMonitor(void);
 CAResult_t CAEthernetGetInterfaceInfo(char **interfaceName, char **ipAddress);
 
 /**
+ * @fn  CAEthernetGetInterfaceSubnetMask
+ * @brief  API to get local adapter network subnet mask.
+ * @remarks  @subnetMaskmust be freed using free().
+ *
+ * @param[out]  subnetMask  Local adapter interface subnet mask
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetGetInterfaceSubnetMask(char **subnetMask);
+
+/**
  * @fn  CAEthernetIsConnected
  * @brief  API to get ethernet adapter connection state.
  *
@@ -443,4 +354,4 @@ void CAEthernetSetConnectionStateChangeCallback(CAEthernetConnectionStateChangeC
 }
 #endif
 
-#endif //_CA_ETHERNET_INTERFACE_
+#endif //_CA_ETHERNET_INTERFACE_H_
diff --git a/resource/csdk/connectivity/inc/caethernetinterface_singlethread.h b/resource/csdk/connectivity/inc/caethernetinterface_singlethread.h
new file mode 100644 (file)
index 0000000..25383b2
--- /dev/null
@@ -0,0 +1,338 @@
+/******************************************************************
+*
+* 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 caethernetinterface_singlethread.h
+ * @brief This file provides APIs ethernet client/server/network monitor modules
+ */
+
+#ifndef _CA_ETHERNET_INTERFACE_SINGLETHREAD_H_
+#define _CA_ETHERNET_INTERFACE_SINGLETHREAD_H_
+
+#include <stdbool.h>
+
+#include "cacommon.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @enum CAAdapterServerType_t
+ * @brief Enum for defining different server types.
+ */
+typedef enum
+{
+    CA_UNICAST_SERVER = 0,
+    CA_MULTICAST_SERVER,
+    CA_SECURED_UNICAST_SERVER
+} CAAdapterServerType_t;
+
+/**
+ * @fn  CAEthernetPacketReceivedCallback
+ * @brief  Callback to be notified on receival of any data from remote OIC devices.
+ *
+ * @param[in]  ipAddress  IP address of remote OIC device.
+ * @param[in]  port  Port number on which data is received.
+ * @param[in]  data  Data received from remote OIC device.
+ * @param[in]  dataLength  Length of data in bytes.
+ * @param[in]  secure  Indicates the data is secure or not.
+ *
+ * @pre  Callback must be registered using CAEthernetSetPacketReceiveCallback()
+ */
+typedef void (*CAEthernetPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
+              const void *data, const uint32_t dataLength);
+
+/**
+ * @fn  CAEthernetExceptionCallback
+ * @brief  Callback to be notified when exception occures on multicast/unicast server.
+ *
+ * @param[in]  type  Type of server either #CA_UNICAST_SERVER or $CA_MULTICAST_SERVER
+ *
+ * @pre  Callback must be registered using CAEthernetSetExceptionCallback()
+ */
+typedef void (*CAEthernetExceptionCallback)(CAAdapterServerType_t type);
+
+/**
+ * @fn  CAEthernetInitializeServer
+ * @brief  API to initialize Ethernet server
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAEthernetInitializeServer(void);
+
+/**
+ * @fn  CAEthernetTerminateServer
+ * @brief  API to terminate Ethernet server
+ */
+void CAEthernetTerminateServer(void);
+
+/**
+ * @fn  CAEthernetStartMulticastServer
+ * @brief  API to start multicast server for specified multicast address and port
+ *
+ * @param[in]  localAddress  Local adapter address to which server to be binded.
+ * @param[in]  multicastAddress  Multicast group address.
+ * @param[in]  multicastPort  Port number on which server to be running.
+ * @param[out]  serverFD  Multicast server socket FD.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_SERVER_STARTED_ALREADY Multicast server is already started and running.
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
+                                          const int16_t multicastPort, int32_t *serverFD);
+
+/**
+ * @fn  CAEthernetStartUnicastServer
+ * @brief  API to start unicast server for specified local address and port
+ *
+ * @param[in]  localAddress  Local adapter address to which server to be binded.
+ * @param[in][out]  port  Port number on which server to be running.
+ * Port number on which server actually started will be returned.
+ * @param[in]  forceStart  Indicate whether to start server forcesfully on specified port or not.
+ * @param[in]  secured  true if the secure server to be started, otherwise false.
+ * @param[out]  serverFD  Unicast server socket FD.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
+                                        const bool forceStart, int32_t *serverFD);
+
+/**
+ * @fn  CAEthernetStopMulticastServer
+ * @brief  API to stop multicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopMulticastServer(void);
+
+/**
+ * @fn  CAEthernetStopUnicastServer
+ * @brief  API to stop unicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopUnicastServer();
+
+/**
+ * @fn  CAEthernetStopSecureUnicastServer
+ * @brief  API to stop secured unicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopSecureUnicastServer();
+
+/**
+ * @fn  CAEthernetGetUnicastServerInfo
+ * @brief  API to get running unicast server information.
+ * @remarks  @ipAddress must be freed using free().
+ *
+ * @param[in]  secure  true if the secure server information needed, otherwise false.
+ * @param[in]  ipAddress  IP address on which server is binded and running.
+ * @param[out]  port  Port number on which server is running
+ * @param[out]  serverFD  Server socket fd.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+
+CAResult_t CAEthernetGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
+
+/**
+ * @fn  CAEthernetSetPacketReceiveCallback
+ * @brief  API to set callback for receiving data packets from peer devices.
+ *
+ * @param[in]  callback Callback to be notified on receival of unicast/multicast data packets.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback);
+
+/**
+ * @fn  CAEthernetReadData
+ * @brief  API to pull data
+ */
+void CAEthernetPullData();
+
+/**
+ * @fn  CAEthernetSetExceptionCallback
+ * @brief  API to set callback for receiving exception notifications.
+ *
+ * @param[in]  callback  Callback to be notified on occurance of exception running servers.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback);
+
+/**
+ * @fn  CAEthernetSetUnicastSocket
+ * @brief  API to set socket description for sending unicast UDP data
+ *
+ * @param[in]  socketFD  Socket descriptor used for sending UDP data.
+ *
+ */
+void CAEthernetSetUnicastSocket(const int32_t socketFD);
+
+/**
+ * @fn  CAEthernetSetUnicastPort
+ * @brief  API to set port description for sending unicast UDP data
+ *
+ * @param[in]  port  Port descriptor used for sending UDP data.
+ *
+ */
+void CAEthernetSetUnicastPort(const int32_t port);
+
+/**
+ * @fn  CAEthernetSetSecureUnicastSocket
+ * @brief  API to set socket description for sending secured (encrypted) unicast UDP data
+ *
+ * @param[in]  socketFD  Socket descriptor used for sending secured (encrypted) UDP data.
+ *
+ */
+void CAEthernetSetSecureUnicastSocket(const int32_t socketFD);
+
+/**
+ * @fn  CAEthernetSendUnicastData
+ * @brief  API to send unicast UDP data
+ *
+ * @param[in]  remoteAddress  IP address to which data needs to be send.
+ * @param[in]  port  Port to which data needs to be send.
+ * @param[in]  data  Data to be send.
+ * @param[in]  dataLength  Length of data in bytes
+ * @param[in]  isMulticast  whether data needs to be sent to multicast ip
+ * @param[in]  isSecure  Indicate the whether data needs to be send on secure channel.
+ * @isSecure will be ignored when @isMulticast is true.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+
+uint32_t CAEthernetSendData(const char *remoteAddress, const int16_t port,
+                            const char *buf, const uint32_t bufLen, bool isMulticast);
+
+/**
+ * @fn  CAEthernetConnectionStateChangeCallback
+ * @brief  Callback to be notified when ethernet adapter connection state changes.
+ *
+ * @param[in]  ipAddress  IP address of remote OIC device.
+ * @param[in]  status  Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN.
+ *
+ * @pre  Callback must be registered using CAEthernetSetConnectionStateChangeCallback()
+ */
+typedef void (*CAEthernetConnectionStateChangeCallback)(const char *ipAddress,
+        const CANetworkStatus_t status);
+
+ /**
+ * @fn  CAEthernetInitializeServer
+ * @brief  API to initialize Ethernet server
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAEthernetInitializeNetworkMonitor(void);
+
+/**
+ * @fn  CAEthernetTerminateNetworkMonitor
+ * @brief  API to terminate Ethernet network monitor
+ */
+void CAEthernetTerminateNetworkMonitor(void);
+
+/**
+ * @fn  CAEthernetStartNetworkMonitor
+ * @brief  API to start network monitoring process.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartNetworkMonitor(void);
+
+/**
+ * @fn  CAEthernetStopNetworkMonitor
+ * @brief  API to stop network monitoring process.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopNetworkMonitor(void);
+
+/**
+ * @fn  CAEthernetGetInterfaceInfo
+ * @brief  API to get local adapter network information.
+ * @remarks  @interfaceName and @ipAddress must be freed using free().
+ *
+ * @param[out]  interfaceName  Local adapter interface name
+ * @param[out]  ipAddress  IP address
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetGetInterfaceInfo(char **interfaceName, char **ipAddress);
+
+/**
+ * @fn  CAEthernetIsConnected
+ * @brief  API to get ethernet adapter connection state.
+ *
+ * @return  true if ethernet adapter is connected, otherwise false
+ */
+bool CAEthernetIsConnected(void);
+
+/**
+ * @fn  CAEthernetSetConnectionStateChangeCallback
+ * @brief  API to set callback for receiving local ethernet adapter connection status.
+ *
+ * @param[in]  callback  Callback to be notified when local ethernet adapter connection state changes.
+ *
+ */
+void CAEthernetSetConnectionStateChangeCallback(CAEthernetConnectionStateChangeCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CA_ETHERNET_INTERFACE_SINGLETHREAD_H_
index cec404b..6ce25c2 100644 (file)
@@ -27,9 +27,7 @@
 
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#ifndef ARDUINO
 #include "uthreadpool.h" /* for thread pool */
-#endif  //ARDUINO
 
 /**
  * BLE Interface APIs.
@@ -59,16 +57,10 @@ typedef struct
  * @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)
  */
-#ifdef ARDUINO
-CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
-                          CANetworkPacketReceivedCallback reqRespCallback,
-                          CANetworkChangeCallback netCallback);
-#else
 CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
                           CANetworkPacketReceivedCallback reqRespCallback,
                           CANetworkChangeCallback netCallback,
                           u_thread_pool_t handle);
-#endif //#ifdef ARDUINO
 
 /**
  * @brief Starting LE connectivity adapters . \
diff --git a/resource/csdk/connectivity/inc/caleadapter_singlethread.h b/resource/csdk/connectivity/inc/caleadapter_singlethread.h
new file mode 100644 (file)
index 0000000..5c94f01
--- /dev/null
@@ -0,0 +1,233 @@
+/******************************************************************
+ *
+ * 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 caleadapter_singlethread.h
+ * @brief This file contains the APIs for LE adapters to be implemented
+ */
+#ifndef _CA_LEADAPTER_SINGLETHREAD_H_
+#define _CA_LEADAPTER_SINGLETHREAD_H_
+
+#include "cacommon.h"
+#include "caadapterinterface.h"
+
+/**
+ * BLE Interface APIs.
+ */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @Structure 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.
+ */
+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 */
+} 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)
+ */
+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)
+ */
+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)
+ */
+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)
+ */
+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.
+ */
+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.
+ */
+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)
+ */
+CAResult_t CAStartLENotifyServer();
+
+/**
+ * @brief Send notification information.
+ * 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.
+ */
+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)
+ */
+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)
+ */
+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)
+ */
+CAResult_t CAStopLE();
+
+/**
+ * @brief Terminate the LE connectivity adapter.
+ * Configuration information will be deleted from further use
+ */
+void CATerminateLE();
+
+CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID,
+                                        void *data, uint32_t dataLength, uint32_t *sentLength);
+
+CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID,
+                                        void *data, uint32_t dataLength, uint32_t *sentLength);
+
+void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback);
+
+CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
+        void *data, uint32_t dataLen);
+
+CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
+        void *data,  uint32_t dataLen);
+
+void CABLEClientSendDataThread(void *threadData);
+
+void CABLEClientDataReceiverHandler(void *threadData);
+
+void CATerminateBleQueues();
+
+CAResult_t CAInitBleClientReceiverQueue();
+
+CAResult_t CAInitBleServerReceiverQueue();
+
+void CAInitBleQueues();
+
+void CATerminateBleQueues();
+
+CAResult_t CAInitBleServerQueues();
+
+CAResult_t CAInitBleClientQueues();
+
+CAResult_t CAInitBleServerSenderQueue();
+
+CAResult_t CAInitBleClientSenderQueue();
+
+
+
+/**
+ * @fn CABLEDataReceiverHandler
+ * @brief This function handles data from recv message queue.
+ */
+void CABLEServerDataReceiverHandler(void *context);
+
+/**
+ * @fn CABLESendDataThread
+ * @brief This function handles data from sender message queue.
+ */
+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
+*
+*/
+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.
+*/
+void CAFreeBLEData(CABLEData *bleData);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif //#ifndef _CA_LEADAPTER_SINGLETHREAD_H_
index a6d0921..76062be 100644 (file)
@@ -23,8 +23,8 @@
  * @brief This file provides APIs for BLE modules
  */
 
-#ifndef _CA_LE_INTERFACE_
-#define _CA_LE_INTERFACE_
+#ifndef _CA_LE_INTERFACE_H_
+#define _CA_LE_INTERFACE_H_
 
 #include <stdbool.h>
 
@@ -171,4 +171,4 @@ void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback);
 }
 #endif
 
-#endif //_CA_LE_INTERFACE_
+#endif //_CA_LE_INTERFACE_H_
diff --git a/resource/csdk/connectivity/inc/caleinterface_singlethread.h b/resource/csdk/connectivity/inc/caleinterface_singlethread.h
new file mode 100644 (file)
index 0000000..8ed8c80
--- /dev/null
@@ -0,0 +1,174 @@
+/******************************************************************
+*
+* 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 caleinterface_singlethread.h
+ * @brief This file provides APIs for BLE modules
+ */
+
+#ifndef _CA_LE_INTERFACE_SINGLETHREAD_H_
+#define _CA_LE_INTERFACE_SINGLETHREAD_H_
+
+#include <stdbool.h>
+
+#include "cacommon.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.
+ */
+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. */
+} 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
+*/
+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
+*/
+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
+*/
+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);
+
+/**
+* @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
+*/
+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
+*/
+void CAStopBLEGattClient();
+
+/**
+* @fn  CATerminateBLEGattClient
+* @brief  Used to unset all the callbacks and stop service discovery
+*
+* @return  void
+*/
+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
+*/
+CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char  *data,
+        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
+ *
+ * @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  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.
+ *
+ * @return  void
+ */
+void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CA_LE_INTERFACE_SINGLETHREAD_H_
index c3840be..89f902f 100644 (file)
@@ -23,8 +23,8 @@
  * @brief This file contains message functionality.
  */
 
-#ifndef __CA_MESSAGE_HANDLER_H_
-#define __CA_MESSAGE_HANDLER_H_
+#ifndef __CA_MESSAGE_HANDLER_SINGLETHREAD_H_
+#define __CA_MESSAGE_HANDLER_SINGLETHREAD_H_
 
 #include <stdint.h>
 #include "cacommon.h"
@@ -108,4 +108,4 @@ void CAHandleRequestResponseCallbacks();
 } /* extern "C" */
 #endif
 
-#endif //#ifndef __CA_MESSAGE_HANDLER_H_
+#endif //#ifndef __CA_MESSAGE_HANDLER_SINGLETHREAD_H_
diff --git a/resource/csdk/connectivity/inc/caprotocolmessage_singlethread.h b/resource/csdk/connectivity/inc/caprotocolmessage_singlethread.h
new file mode 100644 (file)
index 0000000..f0e212a
--- /dev/null
@@ -0,0 +1,211 @@
+/******************************************************************
+ *
+ * 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 caprotocolmessage_singlethread.h
+ * @brief This file contains common function for handling protocol messages.
+ */
+
+#ifndef __CA_PROTOCOL_MESSAGE_SINGLETHREAD_H_
+#define __CA_PROTOCOL_MESSAGE_SINGLETHREAD_H_
+
+#include "cacommon.h"
+#include "config.h"
+#include "coap.h"
+#include "debug.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef uint32_t code_t;
+
+/**
+ * @brief   generates pdu structure from the given information.
+ * @param   uri              [IN]    uri information of the pdu
+ * @param   code              [IN]    cod of the pdu packet
+ * @param   info              [IN]    pdu information such as request code ,response code and payload
+ * @return  coap_pdu_t     created pdu
+ */
+coap_pdu_t *CAGeneratePdu(const char *uri, const uint32_t code, const CAInfo_t info);
+
+/**
+ * function for generating
+ */
+
+/**
+ * @brief   extracts request information from received pdu.
+ * @param   pdu              [IN]    received pdu
+ * @param   outReqInfo     [OUT]    request info structure made from received pdu
+ * @param   outUri           [OUT]    uri received in the received pdu
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo,
+                                 char *outUri);
+
+/**
+ * @brief   extracts response information from received pdu.
+ * @param   pdu              [IN]    received pdu
+ * @param   outResInfo     [OUT]    request info structure made from received pdu
+ * @param   outUri           [OUT]    uri received in the received pdu
+ * @return  0 or 1 ( CAResult_t error codes in cacommon.h)
+ */
+uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo,
+                                  char *outUri);
+
+/**
+ * @brief   creates pdu from the request information
+ * @param   code         [IN]    request or response code
+ * @param   options      [IN]    options for the request and response
+ * @param   outUri       [IN]    information to create pdu
+ * @return  coap_pdu_t
+ */
+coap_pdu_t *CACreatePDUforRequest(const code_t code, coap_list_t *options,
+                                  const CAInfo_t info);
+
+/**
+ * @brief   creates pdu from the request information and paylod
+ * @param   code         [IN]    request or response code alloted
+ * @param   options      [IN]    options for the request and response backpacked
+ * @param   payload      [IN]    payload for the request or response consumed
+ * @param   outUri       [IN]    information to create pdu
+ * @return  coap_pdu_t
+ */
+
+coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *optlist,
+        const char *payload, const CAInfo_t info);
+
+/**
+ * @brief   parse the URI and creates the options
+ * @param   uriInfo      [IN]   uri information
+ * @param   options      [IN]   options information
+ * @return  None
+ */
+void CAParseURI(const char *uriInfo, coap_list_t **options);
+
+/**
+ * @brief   create option list from header information in the info
+ * @param   code         [IN]   uri information
+ * @param   info         [IN]   options information
+ * @param   optlist      [IN]   options information
+ * @return  None
+ */
+void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist);
+
+/**
+ * @brief   creates option node from key lenght and data
+ * @param   key          [IN]    key for the that needs to be sent
+ * @param   length       [IN]    length of the data that needs to be sent
+ * @param   data         [IN]    data that needs to be sent
+ * @return  created list
+ */
+coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length,
+                                   const uint8_t *data);
+
+/**
+ * @brief   order the inserted options
+ * @param   a            [IN]    option 1 for insertion
+ * @param   b            [IN]    option 2 for insertion
+ * @return  0 or 1
+ */
+int CAOrderOpts(void *a, void *b);
+
+/**
+ * @brief   number of options count
+ * @param   opt_iter     [IN]   option iteration for count
+ * @return number of options
+ */
+uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter);
+
+/**
+ * @brief   gets option data
+ * @param   data             [IN]    data that is received
+ * @param   length           [IN]    length of the data
+ * @param   result           [IN]    result of the operation
+ * @param   buflen           [IN]    buffer length of the result
+ * @param   encode_always    [IN]    encoded data
+ * @return  0 or 1
+ */
+uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result, uint32_t buflen,
+                         uint32_t encode_always);
+
+/**
+ * @brief   extracts request information from received pdu.
+ * @param   pdu              [IN]  received pdu
+ * @param   outCode          [OUT]    code of the received pdu
+ * @param   outInfo          [OUT]    request info structure made from received pdu
+ * @param   outUri           [OUT]    uri received in the received pdu
+ * @return  None
+ */
+void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo,
+                         char *outUri);
+
+/**
+ * @brief   create pdu fromn received data
+ * @param   data         [IN]   received data
+ * @param   length       [IN]   length of the data received
+ * @param   outCode      [IN]   code received
+ * @return  None
+ */
+coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode);
+
+/**
+ * @brief  generates the token
+ * @param   token        [OUT]   generated token
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+
+CAResult_t CAGenerateTokenInternal(CAToken_t *token);
+
+/**
+ * @brief  destroys the token
+ * @param   token        [IN]   generated token
+ * @return  none
+ */
+void CADestroyTokenInternal(CAToken_t token);
+
+/**
+ * @brief   destroy the ca info structure
+ * @param   info         [IN]   info structure  created from received  packet
+ * @return  none
+ */
+void CADeinitialize(CAInfo_t *info);
+
+/**
+ * @brief   gets message type from PDU binary data
+ * @param   pdu        [IN]    pdu data
+ * @param   size       [IN]    size of pdu data
+ * @return  message type
+ */
+CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void* pdu, uint32_t size);
+
+/**
+ * @brief   gets message ID PDU binary data
+ * @param   pdu        [IN]    pdu data
+ * @param   size       [IN]    size of pdu data
+ * @return  message ID
+ */
+uint16_t CAGetMessageIdFromPduBinaryData(const void* pdu, uint32_t size);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif //#ifndef __CA_PROTOCOL_MESSAGE_SINGLETHREAD_H_
index 2262a0b..4c4745c 100644 (file)
  *
  ******************************************************************/
 /**
- * @file caretransmission.h
+ * @file caretransmission_singlethread.h
  * @brief
  */
-#ifndef __CA_RETRANSMISSION_H_
-#define __CA_RETRANSMISSION_H_
+#ifndef __CA_RETRANSMISSION_SINGLETHREAD_H_
+#define __CA_RETRANSMISSION_SINGLETHREAD_H_
 
 #include <stdint.h>
 
@@ -91,4 +91,4 @@ void CARetransmissionBaseRoutine(void *threadValue);
 } /* extern "C" */
 #endif
 
-#endif  // __CA_RETRANSMISSION_H_
+#endif  // __CA_RETRANSMISSION_SINGLETHREAD_H_
index 66f8766..55d8653 100644 (file)
@@ -27,9 +27,7 @@
 
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#ifndef ARDUINO
 #include "uthreadpool.h" /* for thread pool */
-#endif  //ARDUINO
 
 #ifdef __cplusplus
 extern "C"
@@ -44,15 +42,9 @@ extern "C"
  * @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)
  */
-#ifdef ARDUINO
-CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
-                            CANetworkPacketReceivedCallback networkPacketCallback,
-                            CANetworkChangeCallback netCallback);
-#else
 CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
                             CANetworkPacketReceivedCallback networkPacketCallback,
                             CANetworkChangeCallback netCallback, u_thread_pool_t handle);
-#endif
 
 /**
  * @brief Start WiFi Interface adapter.
diff --git a/resource/csdk/connectivity/inc/cawifiadapter_singlethread.h b/resource/csdk/connectivity/inc/cawifiadapter_singlethread.h
new file mode 100644 (file)
index 0000000..1aa88d9
--- /dev/null
@@ -0,0 +1,124 @@
+/******************************************************************
+ *
+ * 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 cawifiadapter_singlethread.h
+ * @brief This file contains the APIs for WiFi Adapter.
+ */
+#ifndef __CA_WIFI_ADAPTER_SINGLETHREAD_H__
+#define __CA_WIFI_ADAPTER_SINGLETHREAD_H__
+
+#include "cacommon.h"
+#include "caadapterinterface.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @brief API to initialize WiFi Interface.
+ * @param registerCallback [IN] To register WIFI interfaces to Connectivity Abstraction Layer
+ * @param networkPacketCallback [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)
+ */
+CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
+                            CANetworkPacketReceivedCallback networkPacketCallback,
+                            CANetworkChangeCallback netCallback);
+
+/**
+ * @brief Start WiFi Interface adapter.
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAStartWIFI();
+
+/**
+ * @brief Starting listening server for receiving multicast search requests
+ * Transport Specific Behavior:
+ * WIFI Starts Multicast Server on  all available IPs and prefixed port number and
+ * as per OIC Specification.
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAStartWIFIListeningServer();
+
+/**
+ * @brief for starting discovery servers for receiving multicast advertisements
+ * Transport Specific Behavior:
+ * WIFI Starts Start multicast server on all available IPs and prefixed port
+ * number as per OIC Specification
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAStartWIFIDiscoveryServer();
+
+/**
+ * @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.
+ */
+uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
+                               uint32_t dataLen);
+
+/**
+ * @brief Sends Multicast data to the endpoint using the WIFI 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.
+ */
+uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLen);
+
+/**
+ * @brief Get WIFI 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)
+ */
+CAResult_t CAGetWIFIInterfaceInformation(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)
+ */
+CAResult_t CAReadWIFIData();
+
+/**
+ * @brief Stopping the adapters and close socket connections
+ *   WIFI Stops all multicast and unicast servers and close sockets.
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAStopWIFI();
+
+/**
+ * @brief Terminate the WIFI connectivity adapter.
+ * Configuration information will be deleted from further use
+ */
+void CATerminateWIfI();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif  // #ifndef __CA_WIFI_ADAPTER_SINGLETHREAD_H__
index 7845702..8e36aa2 100644 (file)
  * @brief This file provides APIs wifi client/server/network monitor modules
  */
 
-#ifndef _CA_WIFI_INTERFACE_
-#define _CA_WIFI_INTERFACE_
+#ifndef _CA_WIFI_INTERFACE_H_
+#define _CA_WIFI_INTERFACE_H_
 
 #include <stdbool.h>
 
 #include "cacommon.h"
-#ifndef ARDUINO
 #include "uthreadpool.h"
-#endif  //ARDUINO
 
 #ifdef __cplusplus
 extern "C"
@@ -61,15 +59,9 @@ typedef enum
  *
  * @pre  Callback must be registered using CAWiFiSetPacketReceiveCallback()
  */
-#ifndef ARDUINO
 typedef void (*CAWiFiPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
         const void *data, const uint32_t dataLength, const CABool_t isSecure);
 
-#else
-typedef void (*CAWiFiPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
-        const void *data, const uint32_t dataLength);
-#endif  //ARDUINO
-
 /**
  * @fn  CAWiFiExceptionCallback
  * @brief  Callback to be notified when exception occures on multicast/unicast server.
@@ -91,15 +83,8 @@ typedef void (*CAWiFiExceptionCallback)(CAAdapterServerType_t type);
  * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
  * @retval  #CA_STATUS_FAILED Initialization failed
  */
-#ifdef ARDUINO
-
-CAResult_t CAWiFiInitializeServer(void);
-
-#else
-
 CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool);
 
-#endif //ARDUINO
 
 /**
  * @fn  CAWiFiTerminateServer
@@ -142,15 +127,8 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult
  * @retval  #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
  * @retval  #CA_STATUS_FAILED Operation failed
  */
-
-#ifdef ARDUINO
-CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
-                                    const bool forceStart, int32_t *serverFD);
-#else
-
 CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
                                     const bool forceStart, const CABool_t isSecured, int32_t *serverFD);
-#endif //ARDUINO
 
 /**
  * @fn  CAWiFiStopMulticastServer
@@ -199,17 +177,9 @@ CAResult_t CAWiFiStopSecureUnicastServer();
  * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
  * @retval  #CA_STATUS_FAILED Operation failed
  */
-
-#ifdef ARDUINO
-
-CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
-
-#else
-
 CAResult_t CAWiFiGetUnicastServerInfo(const CABool_t isSecured, char **ipAddress, int16_t *port,
                                       int32_t *serverFD);
 
-#endif // ARDUINO
 
 /**
  * @fn  CAWiFiSetPacketReceiveCallback
@@ -223,14 +193,6 @@ CAResult_t CAWiFiGetUnicastServerInfo(const CABool_t isSecured, char **ipAddress
  */
 void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback);
 
-#ifdef ARDUINO
-/**
- * @fn  CAWiFiReadData
- * @brief  API to pull data
- */
-void CAWiFiPullData();
-#endif // ARDUINO
-
 /**
  * @fn  CAWiFiSetExceptionCallback
  * @brief  API to set callback for receiving exception notifications.
@@ -280,20 +242,10 @@ void CAWiFiSetSecureUnicastSocket(const int32_t socketFD);
  * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
  * @retval  #CA_STATUS_FAILED Operation failed
  */
-
-#ifdef ARDUINO
-
-uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
-                        const void *data, const uint32_t dataLength, bool isMulticast);
-
-#else
-
 uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
                         const void *data, const uint32_t dataLength,
                         CABool_t isMulticast, CABool_t isSecured);
 
-#endif //ARDUINO
-
 /**
  * @fn  CAWiFiConnectionStateChangeCallback
  * @brief  Callback to be notified when wifi adapter connection state changes.
@@ -317,29 +269,8 @@ typedef void (*CAWiFiConnectionStateChangeCallback)(const char *ipAddress,
  * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
  * @retval  #CA_STATUS_FAILED Initialization failed
  */
-
-#ifndef ARDUINO
-
 CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool);
 
-#else
-
-CAResult_t CAWiFiInitializeNetworkMonitor(void);
-
-#endif //ARDUINO
-
-#ifdef ARDUINO
-/**
- * @fn  CAWiFiInitializeServer
- * @brief  API to initialize Wifi server
- *
- * @return  #CA_STATUS_OK on success otherwise proper error code.
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Initialization failed
- */
-CAResult_t CAWiFiInitializeNetworkMonitor(void);
-#endif //ARDUINO
-
 /**
  * @fn  CAWiFiTerminateNetworkMonitor
  * @brief  API to terminate Wifi network monitor
@@ -382,6 +313,20 @@ CAResult_t CAWiFiStopNetworkMonitor(void);
 CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress);
 
 /**
+ * @fn  CAWiFiGetInterfaceSubnetMask
+ * @brief  API to get local adapter network subnet mask.
+ * @remarks  @subnetMaskmust be freed using free().
+ *
+ * @param[out]  subnetMask  Local adapter interface subnet mask
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiGetInterfaceSubnetMask(char **subnetMask);
+
+/**
  * @fn  CAWiFiIsConnected
  * @brief  API to get wifi adapter connection state.
  *
@@ -402,4 +347,4 @@ void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback
 }
 #endif
 
-#endif //_CA_WIFI_INTERFACE_
+#endif //_CA_WIFI_INTERFACE_H_
diff --git a/resource/csdk/connectivity/inc/cawifiinterface_singlethread.h b/resource/csdk/connectivity/inc/cawifiinterface_singlethread.h
new file mode 100644 (file)
index 0000000..2aa9d37
--- /dev/null
@@ -0,0 +1,347 @@
+/******************************************************************
+*
+* 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 cawifiinterface.h
+ * @brief This file provides APIs wifi client/server/network monitor modules
+ */
+
+#ifndef _CA_WIFI_INTERFACE_SINGLETHREAD_H_
+#define _CA_WIFI_INTERFACE_SINGLETHREAD_H_
+
+#include <stdbool.h>
+
+#include "cacommon.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @enum CAAdapterServerType_t
+ * @brief Enum for defining different server types.
+ */
+typedef enum
+{
+    CA_UNICAST_SERVER = 0,
+    CA_MULTICAST_SERVER,
+    CA_SECURED_UNICAST_SERVER
+} CAAdapterServerType_t;
+
+/**
+ * @fn  CAWiFiPacketReceivedCallback
+ * @brief  Callback to be notified on receival of any data from remote OIC devices.
+ *
+ * @param[in]  ipAddress  IP address of remote OIC device.
+ * @param[in]  port  Port number on which data is received.
+ * @param[in]  data  Data received from remote OIC device.
+ * @param[in]  dataLength  Length of data in bytes.
+ * @param[in]  secure  Indicates the data is secure or not.
+ *
+ * @pre  Callback must be registered using CAWiFiSetPacketReceiveCallback()
+ */
+typedef void (*CAWiFiPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
+        const void *data, const uint32_t dataLength);
+
+/**
+ * @fn  CAWiFiExceptionCallback
+ * @brief  Callback to be notified when exception occures on multicast/unicast server.
+ *
+ * @param[in]  type  Type of server either #CA_UNICAST_SERVER or $CA_MULTICAST_SERVER
+ *
+ * @pre  Callback must be registered using CAWiFiSetExceptionCallback()
+ */
+typedef void (*CAWiFiExceptionCallback)(CAAdapterServerType_t type);
+
+/**
+ * @fn  CAWiFiInitializeServer
+ * @brief  API to initialize Wifi server
+ *
+ * @param[in]  threadPool  Thread pool for managing Unicast/Multicast server threads.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeServer(void);
+
+/**
+ * @fn  CAWiFiTerminateServer
+ * @brief  API to terminate Wifi server
+ */
+void CAWiFiTerminateServer(void);
+
+/**
+ * @fn  CAWiFiStartMulticastServer
+ * @brief  API to start multicast server for specified multicast address and port
+ *
+ * @param[in]  localAddress  Local adapter address to which server to be binded.
+ * @param[in]  multicastAddress  Multicast group address.
+ * @param[in]  multicastPort  Port number on which server to be running.
+ * @param[out]  serverFD  Multicast server socket FD.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_SERVER_STARTED_ALREADY Multicast server is already started and running.
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
+                                      const int16_t multicastPort, int32_t *serverFD);
+
+/**
+ * @fn  CAWiFiStartUnicastServer
+ * @brief  API to start unicast server for specified local address and port
+ *
+ * @param[in]  localAddress  Local adapter address to which server to be binded.
+ * @param[in][out]  port  Port number on which server to be running.
+ * Port number on which server actually started will be returned.
+ * @param[in]  forceStart  Indicate whether to start server forcesfully on specified port or not.
+ * @param[in]  secured  true if the secure server to be started, otherwise false.
+ * @param[out]  serverFD  Unicast server socket FD.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+                                    const bool forceStart, int32_t *serverFD);
+
+/**
+ * @fn  CAWiFiStopMulticastServer
+ * @brief  API to stop multicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopMulticastServer(void);
+
+/**
+ * @fn  CAWiFiStopUnicastServer
+ * @brief  API to stop unicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopUnicastServer();
+
+#ifdef __WITH_DTLS__
+/**
+ * @fn  CAWiFiStopSecureUnicastServer
+ * @brief  API to stop secured unicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopSecureUnicastServer();
+#endif
+
+/**
+ * @fn  CAWiFiGetUnicastServerInfo
+ * @brief  API to get running unicast server information.
+ * @remarks  @ipAddress must be freed using free().
+ *
+ * @param[in]  secure  true if the secure server information needed, otherwise false.
+ * @param[in]  ipAddress  IP address on which server is binded and running.
+ * @param[out]  port  Port number on which server is running
+ * @param[out]  serverFD  Server socket fd.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
+
+/**
+ * @fn  CAWiFiSetPacketReceiveCallback
+ * @brief  API to set callback for receiving data packets from peer devices.
+ *
+ * @param[in]  callback Callback to be notified on receival of unicast/multicast data packets.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback);
+
+/**
+ * @fn  CAWiFiReadData
+ * @brief  API to pull data
+ */
+void CAWiFiPullData();
+
+/**
+ * @fn  CAWiFiSetExceptionCallback
+ * @brief  API to set callback for receiving exception notifications.
+ *
+ * @param[in]  callback  Callback to be notified on occurance of exception running servers.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback);
+
+/**
+ * @fn  CAWiFiSetUnicastSocket
+ * @brief  API to set socket description for sending unicast UDP data
+ *
+ * @param[in]  socketFD  Socket descriptor used for sending UDP data.
+ *
+ */
+void CAWiFiSetUnicastSocket(const int32_t socketFD);
+
+#ifdef __WITH_DTLS__
+/**
+ * @fn  CAWiFiSetSecureUnicastSocket
+ * @brief  API to set socket description for sending secured (encrypted) unicast UDP data
+ *
+ * @param[in]  socketFD  Socket descriptor used for sending secured (encrypted) UDP data.
+ *
+ */
+void CAWiFiSetSecureUnicastSocket(const int32_t socketFD);
+#endif
+
+/**
+ * @fn  CAWiFiSendUnicastData
+ * @brief  API to send unicast UDP data
+ *
+ * @param[in]  remoteAddress  IP address to which data needs to be send.
+ * @param[in]  port  Port to which data needs to be send.
+ * @param[in]  data  Data to be send.
+ * @param[in]  dataLength  Length of data in bytes
+ * @param[in]  isMulticast  whether data needs to be sent to multicast ip
+ * @param[in]  isSecure  Indicate the whether data needs to be send on secure channel.
+ * @isSecure will be ignored when @isMulticast is true.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+                        const void *data, const uint32_t dataLength, bool isMulticast);
+
+/**
+ * @fn  CAWiFiConnectionStateChangeCallback
+ * @brief  Callback to be notified when wifi adapter connection state changes.
+ *
+ * @param[in]  ipAddress  IP address of remote OIC device.
+ * @param[in]  status  Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN.
+ *
+ * @pre  Callback must be registered using CAWiFiSetConnectionStateChangeCallback()
+ */
+typedef void (*CAWiFiConnectionStateChangeCallback)(const char *ipAddress,
+        const CANetworkStatus_t status);
+
+/**
+ * @fn  CAWiFiInitializeNetworkMonitor
+ * @brief  API to initialize Wifi network monitor
+ *
+ * @param[in]  threadPool  Thread pool for managing network monitor thread.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeNetworkMonitor(void);
+
+/**
+ * @fn  CAWiFiInitializeServer
+ * @brief  API to initialize Wifi server
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeNetworkMonitor(void);
+
+/**
+ * @fn  CAWiFiTerminateNetworkMonitor
+ * @brief  API to terminate Wifi network monitor
+ */
+void CAWiFiTerminateNetworkMonitor(void);
+
+/**
+ * @fn  CAWiFiStartNetworkMonitor
+ * @brief  API to start network monitoring process.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStartNetworkMonitor(void);
+
+/**
+ * @fn  CAWiFiStopNetworkMonitor
+ * @brief  API to stop network monitoring process.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopNetworkMonitor(void);
+
+/**
+ * @fn  CAWiFiGetInterfaceInfo
+ * @brief  API to get local adapter network information.
+ * @remarks  @interfaceName and @ipAddress must be freed using free().
+ *
+ * @param[out]  interfaceName  Local adapter interface name
+ * @param[out]  ipAddress  IP address
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress);
+
+/**
+ * @fn  CAWiFiIsConnected
+ * @brief  API to get wifi adapter connection state.
+ *
+ * @return  true if wifi adapter is connected, otherwise false
+ */
+bool CAWiFiIsConnected(void);
+
+/**
+ * @fn  CAWiFiSetConnectionStateChangeCallback
+ * @brief  API to set callback for receiving local wifi adapter connection status.
+ *
+ * @param[in]  callback  Callback to be notified when local wifi adapter connection state changes.
+ *
+ */
+void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CA_WIFI_INTERFACE_SINGLETHREAD_H_
index d994c28..ce6b20b 100644 (file)
@@ -35,7 +35,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 #include "Arduino.h"
 #include "caadapterinterface.h"
 #include "cacommon.h"
-#include "caleadapter.h"
+#include "caleadapter_singlethread.h"
 #include <TimedAction.h>
 #include <logger.h>
 
@@ -192,7 +192,7 @@ void loop()
 
 #include "Arduino.h"
 
-#include "cawifiadapter.h"
+#include "cawifiadapter_singlethread.h"
 
 #include <logger.h>
 #include "caadapterinterface.h"
index ce04425..3065ea7 100644 (file)
 # *
 #******************************************************************/
 
-cd ../../lib/libcoap-4.1.1
-make clean
-make
-
 cd ../../build/linux
 make clean
 if echo $1 | grep -q -i "WITH_DTLS"
index 10f62f6..268e2ce 100644 (file)
@@ -37,9 +37,7 @@
  * @brief
  */
 #define IDENTITY     ("1111111111111111")
-
-/**
- * @def RS_CLIENT_PSK
+/* @def RS_CLIENT_PSK
  * @brief
  */
 #define RS_CLIENT_PSK   ("AAAAAAAAAAAAAAAA")
@@ -48,6 +46,7 @@
 int gReceived;
 CABool_t gLocalUnicastPort;
 CABool_t gLocalSecurePort;
+CAConnectivityType_t gSelectedNwType = CA_ETHERNET;
 
 char get_menu();
 void process();
@@ -152,6 +151,7 @@ int main()
         return 0;
     }
 
+#if 0
     // network enable
     // default
     printf("select default network(WIFI)\n");
@@ -161,6 +161,7 @@ int main()
         printf("CASelectNetwork fail\n");
         return 0;
     }
+#endif
 
     // set handler.
     res = CARegisterHandler(request_handler, response_handler);
@@ -427,6 +428,8 @@ void send_request()
         return;
     }
 
+    endpoint->connectivityType = gSelectedNwType;
+
     char buf[MAX_BUF_LEN];
     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
 
@@ -702,12 +705,13 @@ void select_network()
 
     int number = buf[0] - '0';
 
-    number = (number < 0 || number > 3) ? 1 : number;
+    number = (number < 0 || number > 3) ? 0 : number;
 
     CAResult_t res = CASelectNetwork(1 << number);
     if (res != CA_STATUS_OK)
     {
         printf("select network error\n");
+        gSelectedNwType = 1 << number;
     }
     else
     {
@@ -911,6 +915,7 @@ void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *re
                 printf("Failed to create duplicate of remote endpoint!\n");
                 return;
             }
+            endpoint->connectivityType = object->connectivityType;
             endpoint->isSecured = CA_TRUE;
             object = endpoint;
         }
index 0a2a305..3d71338 100644 (file)
@@ -9,7 +9,7 @@ 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 "sudo gbs build -A armv7l --include-all"
+       To Build in Tizen GBS Platform, Use this command "gbs build -A armv7l --include-all -B ~/GBS-ROOT-NEW"
 3) For Verification, Build Sample Console App and execute in Tizen Device      
 
 Procedure to Execute Sample App:
@@ -22,6 +22,7 @@
 #include "cawifiinterface.h"
 #include "dtls.h"
 
+
 /**
  * @def NET_DTLS_TAG
  * @brief Logging tag for module name
@@ -51,8 +52,8 @@ static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstS
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
-    VERIFY_NON_NULL_RET(dstSession, NET_DTLS_TAG, "Param dstSession is NULL", DTLS_FAIL);
-    VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL", DTLS_FAIL);
+    VERIFY_NON_NULL_RET(dstSession, NET_DTLS_TAG, "Param dstSession is NULL" , DTLS_FAIL);
+    VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , DTLS_FAIL);
 
     if (0 == dataLen)
     {
@@ -68,8 +69,7 @@ static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstS
         return DTLS_FAIL;
     }
 
-    int32_t retLen = dtls_write(gCaDtlsContext->dtlsContext, (session_t *) dstSession, data,
-            dataLen);
+    int32_t retLen = dtls_write(gCaDtlsContext->dtlsContext, (session_t *)dstSession, data, dataLen);
     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "dtls_write retun len [%d]", retLen);
     if (0 == retLen)
     {
@@ -104,8 +104,7 @@ static eDtlsRet_t CAAdapterNetDtlsDecryptInternal(const stCADtlsAddrInfo_t *srcS
     eDtlsRet_t ret = DTLS_FAIL;
 
     ///  TODO: how to protect gCaDtlsContext as dtls_handle_message is blocking call
-    if (dtls_handle_message(gCaDtlsContext->dtlsContext, (session_t *) srcSession, buf, bufLen)
-            == 0)
+    if (dtls_handle_message(gCaDtlsContext->dtlsContext, (session_t *)srcSession, buf, bufLen) == 0)
     {
         OIC_LOG(DEBUG, NET_DTLS_TAG, "dtls_handle_message success");
         ret = DTLS_OK;
@@ -141,9 +140,8 @@ static void CAClearCacheList()
     list_length = u_arraylist_length(gCaDtlsContext->cacheList);
     for (list_index = 0; list_index < list_length; list_index++)
     {
-        stCACacheMessage_t *msg = (stCACacheMessage_t *) u_arraylist_get(gCaDtlsContext->cacheList,
-                list_index);
-        CAFreeCacheMsg(msg);
+        stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(gCaDtlsContext->cacheList, list_index);
+        CAFreeCacheMsg(msg);
     }
     u_arraylist_free(gCaDtlsContext->cacheList);
     gCaDtlsContext->cacheList = NULL;
@@ -163,7 +161,7 @@ static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
         return CA_STATUS_FAILED;
     }
 
-    CAResult_t result = u_arraylist_add(gCaDtlsContext->cacheList, (void *) msg);
+    CAResult_t result = u_arraylist_add(gCaDtlsContext->cacheList, (void *)msg);
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
@@ -174,15 +172,17 @@ static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
     return result;
 }
 
-static CABool_t CAIsAddressMatching(const stCADtlsAddrInfo_t *a, const stCADtlsAddrInfo_t *b)
+
+static CABool_t CAIsAddressMatching(const stCADtlsAddrInfo_t *a,  const stCADtlsAddrInfo_t *b)
 {
     if (a->size != b->size || a->addr.sa.sa_family != b->addr.sa.sa_family)
-        return CA_FALSE;
+       return CA_FALSE;
 
-    if ((a->addr.sin.sin_port == b->addr.sin.sin_port)
-            && (memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr, sizeof(struct in_addr)) == 0))
+    if ((a->addr.sin.sin_port == b->addr.sin.sin_port) &&
+     (memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr,
+           sizeof(struct in_addr)) == 0))
     {
-        return CA_TRUE;
+         return CA_TRUE;
     }
     return CA_FALSE;
 }
@@ -200,24 +200,23 @@ static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
     list_length = u_arraylist_length(gCaDtlsContext->cacheList);
     for (list_index = 0; list_index < list_length; list_index++)
     {
-        stCACacheMessage_t *msg = (stCACacheMessage_t *) u_arraylist_get(gCaDtlsContext->cacheList,
-                list_index);
-        if ((NULL != msg) && (CA_TRUE == CAIsAddressMatching(msg->destSession, dstSession)))
-        {
-            eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(msg->destSession, msg->data,
-                    msg->dataLen);
-            if (ret == DTLS_OK)
-            {
-                OIC_LOG(DEBUG, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal success");
-            }
-            else
-            {
-                OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal failed.");
-            }
-            u_arraylist_remove(gCaDtlsContext->cacheList, list_index);
-            CAFreeCacheMsg(msg);
-            break;
-        }
+        stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(gCaDtlsContext->cacheList, list_index);
+        if((NULL != msg) && (CA_TRUE == CAIsAddressMatching(msg->destSession, dstSession)))
+       {
+               eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(msg->destSession,
+                             msg->data, msg->dataLen);
+               if (ret == DTLS_OK)
+               {
+                       OIC_LOG(DEBUG, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal success");
+               }
+               else
+               {
+                       OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal failed.");
+               }
+               u_arraylist_remove(gCaDtlsContext->cacheList, list_index);
+               CAFreeCacheMsg(msg);
+               break;
+       }
 
     }
     u_mutex_unlock(gDtlsListMutex);
@@ -225,8 +224,10 @@ static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
 }
 
-static int32_t CAReadDecryptedPayload(dtls_context_t *dtlsContext, session_t *session, uint8_t *buf,
-        size_t bufLen)
+static int32_t CAReadDecryptedPayload(dtls_context_t *dtlsContext,
+                                      session_t *session,
+                                      uint8_t *buf,
+                                      size_t bufLen )
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
@@ -234,12 +235,12 @@ static int32_t CAReadDecryptedPayload(dtls_context_t *dtlsContext, session_t *se
 
     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%d]", bufLen);
 
-    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *) session;
+    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
 
     char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
     uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
+    eDtlsAdapterType_t type = (eDtlsAdapterType_t)addrInfo->ifIndex;
 
-    //Notify data to upper layer
     u_mutex_lock(gDtlsContextMutex);
     if (NULL == gCaDtlsContext)
     {
@@ -247,21 +248,27 @@ static int32_t CAReadDecryptedPayload(dtls_context_t *dtlsContext, session_t *se
         u_mutex_unlock(gDtlsContextMutex);
         return 0;
     }
-    if (gCaDtlsContext->gPacketReceivedCallback)
+
+    if((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
+            (NULL != gCaDtlsContext->adapterCallbacks[type].recvCallback))
     {
-        gCaDtlsContext->gPacketReceivedCallback(remoteAddress, port, buf, bufLen, CA_TRUE);
+       gCaDtlsContext->adapterCallbacks[type].recvCallback(remoteAddress, port,
+                                      buf,  bufLen, CA_TRUE);
     }
     else
     {
-        OIC_LOG(ERROR, NET_DTLS_TAG, "gPacketReceivedCallback NULL");
+         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "recvCallback Callback or adapter type is wrong [%d]", type );
     }
     u_mutex_unlock(gDtlsContextMutex);
+
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
     return 0;
 }
 
-static int32_t CASendSecureData(dtls_context_t *dtlsContext, session_t *session, uint8_t *buf,
-        size_t bufLen)
+static int32_t CASendSecureData(dtls_context_t *dtlsContext,
+                                session_t *session,
+                                uint8_t *buf,
+                                size_t bufLen)
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
@@ -274,12 +281,24 @@ static int32_t CASendSecureData(dtls_context_t *dtlsContext, session_t *session,
         return 0;
     }
 
-    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *) session;
+    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
 
     char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
     uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
+    eDtlsAdapterType_t type = (eDtlsAdapterType_t)addrInfo->ifIndex;
 
-    uint32_t sentLen = CAWiFiSendData(remoteAddress, port, buf, bufLen, CA_FALSE, CA_TRUE);
+    //Mutex is not required for gCaDtlsContext. It will be called in same thread.
+    int32_t sentLen = 0;
+    if((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
+            (NULL != gCaDtlsContext->adapterCallbacks[type].sendCallback))
+    {
+       sentLen = gCaDtlsContext->adapterCallbacks[type].sendCallback(remoteAddress, port,
+                                      buf,  bufLen);
+    }
+    else
+    {
+         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "send Callback or adapter type is wrong [%d]", type );
+    }
 
     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "sent buffer length [%d]", sentLen);
 
@@ -287,8 +306,11 @@ static int32_t CASendSecureData(dtls_context_t *dtlsContext, session_t *session,
     return sentLen;
 }
 
-static int32_t CAHandleSecureEvent(dtls_context_t *dtlsContext, session_t *session,
-        dtls_alert_level_t level, unsigned short code)
+
+static int32_t CAHandleSecureEvent(dtls_context_t *dtlsContext,
+                                   session_t *session,
+                                   dtls_alert_level_t level,
+                                   unsigned short code)
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
@@ -299,40 +321,39 @@ static int32_t CAHandleSecureEvent(dtls_context_t *dtlsContext, session_t *sessi
     if (!level && (code == DTLS_EVENT_CONNECTED))
     {
         OIC_LOG(DEBUG, NET_DTLS_TAG, "Received DTLS_EVENT_CONNECTED. Sending Cached data");
-        CASendCachedMsg((stCADtlsAddrInfo_t *) session);
+        CASendCachedMsg((stCADtlsAddrInfo_t *)session);
     }
 
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
     return 0;
 }
 
-static int32_t CAGetPskCredentials(dtls_context_t *ctx, const session_t *session,
-        dtls_credentials_type_t type, const unsigned char *desc, size_t descLen,
-        unsigned char *result, size_t resultLen)
+
+static int32_t CAGetPskCredentials(dtls_context_t *ctx,
+                                   const session_t *session,
+                                   dtls_credentials_type_t type,
+                                   const unsigned char *desc, size_t descLen,
+                                   unsigned char *result, size_t resultLen)
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
-    int32_t ret = -1;
+    int32_t ret  = -1;
 
     CADtlsPskCredsBlob_t * credInfo = NULL;
     CAGetDtlsPskCredentials(&credInfo);
 
     VERIFY_NON_NULL_RET(credInfo, NET_DTLS_TAG, "CAGetDtlsPskCredentials credInfo is NULL", 0);
 
-    if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY))
-    {
-        if (DTLS_PSK_ID_LEN <= resultLen)
-        {
+    if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY)) {
+        if (DTLS_PSK_ID_LEN <= resultLen){
             memcpy(result, credInfo->rsIdentity, DTLS_PSK_ID_LEN);
             ret = DTLS_PSK_ID_LEN;
         }
     }
 
-    if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN))
-    {
+    if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN)) {
         int index = 0;
-        for (index = 0; index < credInfo->num; index++)
-        {
+        for (index =0; index < credInfo->num; index++) {
             if (memcmp(desc, credInfo->creds[index].clientIdentity, DTLS_PSK_ID_LEN) == 0)
             {
                 memcpy(result, credInfo->creds[index].rsClientPsk, DTLS_PSK_PSK_LEN);
@@ -344,7 +365,8 @@ static int32_t CAGetPskCredentials(dtls_context_t *ctx, const session_t *session
     return ret;
 }
 
-void CADTLSSetPacketReceiveCallback(CAPacketReceivedCallback callback)
+void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
+                                    CAPacketSendCallback sendCallback, eDtlsAdapterType_t type)
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
     u_mutex_lock(gDtlsContextMutex);
@@ -355,7 +377,11 @@ void CADTLSSetPacketReceiveCallback(CAPacketReceivedCallback callback)
         return;
     }
 
-    gCaDtlsContext->gPacketReceivedCallback = callback;
+    if((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type))
+    {
+        gCaDtlsContext->adapterCallbacks[type].recvCallback = recvCallback;
+        gCaDtlsContext->adapterCallbacks[type].sendCallback = sendCallback;
+    }
 
     u_mutex_unlock(gDtlsContextMutex);
 
@@ -365,12 +391,17 @@ void CADTLSSetPacketReceiveCallback(CAPacketReceivedCallback callback)
 CAResult_t CAAdapterNetDtlsInit()
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
-    u_mutex_init();
+
     if (NULL == gDtlsContextMutex)
     {
+        u_mutex_init();
         gDtlsContextMutex = u_mutex_new();
-        VERIFY_NON_NULL_RET(gDtlsContextMutex, NET_DTLS_TAG, "malloc failed",
-                CA_MEMORY_ALLOC_FAILED);
+        VERIFY_NON_NULL_RET(gDtlsContextMutex, NET_DTLS_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
+    }
+    else
+    {
+         OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsInit done already!");
+         return CA_STATUS_OK;
     }
 
     if (NULL == gDtlsListMutex)
@@ -385,14 +416,14 @@ CAResult_t CAAdapterNetDtlsInit()
     }
 
     u_mutex_lock(gDtlsContextMutex);
-    gCaDtlsContext = (stCADtlsContext_t *) OICMalloc(sizeof(stCADtlsContext_t));
+    gCaDtlsContext = (stCADtlsContext_t *)OICMalloc(sizeof(stCADtlsContext_t));
 
     if (NULL == gCaDtlsContext)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
         u_mutex_unlock(gDtlsContextMutex);
         u_mutex_free(gDtlsContextMutex);
-        u_mutex_free(gDtlsListMutex);
+       u_mutex_free(gDtlsListMutex);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
@@ -404,10 +435,10 @@ CAResult_t CAAdapterNetDtlsInit()
     if (NULL == gCaDtlsContext->cacheList)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "cacheList initialization failed!");
-        u_mutex_unlock(gDtlsListMutex);
+       u_mutex_unlock(gDtlsListMutex);
         u_mutex_unlock(gDtlsContextMutex);
         u_mutex_free(gDtlsContextMutex);
-        u_mutex_free(gDtlsListMutex);
+       u_mutex_free(gDtlsListMutex);
         OICFree(gCaDtlsContext);
         gCaDtlsContext = NULL;
         return CA_STATUS_FAILED;
@@ -418,7 +449,7 @@ CAResult_t CAAdapterNetDtlsInit()
 
     gCaDtlsContext->dtlsContext = dtls_new_context(gCaDtlsContext);
 
-    if (NULL == gCaDtlsContext->dtlsContext)
+    if (NULL ==  gCaDtlsContext->dtlsContext)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "dtls_new_context failed");
         u_mutex_unlock(gDtlsContextMutex);
@@ -427,7 +458,7 @@ CAResult_t CAAdapterNetDtlsInit()
     }
 
     gCaDtlsContext->callbacks.write = CASendSecureData;
-    gCaDtlsContext->callbacks.read = CAReadDecryptedPayload;
+    gCaDtlsContext->callbacks.read  = CAReadDecryptedPayload;
     gCaDtlsContext->callbacks.event = CAHandleSecureEvent;
     gCaDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
 
@@ -452,20 +483,25 @@ void CAAdapterNetDtlsDeInit()
     u_mutex_unlock(gDtlsContextMutex);
 
     u_mutex_free(gDtlsContextMutex);
+    gDtlsContextMutex = NULL;
     u_mutex_free(gDtlsListMutex);
+    gDtlsListMutex = NULL;
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
 }
 
-CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress, const uint32_t port, const void *data,
-        uint32_t dataLen, uint8_t *cacheFlag)
+CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
+                                   const uint32_t port,
+                                   const void *data,
+                                   uint32_t dataLen,
+                                   uint8_t *cacheFlag,
+                                   eDtlsAdapterType_t adapterType)
 {
 
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
-    VERIFY_NON_NULL_RET(remoteAddress, NET_DTLS_TAG, "Param remoteAddress is NULL",
-            CA_STATUS_FAILED);
+    VERIFY_NON_NULL_RET(remoteAddress, NET_DTLS_TAG, "Param remoteAddress is NULL" , CA_STATUS_FAILED);
 
-    VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL", CA_STATUS_FAILED);
+    VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , CA_STATUS_FAILED);
 
     if (0 == dataLen)
     {
@@ -475,9 +511,9 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress, const uint32_t por
 
     OIC_LOG_V(DEBUG, NET_DTLS_TAG, " Data to be encrypted dataLen [%d]", dataLen);
 
-    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *) OICMalloc(sizeof(stCADtlsAddrInfo_t));
+    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)OICMalloc(sizeof(stCADtlsAddrInfo_t));
 
-    VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
+    VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "malloc failed" , CA_MEMORY_ALLOC_FAILED);
 
     memset(addrInfo, 0x0, sizeof(stCADtlsAddrInfo_t));
 
@@ -491,9 +527,10 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress, const uint32_t por
         return CA_STATUS_FAILED;
     }
     addrInfo->size = sizeof(addrInfo->addr);
+    addrInfo->ifIndex = adapterType;
 
     ///TODO: we need to check this memory allocation is needed or not
-    uint8_t *buf = (uint8_t *) OICMalloc(sizeof(uint8_t) * (dataLen + 1));
+    uint8_t *buf = (uint8_t *)OICMalloc(sizeof(uint8_t) * (dataLen + 1));
     if (NULL == buf)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "malloc failed!");
@@ -506,7 +543,7 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress, const uint32_t por
     eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(addrInfo, buf, dataLen);
     if (ret == DTLS_SESSION_INITIATED)
     {
-        stCACacheMessage_t *message = (stCACacheMessage_t *) OICMalloc(sizeof(stCACacheMessage_t));
+        stCACacheMessage_t *message = (stCACacheMessage_t *)OICMalloc(sizeof(stCACacheMessage_t));
         if (NULL == message)
         {
             OIC_LOG(ERROR, NET_DTLS_TAG, "malloc failed!");
@@ -518,7 +555,7 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress, const uint32_t por
 
         message->data = buf;
         message->dataLen = dataLen;
-        message->destSession = addrInfo;
+       message->destSession = addrInfo;
 
         CAResult_t result = CADtlsCacheMsg(message);
         if (CA_STATUS_OK == result)
@@ -550,14 +587,18 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress, const uint32_t por
     return CA_STATUS_FAILED;
 }
 
-CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress, const uint32_t port, uint8_t *data,
-        uint32_t dataLen)
+
+CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress,
+                                   const uint32_t port,
+                                   uint8_t *data,
+                                   uint32_t dataLen,
+                                   eDtlsAdapterType_t adapterType)
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
-    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *) OICMalloc(sizeof(stCADtlsAddrInfo_t));
+    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)OICMalloc(sizeof(stCADtlsAddrInfo_t));
 
-    VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
+    VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "malloc failed" , CA_MEMORY_ALLOC_FAILED);
 
     memset(addrInfo, 0x0, sizeof(stCADtlsAddrInfo_t));
 
@@ -571,8 +612,9 @@ CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress, const uint32_t por
         return CA_STATUS_FAILED;
     }
     addrInfo->size = sizeof(addrInfo->addr);
+    addrInfo->ifIndex = adapterType;
 
-    uint8_t *buf = (uint8_t *) OICMalloc(sizeof(uint8_t) * (dataLen + 1));
+    uint8_t *buf = (uint8_t *)OICMalloc(sizeof(uint8_t) * (dataLen + 1));
     if (NULL == buf)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "malloc failed!");
index 0f87e4e..743b178 100644 (file)
@@ -206,3 +206,96 @@ void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndpoint)
     }
 }
 
+bool CAAdapterIsSameSubnet(const char *ipAddress1, const char *ipAddress2,
+                           const char *netMask)
+{
+    VERIFY_NON_NULL_RET(ipAddress1, CA_ADAPTER_UTILS_TAG, "First address", false);
+    VERIFY_NON_NULL_RET(ipAddress2, CA_ADAPTER_UTILS_TAG, "Second address", false);
+    VERIFY_NON_NULL_RET(netMask, CA_ADAPTER_UTILS_TAG, "netMask", false);
+    int32_t ipList1[8] = {0};
+    int32_t ipList2[8] = {0};
+    int32_t maskList[8] = {0};
+
+    /* IP address check */
+    if(!ipAddress1 || !ipAddress2)
+    {
+        return false;
+    }
+
+    /* Local Loopback Address */
+    if(0 == strncmp(ipAddress1, "127.", 4)
+       || 0 == strncmp(ipAddress2, "127.", 4))
+    {
+        return true;
+    }
+
+    char *ipAdrs1 = strdup(ipAddress1);
+    int16_t index = 0;
+    int16_t lastDotIndex = 0;
+    int16_t ip1TokenCount = 0;
+    while('\0' != ipAdrs1[index])
+    {
+        if('.' == ipAdrs1[index])
+        {
+            ipAdrs1[index] = '\0';
+            ipList1[ip1TokenCount++] = atoi(ipAdrs1 + lastDotIndex);
+            lastDotIndex = index + 1;
+        }
+        index++;
+    }
+    // Add last touple
+    ipList1[ip1TokenCount] = atoi(ipAdrs1 + lastDotIndex);
+
+    char *ipAdrs2 = strdup(ipAddress2);
+    index = 0;
+    lastDotIndex = 0;
+    int16_t ip2TokenCount = 0;
+    while('\0' != ipAdrs2[index])
+    {
+        if('.' == ipAdrs2[index])
+        {
+            ipAdrs2[index] = '\0';
+            ipList2[ip2TokenCount++] = atoi(ipAdrs2 + lastDotIndex);
+            lastDotIndex = index + 1;
+        }
+        index++;
+    }
+    // Add last touple
+    ipList2[ip2TokenCount] = atoi(ipAdrs2 + lastDotIndex);
+
+    char *nMask = strdup(netMask);
+    index = 0;
+    lastDotIndex = 0;
+    int16_t maskTokenCount = 0;
+    while('\0' != nMask[index])
+    {
+        if('.' == nMask[index])
+        {
+            nMask[index] = '\0';
+            maskList[maskTokenCount++] = atoi(nMask + lastDotIndex);
+            lastDotIndex = index + 1;
+        }
+        index++;
+    }
+    // Add last touple
+    maskList[maskTokenCount] = atoi(nMask + lastDotIndex);
+
+       if(ip1TokenCount < 3 || ip2TokenCount < 3 || maskTokenCount < 3)
+       {
+        OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Address or mask is invalid!");
+               return false;
+       }
+
+    OICFree(ipAdrs1);
+    OICFree(ipAdrs2);
+    OICFree(nMask);
+
+    if(((ipList1[0]& maskList[0]) == (ipList2[0]& maskList[0]))
+       &&((ipList1[1]& maskList[1]) == (ipList2[1]& maskList[1]))
+       &&((ipList1[2]& maskList[2]) == (ipList2[2]& maskList[2]))
+       &&((ipList1[3]& maskList[3]) == (ipList2[3]& maskList[3])))
+    {
+        return true;
+    }
+    return false;
+}
\ No newline at end of file
index 0f897c0..800d9cb 100644 (file)
@@ -763,7 +763,7 @@ void CABTManagerDataReceiverHandler(void *context)
         if (NULL == header)
         {
             OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Out of memory (header)!");
-            return CA_MEMORY_ALLOC_FAILED;
+            return;
         }
         memcpy(header, (char *)message->data, CA_HEADER_LENGTH);
         totalDataLen = CAParseHeader(header);
@@ -1204,7 +1204,7 @@ void CABTAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState,
             if (gServerState == TRUE)
             {
                 CABTManagerStartServer();
-                gServerState == FALSE;
+                gServerState = FALSE;
             }
         }
         //Notity to upper layer
index 504201d..48b3c49 100644 (file)
 * limitations under the License.
 *
 ******************************************************************/
-#include "caleadapter.h"
+#include "caleadapter_singlethread.h"
 
 #include <TimedAction.h>
 
-#include "caleinterface.h"
+#include "caleinterface_singlethread.h"
 #include "caleserver.h"
 #include "logger.h"
 #include "caadapterutils.h"
index 7d10e08..fa4595d 100644 (file)
@@ -175,6 +175,7 @@ void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic,
     {
         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
         u_mutex_unlock(gBleReqRespClientCbMutex);
+        OICFree(data);
         return;
     }
     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
@@ -601,8 +602,8 @@ CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, i
         if (CA_STATUS_OK != result)
         {
             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!");
-            OICFree(stTemp);
             OICFree(stTemp->address);
+            OICFree(stTemp);
             CAFreeBLEServiceInfo(bleServiceInfo);
             bleServiceInfo = NULL;
             u_mutex_unlock(gBleServiceListMutex);
@@ -662,7 +663,7 @@ void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const cha
         OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
 
         ret = CABleGattStartDeviceDiscovery();
-        if (CA_STATUS_OK != result)
+        if (CA_STATUS_OK != ret)
         {
             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
             return;
index 31d9ad9..521b585 100644 (file)
@@ -632,6 +632,7 @@ void CABleGattRemoteCharacteristicWriteCb(char *charPath,
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gReqRespCallback is NULL!");
         u_mutex_unlock(gBleReqRespCbMutex);
+        OICFree(data);
         return;
     }
 
index 772ab1f..6afa833 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "cainterface.h"
 #include "caremotehandler.h"
-#include "caprotocolmessage.h"
+#include "caprotocolmessage_singlethread.h"
 #include "canetworkconfigurator.h"
 #include "logger.h"
 
index 1c92ab6..2d290a2 100644 (file)
 #include <stdint.h>
 
 #include "cainterfacecontroller.h"
-#include "cawifiadapter.h"
 #include "caethernetadapter.h"
 #include "caedradapter.h"
 #include "caleadapter.h"
 #include "cawifiadapter.h"
-#include "caethernetadapter.h"
 #include "canetworkconfigurator.h"
 #include "caremotehandler.h"
 #include "oic_malloc.h"
index f282f9b..88d8192 100644 (file)
 #include <string.h>
 #include <stdint.h>
 
-#include "cawifiadapter.h"
-#include "caethernetadapter.h"
-#include "caedradapter.h"
-#include "caleadapter.h"
+#include "cawifiadapter_singlethread.h"
+#include "caethernetadapter_singlethread.h"
+#include "caedradapter_singlethread.h"
+#include "caleadapter_singlethread.h"
 
 #include "canetworkconfigurator.h"
 #include "oic_malloc.h"
@@ -458,7 +458,6 @@ CAResult_t CAReadData()
 
     if (!list)
     {
-        OIC_LOG(DEBUG, TAG, "No selected network");
         return CA_STATUS_FAILED;
     }
     void *ptrType = NULL;
index 55c7196..ee40a82 100644 (file)
@@ -28,7 +28,7 @@
 #include "cainterface.h"
 #include "caremotehandler.h"
 #include "cainterfacecontroller_singlethread.h"
-#include "caprotocolmessage.h"
+#include "caprotocolmessage_singlethread.h"
 #include "logger.h"
 #include "config.h" /* for coap protocol */
 #include "coap.h"
@@ -40,6 +40,7 @@
 #define MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG1, "Out of memory"); goto memory_error_exit;} }
 
 #define MAX_THREAD_POOL_SIZE    10
+#define CA_MAX_RT_ARRAY_SIZE    3
 
 typedef enum
 {
@@ -312,6 +313,13 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequ
     CARemoteEndpoint_t *remoteEndpoint = NULL;
     CARequestInfo_t *requestInfo = NULL;
 
+    // If max retransmission queue is reached, then don't handle new request
+    if (CA_MAX_RT_ARRAY_SIZE == u_arraylist_length(gRetransmissionContext.dataList))
+    {
+        OIC_LOG(DEBUG, TAG1, "max RT queue size rchd");
+        return CA_SEND_FAILED;
+    }
+
     CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
     MEMORY_ALLOC_CHECK(data);
 
index ee9deaf..25a3652 100644 (file)
 #define CA_BUFSIZE 128\r
 #define CA_COAP_MESSAGE_CON 0\r
 \r
-#ifdef __ARDUINO__\r
-#include "util.h"\r
-#else\r
 #include <time.h>\r
-#endif //#ifdef __ARDUINO__\r
+\r
 \r
 uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo,\r
                                  char *outUri)\r
@@ -563,9 +560,7 @@ CAResult_t CAGenerateTokenInternal(CAToken_t *token)
     // set random byte\r
     uint32_t index;\r
 \r
-#ifndef __ARDUINO__\r
     srand(time(NULL));\r
-#endif //#ifndef __ARDUINO__\r
     for (index = 0; index < CA_MAX_TOKEN_LEN; index++)\r
     {\r
         // use valid characters\r
diff --git a/resource/csdk/connectivity/src/caprotocolmessage_singlethread.c b/resource/csdk/connectivity/src/caprotocolmessage_singlethread.c
new file mode 100644 (file)
index 0000000..f0ec4da
--- /dev/null
@@ -0,0 +1,677 @@
+/******************************************************************
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "caprotocolmessage_singlethread.h"
+#include "logger.h"
+#include "oic_malloc.h"
+
+#define TAG "CA"
+
+#define CA_MAX_TOKEN_LEN   (8)
+#define CA_FLAGS_BLOCK 0x01
+#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)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    if (NULL == pdu)
+        return 0;
+
+    uint32_t code = CA_NOT_FOUND;
+    CAGetRequestPDUInfo(pdu, &code, &(outReqInfo->info), outUri);
+    outReqInfo->method = code;
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return 1;
+}
+
+uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo,
+                                  char *outUri)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (NULL == pdu)
+        return 0;
+
+    uint32_t code = CA_NOT_FOUND;
+    CAGetRequestPDUInfo(pdu, &code, &(outResInfo->info), outUri);
+    outResInfo->result = code;
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return 1;
+}
+
+coap_pdu_t *CAGeneratePdu(const char *uri, const uint32_t code, const CAInfo_t info)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    coap_pdu_t *pdu;
+    char *coapUri = NULL;
+    uint32_t coapHeaderLength = 12;
+    uint32_t length;
+    coap_list_t *optlist = NULL;
+
+    if (NULL == uri)
+        return NULL;
+
+    length = strlen(uri);
+    if (CA_MAX_URI_LENGTH < length)
+    {
+        OIC_LOG(DEBUG, TAG, "URI len err");
+        return NULL;
+    }
+
+    coapUri = (char *) OICMalloc(length + coapHeaderLength + 1);
+    if (coapUri == NULL)
+    {
+        OIC_LOG(ERROR, TAG, "Mem alloc failed");
+        return NULL;
+    }
+    memset(coapUri, 0, length + coapHeaderLength + 1);
+
+    if (NULL != coapUri)
+    {
+        memcpy(coapUri, "coap://[::]/", coapHeaderLength);
+        memcpy(coapUri + coapHeaderLength, uri, length);
+
+        // parsing options in URI
+        CAParseURI(coapUri, &optlist);
+
+        // parsing options in HeadOption
+        CAParseHeadOption(code, info, &optlist);
+
+        OICFree(coapUri);
+    }
+
+    if (NULL != info.payload) // payload is include in request / response
+    {
+        if (!(pdu = CACreatePDUforRequestWithPayload((code_t) code, optlist, info.payload, info)))
+            return NULL;
+    }
+    else // payload is not include in request / response
+    {
+        if (!(pdu = CACreatePDUforRequest((code_t) code, optlist, info)))
+            return NULL;
+    }
+
+    // pdu print method : coap_show_pdu(pdu);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return pdu;
+}
+
+coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    coap_pdu_t *outpdu = coap_new_pdu();
+
+    coap_pdu_parse((unsigned char *) data, length, outpdu);
+    (*outCode) = (uint32_t) outpdu->hdr->code;
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return outpdu;
+}
+
+coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *options,
+                                             const char *payload, const CAInfo_t info)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    coap_pdu_t *pdu;
+    coap_list_t *opt;
+
+    uint32_t CAFlags = 0;
+    coap_block_t CABlock =
+    { .num = 0, .m = 0, .szx = 6 };
+
+    if (!(pdu = coap_new_pdu()))
+        return NULL;
+
+    unsigned short message_id;
+
+    if (info.messageId == 0)
+    {
+        /* initialize message id */
+        prng((unsigned char * )&message_id, sizeof(unsigned short));
+        ++message_id;
+
+        OIC_LOG_V(DEBUG, TAG, "gen msg id(%d)", message_id);
+    }
+    else
+    {
+        /* use saved message id */
+        message_id = info.messageId;
+    }
+
+    pdu->hdr->type = info.type;
+    pdu->hdr->id = htons(message_id);
+    pdu->hdr->code = code;
+
+    if (info.token)
+    {
+        pdu->hdr->token_length = CA_MAX_TOKEN_LEN;
+        if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char *) info.token))
+        {
+            OIC_LOG(DEBUG, TAG, "cant add token");
+        }
+    }
+    for (opt = options; opt; opt = opt->next)
+    {
+        coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option * )opt->data),
+                        COAP_OPTION_LENGTH(*(coap_option * )opt->data),
+                        COAP_OPTION_DATA(*(coap_option * )opt->data));
+    }
+
+    if (NULL != payload)
+    {
+        uint32_t len = strlen(payload);
+        if ((CAFlags & CA_FLAGS_BLOCK) == 0)
+        {
+            OIC_LOG_V(DEBUG, TAG, "add data, payload: %s", payload);
+            coap_add_data(pdu, len, (const unsigned char *) payload);
+        }
+        else
+        {
+            OIC_LOG_V(DEBUG, TAG, "add block, payload: %s", payload);
+            coap_add_block(pdu, len, (const unsigned char *) payload, CABlock.num, CABlock.szx);
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return pdu;
+}
+
+coap_pdu_t *CACreatePDUforRequest(const code_t code, coap_list_t *options,
+                                  const CAInfo_t info)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    coap_pdu_t *pdu;
+    coap_list_t *opt;
+
+    if (!(pdu = coap_new_pdu()))
+    {
+        OIC_LOG(ERROR, TAG, "mem alloc failed");
+        return NULL;
+    }
+
+    unsigned short message_id;
+
+    if (info.messageId == 0)
+    {
+        /* initialize message id */
+        prng((unsigned char * )&message_id, sizeof(unsigned short));
+        ++message_id;
+
+        OIC_LOG_V(DEBUG, TAG, "gen msg id(%d)", message_id);
+    }
+    else
+    {
+        /* use saved message id */
+        message_id = info.messageId;
+    }
+
+    pdu->hdr->type = info.type;
+    pdu->hdr->id = htons(message_id);
+    pdu->hdr->code = code;
+
+    OIC_LOG_V(DEBUG, TAG, "token info : %s, %d", info.token, strlen(info.token));
+    pdu->hdr->token_length = CA_MAX_TOKEN_LEN;
+
+    if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char *) info.token))
+    {
+        OIC_LOG(DEBUG, TAG, "cant add data");
+    }
+
+    for (opt = options; opt; opt = opt->next)
+    {
+        coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option * )opt->data),
+                        COAP_OPTION_LENGTH(*(coap_option * )opt->data),
+                        COAP_OPTION_DATA(*(coap_option * )opt->data));
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return pdu;
+}
+
+void CAParseURI(const char *uriInfo, coap_list_t **optlist)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    unsigned char portbuf[2];
+    unsigned char _buf[CA_BUFSIZE];
+    unsigned char *buf = _buf;
+    coap_uri_t uri;
+    size_t buflen;
+    uint32_t res;
+
+    OIC_LOG_V(DEBUG, TAG, "url : %s", uriInfo);
+
+    /* split arg into Uri-* options */
+    coap_split_uri((unsigned char *) uriInfo, strlen(uriInfo), &uri);
+
+    if (uri.port != COAP_DEFAULT_PORT)
+    {
+        coap_insert(optlist,
+                    CACreateNewOptionNode(COAP_OPTION_URI_PORT,
+                                          coap_encode_var_bytes(portbuf, uri.port), portbuf),
+                                          CAOrderOpts);
+    }
+
+    if (uri.path.length)
+    {
+        buflen = CA_BUFSIZE;
+        res = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
+
+        while (res--)
+        {
+            coap_insert(optlist,
+                        CACreateNewOptionNode(COAP_OPTION_URI_PATH, COAP_OPT_LENGTH(buf),
+                                              COAP_OPT_VALUE(buf)), CAOrderOpts);
+            buf += COAP_OPT_SIZE(buf);
+        }
+    }
+
+    if (uri.query.length)
+    {
+        buflen = CA_BUFSIZE;
+        buf = _buf;
+        res = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);
+
+        while (res--)
+        {
+            coap_insert(optlist,
+                        CACreateNewOptionNode(COAP_OPTION_URI_QUERY, COAP_OPT_LENGTH(buf),
+                                              COAP_OPT_VALUE(buf)), CAOrderOpts);
+
+            buf += COAP_OPT_SIZE(buf);
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG_V(DEBUG, TAG, "parse Head Opt: %d", info.numOptions);
+
+    uint32_t i;
+    for (i = 0; i < info.numOptions; i++)
+    {
+        uint32_t id = info.options[i].optionID;
+        if (COAP_OPTION_URI_PATH == id || COAP_OPTION_URI_QUERY == id)
+        {
+            OIC_LOG_V(DEBUG, TAG, "not Header Opt: %d", id);
+        }
+        else
+        {
+            OIC_LOG_V(DEBUG, TAG, "Head Opt ID: %d", info.options[i].optionID);
+            OIC_LOG_V(DEBUG, TAG, "Head Opt data: %s", info.options[i].optionData);
+            OIC_LOG_V(DEBUG, TAG, "Head Opt len: %d", info.options[i].optionLength);
+
+            coap_insert(optlist,
+                        CACreateNewOptionNode(info.options[i].optionID,
+                                            info.options[i].optionLength,
+                                              info.options[i].optionData), CAOrderOpts);
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length,
+                                   const uint8_t *data)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    coap_option *option;
+    coap_list_t *node;
+
+    option = coap_malloc(sizeof(coap_option) + length);
+    if (!option)
+    {
+        OIC_LOG(ERROR, TAG, "mem alloc failed");
+        return NULL;
+    }
+    memset(option, 0, sizeof(coap_option) + length);
+
+    COAP_OPTION_KEY(*option) = key;
+    COAP_OPTION_LENGTH(*option) = length;
+    memcpy(COAP_OPTION_DATA(*option), data, length);
+
+    /* we can pass NULL here as delete function since option is released automatically  */
+    node = coap_new_listnode(option, NULL);
+
+    if (!node)
+    {
+        OIC_LOG(DEBUG, TAG, "new_listnode rets NULL");
+        coap_free(option);
+        return NULL;
+    }
+    //coap_free(option);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return node;
+}
+
+int CAOrderOpts(void *a, void *b)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (!a || !b)
+    {
+        return a < b ? -1 : 1;
+    }
+
+    if (COAP_OPTION_KEY(*(coap_option *)a) < COAP_OPTION_KEY(*(coap_option * )b))
+    {
+        return -1;
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return COAP_OPTION_KEY(*(coap_option *)a) == COAP_OPTION_KEY(*(coap_option * )b);
+}
+
+uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    uint32_t count = 0;
+    coap_opt_t *option;
+
+    while ((option = coap_option_next(&opt_iter)))
+    {
+        if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)
+        {
+
+        }
+        else
+        {
+            count++;
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return count;
+}
+
+void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo,
+                         char *outUri)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */
+    uint32_t encode = 0;
+    coap_opt_iterator_t opt_iter;
+    coap_opt_t *option;
+    char optionResult[CA_MAX_URI_LENGTH] =
+    { 0, };
+    uint32_t count = 0, idx = 0;
+    uint32_t optionLength = 0;
+    uint32_t isfirstsetflag = 0;
+
+    coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL);
+
+    memset(optionResult, 0, sizeof(optionResult));
+
+    // set code
+    (*outCode) = (uint32_t) pdu->hdr->code;
+
+    // init HeaderOption list
+    count = CAGetOptionCount(opt_iter);
+
+    memset(outInfo, 0, sizeof(CAInfo_t));
+    outInfo->numOptions = count;
+    // set type
+    outInfo->type = pdu->hdr->type;
+
+    // set message id
+    outInfo->messageId = ntohs(pdu->hdr->id);
+
+    if (count > 0)
+    {
+        outInfo->options = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * count);
+        if (outInfo->options == NULL)
+        {
+            OIC_LOG(DEBUG, TAG, "Mem alloc failed");
+            return;
+        }
+        memset(outInfo->options, 0, sizeof(CAHeaderOption_t) * count);
+    }
+
+    while ((option = coap_option_next(&opt_iter)))
+    {
+
+        if (CAGetOptionData((uint8_t *)(COAP_OPT_VALUE(option)),
+                            COAP_OPT_LENGTH(option), (uint8_t *)buf, sizeof(buf),
+                            encode))
+        {
+            if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)
+            {
+                if (0 == isfirstsetflag)
+                {
+                    isfirstsetflag = 1;
+                    memcpy(optionResult + optionLength, buf, strlen((const char *) buf));
+                    optionLength += strlen((const char *) buf);
+
+                }
+                else
+                {
+                    if (COAP_OPTION_URI_PATH == opt_iter.type)
+                    {
+                        memcpy(optionResult + optionLength, "/", 1);
+                        optionLength++;
+                    }
+                    else if (COAP_OPTION_URI_QUERY == opt_iter.type)
+                    {
+                        memcpy(optionResult + optionLength, "?", 1);
+                        optionLength++;
+                    }
+                    memcpy(optionResult + optionLength, buf, strlen((const char *) buf));
+                    optionLength += strlen((const char *) buf);
+                }
+            }
+            else
+            {
+
+                if (idx < count)
+                {
+                    uint32_t length = (uint32_t) strlen((const char *) buf);
+
+                    if (length <= CA_MAX_HEADER_OPTION_DATA_LENGTH)
+                    {
+                        outInfo->options[idx].optionID = opt_iter.type;
+                        outInfo->options[idx].optionLength = length;
+                        outInfo->options[idx].protocolID = CA_COAP_ID;
+                        memcpy(outInfo->options[idx].optionData, buf, length);
+                        idx++;
+                    }
+                }
+            }
+        }
+    }
+
+    // set token data
+    if (pdu->hdr->token_length > 0)
+    {
+        OIC_LOG(DEBUG, TAG, "pdu->hdr->token_length>0");
+        outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN);
+        if (outInfo->token == NULL)
+        {
+            OIC_LOG(DEBUG, TAG, "Mem alloc failed");
+            OICFree(outInfo->options);
+            return;
+        }
+        memcpy(outInfo->token, pdu->hdr->token, CA_MAX_TOKEN_LEN);
+    }
+
+    // set payload data
+    if (NULL != pdu->data)
+    {
+        OIC_LOG(DEBUG, TAG, "inside pdu->data");
+        outInfo->payload = (char *) OICMalloc(strlen((const char *) pdu->data) + 1);
+        if (outInfo->payload == NULL)
+        {
+            OIC_LOG(DEBUG, TAG, "Mem alloc failed");
+            OICFree(outInfo->options);
+            OICFree(outInfo->token);
+            return;
+        }
+        memcpy(outInfo->payload, pdu->data, strlen((const char *) pdu->data) + 1);
+    }
+
+
+    memcpy(outUri, optionResult, strlen(optionResult));
+    OIC_LOG_V(DEBUG, TAG, "made URL:%s\n", optionResult);
+    OIC_LOG(DEBUG, TAG, "OUT");
+
+}
+
+CAResult_t CAGenerateTokenInternal(CAToken_t *token)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (token == NULL)
+    {
+        return CA_STATUS_FAILED;
+    }
+
+    // memory allocation
+    char *temp = (char *) OICMalloc(sizeof(char) * (CA_MAX_TOKEN_LEN + 1));
+    if (temp == NULL)
+    {
+        OIC_LOG(DEBUG, TAG, "Mem alloc failed");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+    memset(temp, 0, sizeof(char) * (CA_MAX_TOKEN_LEN + 1));
+
+    // set random byte
+    uint32_t index;
+
+    for (index = 0; index < CA_MAX_TOKEN_LEN; index++)
+    {
+        // use valid characters
+        temp[index] = (rand() % 94 + 33) & 0xFF;
+    }
+
+    temp[index] = '\0';
+    // save token
+    *token = temp;
+
+    OIC_LOG_V(DEBUG, TAG, "gen token(%s)", *token);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CADestroyTokenInternal(CAToken_t token)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (token != NULL)
+    {
+        OIC_LOG_V(DEBUG, TAG, "destroy token(%s)!!", token);
+
+        OICFree(token);
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CADeinitialize(CAInfo_t *info)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    if (NULL != info)
+    {
+        if (NULL != info->options)
+        {
+            OIC_LOG(DEBUG, TAG, "free opt");
+            OICFree(info->options);
+        }
+
+        if (NULL != info->token)
+        {
+            OIC_LOG(DEBUG, TAG, "free tok");
+            OICFree(info->token);
+        }
+
+        if (NULL != info->payload)
+        {
+            OIC_LOG(DEBUG, TAG, "free payld");
+            OICFree(info->payload);
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result,
+                         uint32_t buflen, uint32_t encode_always)
+{
+    const unsigned char hex[] = "0123456789ABCDEF";
+    uint32_t cnt = 0;
+    assert(data || len == 0);
+
+    if (buflen == 0 || len == 0)
+        return 0;
+
+    while (len)
+    {
+        if (!encode_always)
+        {
+            if (cnt == buflen)
+                break;
+            *result++ = *data;
+            ++cnt;
+        }
+        else
+        {
+            if (cnt + 4 < buflen)
+            {
+                *result++ = '\\';
+                *result++ = 'x';
+                *result++ = hex[(*data & 0xf0) >> 4];
+                *result++ = hex[*data & 0x0f];
+                cnt += 4;
+            }
+            else
+                break;
+        }
+
+        ++data;
+        --len;
+    }
+
+    *result = '\0';
+    return cnt;
+}
+
+CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void* pdu, uint32_t size)
+{
+    // pdu minimum size is 4 byte.
+    if (size < 4)
+        return CA_MSG_NONCONFIRM;
+
+    coap_hdr_t* hdr = (coap_hdr_t*) pdu;
+
+    return (CAMessageType_t) hdr->type;
+}
+
+uint16_t CAGetMessageIdFromPduBinaryData(const void* pdu, uint32_t size)
+{
+    // pdu minimum size is 4 byte.
+    if (size < 4)
+        return 0;
+
+    coap_hdr_t* hdr = (coap_hdr_t*) pdu;
+
+    return ntohs(hdr->id);
+}
index 3ce5406..0894b46 100644 (file)
@@ -131,6 +131,12 @@ CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread)
         return CA_STATUS_FAILED;
     }
 
+    if (CA_FALSE == thread->isStop) //Queueing thread already running
+    {
+        OIC_LOG_V(DEBUG, TAG, "queueing thread already running..");
+        return CA_STATUS_OK;
+    }
+
     thread->isStop = CA_FALSE;
     CAResult_t res = u_thread_pool_add_task(thread->threadPool, CAQueueingThreadBaseRoutine,
                                             thread);
index 4a7a262..ee630cf 100644 (file)
 #include <TimedAction.h>
 
 #include "caremotehandler.h"
-#include "caprotocolmessage.h"
+#include "caprotocolmessage_singlethread.h"
 #include "oic_malloc.h"
 #include "logger.h"
 
-#define TAG "RET"
+#define TAG "RT"
 
 typedef struct
 {
@@ -71,7 +71,7 @@ static CABool_t CACheckTimeout(uint64_t currentTime, uint64_t timeStamp, uint8_t
 
     if (currentTime >= timeStamp + timeOut)
     {
-        OIC_LOG_V(DEBUG, TAG, "%d sec time out!!, tried count(%d)", (2 << triedCount), triedCount);
+        OIC_LOG_V(DEBUG, TAG, "timeout=%d, tried cnt=%d", (2 << triedCount), triedCount);
         return CA_TRUE;
     }
 
@@ -90,7 +90,7 @@ void CACheckRetransmissionList()
     OIC_LOG_V(DEBUG, TAG, "len=%d", len);
     for (i = 0; i < len; i++)
     {
-        CARetransmissionData_t* retData = 
+        CARetransmissionData_t* retData =
             (CARetransmissionData_t*)u_arraylist_get(gRetransmissionPtr->dataList, i);
 
         if (retData == NULL)
@@ -102,11 +102,11 @@ void CACheckRetransmissionList()
         if (CACheckTimeout(currentTime, retData->timeStamp, retData->triedCount))
         {
 
-            OIC_LOG(DEBUG, TAG, "CCT-Success, retransmit data");
+            OIC_LOG(DEBUG, TAG, "RTdata-Success");
            // #2. if time's up, send the data.
             if (gRetransmissionPtr->dataSendMethod != NULL)
             {
-                OIC_LOG_V(DEBUG, TAG, "retry CON datamsgid=%d", retData->messageId);
+                OIC_LOG_V(DEBUG, TAG, "retry CON data-msgid=%d", retData->messageId);
                 gRetransmissionPtr->dataSendMethod(retData->endpoint, retData->pdu, retData->size);
             }
 
@@ -118,9 +118,14 @@ void CACheckRetransmissionList()
         // #4. if tried count is max, remove the retransmission data from list.
         if (retData->triedCount >= gRetransmissionPtr->config.tryingCount)
         {
-            CARetransmissionData_t* removedData = 
+            CARetransmissionData_t* removedData =
                 (CARetransmissionData_t*)u_arraylist_remove(gRetransmissionPtr->dataList, i);
-
+            if (NULL == removedData)
+            {
+                OIC_LOG(DEBUG, TAG, "Removed data is NULL");
+                return;
+            }
+            OIC_LOG(DEBUG, TAG, "max trycount rchd");
             OIC_LOG_V(DEBUG, TAG, "max trycount, remove retransmission CON data!!, messageid=%d",
                                                                             removedData->messageId);
 
@@ -160,14 +165,13 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t* context,
                                             CADataSendMethod_t retransmissionSendMethod,
                                             CARetransmissionConfig_t* config)
 {
+    OIC_LOG(DEBUG, TAG, "IN");
     if (context == NULL)
     {
-        OIC_LOG_V(DEBUG, TAG, "thread instance is empty..");
+        OIC_LOG_V(DEBUG, TAG, "error");
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG_V(DEBUG, TAG, "thread initialize..");
-
     memset(context, 0, sizeof(CARetransmission_t));
 
     CARetransmissionConfig_t cfg;
@@ -193,7 +197,7 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t* context,
     // Enable TimedAction for CACheckRetransmissionList API
     gRetransmissionPtr = context;
     gRcvAction.enable();
-
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -201,6 +205,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t* context,
                                                 const CARemoteEndpoint_t* endpoint,
                                                 const void* pdu, uint32_t size)
 {
+    OIC_LOG(DEBUG, TAG, "IN");
     if (context == NULL || endpoint == NULL || pdu == NULL)
     {
         OIC_LOG_V(DEBUG, TAG, "error");
@@ -231,7 +236,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t* context,
 
     if (retData == NULL)
     {
-        OIC_LOG_V(DEBUG, TAG, "memory error!!");
+        OIC_LOG_V(DEBUG, TAG, "error");
         return CA_MEMORY_ALLOC_FAILED;
     }
     memset(retData, 0, sizeof(CARetransmissionData_t));
@@ -241,7 +246,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t* context,
     if (pduData == NULL)
     {
         OICFree(retData);
-        OIC_LOG_V(DEBUG, TAG, "memory error!!");
+        OIC_LOG_V(DEBUG, TAG, "error");
         return CA_MEMORY_ALLOC_FAILED;
     }
     memset(pduData, 0, sizeof(int8_t) * size);
@@ -271,23 +276,24 @@ CAResult_t CARetransmissionSentData(CARetransmission_t* context,
     // #4. Initiate Re-transmission for added entry
     gRetransmissionPtr = context;
     CACheckRetransmissionList();
-
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CARetransmissionReceivedData(CARetransmission_t* context,
         const CARemoteEndpoint_t* endpoint, const void* pdu, uint32_t size)
 {
+    OIC_LOG(DEBUG, TAG, "IN");
     if (context == NULL || endpoint == NULL || pdu == NULL)
     {
-        OIC_LOG_V(DEBUG, TAG, "invalid parameter..");
+        OIC_LOG_V(DEBUG, TAG, "error");
         return CA_STATUS_INVALID_PARAM;
     }
 
     // #0. check support connectivity type
     if (!(context->config.supportType & endpoint->connectivityType))
     {
-        OIC_LOG_V(DEBUG, TAG, "not supported conntype=%d", endpoint->connectivityType);
+        OIC_LOG_V(DEBUG, TAG, "not supp conntype=%d", endpoint->connectivityType);
         return CA_STATUS_OK;
     }
 
@@ -309,7 +315,7 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t* context,
     // find index
     for (i = 0; i < len; i++)
     {
-        CARetransmissionData_t* retData = 
+        CARetransmissionData_t* retData =
             (CARetransmissionData_t*)u_arraylist_get(context->dataList, i);
 
         if (retData == NULL)
@@ -324,51 +330,54 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t* context,
     // #2. remove data from list
     if (i < len)
     {
-        CARetransmissionData_t* removedData = 
+        CARetransmissionData_t* removedData =
             (CARetransmissionData_t*)u_arraylist_remove(context->dataList, i);
+        if (NULL == removedData)
+        {
+            OIC_LOG(DEBUG, TAG, "Removed data is NULL");
+            return CA_STATUS_FAILED;
+        }
 
-        OIC_LOG_V(DEBUG, TAG, "remove retransmission CON data!!, message id(%d)", messageId);
+        OIC_LOG_V(DEBUG, TAG, "remove RTCON data, msgid=%d", messageId);
 
         CADestroyRemoteEndpointInternal(removedData->endpoint);
         OICFree(removedData->pdu);
 
         OICFree(removedData);
     }
-
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CARetransmissionStop(CARetransmission_t* context)
 {
+    OIC_LOG(DEBUG, TAG, "IN");
     if (context == NULL)
     {
-        OIC_LOG_V(DEBUG, TAG, "context is empty..");
+        OIC_LOG_V(DEBUG, TAG, "error");
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG_V(DEBUG, TAG, "retransmission stop request!!");
-
     // Disable TimedAction for CACheckRetransmissionList API
     gRcvAction.disable();
 
     // set stop flag
     context->isStop = CA_TRUE;
-
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CARetransmissionDestroy(CARetransmission_t* context)
 {
+    OIC_LOG(DEBUG, TAG, "IN");
     if (context == NULL)
     {
-        OIC_LOG_V(DEBUG, TAG, "context is empty..");
+        OIC_LOG_V(DEBUG, TAG, "error");
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG_V(DEBUG, TAG, "retransmission context destroy..");
-
     u_arraylist_free(context->dataList);
-
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
index a0b64db..a79190e 100644 (file)
@@ -29,7 +29,7 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
 #include "caadapterutils.h"
 
 #define MOD_NAME "EU"
index 9cdee4e..f67944f 100644 (file)
@@ -36,7 +36,7 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
 #include "caadapterutils.h"
 
 #ifdef __cplusplus
index 556b4b7..21bea62 100644 (file)
@@ -17,7 +17,7 @@
 * limitations under the License.
 *
 ******************************************************************/
-#include "caethernetinterface.h"
+#include "caethernetinterface_singlethread.h"
 
 #include <Arduino.h>
 #include <Ethernet.h>
@@ -30,7 +30,7 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
 #include "caethernetadapterutils.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
index e90a7b5..5e15d75 100644 (file)
@@ -18,7 +18,7 @@
 *
 ******************************************************************/
 
-#include "caethernetinterface.h"
+#include "caethernetinterface_singlethread.h"
 
 #include <Arduino.h>
 #include <Ethernet.h>
@@ -28,7 +28,7 @@
 #include <IPAddress.h>
 #include "logger.h"
 #include "caadapterutils.h"
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
 
 #define ETHERNET_MONITOR_TAG "ETHERNET_MONITOR"
 
index 67deff5..316c242 100644 (file)
@@ -18,7 +18,7 @@
 *
 ******************************************************************/
 
-#include "caethernetinterface.h"
+#include "caethernetinterface_singlethread.h"
 
 #include <Arduino.h>
 #include <Ethernet.h>
@@ -32,7 +32,7 @@
 #include "cacommon.h"
 #include "cainterface.h"
 #include "caadapterinterface.h"
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
 #include "caethernetadapterutils.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
@@ -197,6 +197,10 @@ void CAPacketReceivedCallback(const char *ipAddress, const uint32_t port,
 void CAArduinoCheckData()
 {
     void *data = malloc(COAP_MAX_PDU_SIZE);
+    if (NULL == data)
+    {
+        return;
+    }
     memset(data, 0, COAP_MAX_PDU_SIZE);
     int32_t dataLen = 0;
     uint8_t senderAddr[4] = { 0 };
index 61677f2..0975ae0 100644 (file)
 #include "caethernetinterface.h"
 #include "caqueueingthread.h"
 #include "caadapterutils.h"
+#ifdef __WITH_DTLS__
+#include "caadapternetdtls.h"
+#endif
 #include "umutex.h"
 #include "logger.h"
 #include "oic_malloc.h"
 
 /**
- * @def WIFI_ETHERNET_ADAPTER_TAG
+ * @def ETHERNET_ADAPTER_TAG
  * @brief Logging tag for module name
  */
 #define ETHERNET_ADAPTER_TAG "ETHERNET_ADAP"
  * @def CA_PORT
  * @brief Port to listen for incoming data
  */
-#define CA_PORT   5283
+#define CA_PORT   5683
+
+/**
+ * @def CA_PORT
+ * @brief Port to listen for incoming data
+ */
+#define CA_SECURE_PORT   5684
 
 /**
  * @def CA_MCAST_PORT
@@ -73,7 +82,7 @@ static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
  * @var gEthernetNetworkChangeCallback
  * @brief Network Changed Callback to CA
  */
-CANetworkChangeCallback gEthernetNetworkChangeCallback = NULL;
+static CANetworkChangeCallback gNetworkChangeCallback = NULL;
 
 /**
  * @var gIsMulticastServerStarted
@@ -93,6 +102,14 @@ static bool gStartUnicastServerRequested = false;
  */
 static int16_t gUnicastServerport = 0;
 
+#ifdef __WITH_DTLS__
+/**
+ * @var gSecureUnicastServerport
+ * @brief port number on which secure unicast server is running.
+ */
+static int16_t gSecureUnicastServerport = 0;
+#endif
+
 /**
  * @var gIsStartServerCalled
  * @brief Flag to check if server start requested by CA.
@@ -118,7 +135,11 @@ static void CAEthernetNotifyNetworkChange(const char *address, const int16_t por
 static void CAEthernetConnectionStateCB(const char *ipAddress,
                                         const CANetworkStatus_t status);
 static void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
-                                       const void *data, const uint32_t dataLength);
+        const void *data, const uint32_t dataLength, const CABool_t isSecured);
+#ifdef __WITH_DTLS__
+static uint32_t CAEthernetPacketSendCB(const char *ipAddress, const uint32_t port,
+                                 const void *data, const uint32_t dataLength);
+#endif
 static CAResult_t CAEthernetStopServers();
 static void CAEthernetSendDataThread(void *threadData);
 static CAEthernetData *CACreateEthernetData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
@@ -172,6 +193,8 @@ void CAEthernetDeinitializeQueueHandles()
 void CAEthernetNotifyNetworkChange(const char *address, const int16_t port,
                                    const CANetworkStatus_t status)
 {
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
     CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_ETHERNET, address);
     if (!localEndpoint)
     {
@@ -180,9 +203,9 @@ void CAEthernetNotifyNetworkChange(const char *address, const int16_t port,
     }
     localEndpoint->addressInfo.IP.port = port;
 
-    if (NULL != gEthernetNetworkChangeCallback)
+    if (NULL != gNetworkChangeCallback)
     {
-        gEthernetNetworkChangeCallback(localEndpoint, status);
+        gNetworkChangeCallback(localEndpoint, status);
     }
 
     CAAdapterFreeLocalEndpoint(localEndpoint);
@@ -194,13 +217,17 @@ void CAEthernetConnectionStateCB(const char *ipAddress,
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
 
     CAResult_t ret = CA_STATUS_FAILED;
-    /* If Ethernet is connected, then get the latest IP from the Ethernet Interface
-      * and start unicast and multicast servers if requested earlier */
+
+    /**
+     * If Ethernet is connected, then get the latest IP from the Ethernet Interface
+     * and start unicast and multicast servers if requested earlier
+     */
     if (CA_INTERFACE_UP == status)
     {
         int16_t port = CA_PORT;
         int32_t serverFd = -1;
-        /* Start Unicast server if requested earlier */
+
+        // Start Unicast server if requested earlier
         if (gStartUnicastServerRequested)
         {
             ret = CAEthernetStartUnicastServer("0.0.0.0", &port, false, false, &serverFd);
@@ -214,9 +241,25 @@ void CAEthernetConnectionStateCB(const char *ipAddress,
             {
                 OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to start Unicast server [%d]", ret);
             }
+
+#ifdef __WITH_DTLS__
+            port = CA_SECURE_PORT;
+            ret = CAEthernetStartUnicastServer("0.0.0.0", &port, false, true, &serverFd);
+            if (CA_STATUS_OK == ret)
+            {
+                OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Secure Unicast server started on %d", port);
+                CAEthernetSetSecureUnicastSocket(serverFd);
+                gSecureUnicastServerport = port;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to start secure Unicast server [%d]",
+                          ret);
+            }
+#endif
         }
 
-        /* Start Multicast server if requested earlier */
+        // Start Multicast server if requested earlier
         if (gStartMulticastServerRequested)
         {
             int16_t multicastPort = CA_MCAST_PORT;
@@ -235,42 +278,54 @@ void CAEthernetConnectionStateCB(const char *ipAddress,
             }
         }
 
-        char *ipAddress = NULL;
+        char *address = NULL;
         char *ifcName = NULL;
-        ret = CAEthernetGetInterfaceInfo(&ifcName, &ipAddress);
-        if (CA_STATUS_OK != ret)
+        ret = CAEthernetGetInterfaceInfo(&ifcName, &address);
+        if (CA_STATUS_OK != ret || NULL == address)
         {
             OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+            OICFree(address);
+            OICFree(ifcName);
             return;
         }
 
-        /* Notify network change to CA */
-        CAEthernetNotifyNetworkChange(ipAddress, port, status);
-        OICFree(ipAddress);
+        // Notify network change to CA
+        CAEthernetNotifyNetworkChange(address, port, status);
+        OICFree(address);
         OICFree(ifcName);
     }
     else
     {
         CAEthernetNotifyNetworkChange("", 0, status);
-        /* Stop both Unicast and Multicast servers */
-        ret = CAEthernetStopServers();
-        if (CA_STATUS_OK != ret)
-        {
-            OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Servers![%d]", ret);
-            return;
-        }
+
+        // Stop Unicast, Secured unicast and Multicast servers
+        CAEthernetStopServers();
     }
 
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
 }
 
+#ifdef __WITH_DTLS__
+uint32_t CAEthernetPacketSendCB(const char *ipAddress, const uint32_t port,
+                                 const void *data, const uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    uint32_t sentLength = CAEthernetSendData(ipAddress, port, data, dataLength, CA_FALSE, CA_TRUE);
+
+    OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Successfully sent %d of encripted data!", sentLength);
+
+    return sentLength;
+}
+#endif
+
 void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
-                                const void *data, const uint32_t dataLength)
+        const void *data, const uint32_t dataLength, const CABool_t isSecured)
 {
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
     OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Address: %s, port:%d, data:%s", ipAddress, port, data);
 
-    /* CA is freeing this memory */
+    // CA is freeing this memory
     CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_ETHERNET, ipAddress, NULL);
     if (NULL == endPoint)
     {
@@ -278,6 +333,7 @@ void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
         return;
     }
     endPoint->addressInfo.IP.port = port;
+    endPoint->isSecured = isSecured;
 
     void *buf = OICMalloc(dataLength + 1);
     if (NULL == buf)
@@ -292,6 +348,7 @@ void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
     {
         gNetworkPacketCallback(endPoint, buf, dataLength);
     }
+
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
 }
 
@@ -306,7 +363,7 @@ CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
     VERIFY_NON_NULL(handle, ETHERNET_ADAPTER_TAG, "thread pool handle");
 
     gThreadPool  = handle;
-    gEthernetNetworkChangeCallback = netCallback;
+    gNetworkChangeCallback = netCallback;
     gNetworkPacketCallback = networkPacketCallback;
 
     CAResult_t ret = CAEthernetInitializeNetworkMonitor(gThreadPool);
@@ -324,7 +381,12 @@ CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
         CATerminateEthernet();
         return ret;
     }
+
     CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCB);
+#ifdef __WITH_DTLS__
+    CAAdapterNetDtlsInit();
+    CADTLSSetAdapterCallbacks(CAEthernetPacketReceivedCB, CAEthernetPacketSendCB, DTLS_ETHERNET);
+#endif
 
     CAConnectivityHandler_t ethernetHandler;
     ethernetHandler.startAdapter = CAStartEthernet;
@@ -346,7 +408,6 @@ CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
     }
 
     OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "IntializeEthernet is Success");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -354,11 +415,20 @@ CAResult_t CAStartEthernet()
 {
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
 
-    /* Start monitoring Ethernet network */
+    // Start monitoring Ethernet network
     CAResult_t ret = CAEthernetStartNetworkMonitor();
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Start n/w monitor");
+        return ret;
+    }
+
+    // Start send queue thread
+    if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Start Send Data Thread");
+        CAStopEthernet();
+        return CA_STATUS_FAILED;
     }
 
     gStartUnicastServerRequested = true;
@@ -366,13 +436,21 @@ CAResult_t CAStartEthernet()
     if (false == retVal)
     {
         OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Ethernet is not Connected");
-        return ret;
+        return CA_STATUS_OK;
     }
 
+    char *ifcName;
+    char *ifcAdrs;
+    ret = CAEthernetGetInterfaceInfo(&ifcName, &ifcAdrs);
+    if(CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Failed to get ethernet interface info [%d]", ret);
+        return ret;
+    }
     int16_t unicastPort = CA_PORT;
     int32_t serverFd = 0;
     // Address is hardcoded as we are using Single Interface
-    ret = CAEthernetStartUnicastServer("0.0.0.0", &unicastPort, false, false, &serverFd);
+    ret = CAEthernetStartUnicastServer(ifcAdrs, &unicastPort, false, false, &serverFd);
     if (CA_STATUS_OK == ret)
     {
         OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
@@ -380,14 +458,19 @@ CAResult_t CAStartEthernet()
         gUnicastServerport = unicastPort;
     }
 
-    // Start send queue thread
-    if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
+#ifdef __WITH_DTLS__
+    // Address is hardcoded as we are using Single Interface
+    unicastPort = CA_SECURE_PORT;
+    ret = CAEthernetStartUnicastServer(ifcAdrs, &unicastPort, false, true, &serverFd);
+    if (CA_STATUS_OK == ret)
     {
-        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Start Send Data Thread");
-        CAStopEthernet();
-        return CA_STATUS_FAILED;
+        OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Secure Unicast server started on %d port", unicastPort);
+        CAEthernetSetSecureUnicastSocket(serverFd);
+        gSecureUnicastServerport = unicastPort;
     }
-
+#endif
+    OICFree(ifcName);
+    OICFree(ifcAdrs);
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
     return ret;
 }
@@ -412,17 +495,27 @@ CAResult_t CAStartEthernetListeningServer()
     {
         OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG,
                   "Failed to Start Multicast Server, Ethernet not Connected");
-        return CA_ADAPTER_NOT_ENABLED;
+        return CA_STATUS_OK;
     }
 
+    char *ifcName;
+    char *ifcAdrs;
+    ret = CAEthernetGetInterfaceInfo(&ifcName, &ifcAdrs);
+    if(CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Failed to get ethernet interface info [%d]", ret);
+        return ret;
+    }
     int32_t multicastFd = 0;
-    ret = CAEthernetStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &multicastFd);
+    ret = CAEthernetStartMulticastServer(ifcAdrs, CA_MULTICAST_IP, multicastPort, &multicastFd);
     if (CA_STATUS_OK == ret)
     {
         OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "Multicast Server is Started Successfully");
         gIsMulticastServerStarted = true;
     }
 
+    OICFree(ifcName);
+    OICFree(ifcAdrs);
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
     return ret;
 }
@@ -430,8 +523,6 @@ CAResult_t CAStartEthernetListeningServer()
 CAResult_t CAStartEthernetDiscoveryServer()
 {
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    /* Both listening and discovery server are same */
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
     return CAStartEthernetListeningServer();
 }
 
@@ -501,6 +592,7 @@ CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint3
     VERIFY_NON_NULL(info, ETHERNET_ADAPTER_TAG, "info");
     VERIFY_NON_NULL(size, ETHERNET_ADAPTER_TAG, "size");
 
+    CALocalConnectivity_t *netInfo = NULL;
     bool retVal = CAEthernetIsConnected();
     if (false == retVal)
     {
@@ -509,33 +601,63 @@ CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint3
         return CA_ADAPTER_NOT_ENABLED;
     }
 
+    int32_t netInfoSize = 1;
+#ifdef __WITH_DTLS__
+    if (gSecureUnicastServerport)
+    {
+        netInfoSize = 2;
+    }
+#endif
+    netInfo = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t) * netInfoSize);
+    VERIFY_NON_NULL_RET(netInfo, ETHERNET_ADAPTER_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
+    memset(netInfo, 0, sizeof(CALocalConnectivity_t) * netInfoSize);
+
     char *ipAddress = NULL;
     char *ifcName = NULL;
     CAResult_t ret = CAEthernetGetInterfaceInfo(&ifcName, &ipAddress);
-    if (CA_STATUS_OK != ret)
+    if (CA_STATUS_OK != ret || NULL == ipAddress)
     {
         OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+
+        OICFree(netInfo);
+        OICFree(ipAddress);
+        OICFree(ifcName);
         return ret;
     }
 
     // Create local endpoint using util function
-    (*info) = CAAdapterCreateLocalEndpoint(CA_ETHERNET, ipAddress);
-    if (NULL == (*info))
+    CALocalConnectivity_t *endpoint = CAAdapterCreateLocalEndpoint(CA_ETHERNET, ipAddress);
+    if (NULL == endpoint)
     {
         OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to create Local Endpoint!",
                   CA_MEMORY_ALLOC_FAILED);
+        OICFree(netInfo);
         OICFree(ipAddress);
         OICFree(ifcName);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    (*info)->addressInfo.IP.port = gUnicastServerport;
-    (*size) = 1;
+    // copy unciast server information
+    endpoint->isSecured = CA_FALSE;
+    endpoint->addressInfo.IP.port = gUnicastServerport;
+    memcpy(&netInfo[0], endpoint, sizeof(CALocalConnectivity_t));
+    *size = 1;
+#ifdef __WITH_DTLS__
+    // copy sevure unicast server information
+    if (gSecureUnicastServerport)
+    {
+        endpoint->isSecured = CA_TRUE;
+        endpoint->addressInfo.IP.port = gSecureUnicastServerport;
+        memcpy(&netInfo[1], endpoint, sizeof(CALocalConnectivity_t));
+        *size = 2;
+    }
+#endif
+    *info = netInfo;
 
     OICFree(ipAddress);
     OICFree(ifcName);
+    CAAdapterFreeLocalEndpoint(endpoint);
 
-    OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "GetEthernetInterfaceInformation success");
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -543,31 +665,37 @@ CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint3
 CAResult_t CAReadEthernetData()
 {
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CAEthernetStopServers()
 {
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    CAResult_t result = CAEthernetStopUnicastServer();
-    if (CA_STATUS_OK != result)
+
+    // Stop unicast server and set client socket accordingly
+    if (CA_STATUS_OK == CAEthernetStopUnicastServer())
     {
-        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Unicast Server![%d]", result);
-        return result;
+        CAEthernetSetUnicastSocket(-1);
+        gUnicastServerport = -1;
     }
-    CAEthernetSetUnicastSocket(-1);
-    gUnicastServerport = -1;
 
-    result = CAEthernetStopMulticastServer();
-    if (CA_STATUS_OK != result)
+#ifdef __WITH_DTLS__
+    // Stop secure unicast server and set client socket accordingly
+    if (CA_STATUS_OK == CAEthernetStopSecureUnicastServer())
     {
-        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Multicast Server![%d]", result);
-        return result;
+        CAEthernetSetSecureUnicastSocket(-1);
+        gSecureUnicastServerport = -1;
     }
-    gIsMulticastServerStarted = false;
+#endif
+
+    //Stop multicast server and set the state accordingly
+    if (CA_STATUS_OK == CAEthernetStopMulticastServer())
+    {
+        gIsMulticastServerStarted = false;
+    }
+
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return result;
+    return CA_STATUS_OK;
 }
 
 CAResult_t CAStopEthernet()
@@ -577,35 +705,42 @@ CAResult_t CAStopEthernet()
     gStartUnicastServerRequested = false;
     gStartMulticastServerRequested = false;
 
-    // Stop Ethernet network monitor
+    // Stop ethernet network monitor
     CAEthernetStopNetworkMonitor();
 
-    //Stop send queue thread
-    CAQueueingThreadStop(gSendQueueHandle);
-
-    // Stop unicast/multicast servers running
-    CAResult_t result = CAEthernetStopServers();
-    if (CA_STATUS_OK != result)
+    // Stop send queue thread
+    if (gSendQueueHandle && CA_FALSE == gSendQueueHandle->isStop)
     {
-        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Servers![%d]", result);
+        CAQueueingThreadStop(gSendQueueHandle);
     }
 
+    // Stop Unicast, Secured unicast and Multicast servers running
+    CAEthernetStopServers();
+
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return result;
+    return CA_STATUS_OK;
 }
 
 void CATerminateEthernet()
 {
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
 
+#ifdef __WITH_DTLS__
+    CADTLSSetAdapterCallbacks(NULL, NULL, DTLS_ETHERNET);
+    CAAdapterNetDtlsDeInit();
+#endif
+
+    // Stop ethernet adapter
+    CAStopEthernet();
+
+    // Terminate network monitor
     CAEthernetSetConnectionStateChangeCallback(NULL);
     CAEthernetTerminateNetworkMonitor();
-    OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "nw monitor terminated");
-    CAEthernetDeinitializeQueueHandles();
-    OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "sendQueue terminated");
 
+    // Terminate message queue handler
+    CAEthernetDeinitializeQueueHandles();
     CAEthernetSetPacketReceiveCallback(NULL);
-    OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "TerminateEthernet Success");
+
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
     return;
 }
@@ -617,29 +752,51 @@ void CAEthernetSendDataThread(void *threadData)
     CAEthernetData *ethernetData = (CAEthernetData *) threadData;
     if (!ethernetData)
     {
-        OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Invalid ethernetdata!");
+        OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Invalid ethernet data!");
         return;
     }
 
     if (NULL != ethernetData->remoteEndpoint)
     {
-        OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Send Unicast Data is called");
-        CAEthernetSendData(ethernetData->remoteEndpoint->addressInfo.IP.ipAddress,
-                           ethernetData->remoteEndpoint->addressInfo.IP.port, ethernetData->data,
-                           ethernetData->dataLen, false, false);
+        char *address = ethernetData->remoteEndpoint->addressInfo.IP.ipAddress;
+        uint32_t port = ethernetData->remoteEndpoint->addressInfo.IP.port;
+
+#ifdef __WITH_DTLS__
+        if (!ethernetData->remoteEndpoint->isSecured)
+        {
+            CAEthernetSendData(address, port, ethernetData->data, ethernetData->dataLen, false,
+                           ethernetData->remoteEndpoint->isSecured);
+        }
+        else
+        {
+            OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt called!");
+            uint8_t cacheFalg = 0;
+            CAResult_t  result = CAAdapterNetDtlsEncrypt(address, port, ethernetData->data,
+                                 ethernetData->dataLen, &cacheFalg, DTLS_ETHERNET);
+
+            if (CA_STATUS_OK != result)
+            {
+                OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt failed!");
+            }
+            OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt returned with cache[%d]",
+                      cacheFalg);
+        }
+#else
+        CAEthernetSendData(address, port, ethernetData->data, ethernetData->dataLen, false,
+                       ethernetData->remoteEndpoint->isSecured);
+#endif
     }
     else
     {
         OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Send Multicast Data is called");
-        CAEthernetSendData(CA_MULTICAST_IP, CA_MCAST_PORT, ethernetData->data, ethernetData->dataLen, true
-                           , false);
+        CAEthernetSendData(CA_MULTICAST_IP, CA_MCAST_PORT, ethernetData->data,
+                       ethernetData->dataLen, true, false);
     }
 
-    //Free Ethernet data
+    //Free ethernet data
     CAFreeEthernetData(ethernetData);
 
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return ;
 }
 
 CAEthernetData *CACreateEthernetData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
@@ -660,6 +817,7 @@ CAEthernetData *CACreateEthernetData(const CARemoteEndpoint_t *remoteEndpoint, v
         CAFreeEthernetData(ethernetData);
         return NULL;
     }
+
     memcpy(ethernetData->data, data, dataLength);
     ethernetData->dataLen = dataLength;
 
@@ -669,7 +827,9 @@ CAEthernetData *CACreateEthernetData(const CARemoteEndpoint_t *remoteEndpoint, v
 void CAFreeEthernetData(CAEthernetData *ethernetData)
 {
     if (!ethernetData)
+    {
         return;
+    }
 
     CAAdapterFreeRemoteEndpoint(ethernetData->remoteEndpoint);
     OICFree(ethernetData->data);
index 13282d9..573ff3d 100644 (file)
  *
  ******************************************************************/
 
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
 
 #include <stdio.h>
 #include <stdint.h>
 #include "caadapterutils.h"
 #include "logger.h"
 #include "oic_malloc.h"
-#include "caethernetinterface.h"
+#include "caethernetinterface_singlethread.h"
 
 /**
  * @def ETHERNET_ADAPTER_TAG
@@ -35,9 +35,9 @@
 
 /**
  * @def CA_PORT
- * @brief Port to listen for incoming data
+ * @brief Port to listen for incoming data. Port 5683 is as per COAP RFC.
  */
-#define CA_PORT   5283
+#define CA_PORT   5683
 
 #define CA_MCAST_PORT   5298
 
@@ -113,7 +113,7 @@ void CAEthernetNotifyNetworkChange(const char *address, const int16_t port,
     CAAdapterFreeLocalEndpoint(localEndpoint);
 }
 
-void CAEthernetConnectionStateCB(const char *ipAddress,
+void CAEthernetConnectionStateCB(const char *ipAddr,
                                  const CANetworkStatus_t status)
 {
     OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
@@ -415,9 +415,7 @@ CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint3
 
 CAResult_t CAReadEthernetData()
 {
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
     CAEthernetPullData();
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
index 3f16301..f74fc4a 100644 (file)
  */
 static int32_t gUnicastServerSocketDescClient = -1;
 
-void CAEthernetSetUnicastSocket(const int32_t socketFD)
-{
-    OIC_LOG(DEBUG, ETHERNET_CLIENT_TAG, "IN");
-
-    gUnicastServerSocketDescClient = socketFD;
-}
+#ifdef __WITH_DTLS__
+/**
+ * @var gUnicastServerSocketDescClient
+ * @brief socket descriptor for secure unicast server
+ */
+static int32_t gUnicastServerSecureSocketDescClient = -1;
+#endif
 
-uint32_t CAEthernetSendData(const char *remoteAddress, const uint32_t port,
-                            const void *data, const uint32_t dataLength,
-                            CABool_t isMulticast, CABool_t isSecure)
+static uint32_t CASendData(const char *remoteAddress, const uint32_t port,
+                           const void *data, const uint32_t dataLength, int32_t sockfd)
 {
     OIC_LOG(DEBUG, ETHERNET_CLIENT_TAG, "IN");
 
     VERIFY_NON_NULL_RET(remoteAddress, ETHERNET_CLIENT_TAG, "IP address is NULL", 0);
     VERIFY_NON_NULL_RET(data, ETHERNET_CLIENT_TAG, "data is NULL", 0);
 
-    if (dataLength == 0)
+    if (0 == dataLength)
     {
         OIC_LOG(ERROR, ETHERNET_CLIENT_TAG, "Data length is 0 !");
         return 0;
     }
 
-    if (0 > gUnicastServerSocketDescClient)
+    if (0 > sockfd)
     {
         OIC_LOG(ERROR, ETHERNET_CLIENT_TAG, "Unicast Server is not running !");
         return 0;
@@ -73,23 +73,58 @@ uint32_t CAEthernetSendData(const char *remoteAddress, const uint32_t port,
     destAddr.sin_port = htons(port);
 
     // Conversion from ASCII format to Network format
-    if (inet_aton(remoteAddress, &destAddr.sin_addr) == 0)
+    if (0 == inet_aton(remoteAddress, &destAddr.sin_addr))
     {
         OIC_LOG(ERROR, ETHERNET_CLIENT_TAG, "Failed to convert from ASCII to Network Address");
         return 0;
     }
 
-    int32_t sendDataLength = sendto(gUnicastServerSocketDescClient, data, dataLength, 0,
+    int32_t sendDataLength = sendto(sockfd, data, dataLength, 0,
                                     (struct sockaddr *)&destAddr, sizeof(destAddr));
-    if (sendDataLength == -1)
+    if (-1 == sendDataLength)
     {
         OIC_LOG_V(ERROR, ETHERNET_CLIENT_TAG, "Failed to Send Data, Error code: %s", strerror(errno));
         return 0;
     }
 
     OIC_LOG_V(INFO, ETHERNET_CLIENT_TAG, "Sending data is successful, sent bytes[%d]", sendDataLength);
-
-    OIC_LOG(DEBUG, ETHERNET_CLIENT_TAG, "OUT");
     return sendDataLength;
 }
 
+void CAEthernetSetUnicastSocket(const int32_t socketFD)
+{
+    OIC_LOG(DEBUG, ETHERNET_CLIENT_TAG, "IN");
+    gUnicastServerSocketDescClient = socketFD;
+}
+
+#ifdef __WITH_DTLS__
+void CAEthernetSetSecureUnicastSocket(const int32_t socketFD)
+{
+    OIC_LOG(DEBUG, ETHERNET_CLIENT_TAG, "IN");
+    gUnicastServerSecureSocketDescClient = socketFD;
+}
+#endif
+
+uint32_t CAEthernetSendData(const char *remoteAddress, const uint32_t port,
+                            const void *data, const uint32_t dataLength,
+                            CABool_t isMulticast, CABool_t isSecured)
+{
+    uint32_t len = 0;
+
+#ifdef __WITH_DTLS__
+    if (CA_TRUE == isSecured)
+    {
+        len  = CASendData(remoteAddress, port,
+                          data, dataLength, gUnicastServerSecureSocketDescClient);
+    }
+    else
+    {
+#endif
+        len =  CASendData(remoteAddress, port,
+                          data, dataLength, gUnicastServerSocketDescClient);
+#ifdef __WITH_DTLS__
+    }
+#endif
+    return len;
+}
+
index 0a83453..999bdb8 100644 (file)
 
 #include "caethernetinterface.h"
 
-#include <string.h>
+#include <sys/types.h>
 #include <ifaddrs.h>
+#include <net/if.h>
+#include <sys/socket.h>
 #include <netdb.h>
+#include <string.h>
+#include <errno.h>
 
 #include "caadapterutils.h"
 #include "umutex.h"
@@ -56,6 +60,12 @@ static char *gEthernetInterfaceName = NULL;
 static char *gEthernetIPAddress = NULL;
 
 /**
+ * @var gEthernetSubnetMask
+ * @brief  Maintains interface subnetmask.
+ */
+static char *gEthernetSubnetMask = NULL;
+
+/**
  * @var gThreadPool
  * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
  */
@@ -77,7 +87,8 @@ static CAEthernetConnectionStateChangeCallback gNetworkChangeCb = NULL;
  * @fn CAEthernetGetInterfaceInformation
  * @brief This methods gets local interface name and IP address information.
  */
-static void CAEthernetGetInterfaceInformation(char **interfaceName, char **ipAddress);
+static void CAEthernetGetInterfaceInformation(char **interfaceName, char **ipAddress,
+                                              char **subnetMask);
 
 static void CANetworkMonitorThread(void *threadData);
 
@@ -93,7 +104,7 @@ CAResult_t CAEthernetInitializeNetworkMonitor(const u_thread_pool_t threadPool)
     }
 
     u_mutex_lock(gEthernetNetInfoMutex);
-    CAEthernetGetInterfaceInformation(&gEthernetInterfaceName, &gEthernetIPAddress);
+    CAEthernetGetInterfaceInformation(&gEthernetInterfaceName, &gEthernetIPAddress, &gEthernetSubnetMask);
     u_mutex_unlock(gEthernetNetInfoMutex);
 
     nwConnectivityStatus = (gEthernetIPAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
@@ -139,8 +150,8 @@ CAResult_t CAEthernetStartNetworkMonitor(void)
 
     if (gStopNetworkMonitor)
     {
-        OIC_LOG_V(ERROR, ETHERNET_MONITOR_TAG, "Network Monitor Thread is already running!");
-        return CA_SERVER_STARTED_ALREADY;
+        OIC_LOG_V(ERROR, ETHERNET_MONITOR_TAG, "Stop network monitor requested");
+        return CA_STATUS_FAILED;
     }
 
     if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CANetworkMonitorThread,
@@ -160,8 +171,7 @@ CAResult_t CAEthernetStopNetworkMonitor(void)
 
     if (gStopNetworkMonitor)
     {
-        OIC_LOG(DEBUG, ETHERNET_MONITOR_TAG, "CAEthernetStopNetworkMonitor, already stopped");
-
+        OIC_LOG(DEBUG, ETHERNET_MONITOR_TAG, "CAEthernetStopNetworkMonitor, already stopped!");
         return CA_STATUS_OK;
     }
 
@@ -177,21 +187,43 @@ CAResult_t CAEthernetGetInterfaceInfo(char **interfaceName, char **ipAddress)
 {
     OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
 
-    u_mutex_lock(gEthernetNetInfoMutex);
+    VERIFY_NON_NULL(interfaceName, ETHERNET_MONITOR_TAG, "interface name");
+    VERIFY_NON_NULL(ipAddress, ETHERNET_MONITOR_TAG, "ip address");
 
-    if (gEthernetInterfaceName && strlen(gEthernetInterfaceName))
+    // Get the interface and ipaddress information from cache
+    u_mutex_lock(gEthernetNetInfoMutex);
+    if(gEthernetInterfaceName == NULL || gEthernetIPAddress == NULL)
     {
-        *interfaceName = (gEthernetInterfaceName) ? strndup(gEthernetInterfaceName,
-                         strlen(gEthernetInterfaceName)) :
-                         NULL;
+        OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "Network not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
-    if (gEthernetIPAddress && strlen(gEthernetIPAddress))
+    *interfaceName = (gEthernetInterfaceName) ? strndup(gEthernetInterfaceName,
+                               strlen(gEthernetInterfaceName)) : NULL;
+    *ipAddress = (gEthernetIPAddress) ? strndup(gEthernetIPAddress,strlen(gEthernetIPAddress))
+                               : NULL;
+
+    u_mutex_unlock(gEthernetNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetGetInterfaceSubnetMask(char **subnetMask)
+{
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
+
+    VERIFY_NON_NULL(subnetMask, ETHERNET_MONITOR_TAG, "subnet mask");
+
+    u_mutex_lock(gEthernetNetInfoMutex);
+    if(NULL == gEthernetSubnetMask)
     {
-        *ipAddress = (gEthernetIPAddress) ? strndup(gEthernetIPAddress, strlen(gEthernetIPAddress)) :
-                     NULL;
+        OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "There is no subnet mask information!");
+        return CA_STATUS_FAILED;
     }
 
+    *subnetMask = (gEthernetSubnetMask) ? strndup(gEthernetSubnetMask,strlen(gEthernetSubnetMask))
+                               : NULL;
     u_mutex_unlock(gEthernetNetInfoMutex);
 
     OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "OUT");
@@ -202,7 +234,7 @@ bool CAEthernetIsConnected(void)
 {
     OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
 
-    if (nwConnectivityStatus == CA_INTERFACE_DOWN)
+    if (CA_INTERFACE_DOWN == nwConnectivityStatus)
         return false;
 
     return true;
@@ -211,50 +243,81 @@ bool CAEthernetIsConnected(void)
 void CAEthernetSetConnectionStateChangeCallback(CAEthernetConnectionStateChangeCallback callback)
 {
     OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
-
     gNetworkChangeCb = callback;
 }
 
-void CAEthernetGetInterfaceInformation(char **interfaceName, char **ipAddress)
+void CAEthernetGetInterfaceInformation(char **interfaceName, char **ipAddress, char ** subnetMask)
 {
     struct ifaddrs *ifa = NULL;
     struct ifaddrs *ifp = NULL;
+    const char *matchName = "eth";
+
+    if (!interfaceName || !ipAddress || !subnetMask)
+    {
+        OIC_LOG(ERROR, ETHERNET_MONITOR_TAG, "Invalid input: interface/ipaddress holder is NULL!");
+        return;
+    }
 
-    if (getifaddrs(&ifp) < 0)
+    if (-1 == getifaddrs(&ifp))
     {
-        OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "Get network interface list error");
+        OIC_LOG_V(ERROR, ETHERNET_MONITOR_TAG, "Failed to get interface list!, Error code: %s",
+                          strerror(errno));
+        return;
     }
 
     for (ifa = ifp; ifa; ifa = ifa->ifa_next)
     {
-        char localIPAddress[CA_IPADDR_SIZE];
-        socklen_t len;
+        char interfaceAddress[CA_IPADDR_SIZE];
+        char interfaceSubnetMask[CA_IPADDR_SIZE] = {0};
+        socklen_t len = sizeof(struct sockaddr_in);
 
-        if (ifa->ifa_addr == NULL)
+        if (NULL == ifa->ifa_addr)
+        {
             continue;
+        }
 
-        if (ifa->ifa_addr->sa_family == AF_INET)
-            len = sizeof(struct sockaddr_in);
-        else if (ifa->ifa_addr->sa_family == AF_INET6)
-            continue;
-        else
+        int type = ifa->ifa_addr->sa_family;
+        if (ifa->ifa_flags & IFF_LOOPBACK
+            || !((ifa->ifa_flags & IFF_UP) && (ifa->ifa_flags & IFF_RUNNING)))
+        {
             continue;
+        }
 
-        if (getnameinfo(ifa->ifa_addr, len, localIPAddress,
-                        sizeof(localIPAddress), NULL, 0, NI_NUMERICHOST) < 0)
+        if (AF_INET != type)
         {
-            OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "Get IPAddress fail");
+            continue;
         }
 
-        // except loopback address
-        if (strcmp(localIPAddress, "127.0.0.1") == 0)
-            continue;
+        if (!strncasecmp(ifa->ifa_name,matchName,strlen(matchName)))
+        {
+            // get the interface ip address
+            if (0 != getnameinfo(ifa->ifa_addr, len, interfaceAddress,
+                            sizeof(interfaceAddress), NULL, 0, NI_NUMERICHOST))
+            {
+                    OIC_LOG_V(ERROR, ETHERNET_MONITOR_TAG, "Failed to get IPAddress, Error code: %s",
+                              strerror(errno));
+                    break;
+            }
 
-        // set interface name
-        *interfaceName = strndup(ifa->ifa_name, strlen(ifa->ifa_name));
+            // get the interface subnet mask
+            if (0 != getnameinfo(ifa->ifa_netmask, len, interfaceSubnetMask,
+                            sizeof(interfaceSubnetMask), NULL, 0, NI_NUMERICHOST))
+            {
+                    OIC_LOG_V(ERROR, ETHERNET_MONITOR_TAG, "Failed to get subnet mask, Error code: %s",
+                              strerror(errno));
+                    break;
+            }
 
-        // set local ip address
-        *ipAddress = strndup(localIPAddress, strlen(localIPAddress));
+            // set interface name
+            *interfaceName = strndup(ifa->ifa_name, strlen(ifa->ifa_name));
+
+            // set local ip address
+            *ipAddress = strndup(interfaceAddress, strlen(interfaceAddress));
+
+            // set subnet mask
+            *subnetMask = strndup(interfaceSubnetMask, strlen(interfaceSubnetMask));
+            break;
+        }
     }
 
     freeifaddrs(ifp);
@@ -262,19 +325,16 @@ void CAEthernetGetInterfaceInformation(char **interfaceName, char **ipAddress)
 
 void CANetworkMonitorThread(void *threadData)
 {
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
+
     while (!gStopNetworkMonitor)
     {
-        if (gStopNetworkMonitor)
-        {
-            OIC_LOG(DEBUG, ETHERNET_MONITOR_TAG, "Stop Network Monitor Thread is called");
-            break;
-        }
-
         // Get network information
         CANetworkStatus_t currNetworkStatus;
         char *interfaceName = NULL;
         char *ipAddress = NULL;
-        CAEthernetGetInterfaceInformation(&interfaceName, &ipAddress);
+        char *subnetMask = NULL;
+        CAEthernetGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
 
         // check current network status
         currNetworkStatus = (ipAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
@@ -289,8 +349,10 @@ void CANetworkMonitorThread(void *threadData)
 
             OICFree(gEthernetInterfaceName);
             OICFree(gEthernetIPAddress);
+            OICFree(gEthernetSubnetMask);
             gEthernetInterfaceName = (interfaceName) ? strndup(interfaceName, strlen(interfaceName)) : NULL;
             gEthernetIPAddress = (ipAddress) ? strndup(ipAddress, strlen(ipAddress)) : NULL;
+            gEthernetSubnetMask = (subnetMask) ? strndup(subnetMask, strlen(subnetMask)) : NULL;
 
             u_mutex_unlock(gEthernetNetInfoMutex);
 
@@ -301,5 +363,8 @@ void CANetworkMonitorThread(void *threadData)
         }
         OICFree(interfaceName);
         OICFree(ipAddress);
+        OICFree(subnetMask);
     }
+
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "OUT");
 }
index 50dcc83..7207d8c 100644 (file)
@@ -30,6 +30,9 @@
 
 #include "pdu.h"
 #include "caadapterutils.h"
+#ifdef __WITH_DTLS__
+#include "caadapternetdtls.h"
+#endif
 #include "umutex.h"
 
 /**
 #define CA_UDP_BIND_RETRY_COUNT 10
 
 /**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @def IPNAMESIZE
+ * @brief max length for ip
  */
-static int32_t gUnicastServerSocketDescriptor = -1;
+#define IPNAMESIZE 16
 
 /**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gUnicastServerSocketFD
+ * @brief Unicast server socket descriptor
  */
-static char *gUnicastServerAddress = NULL;
+static int32_t gUnicastServerSocketFD = -1;
 
 /**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gMutexUnicastServer
+ * @brief Mutex to synchronize unicast server
  */
-static int16_t gUnicastServerPort = -1;
-
-/**
- * @var gMutexUnicastServerSocketDescriptor
- * @brief Mutex for socket descriptor for unicast server
- */
-static u_mutex gMutexUnicastServerSocketDescriptor = NULL;
-/**
- * @var gMulticastServerSocketDescriptor
- * @brief socket descriptor for multicast server
- */
-static int32_t gMulticastServerSocketDescriptor = -1;
-
-/**
- * @var gMutexMulticastServerSocketDescriptor
- * @brief Mutex for socket descriptor for Multicast server
- */
-static u_mutex gMutexMulticastServerSocketDescriptor = NULL;
-
-/**
- * @var gThreadPool
- * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
- */
-static u_thread_pool_t gThreadPool = NULL;
-
-/**
- * @var gMReq
- * @brief ip_mreq structure passed to join a multicast group
- */
-static struct ip_mreq gMReq;
+static u_mutex gMutexUnicastServer = NULL;
 
 /**
  * @var gStopUnicast
@@ -98,10 +72,16 @@ static struct ip_mreq gMReq;
 static bool gStopUnicast = false;
 
 /**
- * @var gMutexStopUnicast
- * @brief Mutex for gStopUnicast
+ * @var gMulticastServerSocketFD
+ * @brief socket descriptor for multicast server
+ */
+static int32_t gMulticastServerSocketFD = -1;
+
+/**
+ * @var gMutexMulticastServer
+ * @brief Mutex to synchronize secure multicast server
  */
-static u_mutex gMutexStopUnicast = NULL;
+static u_mutex gMutexMulticastServer = NULL;
 
 /**
  * @var gStopMulticast
@@ -109,280 +89,221 @@ static u_mutex gMutexStopUnicast = NULL;
  */
 static bool gStopMulticast = false;
 
+#ifdef __WITH_DTLS__
 /**
- * @var gMutexStopMulticast
- * @brief Mutex for gStopMulticast
+ * @var gSecureUnicastServerSocketFD
+ * @brief Secure unicast server socket descriptor
  */
-static u_mutex gMutexStopMulticast = NULL;
+static int32_t gSecureUnicastServerSocketFD = -1;
 
 /**
- * @var gPacketReceivedCallback
- * @brief Callback for notifying the upper layer on receival data from remote OIC device
+ * @var gMutexSecureUnicastServer
+ * @brief Mutex to synchronize secure unicast server
  */
-static CAEthernetPacketReceivedCallback gPacketReceivedCallback = NULL;
+static u_mutex gMutexSecureUnicastServer = NULL;
 
 /**
- * @var gExceptionCallback
- * @brief Callback for notifying the upper layer when unicast/multicast server encounters exception
+ * @var gStopSecureUnicast
+ * @brief Flag to control the unicast secure data receive thread
  */
-static CAEthernetExceptionCallback gExceptionCallback = NULL;
+static bool gStopSecureUnicast = false;
+#endif
 
 /**
- * @var gUnicastRecvBuffer
- * @brief Character buffer used for receiving unicast data from network
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
  */
-static char gUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+static u_thread_pool_t gThreadPool = NULL;
 
 /**
- * @var gMulticastRecvBuffer
- * @brief Character buffer used for receiving multicast data from network
+ * @var gMulticastServerInterface
+ * @brief Local interface on which multicast server is running
  */
-static char gMulticastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+static char gMulticastServerInterface[IPNAMESIZE];
 
 /**
- * @fn CAEthernetServerCreateMutex
- * @brief Creates and initializes mutex
+ * @var gMulticastMemberReq
+ * @brief ip_mreq structure passed to join a multicast group
  */
-static CAResult_t CAEthernetServerCreateMutex(void);
+static struct ip_mreq gMulticastMemberReq;
 
 /**
- * @fn CAEthernetServerDestroyMutex
- * @brief Releases all created mutex
+ * @var gPacketReceivedCallback
+ * @brief Callback for notifying the upper layer on receival data from remote OIC device
  */
-static void CAEthernetServerDestroyMutex(void);
+static CAEthernetPacketReceivedCallback gPacketReceivedCallback = NULL;
 
 /**
- * @fn CAReceiveThreadForMulticast
- * @brief Handler thread for receiving data on multicast server
+ * @var gExceptionCallback
+ * @brief Callback for notifying the upper layer when unicast/multicast server encounters exception
  */
-static void *CAReceiveThreadForMulticast(void *data);
+static CAEthernetExceptionCallback gExceptionCallback = NULL;
 
 /**
- * @fn CAEthernetReceiveThreadForUnicast
- * @brief Handler thread for receiving data on unicast server
+ @brief Thread context information for unicast, multicast and secured unicast server
  */
-static void *CAEthernetReceiveThreadForUnicast(void *data);
-
-CAResult_t CAEthernetInitializeServer(const u_thread_pool_t threadPool)
-{
-    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
-
-    //Input validation
-    VERIFY_NON_NULL(threadPool, ETHERNET_SERVER_TAG, "Thread pool handle is NULL");
-
-    //Initialize mutex
-    if (CA_STATUS_OK != CAEthernetServerCreateMutex())
-    {
-        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create mutex!");
-        return CA_STATUS_FAILED;
-    }
-
-    gThreadPool = threadPool;
-
-    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CAEthernetTerminateServer(void)
+typedef struct
 {
-    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
-
-    gThreadPool = NULL;
+    bool *stopFlag;
+    int32_t socket_fd;
+    CAAdapterServerType_t type;
+}CAAdapterReceiveThreadContext_t;
 
-    //Destroy mutex
-    CAEthernetServerDestroyMutex();
-
-    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
-}
-
-CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
-        const int16_t multicastPort, int32_t *serverFD)
+static void CAReceiveHandler(void *data)
 {
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-    if (gMulticastServerSocketDescriptor != -1)
-    {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast Server is already running!");
-        return CA_SERVER_STARTED_ALREADY;
-    }
+    // Input validation
+    VERIFY_NON_NULL_VOID(data, ETHERNET_SERVER_TAG, "Invalid thread context");
 
-    VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "Local address is NULL");
-    VERIFY_NON_NULL(multicastAddress, ETHERNET_SERVER_TAG, "Multicast address is NULL");
+    CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)data;
+    fd_set reads;
+    struct timeval timeout;
+    char recvBuffer[COAP_MAX_PDU_SIZE] = {0};
 
-    if (0 >= multicastPort)
+    while (true != *(ctx->stopFlag))
     {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: Multicast port is invalid!");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    // Create a datagram socket on which to recv/send.
-    u_mutex_lock(gMutexStopMulticast);
-    gStopMulticast = false;
-    u_mutex_unlock(gMutexStopMulticast);
+        timeout.tv_sec = 1;
+        timeout.tv_usec = 0;
 
-    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+        FD_ZERO(&reads);
+        FD_SET(ctx->socket_fd, &reads);
 
-    // create a UDP socket
-    if ((gMulticastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
-    {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to Create Socket, Error code: %s",
-                  strerror(errno));
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_SOCKET_OPERATION_FAILED;
-    }
+        int32_t ret = select(ctx->socket_fd + 1, &reads, NULL, NULL, &timeout);
+        if (*(ctx->stopFlag) == true)
+        {
+            OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Stop request received for [%d] server", ctx->type);
+            break;
+        }
 
-    // Make the socket non-blocking
-    if (-1 == fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
-    {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
-                  strerror(errno));
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_STATUS_FAILED;
-    }
+        if (ret < 0)
+        {
+            OIC_LOG_V(FATAL, ETHERNET_SERVER_TAG, "select returned error %s", strerror(errno));
+            continue;
+        }
 
-    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket creation success");
+        if (!FD_ISSET(ctx->socket_fd, &reads))
+        {
+            continue;
+        }
 
-    int32_t setOptionOn = 1;
-    if (-1 == setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
-                         (char *) &setOptionOn,
-                         sizeof(setOptionOn)))
-    {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
-                  strerror(errno));
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_SOCKET_OPERATION_FAILED;
-    }
+        memset(recvBuffer, 0, sizeof(recvBuffer));
 
-    struct sockaddr_in sockAddr;
-    memset((char *) &sockAddr, 0, sizeof(sockAddr));
+        // Read data from socket
+        struct sockaddr_in srcSockAddress;
+        int32_t recvLen;
+        socklen_t srcAddressLen = sizeof(srcSockAddress);
+        if (-1 == (recvLen = recvfrom(ctx->socket_fd, recvBuffer,
+                                      sizeof(recvBuffer), 0, (struct sockaddr *) &srcSockAddress,
+                                      &srcAddressLen)))
+        {
+            OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "%s", strerror(errno));
+            continue;
+        }
+        else if (0 == recvLen)
+        {
+            OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Server socket shutdown [%d]!", ctx->type);
 
-    sockAddr.sin_family = AF_INET;
-    sockAddr.sin_port = htons(multicastPort);
-    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+            // Notify upper layer this exception
+            if (gExceptionCallback)
+            {
+                gExceptionCallback(ctx->type);
+            }
+            OICFree(ctx);
+            return;
+        }
 
-    //bind socket to multicast port
-    if (-1 == bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
-                   sizeof(sockAddr)))
-    {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to Bind Socket! Return Code[%d]",
-                  CA_SOCKET_OPERATION_FAILED);
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_SOCKET_OPERATION_FAILED;
-    }
+        const char *srcIPAddress = NULL;
+        int32_t srcPort = -1;
 
-    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket bind success");
+        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+        srcPort = ntohs(srcSockAddress.sin_port);
 
-    //Add membership to receiving socket (join group)
-    memset(&gMReq, 0, sizeof(struct ip_mreq));
-    gMReq.imr_interface.s_addr = htonl(INADDR_ANY);
-    inet_aton(multicastAddress, &gMReq.imr_multiaddr);
+        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Received packet from %s:%d\n",
+                  srcIPAddress, srcPort);
+        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+                  recvBuffer, recvLen);
 
-    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-                         (char *) &gMReq,
-                         sizeof(struct ip_mreq)))
-    {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
-                  strerror(errno));
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_SOCKET_OPERATION_FAILED;
-    }
+        char *netMask = NULL;
+        if (CA_STATUS_OK != CAEthernetGetInterfaceSubnetMask(&netMask))
+        {
+            OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to get ethernet subnet");
+            continue;
+        }
 
-    /**
-      * The task to listen to data from multicastcast 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.
-      */
-    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForMulticast,
-            (void *)NULL))
-    {
-        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+        if(!CAAdapterIsSameSubnet(gMulticastServerInterface, srcIPAddress, netMask))
+        {
+            OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Packet received from different subnet, Ignore!");
+            continue;
+        }
 
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_STATUS_FAILED;
+        OICFree(netMask);
+        switch(ctx->type)
+        {
+            case CA_UNICAST_SERVER:
+            case CA_MULTICAST_SERVER:
+                // Notify data to upper layer
+                if (gPacketReceivedCallback)
+                {
+                    gPacketReceivedCallback(srcIPAddress, srcPort, recvBuffer, recvLen, false);
+                }
+                break;
+#ifdef __WITH_DTLS__
+            case CA_SECURED_UNICAST_SERVER:
+                {
+                    CAResult_t ret = CAAdapterNetDtlsDecrypt(srcIPAddress,
+                                        srcPort,
+                                        (uint8_t *)recvBuffer,
+                                        recvLen, DTLS_ETHERNET);
+                    OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "CAAdapterNetDtlsDecrypt returns [%d]", ret);
+                }
+                break;
+#endif //__WITH_DTLS__
+            default:
+                // Should never occur
+                OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Invalid server type");
+                OICFree(ctx);
+                return;
+        }
     }
 
-    *serverFD = gMulticastServerSocketDescriptor;
-    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-
-    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "thread_pool_add_task done");
-    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast Server Started Successfully");
-
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
-    return CA_STATUS_OK;
-
 }
 
-CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
-                                        const bool forceStart, const bool secured, int32_t *serverFD)
+static CAResult_t CACreateSocket(int32_t* socketFD, const char *localIp, int16_t *port,
+                                 const bool forceStart)
 {
-    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
-
-    if (gUnicastServerSocketDescriptor != -1)
-    {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server is Started Already! Return Code[%d]",
-                  CA_SERVER_STARTED_ALREADY);
-        return CA_SERVER_STARTED_ALREADY;
-    }
-
-    VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "Invalid argument : localAddress is NULL");
-    VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "Invalid argument : port is NULL");
-
-    if (*port < 0)
-    {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: port is invalid!");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    u_mutex_lock(gMutexStopUnicast);
-    gStopUnicast = false;
-    u_mutex_unlock(gMutexStopUnicast);
-
-    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
+    int32_t sock = -1;
     // Create a UDP socket
-    if ((gUnicastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+    if (-1 == (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
     {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to create Socket, Error code: %s",
                   strerror(errno));
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
-        return CA_SOCKET_OPERATION_FAILED;
+        return CA_STATUS_FAILED;
     }
 
     // Make the socket non-blocking
-    if (-1 == fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+    if (-1 == fcntl(sock, F_SETFL, O_NONBLOCK))
     {
         OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
                   strerror(errno));
-        close(gUnicastServerSocketDescriptor);
-        gUnicastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+
+        close(sock);
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket creation success");
-
     if (true == forceStart)
     {
         int32_t setOptionOn = 1;
-        if (-1 == setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+        if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
                              (char *) &setOptionOn,
                              sizeof(setOptionOn)))
         {
             OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
                       strerror(errno));
-            close(gUnicastServerSocketDescriptor);
-            gUnicastServerSocketDescriptor = -1;
-            u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
-            return CA_SOCKET_OPERATION_FAILED;
+
+            close(sock);
+            return CA_STATUS_FAILED;
         }
     }
 
@@ -393,18 +314,24 @@ CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
     memset((char *) &sockAddr, 0, sizeof(sockAddr));
     sockAddr.sin_family = AF_INET;
     sockAddr.sin_port = htons(serverPort);
-    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    if(localIp)
+    {
+        sockAddr.sin_addr.s_addr = inet_addr(localIp);
+    }
+    else
+    {
+        sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    }
 
-    //Trying for bind in a loop
     int16_t i;
     for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
     {
-        if (-1 == bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+        if (-1 == bind(sock, (struct sockaddr *) &sockAddr,
                        sizeof(sockAddr)))
         {
             if (false == forceStart)
             {
-                OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
+                OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
                           strerror(errno));
 
                 //Set the port to next one
@@ -426,22 +353,45 @@ CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
 
     if (false == isBound)
     {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind Socket! Return code[%d]",
-                  CA_SOCKET_OPERATION_FAILED);
-        close(gUnicastServerSocketDescriptor);
-        gUnicastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
-        return CA_SOCKET_OPERATION_FAILED;
+        close(sock);
+        return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket bind success");
+    *port = serverPort;
+    *socketFD = sock;
+    return CA_STATUS_OK;
+}
+
+static CAResult_t CACloseSocket(int32_t *socketFD)
+{
+    if (-1 == *socketFD)
+    {
+        OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Server not running");
+        return CA_SERVER_NOT_STARTED;
+    }
 
-    socklen_t len = 0;
-    char *serverAddress = NULL;
-    if (-1 != getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len))
+    // close the socket
+    if (-1 == close(*socketFD))
     {
-        serverPort = ntohs(sockAddr.sin_port);
-        serverAddress = inet_ntoa(sockAddr.sin_addr);
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
+                  strerror(errno));
+        return CA_STATUS_FAILED;
+    }
+
+    *socketFD = -1;
+    return CA_STATUS_OK;
+}
+
+static CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port,
+                                       const bool forceStart, bool isSecured, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    CAResult_t ret = CACreateSocket(serverFD, localAddress, port, forceStart);
+    if(CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create unicast socket");
+        return ret;
     }
 
     /**
@@ -449,378 +399,392 @@ CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
       * 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.
       */
-    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAEthernetReceiveThreadForUnicast,
-            (void *) NULL))
+    CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
+                                            OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
+    if(!ctx)
     {
-        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Out of memory!");
+        close(*serverFD);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
 
-        close(gUnicastServerSocketDescriptor);
-        gUnicastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+    ctx->stopFlag = &gStopUnicast;
+    ctx->socket_fd = *serverFD;
+    ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER:CA_UNICAST_SERVER;
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, CAReceiveHandler, (void *)ctx))
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create read thread!");
+        OICFree((void *)ctx);
+        close(*serverFD);
         return CA_STATUS_FAILED;
     }
 
-    //Free the server address previously stored
-    OICFree(gUnicastServerAddress);
-    gUnicastServerAddress = NULL;
-    gUnicastServerPort = serverPort;
-    gUnicastServerAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) :
-                            NULL;
-    *port = serverPort;
-    *serverFD = gUnicastServerSocketDescriptor;
-    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
-
-    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Unicast Server Started Successfully");
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CAEthernetStopMulticastServer(void)
+static void CAEthernetServerDestroyMutex(void)
 {
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
-
-    if (gMulticastServerSocketDescriptor == -1)
+    if (gMutexUnicastServer)
     {
-        OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast Server is not yet Started");
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_SERVER_NOT_STARTED;
+        u_mutex_free(gMutexUnicastServer);
+        gMutexUnicastServer = NULL;
     }
 
-    u_mutex_lock(gMutexStopMulticast);
-    gStopMulticast = true;
-
-    // leave the group after you are done
-    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
-                         (char *)&gMReq,
-                         sizeof(struct ip_mreq)))
+#ifdef __WITH_DTLS__
+    if (gMutexSecureUnicastServer)
     {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "cannot leave multicast group, Error code: %s\n",
-                  strerror(errno));
+        u_mutex_free(gMutexSecureUnicastServer);
+        gMutexSecureUnicastServer = NULL;
     }
+#endif
 
-    // close the socket
-    if (-1 == close(gMulticastServerSocketDescriptor))
+    if (gMutexMulticastServer)
     {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast Server socket close failed, Error code: %s\n",
-                  strerror(errno));
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        u_mutex_unlock(gMutexStopMulticast);
-        return CA_SOCKET_OPERATION_FAILED;
+        u_mutex_free(gMutexMulticastServer);
+        gMutexMulticastServer = NULL;
     }
 
-    u_mutex_unlock(gMutexStopMulticast);
-
-    gMulticastServerSocketDescriptor = -1;
-    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-
-    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast Server Stopped Successfully");
-
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
-    return CA_STATUS_OK;
-
 }
 
-CAResult_t CAEthernetStopUnicastServer()
+static CAResult_t CAEthernetServerCreateMutex(void)
 {
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
-    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
 
-    if (gUnicastServerSocketDescriptor == -1)
+    gMutexUnicastServer = u_mutex_new();
+    if (!gMutexUnicastServer)
     {
-        OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Unicast Server is not yet Started");
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
-        return CA_SERVER_NOT_STARTED;
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
+        return CA_STATUS_FAILED;
     }
-    u_mutex_lock(gMutexStopUnicast);
-    gStopUnicast = true;
 
-    // close the socket
-    if (-1 == close(gUnicastServerSocketDescriptor))
+#ifdef __WITH_DTLS__
+    gMutexSecureUnicastServer = u_mutex_new();
+    if (!gMutexSecureUnicastServer)
     {
-        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server socket close failed, Error code: %s\n",
-                  strerror(errno));
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
-        u_mutex_unlock(gMutexStopUnicast);
-        return CA_SOCKET_OPERATION_FAILED;
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
+
+        CAEthernetServerDestroyMutex();
+        return CA_STATUS_FAILED;
     }
+#endif
 
-    u_mutex_unlock(gMutexStopUnicast);
-    gUnicastServerSocketDescriptor = -1;
+    gMutexMulticastServer = u_mutex_new();
+    if (!gMutexMulticastServer)
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
 
-    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        CAEthernetServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
 
-    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Unicast Server Stopped Successfully");
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CAEthernetGetUnicastServerInfo(const bool secure, char **ipAddress, int16_t *port,
-                                          int32_t *serverFD)
+CAResult_t CAEthernetInitializeServer(const u_thread_pool_t threadPool)
 {
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-    //Input validation
-    VERIFY_NON_NULL(ipAddress, ETHERNET_SERVER_TAG, "ipAddress holder is NULL");
-    VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "port holder is NULL");
-    VERIFY_NON_NULL(serverFD, ETHERNET_SERVER_TAG, "serverID holder is NULL");
+    // Input validation
+    VERIFY_NON_NULL(threadPool, ETHERNET_SERVER_TAG, "Thread pool handle is NULL");
 
-    *ipAddress = gUnicastServerAddress;
-    *port = gUnicastServerPort;
-    *serverFD = gUnicastServerSocketDescriptor;
+    // Initialize mutex
+    if (CA_STATUS_OK != CAEthernetServerCreateMutex())
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create mutex!");
+        return CA_STATUS_FAILED;
+    }
+
+    gThreadPool = threadPool;
 
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback)
+void CAEthernetTerminateServer(void)
 {
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-    gPacketReceivedCallback = callback;
-}
+    gThreadPool = NULL;
 
-void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback)
-{
-    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+    // Destroy mutex
+    CAEthernetServerDestroyMutex();
 
-    gExceptionCallback = callback;
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
 }
 
-CAResult_t CAEthernetServerCreateMutex(void)
+CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
+                                        const bool forceStart, const bool isSecured,
+                                        int32_t *serverFD)
 {
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-    gMutexUnicastServerSocketDescriptor = u_mutex_new();
-    if (!gMutexUnicastServerSocketDescriptor)
+    // Input validation
+    VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "localAddress");
+    VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "port");
+    VERIFY_NON_NULL(serverFD, ETHERNET_SERVER_TAG, "server socket FD");
+
+    if (0 >= *port)
     {
-        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
-        return CA_STATUS_FAILED;
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
     }
 
-    gMutexMulticastServerSocketDescriptor = u_mutex_new();
-    if (!gMutexMulticastServerSocketDescriptor)
+    *serverFD = -1;
+    if (CA_FALSE == isSecured)
     {
-        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
+        u_mutex_lock(gMutexUnicastServer);
+        if (-1 != gUnicastServerSocketFD)
+        {
+            OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server is Started Already!",
+                      CA_SERVER_STARTED_ALREADY);
 
-        CAEthernetServerDestroyMutex();
-        return CA_STATUS_FAILED;
-    }
+            *serverFD = gUnicastServerSocketFD;
+            u_mutex_unlock(gMutexUnicastServer);
+            return CA_SERVER_STARTED_ALREADY;
+        }
 
-    gMutexStopUnicast = u_mutex_new();
-    if (!gMutexStopUnicast)
-    {
-        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
+        gStopUnicast = false;
+        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
+                                                 &gUnicastServerSocketFD))
+        {
+            OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to start unicast server!");
+            gUnicastServerSocketFD = -1;
+            u_mutex_unlock(gMutexUnicastServer);
+            return CA_STATUS_FAILED;
+        }
 
-        CAEthernetServerDestroyMutex();
-        return CA_STATUS_FAILED;
+        *serverFD = gUnicastServerSocketFD;
+        u_mutex_unlock(gMutexUnicastServer);
     }
-
-    gMutexStopMulticast = u_mutex_new();
-    if (!gMutexStopMulticast)
+#ifdef __WITH_DTLS__
+    else // Start unicast server for secured communication
     {
-        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
+        u_mutex_lock(gMutexSecureUnicastServer);
+        if (-1 != gSecureUnicastServerSocketFD)
+        {
+            OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server is Started Already!",
+                      CA_SERVER_STARTED_ALREADY);
 
-        CAEthernetServerDestroyMutex();
-        return CA_STATUS_FAILED;
-    }
+            *serverFD = gSecureUnicastServerSocketFD;
+            u_mutex_unlock(gMutexSecureUnicastServer);
+            return CA_SERVER_STARTED_ALREADY;
+        }
 
+        gStopSecureUnicast = false;
+        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
+                                                 &gSecureUnicastServerSocketFD))
+        {
+            OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to start unicast server!");
+            gSecureUnicastServerSocketFD = -1;
+            u_mutex_unlock(gMutexSecureUnicastServer);
+            return CA_STATUS_FAILED;
+        }
+
+        *serverFD = gSecureUnicastServerSocketFD;
+        u_mutex_unlock(gMutexSecureUnicastServer);
+    }
+#endif
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-void CAEthernetServerDestroyMutex(void)
+CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
+        const int16_t multicastPort, int32_t *serverFD)
 {
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-    if (gMutexUnicastServerSocketDescriptor)
-    {
-        u_mutex_free(gMutexUnicastServerSocketDescriptor);
-        gMutexUnicastServerSocketDescriptor = NULL;
-    }
+    // Input validation
+    VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "Local address is NULL");
+    VERIFY_NON_NULL(multicastAddress, ETHERNET_SERVER_TAG, "Multicast address is NULL");
 
-    if (gMutexMulticastServerSocketDescriptor)
+    int16_t port = multicastPort;
+    if (0 >= port)
     {
-        u_mutex_free(gMutexMulticastServerSocketDescriptor);
-        gMutexMulticastServerSocketDescriptor = NULL;
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: Multicast port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
     }
 
-    if (gMutexStopUnicast)
+    u_mutex_lock(gMutexMulticastServer);
+
+    if (gMulticastServerSocketFD != -1)
     {
-        u_mutex_free(gMutexStopUnicast);
-        gMutexStopUnicast = NULL;
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast Server is already running!");
+        u_mutex_unlock(gMutexMulticastServer);
+        return CA_SERVER_STARTED_ALREADY;
     }
 
-    if (gMutexStopMulticast)
+    CAResult_t ret = CACreateSocket(&gMulticastServerSocketFD, multicastAddress, &port, true);
+    if(ret != CA_STATUS_OK)
     {
-        u_mutex_free(gMutexStopMulticast);
-        gMutexStopMulticast = NULL;
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create multicast socket");
+        u_mutex_unlock(gMutexMulticastServer);
+        return ret;
     }
 
-    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
-}
+    // Add membership to receiving socket (join group)
+    memset(&gMulticastMemberReq, 0, sizeof(struct ip_mreq));
+    gMulticastMemberReq.imr_interface.s_addr = inet_addr(localAddress);
+    inet_aton(multicastAddress, &gMulticastMemberReq.imr_multiaddr);
 
-void *CAEthernetReceiveThreadForUnicast(void *data)
-{
-    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
-
-    fd_set reads;
-    struct timeval timeout;
+    if (-1 == setsockopt(gMulticastServerSocketFD, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                         (char *) &gMulticastMemberReq,
+                         sizeof(struct ip_mreq)))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
+                  strerror(errno));
+        close(gMulticastServerSocketFD);
+        gMulticastServerSocketFD = -1;
+        u_mutex_unlock(gMutexMulticastServer);
+        return CA_STATUS_FAILED;
+    }
 
-    //keep listening for data
-    while (!gStopUnicast)
+    /**
+      * The task to listen to data from multicastcast 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(DEBUG, ETHERNET_SERVER_TAG, "Waiting for data..");
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Out of memory!");
+        close(gMulticastServerSocketFD);
+        gMulticastServerSocketFD = -1;
+        return CA_MEMORY_ALLOC_FAILED;
+    }
 
-        timeout.tv_sec = 1;
-        timeout.tv_usec = 0;
+    ctx->stopFlag = &gStopMulticast;
+    ctx->socket_fd = gMulticastServerSocketFD;
+    ctx->type = CA_MULTICAST_SERVER;
 
-        FD_ZERO(&reads);
-        FD_SET(gUnicastServerSocketDescriptor, &reads);
+    gStopMulticast = false;
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, CAReceiveHandler, (void *)ctx))
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "thread_pool_add_task failed!");
 
-        int32_t ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
-        if (gStopUnicast)
-        {
-            OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Stop Unicast is called");
-            break;
-        }
-        if (ret < 0)
-        {
-            OIC_LOG_V(FATAL, ETHERNET_SERVER_TAG, "select returned error %s", strerror(errno));
-            continue;
-        }
-        if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads))
-        {
-            //OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "No data to read");
-            continue;
-        }
+        close(gMulticastServerSocketFD);
+        gMulticastServerSocketFD = -1;
+        gStopMulticast = true;
+        u_mutex_unlock(gMutexMulticastServer);
+        return CA_STATUS_FAILED;
+    }
 
-        memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+    *serverFD = gMulticastServerSocketFD;
+    strncpy(gMulticastServerInterface, localAddress, sizeof(gMulticastServerInterface));
+    u_mutex_unlock(gMutexMulticastServer);
 
-        //Read data from socket
-        struct sockaddr_in srcSockAddress;
-        int32_t recvLen;
-        socklen_t srcAddressLen = sizeof(srcSockAddress);
-        if (-1 == (recvLen = recvfrom(gUnicastServerSocketDescriptor, gUnicastRecvBuffer,
-                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
-                                      &srcAddressLen)))
-        {
-            OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "%s", strerror(errno));
-            continue;
-        }
-        else if (0 == recvLen)
-        {
-            OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Unicast server socket is shutdown !");
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
 
-            //Notify upper layer this exception
-            if (gExceptionCallback)
-            {
-                gExceptionCallback(CA_UNICAST_SERVER);
-            }
-            return NULL;
-        }
+CAResult_t CAEthernetStopUnicastServer()
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-        const char *srcIPAddress = NULL;
-        int32_t srcPort = -1;
+    u_mutex_lock(gMutexUnicastServer);
+    gStopUnicast = true;
+    CAResult_t ret = CACloseSocket(&gUnicastServerSocketFD);
+    u_mutex_unlock(gMutexUnicastServer);
 
-        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
-        srcPort = ntohs(srcSockAddress.sin_port);
+    OIC_LOG_V(INFO, ETHERNET_SERVER_TAG, "Unicast server stopped [%d]", ret);
+    return ret;
+}
 
-        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Received packet from %s:%d\n",
-                  srcIPAddress, srcPort);
-        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
-                  gUnicastRecvBuffer, recvLen);
+#ifdef __WITH_DTLS__
+CAResult_t CAEthernetStopSecureUnicastServer()
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-        //Notify data to upper layer
-        if (gPacketReceivedCallback)
-        {
-            gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen);
-        }
-    }
+    u_mutex_lock(gMutexSecureUnicastServer);
+    gStopSecureUnicast = true;
+    CAResult_t ret = CACloseSocket(&gSecureUnicastServerSocketFD);
+    u_mutex_unlock(gMutexSecureUnicastServer);
 
-    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
-    return NULL;
+    OIC_LOG_V(INFO, ETHERNET_SERVER_TAG, "Secured unicast server stopped [%d]", ret);
+    return ret;
 }
+#endif
 
-void *CAReceiveThreadForMulticast(void *data)
+CAResult_t CAEthernetStopMulticastServer(void)
 {
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-    fd_set reads;
-    struct timeval timeout;
+    u_mutex_lock(gMutexMulticastServer);
 
-    //keep listening for data
-    while (!gStopMulticast)
+    if (gMulticastServerSocketFD == -1)
     {
-        timeout.tv_sec = 1;
-        timeout.tv_usec = 0;
-
-        FD_ZERO(&reads);
-        FD_SET(gMulticastServerSocketDescriptor, &reads);
+        OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast server is not yet started");
+        u_mutex_unlock(gMutexMulticastServer);
+        return CA_SERVER_NOT_STARTED;
+    }
 
-        int32_t ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
-        if (gStopMulticast)
-        {
-            OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Stop Multicast is called");
-            break;
-        }
-        if ( ret < 0)
-        {
-            OIC_LOG_V(FATAL, ETHERNET_SERVER_TAG, "select returned error %s", strerror(errno));
-            continue;
-        }
-        if (!FD_ISSET(gMulticastServerSocketDescriptor, &reads))
-        {
-            continue;
-        }
+    gStopMulticast = true;
 
-        memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+    // leave the group after you are done
+    if (-1 == setsockopt(gMulticastServerSocketFD, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+                         (char *)&gMulticastMemberReq,
+                         sizeof(struct ip_mreq)))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to leave multicast group, Error code: %s\n",
+                  strerror(errno));
+    }
 
-        //Read data from socket
-        struct sockaddr_in srcSockAddress;
-        int32_t recvLen;
-        socklen_t srcAddressLen = sizeof(srcSockAddress);
-        if (-1 == (recvLen = recvfrom(gMulticastServerSocketDescriptor, gMulticastRecvBuffer,
-                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
-                                      &srcAddressLen)))
-        {
-            OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "%s", strerror(errno));
-            continue;
-        }
-        else if (0 == recvLen)
-        {
-            OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast socket is shutdown, returning from \
-                thread\n");
+    CAResult_t ret = CACloseSocket(&gMulticastServerSocketFD);
+    u_mutex_unlock(gMutexMulticastServer);
 
-            //Notify upper layer this exception
-            if (gExceptionCallback)
-            {
-                gExceptionCallback(CA_MULTICAST_SERVER);
-            }
-            return NULL;
-        }
+    OIC_LOG_V(INFO, ETHERNET_SERVER_TAG, "Multicast server stopped [%d]", ret);
+    return ret;
+}
 
-        const char *srcIPAddress = NULL;
-        int32_t srcPort = -1;
+CAResult_t CAEthernetGetUnicastServerInfo(const bool isSecured, char **ipAddress, int16_t *port,
+                                          int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
 
-        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
-        srcPort = ntohs(srcSockAddress.sin_port);
+    // Input validation
+    VERIFY_NON_NULL(ipAddress, ETHERNET_SERVER_TAG, "IP address");
+    VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "Port");
+    VERIFY_NON_NULL(serverFD, ETHERNET_SERVER_TAG, "Server ID");
 
-        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Received packet from %s:%d\n",
-                  srcIPAddress, srcPort);
-        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
-                  gMulticastRecvBuffer, recvLen);
+    struct sockaddr_in sockAddr;
+    socklen_t len = sizeof(struct sockaddr_in);
+    if (-1 == getsockname(gUnicastServerSocketFD, (struct sockaddr *)&sockAddr, &len))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed in getsockname [%s]!", strerror(errno));
+        return CA_STATUS_FAILED;
+    }
 
 
-        //Notify data to upper layer
-        if (gPacketReceivedCallback)
-        {
-            gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen);
-        }
-    }
+    const char *serverAddress = inet_ntoa(sockAddr.sin_addr);
+    *ipAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) : NULL;
+    *port = ntohs(sockAddr.sin_port);
+#ifdef __WITH_DTLS__
+    *serverFD = (CA_TRUE == isSecured) ? gSecureUnicastServerSocketFD : gUnicastServerSocketFD;
+#else
+    *serverFD = gUnicastServerSocketFD;
+#endif
 
     OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
-    return NULL;
+    return CA_STATUS_OK;
 }
 
+void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+    gPacketReceivedCallback = callback;
+}
 
+void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+    gExceptionCallback = callback;
+}
index 15439e4..30e11d9 100644 (file)
@@ -17,7 +17,7 @@
 * limitations under the License.
 *
 ******************************************************************/
-#include "cawifiinterface.h"
+#include "cawifiinterface_singlethread.h"
 
 #include <Arduino.h>
 #include <WiFi.h>
@@ -31,7 +31,7 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#include "cawifiadapter.h"
+#include "cawifiadapter_singlethread.h"
 #include "caadapterutils.h"
 
 /// This is the max buffer size between Arduino and WiFi Shield
index 6256e83..e2d313e 100644 (file)
@@ -18,7 +18,7 @@
 *
 ******************************************************************/
 
-#include "cawifiinterface.h"
+#include "cawifiinterface_singlethread.h"
 
 #include <Arduino.h>
 #include <WiFi.h>
@@ -29,7 +29,7 @@
 #include <IPAddress.h>
 #include "logger.h"
 #include "caadapterutils.h"
-#include "cawifiadapter.h"
+#include "cawifiadapter_singlethread.h"
 
 #define WIFI_MONITOR_TAG "WIFI_MONITOR"
 
index 59906b0..951af15 100644 (file)
@@ -18,7 +18,7 @@
 *
 ******************************************************************/
 
-#include "cawifiinterface.h"
+#include "cawifiinterface_singlethread.h"
 
 #include <Arduino.h>
 #include <WiFi.h>
@@ -33,7 +33,7 @@
 #include "cacommon.h"
 #include "cainterface.h"
 #include "caadapterinterface.h"
-#include "cawifiadapter.h"
+#include "cawifiadapter_singlethread.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
 
@@ -208,6 +208,10 @@ void CAArduinoCheckData()
 {
     OIC_LOG(DEBUG, MOD_NAME, "CAACD Being called");
     char *data = (char *)OICMalloc(COAP_MAX_PDU_SIZE);
+    if (NULL == data)
+    {
+        return;
+    }
     int32_t dataLen = 0;
     char addr[IPNAMESIZE] = {0};
     uint16_t senderPort = 0;
index ebba6be..9c5fd96 100644 (file)
 #include "oic_malloc.h"
 
 /**
- * @def WIFI_ETHERNET_ADAPTER_TAG
+ * @def WIFI_ADAPTER_TAG
  * @brief Logging tag for module name
  */
 #define WIFI_ADAPTER_TAG "WIFI_ADAP"
 
 /**
  * @def CA_PORT
- * @brief Port to listen for incoming data
+ * @brief Port to listen for incoming data. port 5683 is as per COAP RFC.
  */
 #define CA_PORT   5683
 
@@ -82,7 +82,7 @@ static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
  * @var gNetworkChangeCb
  * @brief Network Changed Callback to CA
  */
-CANetworkChangeCallback gNetworkChangeCallback = NULL;
+static CANetworkChangeCallback gNetworkChangeCallback = NULL;
 
 /**
  * @var gIsMulticastServerStarted
@@ -109,6 +109,7 @@ static int16_t gUnicastServerport = 0;
  */
 static int16_t gSecureUnicastServerport = 0;
 #endif
+
 /**
  * @var gIsStartServerCalled
  * @brief Flag to check if server start requested by CA.
@@ -136,6 +137,10 @@ static void CAWiFiConnectionStateCB(const char *ipAddress,
 static void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
                                    const void *data, const uint32_t dataLength,
                                    const CABool_t isSecured);
+#ifdef __WITH_DTLS__
+static uint32_t CAWiFiPacketSendCB(const char *ipAddress, const uint32_t port,
+        const void *data, const uint32_t dataLength);
+#endif
 static CAResult_t CAWiFiStopServers();
 static void CAWiFiSendDataThread(void *threadData);
 static CAWiFiData *CACreateWiFiData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
@@ -189,6 +194,8 @@ void CAWiFiDeinitializeQueueHandles()
 void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
                                const CANetworkStatus_t status)
 {
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
     CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, address);
     if (!localEndpoint)
     {
@@ -212,10 +219,10 @@ void CAWiFiConnectionStateCB(const char *ipAddress,
 
     CAResult_t ret = CA_STATUS_FAILED;
 
-    /* *
-        * If Wifi is connected, then get the latest IP from the WIFI Interface
-        * and start unicast and multicast servers if requested earlier
-        */
+    /**
+     * If Wifi is connected, then get the latest IP from the WIFI Interface
+     * and start unicast and multicast servers if requested earlier
+     */
     if (CA_INTERFACE_UP == status)
     {
         int16_t port = CA_PORT;
@@ -299,6 +306,20 @@ void CAWiFiConnectionStateCB(const char *ipAddress,
     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
 }
 
+#ifdef __WITH_DTLS__
+uint32_t CAWiFiPacketSendCB(const char *ipAddress, const uint32_t port,
+                                 const void *data, const uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    uint32_t sentLength = CAWiFiSendData(ipAddress, port, data, dataLength, CA_FALSE, CA_TRUE);
+
+    OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Successfully sent %d of encripted data!", sentLength);
+
+    return sentLength;
+}
+#endif
+
 void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
                             const void *data, const uint32_t dataLength, const CABool_t isSecured)
 {
@@ -364,7 +385,7 @@ CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
     CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
 #ifdef __WITH_DTLS__
     CAAdapterNetDtlsInit();
-    CADTLSSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
+    CADTLSSetAdapterCallbacks(CAWiFiPacketReceivedCB, CAWiFiPacketSendCB, DTLS_WIFI);
 #endif
 
     CAConnectivityHandler_t wifiHandler;
@@ -387,7 +408,6 @@ CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
     }
 
     OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi is Success");
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -417,10 +437,19 @@ CAResult_t CAStartWIFI()
         return CA_STATUS_OK;
     }
 
+    char *ifcName;
+    char *ifcAdrs;
+    ret = CAWiFiGetInterfaceInfo(&ifcName, &ifcAdrs);
+    if(CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Failed to get wifi interface info [%d]", ret);
+        return ret;
+    }
+
     int16_t unicastPort = CA_PORT;
     int32_t serverFd = 0;
     // Address is hardcoded as we are using Single Interface
-    ret = CAWiFiStartUnicastServer("0.0.0.0", &unicastPort, false, false, &serverFd);
+    ret = CAWiFiStartUnicastServer(ifcAdrs, &unicastPort, false, false, &serverFd);
     if (CA_STATUS_OK == ret)
     {
         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
@@ -431,7 +460,7 @@ CAResult_t CAStartWIFI()
 #ifdef __WITH_DTLS__
     // Address is hardcoded as we are using Single Interface
     unicastPort = CA_SECURE_PORT;
-    ret = CAWiFiStartUnicastServer("0.0.0.0", &unicastPort, false, true, &serverFd);
+    ret = CAWiFiStartUnicastServer(ifcAdrs, &unicastPort, false, true, &serverFd);
     if (CA_STATUS_OK == ret)
     {
         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Secure Unicast server started on %d port", unicastPort);
@@ -439,7 +468,8 @@ CAResult_t CAStartWIFI()
         gSecureUnicastServerport = unicastPort;
     }
 #endif
-
+    OICFree(ifcName);
+    OICFree(ifcAdrs);
     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
     return ret;;
 }
@@ -467,14 +497,25 @@ CAResult_t CAStartWIFIListeningServer()
         return CA_STATUS_OK;
     }
 
+    char *ifcName;
+    char *ifcAdrs;
+    ret = CAWiFiGetInterfaceInfo(&ifcName, &ifcAdrs);
+    if(CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Failed to get wifi interface info [%d]", ret);
+        return ret;
+    }
+
     int32_t multicastFd = 0;
-    ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &multicastFd);
+    ret = CAWiFiStartMulticastServer(ifcAdrs, CA_MULTICAST_IP, multicastPort, &multicastFd);
     if (CA_STATUS_OK == ret)
     {
         OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server is Started Successfully");
         gIsMulticastServerStarted = true;
     }
 
+    OICFree(ifcName);
+    OICFree(ifcAdrs);
     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
     return ret;
 }
@@ -668,7 +709,7 @@ CAResult_t CAStopWIFI()
     // Stop wifi network monitor
     CAWiFiStopNetworkMonitor();
 
-    //Stop send queue thread
+    // Stop send queue thread
     if (gSendQueueHandle && CA_FALSE == gSendQueueHandle->isStop)
     {
         CAQueueingThreadStop(gSendQueueHandle);
@@ -686,7 +727,7 @@ void CATerminateWIfI()
     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
 
 #ifdef __WITH_DTLS__
-    CADTLSSetPacketReceiveCallback(NULL);
+    CADTLSSetAdapterCallbacks(NULL, NULL, DTLS_WIFI);
     CAAdapterNetDtlsDeInit();
 #endif
 
@@ -733,7 +774,7 @@ void CAWiFiSendDataThread(void *threadData)
             OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt called!");
             uint8_t cacheFalg = 0;
             CAResult_t  result = CAAdapterNetDtlsEncrypt(address, port, wifiData->data,
-                                 wifiData->dataLen, &cacheFalg);
+                                 wifiData->dataLen, &cacheFalg, DTLS_WIFI);
 
             if (CA_STATUS_OK != result)
             {
index 3c4771d..e4797ee 100644 (file)
@@ -17,7 +17,7 @@
  * limitations under the License.
  *
  ******************************************************************/
-#include "cawifiadapter.h"
+#include "cawifiadapter_singlethread.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -27,7 +27,7 @@
 #include "caadapterutils.h"
 #include "logger.h"
 #include "oic_malloc.h"
-#include "cawifiinterface.h"
+#include "cawifiinterface_singlethread.h"
 
 /**
  * @def WIFI_ETHERNET_ADAPTER_TAG
@@ -37,7 +37,7 @@
 
 /**
  * @def CA_PORT
- * @brief Port to listen for incoming data
+ * @brief Port to listen for incoming data. Port 5683 is as per COAP RFC.
  */
 #define CA_PORT   5683
 
@@ -119,7 +119,7 @@ void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
     CAAdapterFreeLocalEndpoint(localEndpoint);
 }
 
-void CAWiFiConnectionStateCB(const char *ipAddress,
+void CAWiFiConnectionStateCB(const char *ipAddr,
                              const CANetworkStatus_t status)
 {
     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
@@ -420,9 +420,7 @@ CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t
 
 CAResult_t CAReadWIFIData()
 {
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
     CAWiFiPullData();
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
index 24d337d..8cdbf3e 100644 (file)
@@ -59,6 +59,12 @@ static char *gWifiInterfaceName = NULL;
 static char *gWifiIPAddress = NULL;
 
 /**
+ * @var gWifiSubnetMask
+ * @brief  Maintains interface subnetmask.
+ */
+static char *gWifiSubnetMask = NULL;
+
+/**
  * @var gThreadPool
  * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
  */
@@ -80,7 +86,8 @@ static CAWiFiConnectionStateChangeCallback gNetworkChangeCb = NULL;
  * @fn CAWiFiGetInterfaceInformation
  * @brief This methods gets local interface name and IP address information.
  */
-static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress);
+static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress,
+                                          char **subnetMask);
 
 static void CANetworkMonitorThread(void *threadData);
 
@@ -96,7 +103,7 @@ CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool)
     }
 
     u_mutex_lock(gWifiNetInfoMutex);
-    CAWiFiGetInterfaceInformation(&gWifiInterfaceName, &gWifiIPAddress);
+    CAWiFiGetInterfaceInformation(&gWifiInterfaceName, &gWifiIPAddress, &gWifiSubnetMask);
     u_mutex_unlock(gWifiNetInfoMutex);
 
     nwConnectivityStatus = (gWifiIPAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
@@ -143,11 +150,11 @@ CAResult_t CAWiFiStartNetworkMonitor(void)
     if (gStopNetworkMonitor)
     {
         OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Stop network monitor requested!");
-        return CA_SERVER_STARTED_ALREADY;
+        return CA_STATUS_FAILED;
     }
 
-    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CANetworkMonitorThread,
-            (void *)NULL))
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool,  CANetworkMonitorThread,
+            NULL))
     {
         OIC_LOG(ERROR, WIFI_MONITOR_TAG, "[ThreadPool] thread_pool_add_task failed!");
         return CA_STATUS_FAILED;
@@ -186,6 +193,12 @@ CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
     // Get the interface and ipaddress information from cache
     u_mutex_lock(gWifiNetInfoMutex);
 
+    if(gWifiInterfaceName == NULL || gWifiIPAddress == NULL)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Network not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+
+    }
     *interfaceName = (gWifiInterfaceName) ? strndup(gWifiInterfaceName,strlen(gWifiInterfaceName))
                                : NULL;
     *ipAddress = (gWifiIPAddress) ? strndup(gWifiIPAddress,strlen(gWifiIPAddress))
@@ -197,6 +210,27 @@ CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
     return CA_STATUS_OK;
 }
 
+CAResult_t CAWiFiGetInterfaceSubnetMask(char **subnetMask)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    VERIFY_NON_NULL(subnetMask, WIFI_MONITOR_TAG, "subnet mask");
+
+    u_mutex_lock(gWifiNetInfoMutex);
+    if(NULL == gWifiSubnetMask)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "There is no subnet mask information!");
+        return CA_STATUS_FAILED;
+    }
+
+    *subnetMask = (gWifiSubnetMask) ? strndup(gWifiSubnetMask,strlen(gWifiSubnetMask))
+                               : NULL;
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
 bool CAWiFiIsConnected(void)
 {
     OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
@@ -215,12 +249,13 @@ void CAWiFiSetConnectionStateChangeCallback(
     gNetworkChangeCb = callback;
 }
 
-void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
+void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress, char **subnetMask)
 {
     struct ifaddrs *ifa = NULL;
     struct ifaddrs *ifp = NULL;
+    const char *matchName = "wlan";
 
-    if (!interfaceName || !ipAddress)
+    if (!interfaceName || !ipAddress || !subnetMask)
     {
         OIC_LOG(ERROR, WIFI_MONITOR_TAG, "Invalid input: interface/ipaddress holder is NULL!");
         return;
@@ -235,11 +270,14 @@ void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
 
     for (ifa = ifp; ifa; ifa = ifa->ifa_next)
     {
-        char localIPAddress[CA_IPADDR_SIZE];
+        char interfaceAddress[CA_IPADDR_SIZE] = {0};
+        char interfaceSubnetMask[CA_IPADDR_SIZE] = {0};
         socklen_t len = sizeof(struct sockaddr_in);
 
-        if (ifa->ifa_addr == NULL)
+        if (NULL == ifa->ifa_addr)
+        {
             continue;
+        }
 
         int type = ifa->ifa_addr->sa_family;
         if (ifa->ifa_flags & IFF_LOOPBACK
@@ -253,25 +291,40 @@ void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
             continue;
         }
 
-        if (0 != getnameinfo(ifa->ifa_addr, len, localIPAddress,
-                        sizeof(localIPAddress), NULL, 0, NI_NUMERICHOST))
+        if (!strncasecmp(ifa->ifa_name,matchName,strlen(matchName)))
         {
-                OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get IPAddress, Error code: %s",
-                          strerror(errno));
-                freeifaddrs(ifp);
-                return;
-        }
+            // get the interface ip address
+            if (0 != getnameinfo(ifa->ifa_addr, len, interfaceAddress,
+                            sizeof(interfaceAddress), NULL, 0, NI_NUMERICHOST))
+            {
+                    OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get IPAddress, Error code: %s",
+                              strerror(errno));
+                    break;
+            }
+
+            // get the interface subnet mask
+            if (0 != getnameinfo(ifa->ifa_netmask, len, interfaceSubnetMask,
+                            sizeof(interfaceSubnetMask), NULL, 0, NI_NUMERICHOST))
+            {
+                    OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get subnet mask, Error code: %s",
+                              strerror(errno));
+                    break;
+            }
+
+            // set interface name
+            *interfaceName = strndup(ifa->ifa_name, strlen(ifa->ifa_name));
 
-        // set interface name
-        *interfaceName = strndup(ifa->ifa_name, strlen(ifa->ifa_name));
+            // set local ip address
+            *ipAddress = strndup(interfaceAddress, strlen(interfaceAddress));
 
-        // set local ip address
-        *ipAddress = strndup(localIPAddress, strlen(localIPAddress));
+            // set subnet mask
+            *subnetMask = strndup(interfaceSubnetMask, strlen(interfaceSubnetMask));
+            break;
+        }
     }
 
     freeifaddrs(ifp);
 }
-
 void CANetworkMonitorThread(void *threadData)
 {
     OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
@@ -282,7 +335,8 @@ void CANetworkMonitorThread(void *threadData)
         CANetworkStatus_t currNetworkStatus;
         char *interfaceName = NULL;
         char *ipAddress = NULL;
-        CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress);
+        char *subnetMask = NULL;
+        CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
 
         // check current network status
         currNetworkStatus = (ipAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
@@ -297,8 +351,10 @@ void CANetworkMonitorThread(void *threadData)
 
             OICFree(gWifiInterfaceName);
             OICFree(gWifiIPAddress);
+            OICFree(gWifiSubnetMask);
             gWifiInterfaceName = (interfaceName) ? strndup(interfaceName, strlen(interfaceName)) : NULL;
             gWifiIPAddress = (ipAddress) ? strndup(ipAddress, strlen(ipAddress)) : NULL;
+            gWifiSubnetMask = (subnetMask) ? strndup(subnetMask, strlen(subnetMask)) : NULL;
 
             u_mutex_unlock(gWifiNetInfoMutex);
 
@@ -309,6 +365,7 @@ void CANetworkMonitorThread(void *threadData)
         }
         OICFree(interfaceName);
         OICFree(ipAddress);
+        OICFree(subnetMask);
     }
 
     OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
index a62d74f..9538e03 100644 (file)
 #define CA_UDP_BIND_RETRY_COUNT 10
 
 /**
+ * @def IPNAMESIZE
+ * @brief max length for ip
+ */
+#define IPNAMESIZE 16
+
+/**
  * @var gUnicastServerSocketFD
  * @brief Unicast server socket descriptor
  */
@@ -110,6 +116,12 @@ static bool gStopSecureUnicast = false;
 static u_thread_pool_t gThreadPool = NULL;
 
 /**
+ * @var gMulticastServerInterface
+ * @brief Local interface on which multicast server is running
+ */
+static char gMulticastServerInterface[IPNAMESIZE];
+
+/**
  * @var gMulticastMemberReq
  * @brief ip_mreq structure passed to join a multicast group
  */
@@ -148,7 +160,7 @@ static void CAReceiveHandler(void *data)
     struct timeval timeout;
     char recvBuffer[COAP_MAX_PDU_SIZE] = {0};
 
-    while (*(ctx->stopFlag) == false)
+    while (true != *(ctx->stopFlag))
     {
         timeout.tv_sec = 1;
         timeout.tv_usec = 0;
@@ -209,6 +221,20 @@ static void CAReceiveHandler(void *data)
         OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
                   recvBuffer, recvLen);
 
+        char *netMask = NULL;
+        if (CA_STATUS_OK != CAWiFiGetInterfaceSubnetMask(&netMask))
+        {
+            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to get ethernet subnet");
+            continue;
+        }
+
+        if(!CAAdapterIsSameSubnet(gMulticastServerInterface, srcIPAddress, netMask))
+        {
+            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Packet received from different subnet, Ignore!");
+            continue;
+        }
+
+        OICFree(netMask);
         switch(ctx->type)
         {
             case CA_UNICAST_SERVER:
@@ -225,7 +251,7 @@ static void CAReceiveHandler(void *data)
                     CAResult_t ret = CAAdapterNetDtlsDecrypt(srcIPAddress,
                                         srcPort,
                                         (uint8_t *)recvBuffer,
-                                        recvLen);
+                                        recvLen, DTLS_WIFI);
                     OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "CAAdapterNetDtlsDecrypt returns [%d]", ret);
                 }
                 break;
@@ -241,7 +267,8 @@ static void CAReceiveHandler(void *data)
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
 }
 
-static CAResult_t CAWiFiCreateSocket(int32_t* socketFD, int16_t *port, const bool forceStart)
+static CAResult_t CAWiFiCreateSocket(int32_t* socketFD, const char *localIp, int16_t *port,
+                                     const bool forceStart)
 {
     int32_t sock = -1;
     // Create a UDP socket
@@ -284,7 +311,14 @@ static CAResult_t CAWiFiCreateSocket(int32_t* socketFD, int16_t *port, const boo
     memset((char *) &sockAddr, 0, sizeof(sockAddr));
     sockAddr.sin_family = AF_INET;
     sockAddr.sin_port = htons(serverPort);
-    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    if(localIp)
+    {
+        sockAddr.sin_addr.s_addr = inet_addr(localIp);
+    }
+    else
+    {
+        sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    }
 
     int16_t i;
     for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
@@ -350,8 +384,8 @@ static CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port,
 {
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
 
-    CAResult_t ret = CAWiFiCreateSocket(serverFD, port, forceStart);
-    if(ret != CA_STATUS_OK)
+    CAResult_t ret = CAWiFiCreateSocket(serverFD, localAddress, port, forceStart);
+    if(CA_STATUS_OK != ret)
     {
         OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create unicast socket");
         return ret;
@@ -431,6 +465,8 @@ static CAResult_t CAWiFiServerCreateMutex(void)
     if (!gMutexSecureUnicastServer)
     {
         OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
         return CA_STATUS_FAILED;
     }
 #endif
@@ -581,7 +617,7 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult
         return CA_SERVER_STARTED_ALREADY;
     }
 
-    CAResult_t ret = CAWiFiCreateSocket(&gMulticastServerSocketFD, &port, true);
+    CAResult_t ret = CAWiFiCreateSocket(&gMulticastServerSocketFD, multicastAddress, &port, true);
     if(ret != CA_STATUS_OK)
     {
         OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create multicast socket");
@@ -591,7 +627,7 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult
 
     // Add membership to receiving socket (join group)
     memset(&gMulticastMemberReq, 0, sizeof(struct ip_mreq));
-    gMulticastMemberReq.imr_interface.s_addr = htonl(INADDR_ANY);
+    gMulticastMemberReq.imr_interface.s_addr = inet_addr(localAddress);
     inet_aton(multicastAddress, &gMulticastMemberReq.imr_multiaddr);
 
     if (-1 == setsockopt(gMulticastServerSocketFD, IPPROTO_IP, IP_ADD_MEMBERSHIP,
@@ -640,6 +676,7 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult
     }
 
     *serverFD = gMulticastServerSocketFD;
+    strncpy(gMulticastServerInterface, localAddress, sizeof(gMulticastServerInterface));
     u_mutex_unlock(gMutexMulticastServer);
 
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
index f3bd0b0..b288ed2 100644 (file)
@@ -48,6 +48,12 @@ static char *gWifiInterfaceName = NULL;
 static char *gWifiIPAddress = NULL;
 
 /**
+ * @var gWifiSubnetMask
+ * @brief  Maintains interface subnetmask.
+ */
+static char *gWifiSubnetMask = NULL;
+
+/**
  * @var gNetworkChangeCb
  * @brief  Maintains network connection state change callback.
  */
@@ -70,7 +76,8 @@ static void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData
  * @fn CAWiFiGetInterfaceInformation
  * @brief This methods gets local interface name and IP address information.
  */
-static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress);
+static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress,
+                                          char **subnetMask);
 
 CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool)
 {
@@ -196,6 +203,27 @@ CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
     return CA_STATUS_OK;
 }
 
+CAResult_t CAWiFiGetInterfaceSubnetMask(char **subnetMask)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    VERIFY_NON_NULL(subnetMask, WIFI_MONITOR_TAG, "subnet mask");
+
+    u_mutex_lock(gWifiNetInfoMutex);
+    if(NULL == gWifiSubnetMask)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "There is no subnet mask information!");
+        return CA_STATUS_FAILED;
+    }
+
+    *subnetMask = (gWifiSubnetMask) ? strndup(gWifiSubnetMask,strlen(gWifiSubnetMask))
+                               : NULL;
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
 bool CAWiFiIsConnected(void)
 {
     OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
@@ -248,15 +276,18 @@ void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
         // Get network information
         char *interfaceName = NULL;
         char *ipAddress = NULL;
-        CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress);
+        char *subnetMask = NULL;
+        CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
 
         // Update the cached network information
         u_mutex_lock(gWifiNetInfoMutex);
 
         OICFree(gWifiInterfaceName);
         OICFree(gWifiIPAddress);
+        OICFree(gWifiSubnetMask);
         gWifiInterfaceName = interfaceName;
         gWifiIPAddress = ipAddress;
+        gWifiSubnetMask = subnetMask;
 
         u_mutex_unlock(gWifiNetInfoMutex);
     }
@@ -292,7 +323,7 @@ void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
     return;
 }
 
-void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
+void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress, char **subnetMask)
 {
     OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
 
@@ -311,26 +342,39 @@ void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
         }
     }
 
+    // Get wifi connected IP address
+    wifi_ap_h accessPoint = NULL;
+    if (WIFI_ERROR_NONE != (ret = wifi_get_connected_ap(&accessPoint)))
+    {
+        OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get access point! error num [%d]",
+                  ret);
+
+        OICFree(interfaceName);
+        u_mutex_unlock(gWifiNetInfoMutex);
+        return;
+    }
+
     if (ipAddress)
     {
-        // Get wifi connected IP address
-        wifi_ap_h accessPoint = NULL;
-        if (WIFI_ERROR_NONE != (ret = wifi_get_connected_ap(&accessPoint)))
+        if (WIFI_ERROR_NONE != (ret = wifi_ap_get_ip_address(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
+                                      ipAddress)))
         {
-            OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get access point! error num [%d]",
+            OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface address! error num [%d]",
                       ret);
-
             OICFree(interfaceName);
             u_mutex_unlock(gWifiNetInfoMutex);
             return;
         }
+    }
 
-        if (WIFI_ERROR_NONE != (ret = wifi_ap_get_ip_address(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
-                                      ipAddress)))
+    if (subnetMask)
+    {
+        if (WIFI_ERROR_NONE != (ret = wifi_ap_set_subnet_mask(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
+                                      subnetMask)))
         {
             OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface address! error num [%d]",
                       ret);
-
+            OICFree(ipAddress);
             OICFree(interfaceName);
             u_mutex_unlock(gWifiNetInfoMutex);
             return;
index c7afc02..9538e03 100644 (file)
@@ -30,6 +30,9 @@
 
 #include "pdu.h"
 #include "caadapterutils.h"
+#ifdef __WITH_DTLS__
+#include "caadapternetdtls.h"
+#endif
 #include "umutex.h"
 
 /**
 #define CA_UDP_BIND_RETRY_COUNT 10
 
 /**
+ * @def IPNAMESIZE
+ * @brief max length for ip
+ */
+#define IPNAMESIZE 16
+
+/**
  * @var gUnicastServerSocketFD
  * @brief Unicast server socket descriptor
  */
@@ -88,7 +97,7 @@ static bool gStopMulticast = false;
 static int32_t gSecureUnicastServerSocketFD = -1;
 
 /**
- * @var gMutexUnicastServer
+ * @var gMutexSecureUnicastServer
  * @brief Mutex to synchronize secure unicast server
  */
 static u_mutex gMutexSecureUnicastServer = NULL;
@@ -98,12 +107,6 @@ static u_mutex gMutexSecureUnicastServer = NULL;
  * @brief Flag to control the unicast secure data receive thread
  */
 static bool gStopSecureUnicast = false;
-
-/**
- * @var gSecureUnicastRecvBuffer
- * @brief Character buffer used for receiving unicast data from network
- */
-static char gSecureUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
 #endif
 
 /**
@@ -113,6 +116,12 @@ static char gSecureUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
 static u_thread_pool_t gThreadPool = NULL;
 
 /**
+ * @var gMulticastServerInterface
+ * @brief Local interface on which multicast server is running
+ */
+static char gMulticastServerInterface[IPNAMESIZE];
+
+/**
  * @var gMulticastMemberReq
  * @brief ip_mreq structure passed to join a multicast group
  */
@@ -131,136 +140,58 @@ static CAWiFiPacketReceivedCallback gPacketReceivedCallback = NULL;
 static CAWiFiExceptionCallback gExceptionCallback = NULL;
 
 /**
- * @var gUnicastRecvBuffer
- * @brief Character buffer used for receiving unicast data from network
+ @brief Thread context information for unicast, multicast and secured unicast server
  */
-static char gUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
-
-/**
- * @var gMulticastRecvBuffer
- * @brief Character buffer used for receiving multicast data from network
- */
-static char gMulticastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
-
-static void CAUnicastReceiveHandler(void *data)
+typedef struct
 {
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "[CAUnicastReceiveHandler] IN");
-
-    fd_set reads;
-    struct timeval timeout;
-
-    while (!gStopUnicast)
-    {
-        timeout.tv_sec = 1;
-        timeout.tv_usec = 0;
-
-        FD_ZERO(&reads);
-        FD_SET(gUnicastServerSocketFD, &reads);
-
-        int32_t ret = select(gUnicastServerSocketFD + 1, &reads, NULL, NULL, &timeout);
-        if (gStopUnicast)
-        {
-            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop request already received for unicast server");
-            break;
-        }
-        if (ret < 0)
-        {
-            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
-            continue;
-        }
-        if (!FD_ISSET(gUnicastServerSocketFD, &reads))
-        {
-            continue;
-        }
-
-        memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
-
-        // Read data from socket
-        struct sockaddr_in srcSockAddress;
-        int32_t recvLen;
-        socklen_t srcAddressLen = sizeof(srcSockAddress);
-        if (-1 == (recvLen = recvfrom(gUnicastServerSocketFD, gUnicastRecvBuffer,
-                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
-                                      &srcAddressLen)))
-        {
-            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
-            continue;
-        }
-        else if (0 == recvLen)
-        {
-            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast server socket is shutdown !");
-
-            // Notify upper layer this exception
-            if (gExceptionCallback)
-            {
-                gExceptionCallback(CA_UNICAST_SERVER);
-            }
-            return;
-        }
-
-        const char *srcIPAddress = NULL;
-        int32_t srcPort = -1;
-
-        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
-        srcPort = ntohs(srcSockAddress.sin_port);
-
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
-                  srcIPAddress, srcPort);
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
-                  gUnicastRecvBuffer, recvLen);
-
-        // Notify data to upper layer
-        if (gPacketReceivedCallback)
-        {
-            gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen, false);
-        }
-    }
-
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "[CAUnicastReceiveHandler] OUT");
-}
+    bool *stopFlag;
+    int32_t socket_fd;
+    CAAdapterServerType_t type;
+}CAAdapterReceiveThreadContext_t;
 
-#ifdef __WITH_DTLS__
-static void CASecureUnicastReceiveHandler(void *data)
+static void CAReceiveHandler(void *data)
 {
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "[CASecureUnicastReceiveHandler] IN");
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+    // Input validation
+    VERIFY_NON_NULL_VOID(data, WIFI_SERVER_TAG, "Invalid thread context");
 
+    CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)data;
     fd_set reads;
     struct timeval timeout;
+    char recvBuffer[COAP_MAX_PDU_SIZE] = {0};
 
-    while (!gStopSecureUnicast)
+    while (true != *(ctx->stopFlag))
     {
         timeout.tv_sec = 1;
         timeout.tv_usec = 0;
 
         FD_ZERO(&reads);
-        FD_SET(gSecureUnicastServerSocketFD, &reads);
+        FD_SET(ctx->socket_fd, &reads);
 
-        int32_t ret = select(gSecureUnicastServerSocketFD + 1, &reads, NULL, NULL, &timeout);
-        if (gStopSecureUnicast)
+        int32_t ret = select(ctx->socket_fd + 1, &reads, NULL, NULL, &timeout);
+        if (*(ctx->stopFlag) == true)
         {
-            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop request already received for secure server");
+            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Stop request received for [%d] server", ctx->type);
             break;
         }
-
         if (ret < 0)
         {
             OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
             continue;
         }
-
-        if (!FD_ISSET(gSecureUnicastServerSocketFD, &reads))
+        if (!FD_ISSET(ctx->socket_fd, &reads))
         {
             continue;
         }
 
-        memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+        memset(recvBuffer, 0, sizeof(recvBuffer));
 
         // Read data from socket
         struct sockaddr_in srcSockAddress;
         int32_t recvLen;
         socklen_t srcAddressLen = sizeof(srcSockAddress);
-        if (-1 == (recvLen = recvfrom(gSecureUnicastServerSocketFD, gSecureUnicastRecvBuffer,
-                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+        if (-1 == (recvLen = recvfrom(ctx->socket_fd, recvBuffer,
+                                      sizeof(recvBuffer), 0, (struct sockaddr *) &srcSockAddress,
                                       &srcAddressLen)))
         {
             OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
@@ -268,13 +199,14 @@ static void CASecureUnicastReceiveHandler(void *data)
         }
         else if (0 == recvLen)
         {
-            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast server socket is shutdown !");
+            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Server socket shutdown [%d]!", ctx->type);
 
             // Notify upper layer this exception
             if (gExceptionCallback)
             {
-                gExceptionCallback(CA_UNICAST_SERVER);
+                gExceptionCallback(ctx->type);
             }
+            OICFree(ctx);
             return;
         }
 
@@ -287,108 +219,60 @@ static void CASecureUnicastReceiveHandler(void *data)
         OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
                   srcIPAddress, srcPort);
         OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
-                  gSecureUnicastRecvBuffer, recvLen);
-
-        CAResult_t result = CAAdapterNetDtlsDecrypt(srcIPAddress,
-                            srcPort,
-                            gSecureUnicastRecvBuffer,
-                            recvLen);
-
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, " CAAdapterNetDtlsDecrypt returns [%d]", result);
-    }
-
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "[CASecureUnicastReceiveHandler] OUT");
-}
-#endif
-
-static void CAMulticastReceiveHandler(void *data)
-{
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-
-    fd_set reads;
-    struct timeval timeout;
-
-    while (!gStopMulticast)
-    {
-        timeout.tv_sec = 1;
-        timeout.tv_usec = 0;
-
-        FD_ZERO(&reads);
-        FD_SET(gMulticastServerSocketFD, &reads);
+                  recvBuffer, recvLen);
 
-        int32_t ret = select(gMulticastServerSocketFD + 1, &reads, NULL, NULL, &timeout);
-        if (gStopMulticast)
-        {
-            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop request already received for multicast server");
-            break;
-        }
-        if ( ret < 0)
-        {
-            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
-            continue;
-        }
-        if (!FD_ISSET(gMulticastServerSocketFD, &reads))
+        char *netMask = NULL;
+        if (CA_STATUS_OK != CAWiFiGetInterfaceSubnetMask(&netMask))
         {
+            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to get ethernet subnet");
             continue;
         }
 
-        memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
-
-        // Read data from socket
-        struct sockaddr_in srcSockAddress;
-        int32_t recvLen;
-        socklen_t srcAddressLen = sizeof(srcSockAddress);
-        if (-1 == (recvLen = recvfrom(gMulticastServerSocketFD, gMulticastRecvBuffer,
-                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
-                                      &srcAddressLen)))
+        if(!CAAdapterIsSameSubnet(gMulticastServerInterface, srcIPAddress, netMask))
         {
-            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
+            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Packet received from different subnet, Ignore!");
             continue;
         }
-        else if (0 == recvLen)
-        {
-            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast socket is shutdown!\n");
-
-            // Notify upper layer this exception
-            if (gExceptionCallback)
-            {
-                gExceptionCallback(CA_MULTICAST_SERVER);
-            }
-            return;
-        }
-
-        const char *srcIPAddress = NULL;
-        int32_t srcPort = -1;
-
-        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
-        srcPort = ntohs(srcSockAddress.sin_port);
-
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
-                  srcIPAddress, srcPort);
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
-                  gMulticastRecvBuffer, recvLen);
-
 
-        // Notify data to upper layer
-        if (gPacketReceivedCallback)
+        OICFree(netMask);
+        switch(ctx->type)
         {
-            gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen, false);
+            case CA_UNICAST_SERVER:
+            case CA_MULTICAST_SERVER:
+                // Notify data to upper layer
+                if (gPacketReceivedCallback)
+                {
+                    gPacketReceivedCallback(srcIPAddress, srcPort, recvBuffer, recvLen, false);
+                }
+                break;
+#ifdef __WITH_DTLS__
+            case CA_SECURED_UNICAST_SERVER:
+                {
+                    CAResult_t ret = CAAdapterNetDtlsDecrypt(srcIPAddress,
+                                        srcPort,
+                                        (uint8_t *)recvBuffer,
+                                        recvLen, DTLS_WIFI);
+                    OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "CAAdapterNetDtlsDecrypt returns [%d]", ret);
+                }
+                break;
+#endif //__WITH_DTLS__
+            default:
+                // Should never occur
+                OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Invalid server type");
+                OICFree(ctx);
+                return;
         }
     }
 
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
 }
 
-static CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port,
-                                       const bool forceStart, u_thread_func receiveThread,
-                                       int32_t *serverFD)
+static CAResult_t CAWiFiCreateSocket(int32_t* socketFD, const char *localIp, int16_t *port,
+                                     const bool forceStart)
 {
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-
-    int32_t socketFD = -1;
-
+    int32_t sock = -1;
     // Create a UDP socket
-    if (-1 == (socketFD = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
+    if (-1 == (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
     {
         OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to create Socket, Error code: %s",
                   strerror(errno));
@@ -396,26 +280,26 @@ static CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port,
     }
 
     // Make the socket non-blocking
-    if (-1 == fcntl(socketFD, F_SETFL, O_NONBLOCK))
+    if (-1 == fcntl(sock, F_SETFL, O_NONBLOCK))
     {
         OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
                   strerror(errno));
 
-        close(socketFD);
+        close(sock);
         return CA_STATUS_FAILED;
     }
 
     if (true == forceStart)
     {
         int32_t setOptionOn = 1;
-        if (-1 == setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR,
+        if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
                              (char *) &setOptionOn,
                              sizeof(setOptionOn)))
         {
             OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
                       strerror(errno));
 
-            close(socketFD);
+            close(sock);
             return CA_STATUS_FAILED;
         }
     }
@@ -427,17 +311,24 @@ static CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port,
     memset((char *) &sockAddr, 0, sizeof(sockAddr));
     sockAddr.sin_family = AF_INET;
     sockAddr.sin_port = htons(serverPort);
-    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    if(localIp)
+    {
+        sockAddr.sin_addr.s_addr = inet_addr(localIp);
+    }
+    else
+    {
+        sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    }
 
     int16_t i;
     for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
     {
-        if (-1 == bind(socketFD, (struct sockaddr *) &sockAddr,
+        if (-1 == bind(sock, (struct sockaddr *) &sockAddr,
                        sizeof(sockAddr)))
         {
             if (false == forceStart)
             {
-                OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
+                OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
                           strerror(errno));
 
                 //Set the port to next one
@@ -459,24 +350,71 @@ static CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port,
 
     if (false == isBound)
     {
-        close(socketFD);
+        close(sock);
         return CA_STATUS_FAILED;
     }
 
     *port = serverPort;
-    *serverFD = socketFD;
+    *socketFD = sock;
+    return CA_STATUS_OK;
+}
+
+static CAResult_t CAWiFiCloseSocket(int32_t *socketFD)
+{
+    if (-1 == *socketFD)
+    {
+        OIC_LOG(INFO, WIFI_SERVER_TAG, "Server not running");
+        return CA_SERVER_NOT_STARTED;
+    }
+
+    // close the socket
+    if (-1 == close(*socketFD))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
+                  strerror(errno));
+        return CA_STATUS_FAILED;
+    }
+
+    *socketFD = -1;
+    return CA_STATUS_OK;
+}
+
+static CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port,
+                                       const bool forceStart, bool isSecured, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    CAResult_t ret = CAWiFiCreateSocket(serverFD, localAddress, port, forceStart);
+    if(CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create unicast socket");
+        return ret;
+    }
 
     /**
       * The task to listen for data from unicast 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.
       */
-    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, receiveThread, NULL))
+    CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
+                                            OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
+    if(!ctx)
     {
-        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create read thread!");
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Out of memory!");
+        close(*serverFD);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
 
-        close(socketFD);
+    ctx->stopFlag = &gStopUnicast;
+    ctx->socket_fd = *serverFD;
+    ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER:CA_UNICAST_SERVER;
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, CAReceiveHandler, (void *)ctx))
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create read thread!");
+        OICFree((void *)ctx);
+        close(*serverFD);
         return CA_STATUS_FAILED;
     }
 
@@ -527,6 +465,8 @@ static CAResult_t CAWiFiServerCreateMutex(void)
     if (!gMutexSecureUnicastServer)
     {
         OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
         return CA_STATUS_FAILED;
     }
 #endif
@@ -608,8 +548,8 @@ CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
         }
 
         gStopUnicast = false;
-        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart,
-                CAUnicastReceiveHandler, &gUnicastServerSocketFD))
+        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
+                                                 &gUnicastServerSocketFD))
         {
             OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to start unicast server!");
             gUnicastServerSocketFD = -1;
@@ -635,8 +575,8 @@ CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
         }
 
         gStopSecureUnicast = false;
-        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart,
-                CASecureUnicastReceiveHandler, &gSecureUnicastServerSocketFD))
+        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
+                                                 &gSecureUnicastServerSocketFD))
         {
             OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to start unicast server!");
             gSecureUnicastServerSocketFD = -1;
@@ -661,7 +601,8 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult
     VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Local address is NULL");
     VERIFY_NON_NULL(multicastAddress, WIFI_SERVER_TAG, "Multicast address is NULL");
 
-    if (0 >= multicastPort)
+    int16_t port = multicastPort;
+    if (0 >= port)
     {
         OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: Multicast port is invalid!");
         return CA_STATUS_INVALID_PARAM;
@@ -672,64 +613,21 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult
     if (gMulticastServerSocketFD != -1)
     {
         OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is already running!");
-        return CA_SERVER_STARTED_ALREADY;
-    }
-
-    if ((gMulticastServerSocketFD = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
-    {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
-                  strerror(errno));
-        u_mutex_unlock(gMutexMulticastServer);
-        return CA_STATUS_FAILED;
-    }
-
-    // Make the socket non-blocking
-    if (-1 == fcntl(gMulticastServerSocketFD, F_SETFL, O_NONBLOCK))
-    {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
-                  strerror(errno));
-        close(gMulticastServerSocketFD);
-        gMulticastServerSocketFD = -1;
         u_mutex_unlock(gMutexMulticastServer);
-        return CA_STATUS_FAILED;
+        return CA_SERVER_STARTED_ALREADY;
     }
 
-    OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
-
-    int32_t setOptionOn = 1;
-    if (-1 == setsockopt(gMulticastServerSocketFD, SOL_SOCKET, SO_REUSEADDR,
-                         (char *) &setOptionOn,
-                         sizeof(setOptionOn)))
+    CAResult_t ret = CAWiFiCreateSocket(&gMulticastServerSocketFD, multicastAddress, &port, true);
+    if(ret != CA_STATUS_OK)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
-                  strerror(errno));
-        close(gMulticastServerSocketFD);
-        gMulticastServerSocketFD = -1;
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create multicast socket");
         u_mutex_unlock(gMutexMulticastServer);
-        return CA_STATUS_FAILED;
-    }
-
-    struct sockaddr_in sockAddr;
-    memset((char *) &sockAddr, 0, sizeof(sockAddr));
-
-    sockAddr.sin_family = AF_INET;
-    sockAddr.sin_port = htons(multicastPort);
-    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
-
-    // bind socket to multicast port
-    if (-1 == bind(gMulticastServerSocketFD, (struct sockaddr *) &sockAddr,
-                   sizeof(sockAddr)))
-    {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Bind Socket!");
-        close(gMulticastServerSocketFD);
-        gMulticastServerSocketFD = -1;
-        u_mutex_unlock(gMutexMulticastServer);
-        return CA_STATUS_FAILED;
+        return ret;
     }
 
     // Add membership to receiving socket (join group)
     memset(&gMulticastMemberReq, 0, sizeof(struct ip_mreq));
-    gMulticastMemberReq.imr_interface.s_addr = htonl(INADDR_ANY);
+    gMulticastMemberReq.imr_interface.s_addr = inet_addr(localAddress);
     inet_aton(multicastAddress, &gMulticastMemberReq.imr_multiaddr);
 
     if (-1 == setsockopt(gMulticastServerSocketFD, IPPROTO_IP, IP_ADD_MEMBERSHIP,
@@ -749,9 +647,24 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult
       * 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, WIFI_SERVER_TAG, "Out of memory!");
+        close(gMulticastServerSocketFD);
+        gMulticastServerSocketFD = -1;
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    ctx->stopFlag = &gStopMulticast;
+    ctx->socket_fd = gMulticastServerSocketFD;
+    ctx->type = CA_MULTICAST_SERVER;
+
     gStopMulticast = false;
-    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, CAMulticastReceiveHandler, NULL))
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, CAReceiveHandler, (void *)ctx))
     {
         OIC_LOG(ERROR, WIFI_SERVER_TAG, "thread_pool_add_task failed!");
 
@@ -763,6 +676,7 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult
     }
 
     *serverFD = gMulticastServerSocketFD;
+    strncpy(gMulticastServerInterface, localAddress, sizeof(gMulticastServerInterface));
     u_mutex_unlock(gMutexMulticastServer);
 
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
@@ -774,29 +688,12 @@ CAResult_t CAWiFiStopUnicastServer()
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
 
     u_mutex_lock(gMutexUnicastServer);
-    if (-1 == gUnicastServerSocketFD)
-    {
-        OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast server is not yet started");
-        u_mutex_unlock(gMutexUnicastServer);
-        return CA_SERVER_NOT_STARTED;
-    }
-
     gStopUnicast = true;
-
-    // close the socket
-    if (-1 == close(gUnicastServerSocketFD))
-    {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to close socket, Error code: %s\n",
-                  strerror(errno));
-        u_mutex_unlock(gMutexUnicastServer);
-        return CA_STATUS_FAILED;
-    }
-
-    gUnicastServerSocketFD = -1;
+    CAResult_t ret = CAWiFiCloseSocket(&gUnicastServerSocketFD);
     u_mutex_unlock(gMutexUnicastServer);
 
-    OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast server stopped successfully");
-    return CA_STATUS_OK;
+    OIC_LOG_V(INFO, WIFI_SERVER_TAG, "Unicast server stopped [%d]", ret);
+    return ret;
 }
 
 #ifdef __WITH_DTLS__
@@ -805,29 +702,12 @@ CAResult_t CAWiFiStopSecureUnicastServer()
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
 
     u_mutex_lock(gMutexSecureUnicastServer);
-    if (-1 == gSecureUnicastServerSocketFD)
-    {
-        OIC_LOG(INFO, WIFI_SERVER_TAG, "Secure unicast server is not yet started");
-        u_mutex_unlock(gMutexSecureUnicastServer);
-        return CA_SERVER_NOT_STARTED;
-    }
-
     gStopSecureUnicast = true;
-
-    // close the socket
-    if (-1 == close(gSecureUnicastServerSocketFD))
-    {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
-                  strerror(errno));
-        u_mutex_unlock(gMutexSecureUnicastServer);
-        return CA_STATUS_FAILED;
-    }
-
-    gSecureUnicastServerSocketFD = -1;
+    CAResult_t ret = CAWiFiCloseSocket(&gSecureUnicastServerSocketFD);
     u_mutex_unlock(gMutexSecureUnicastServer);
 
-    OIC_LOG(INFO, WIFI_SERVER_TAG, "Secure unicast server stopped successfully");
-    return CA_STATUS_OK;
+    OIC_LOG_V(INFO, WIFI_SERVER_TAG, "Secured unicast server stopped [%d]", ret);
+    return ret;
 }
 #endif
 
@@ -855,20 +735,11 @@ CAResult_t CAWiFiStopMulticastServer(void)
                   strerror(errno));
     }
 
-    // close the socket
-    if (-1 == close(gMulticastServerSocketFD))
-    {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
-                  strerror(errno));
-        u_mutex_unlock(gMutexMulticastServer);
-        return CA_SOCKET_OPERATION_FAILED;
-    }
-
-    gMulticastServerSocketFD = -1;
+    CAResult_t ret = CAWiFiCloseSocket(&gMulticastServerSocketFD);
     u_mutex_unlock(gMutexMulticastServer);
 
-    OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast server stopped successfully");
-    return CA_STATUS_OK;
+    OIC_LOG_V(INFO, WIFI_SERVER_TAG, "Multicast server stopped [%d]", ret);
+    return ret;
 }
 
 CAResult_t CAWiFiGetUnicastServerInfo(const CABool_t isSecured, char **ipAddress,