From 85adc6b38376555e61804796030d4d3aac94596a Mon Sep 17 00:00:00 2001 From: "ashok.channa" Date: Tue, 16 Dec 2014 19:17:27 +0900 Subject: [PATCH] Implementation of following functionality 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 Change-Id: I8a92b0ef38b16818c740f3e95aad5ce1e65741a4 --- resource/csdk/connectivity/build/Makefile | 10 +- .../build/arduino/arduinomega.properties | 2 +- resource/csdk/connectivity/build/arduino/build.sh | 8 +- resource/csdk/connectivity/build/tizen/gbsbuild.sh | 6 +- resource/csdk/connectivity/inc/caadapternetdtls.h | 62 +- resource/csdk/connectivity/inc/caadapterutils.h | 8 + resource/csdk/connectivity/inc/caedradapter.h | 9 - .../connectivity/inc/caedradapter_singlethread.h | 176 ++++ resource/csdk/connectivity/inc/caethernetadapter.h | 7 - .../inc/caethernetadapter_singlethread.h | 123 +++ .../csdk/connectivity/inc/caethernetinterface.h | 131 +-- .../inc/caethernetinterface_singlethread.h | 338 +++++++ resource/csdk/connectivity/inc/caleadapter.h | 8 - .../connectivity/inc/caleadapter_singlethread.h | 233 +++++ resource/csdk/connectivity/inc/caleinterface.h | 6 +- .../connectivity/inc/caleinterface_singlethread.h | 174 ++++ .../inc/camessagehandler_singlethread.h | 6 +- .../inc/caprotocolmessage_singlethread.h | 211 +++++ .../inc/caretransmission_singlethread.h | 8 +- resource/csdk/connectivity/inc/cawifiadapter.h | 8 - .../connectivity/inc/cawifiadapter_singlethread.h | 124 +++ resource/csdk/connectivity/inc/cawifiinterface.h | 89 +- .../inc/cawifiinterface_singlethread.h | 347 ++++++++ .../connectivity/samples/arduino/sample_main.cpp | 4 +- resource/csdk/connectivity/samples/linux/sample.sh | 4 - .../csdk/connectivity/samples/linux/sample_main.c | 13 +- .../csdk/connectivity/samples/tizen/README.txt | 2 +- .../src/{ => adapter_util}/caadapternetdtls.c | 212 +++-- .../connectivity/src/adapter_util/caadapterutils.c | 93 ++ .../src/bt_edr_adapter/tizen/cabtmanager.c | 4 +- .../src/bt_le_adapter/arduino/caleadapter.cpp | 4 +- .../src/bt_le_adapter/tizen/cableclient.c | 5 +- .../src/bt_le_adapter/tizen/cableserver.c | 1 + .../src/caconnectivitymanager_singlethread.c | 2 +- .../csdk/connectivity/src/cainterfacecontroller.c | 2 - .../src/cainterfacecontroller_singlethread.c | 9 +- .../src/camessagehandler_singlethread.c | 10 +- resource/csdk/connectivity/src/caprotocolmessage.c | 7 +- .../src/caprotocolmessage_singlethread.c | 677 ++++++++++++++ resource/csdk/connectivity/src/caqueueingthread.c | 6 + .../src/caretransmission_singlethread.cpp | 67 +- .../arduino/caethernetadapterutils.cpp | 2 +- .../arduino/caethernetadapterutils.h | 2 +- .../ethernet_adapter/arduino/caethernetclient.cpp | 4 +- .../arduino/caethernetnwmonitor.cpp | 4 +- .../ethernet_adapter/arduino/caethernetserver.cpp | 8 +- .../src/ethernet_adapter/caethernetadapter.c | 322 +++++-- .../caethernetadapter_singlethread.c | 12 +- .../src/ethernet_adapter/linux/caethernetclient.c | 67 +- .../ethernet_adapter/linux/caethernetnwmonitor.c | 155 +++- .../src/ethernet_adapter/linux/caethernetserver.c | 990 ++++++++++----------- .../src/wifi_adapter/arduino/cawificlient.cpp | 4 +- .../src/wifi_adapter/arduino/cawifinwmonitor.cpp | 4 +- .../src/wifi_adapter/arduino/cawifiserver.cpp | 8 +- .../connectivity/src/wifi_adapter/cawifiadapter.c | 73 +- .../src/wifi_adapter/cawifiadapter_singlethread.c | 10 +- .../src/wifi_adapter/linux/cawifinwmonitor.c | 101 ++- .../src/wifi_adapter/linux/cawifiserver.c | 53 +- .../src/wifi_adapter/tizen/cawifinwmonitor.c | 66 +- .../src/wifi_adapter/tizen/cawifiserver.c | 493 ++++------ 60 files changed, 4151 insertions(+), 1443 deletions(-) create mode 100644 resource/csdk/connectivity/inc/caedradapter_singlethread.h create mode 100644 resource/csdk/connectivity/inc/caethernetadapter_singlethread.h create mode 100644 resource/csdk/connectivity/inc/caethernetinterface_singlethread.h create mode 100644 resource/csdk/connectivity/inc/caleadapter_singlethread.h create mode 100644 resource/csdk/connectivity/inc/caleinterface_singlethread.h create mode 100644 resource/csdk/connectivity/inc/caprotocolmessage_singlethread.h create mode 100644 resource/csdk/connectivity/inc/cawifiadapter_singlethread.h create mode 100644 resource/csdk/connectivity/inc/cawifiinterface_singlethread.h rename resource/csdk/connectivity/src/{ => adapter_util}/caadapternetdtls.c (71%) create mode 100644 resource/csdk/connectivity/src/caprotocolmessage_singlethread.c diff --git a/resource/csdk/connectivity/build/Makefile b/resource/csdk/connectivity/build/Makefile index b57c9f6..261f50e 100644 --- a/resource/csdk/connectivity/build/Makefile +++ b/resource/csdk/connectivity/build/Makefile @@ -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**********) diff --git a/resource/csdk/connectivity/build/arduino/arduinomega.properties b/resource/csdk/connectivity/build/arduino/arduinomega.properties index 329914a..3628952 100644 --- a/resource/csdk/connectivity/build/arduino/arduinomega.properties +++ b/resource/csdk/connectivity/build/arduino/arduinomega.properties @@ -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) diff --git a/resource/csdk/connectivity/build/arduino/build.sh b/resource/csdk/connectivity/build/arduino/build.sh index 04abff2..3aa2b31 100644 --- a/resource/csdk/connectivity/build/arduino/build.sh +++ b/resource/csdk/connectivity/build/arduino/build.sh @@ -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 diff --git a/resource/csdk/connectivity/build/tizen/gbsbuild.sh b/resource/csdk/connectivity/build/tizen/gbsbuild.sh index 718a9e3..c3394b1 100644 --- a/resource/csdk/connectivity/build/tizen/gbsbuild.sh +++ b/resource/csdk/connectivity/build/tizen/gbsbuild.sh @@ -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 diff --git a/resource/csdk/connectivity/inc/caadapternetdtls.h b/resource/csdk/connectivity/inc/caadapternetdtls.h index e327cda..b53e355 100644 --- a/resource/csdk/connectivity/inc/caadapternetdtls.h +++ b/resource/csdk/connectivity/inc/caadapternetdtls.h @@ -25,13 +25,29 @@ #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 diff --git a/resource/csdk/connectivity/inc/caadapterutils.h b/resource/csdk/connectivity/inc/caadapterutils.h index 7a1ec28..4878a7f 100644 --- a/resource/csdk/connectivity/inc/caadapterutils.h +++ b/resource/csdk/connectivity/inc/caadapterutils.h @@ -26,6 +26,8 @@ #ifndef _CA_ADAPTER_UTILS_H_ #define _CA_ADAPTER_UTILS_H_ +#include + #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 diff --git a/resource/csdk/connectivity/inc/caedradapter.h b/resource/csdk/connectivity/inc/caedradapter.h index 02328ac..558a544 100644 --- a/resource/csdk/connectivity/inc/caedradapter.h +++ b/resource/csdk/connectivity/inc/caedradapter.h @@ -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 index 0000000..ed1ba73 --- /dev/null +++ b/resource/csdk/connectivity/inc/caedradapter_singlethread.h @@ -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_ diff --git a/resource/csdk/connectivity/inc/caethernetadapter.h b/resource/csdk/connectivity/inc/caethernetadapter.h index d4240fb..9ee9ecd 100644 --- a/resource/csdk/connectivity/inc/caethernetadapter.h +++ b/resource/csdk/connectivity/inc/caethernetadapter.h @@ -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 index 0000000..5a59a0f --- /dev/null +++ b/resource/csdk/connectivity/inc/caethernetadapter_singlethread.h @@ -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__ diff --git a/resource/csdk/connectivity/inc/caethernetinterface.h b/resource/csdk/connectivity/inc/caethernetinterface.h index 7aa8c2c..0fe6e21 100644 --- a/resource/csdk/connectivity/inc/caethernetinterface.h +++ b/resource/csdk/connectivity/inc/caethernetinterface.h @@ -23,15 +23,13 @@ * @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 #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 index 0000000..25383b2 --- /dev/null +++ b/resource/csdk/connectivity/inc/caethernetinterface_singlethread.h @@ -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 + +#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_ diff --git a/resource/csdk/connectivity/inc/caleadapter.h b/resource/csdk/connectivity/inc/caleadapter.h index cec404b..6ce25c2 100644 --- a/resource/csdk/connectivity/inc/caleadapter.h +++ b/resource/csdk/connectivity/inc/caleadapter.h @@ -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 index 0000000..5c94f01 --- /dev/null +++ b/resource/csdk/connectivity/inc/caleadapter_singlethread.h @@ -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_ diff --git a/resource/csdk/connectivity/inc/caleinterface.h b/resource/csdk/connectivity/inc/caleinterface.h index a6d0921..76062be 100644 --- a/resource/csdk/connectivity/inc/caleinterface.h +++ b/resource/csdk/connectivity/inc/caleinterface.h @@ -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 @@ -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 index 0000000..8ed8c80 --- /dev/null +++ b/resource/csdk/connectivity/inc/caleinterface_singlethread.h @@ -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 + +#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_ diff --git a/resource/csdk/connectivity/inc/camessagehandler_singlethread.h b/resource/csdk/connectivity/inc/camessagehandler_singlethread.h index c3840be..89f902f 100644 --- a/resource/csdk/connectivity/inc/camessagehandler_singlethread.h +++ b/resource/csdk/connectivity/inc/camessagehandler_singlethread.h @@ -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 #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 index 0000000..f0e212a --- /dev/null +++ b/resource/csdk/connectivity/inc/caprotocolmessage_singlethread.h @@ -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_ diff --git a/resource/csdk/connectivity/inc/caretransmission_singlethread.h b/resource/csdk/connectivity/inc/caretransmission_singlethread.h index 2262a0b..4c4745c 100644 --- a/resource/csdk/connectivity/inc/caretransmission_singlethread.h +++ b/resource/csdk/connectivity/inc/caretransmission_singlethread.h @@ -18,11 +18,11 @@ * ******************************************************************/ /** - * @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 @@ -91,4 +91,4 @@ void CARetransmissionBaseRoutine(void *threadValue); } /* extern "C" */ #endif -#endif // __CA_RETRANSMISSION_H_ +#endif // __CA_RETRANSMISSION_SINGLETHREAD_H_ diff --git a/resource/csdk/connectivity/inc/cawifiadapter.h b/resource/csdk/connectivity/inc/cawifiadapter.h index 66f8766..55d8653 100644 --- a/resource/csdk/connectivity/inc/cawifiadapter.h +++ b/resource/csdk/connectivity/inc/cawifiadapter.h @@ -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 index 0000000..1aa88d9 --- /dev/null +++ b/resource/csdk/connectivity/inc/cawifiadapter_singlethread.h @@ -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__ diff --git a/resource/csdk/connectivity/inc/cawifiinterface.h b/resource/csdk/connectivity/inc/cawifiinterface.h index 7845702..8e36aa2 100644 --- a/resource/csdk/connectivity/inc/cawifiinterface.h +++ b/resource/csdk/connectivity/inc/cawifiinterface.h @@ -23,15 +23,13 @@ * @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 #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 index 0000000..2aa9d37 --- /dev/null +++ b/resource/csdk/connectivity/inc/cawifiinterface_singlethread.h @@ -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 + +#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_ diff --git a/resource/csdk/connectivity/samples/arduino/sample_main.cpp b/resource/csdk/connectivity/samples/arduino/sample_main.cpp index d994c28..ce6b20b 100644 --- a/resource/csdk/connectivity/samples/arduino/sample_main.cpp +++ b/resource/csdk/connectivity/samples/arduino/sample_main.cpp @@ -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 #include @@ -192,7 +192,7 @@ void loop() #include "Arduino.h" -#include "cawifiadapter.h" +#include "cawifiadapter_singlethread.h" #include #include "caadapterinterface.h" diff --git a/resource/csdk/connectivity/samples/linux/sample.sh b/resource/csdk/connectivity/samples/linux/sample.sh index ce04425..3065ea7 100644 --- a/resource/csdk/connectivity/samples/linux/sample.sh +++ b/resource/csdk/connectivity/samples/linux/sample.sh @@ -18,10 +18,6 @@ # * #******************************************************************/ -cd ../../lib/libcoap-4.1.1 -make clean -make - cd ../../build/linux make clean if echo $1 | grep -q -i "WITH_DTLS" diff --git a/resource/csdk/connectivity/samples/linux/sample_main.c b/resource/csdk/connectivity/samples/linux/sample_main.c index 10f62f6..268e2ce 100644 --- a/resource/csdk/connectivity/samples/linux/sample_main.c +++ b/resource/csdk/connectivity/samples/linux/sample_main.c @@ -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; } diff --git a/resource/csdk/connectivity/samples/tizen/README.txt b/resource/csdk/connectivity/samples/tizen/README.txt index 0a2a305..3d71338 100644 --- a/resource/csdk/connectivity/samples/tizen/README.txt +++ b/resource/csdk/connectivity/samples/tizen/README.txt @@ -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: diff --git a/resource/csdk/connectivity/src/caadapternetdtls.c b/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c similarity index 71% rename from resource/csdk/connectivity/src/caadapternetdtls.c rename to resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c index 4313378..234969e 100644 --- a/resource/csdk/connectivity/src/caadapternetdtls.c +++ b/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c @@ -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!"); diff --git a/resource/csdk/connectivity/src/adapter_util/caadapterutils.c b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c index 0f87e4e..743b178 100644 --- a/resource/csdk/connectivity/src/adapter_util/caadapterutils.c +++ b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c @@ -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 diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c index 0f897c0..800d9cb 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c @@ -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 diff --git a/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleadapter.cpp b/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleadapter.cpp index 504201d..48b3c49 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleadapter.cpp +++ b/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleadapter.cpp @@ -17,11 +17,11 @@ * limitations under the License. * ******************************************************************/ -#include "caleadapter.h" +#include "caleadapter_singlethread.h" #include -#include "caleinterface.h" +#include "caleinterface_singlethread.h" #include "caleserver.h" #include "logger.h" #include "caadapterutils.h" diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c index 7d10e08..fa4595d 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c @@ -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; diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c index 31d9ad9..521b585 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c @@ -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; } diff --git a/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c b/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c index 772ab1f..6afa833 100644 --- a/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c +++ b/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c @@ -24,7 +24,7 @@ #include "cainterface.h" #include "caremotehandler.h" -#include "caprotocolmessage.h" +#include "caprotocolmessage_singlethread.h" #include "canetworkconfigurator.h" #include "logger.h" diff --git a/resource/csdk/connectivity/src/cainterfacecontroller.c b/resource/csdk/connectivity/src/cainterfacecontroller.c index 1c92ab6..2d290a2 100644 --- a/resource/csdk/connectivity/src/cainterfacecontroller.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller.c @@ -24,12 +24,10 @@ #include #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" diff --git a/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c b/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c index f282f9b..88d8192 100644 --- a/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c @@ -25,10 +25,10 @@ #include #include -#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; diff --git a/resource/csdk/connectivity/src/camessagehandler_singlethread.c b/resource/csdk/connectivity/src/camessagehandler_singlethread.c index 55c7196..ee40a82 100644 --- a/resource/csdk/connectivity/src/camessagehandler_singlethread.c +++ b/resource/csdk/connectivity/src/camessagehandler_singlethread.c @@ -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); diff --git a/resource/csdk/connectivity/src/caprotocolmessage.c b/resource/csdk/connectivity/src/caprotocolmessage.c index ee9deaf..25a3652 100644 --- a/resource/csdk/connectivity/src/caprotocolmessage.c +++ b/resource/csdk/connectivity/src/caprotocolmessage.c @@ -34,11 +34,8 @@ #define CA_BUFSIZE 128 #define CA_COAP_MESSAGE_CON 0 -#ifdef __ARDUINO__ -#include "util.h" -#else #include -#endif //#ifdef __ARDUINO__ + uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, char *outUri) @@ -563,9 +560,7 @@ CAResult_t CAGenerateTokenInternal(CAToken_t *token) // set random byte uint32_t index; -#ifndef __ARDUINO__ srand(time(NULL)); -#endif //#ifndef __ARDUINO__ for (index = 0; index < CA_MAX_TOKEN_LEN; index++) { // use valid characters diff --git a/resource/csdk/connectivity/src/caprotocolmessage_singlethread.c b/resource/csdk/connectivity/src/caprotocolmessage_singlethread.c new file mode 100644 index 0000000..f0ec4da --- /dev/null +++ b/resource/csdk/connectivity/src/caprotocolmessage_singlethread.c @@ -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 +#include +#include + + +#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); +} diff --git a/resource/csdk/connectivity/src/caqueueingthread.c b/resource/csdk/connectivity/src/caqueueingthread.c index 3ce5406..0894b46 100644 --- a/resource/csdk/connectivity/src/caqueueingthread.c +++ b/resource/csdk/connectivity/src/caqueueingthread.c @@ -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); diff --git a/resource/csdk/connectivity/src/caretransmission_singlethread.cpp b/resource/csdk/connectivity/src/caretransmission_singlethread.cpp index 4a7a262..ee630cf 100644 --- a/resource/csdk/connectivity/src/caretransmission_singlethread.cpp +++ b/resource/csdk/connectivity/src/caretransmission_singlethread.cpp @@ -25,11 +25,11 @@ #include #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 data, msgid=%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; } diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.cpp b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.cpp index a0b64db..a79190e 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.cpp +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.cpp @@ -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" diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.h b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.h index 9cdee4e..f67944f 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.h +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.h @@ -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 diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetclient.cpp b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetclient.cpp index 556b4b7..21bea62 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetclient.cpp +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetclient.cpp @@ -17,7 +17,7 @@ * limitations under the License. * ******************************************************************/ -#include "caethernetinterface.h" +#include "caethernetinterface_singlethread.h" #include #include @@ -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" diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetnwmonitor.cpp b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetnwmonitor.cpp index e90a7b5..5e15d75 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetnwmonitor.cpp +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetnwmonitor.cpp @@ -18,7 +18,7 @@ * ******************************************************************/ -#include "caethernetinterface.h" +#include "caethernetinterface_singlethread.h" #include #include @@ -28,7 +28,7 @@ #include #include "logger.h" #include "caadapterutils.h" -#include "caethernetadapter.h" +#include "caethernetadapter_singlethread.h" #define ETHERNET_MONITOR_TAG "ETHERNET_MONITOR" diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetserver.cpp b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetserver.cpp index 67deff5..316c242 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetserver.cpp +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetserver.cpp @@ -18,7 +18,7 @@ * ******************************************************************/ -#include "caethernetinterface.h" +#include "caethernetinterface_singlethread.h" #include #include @@ -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 }; diff --git a/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c b/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c index 61677f2..0975ae0 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c @@ -27,12 +27,15 @@ #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" @@ -41,7 +44,13 @@ * @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); diff --git a/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter_singlethread.c b/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter_singlethread.c index 13282d9..573ff3d 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter_singlethread.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter_singlethread.c @@ -18,14 +18,14 @@ * ******************************************************************/ -#include "caethernetadapter.h" +#include "caethernetadapter_singlethread.h" #include #include #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; } diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c index 3f16301..f74fc4a 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c @@ -39,29 +39,29 @@ */ 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; +} + diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c index 0a83453..999bdb8 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c @@ -20,9 +20,13 @@ #include "caethernetinterface.h" -#include +#include #include +#include +#include #include +#include +#include #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"); } diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c index 50dcc83..7207d8c 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c @@ -30,6 +30,9 @@ #include "pdu.h" #include "caadapterutils.h" +#ifdef __WITH_DTLS__ +#include "caadapternetdtls.h" +#endif #include "umutex.h" /** @@ -45,51 +48,22 @@ #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; +} diff --git a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawificlient.cpp b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawificlient.cpp index 15439e4..30e11d9 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawificlient.cpp +++ b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawificlient.cpp @@ -17,7 +17,7 @@ * limitations under the License. * ******************************************************************/ -#include "cawifiinterface.h" +#include "cawifiinterface_singlethread.h" #include #include @@ -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 diff --git a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifinwmonitor.cpp b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifinwmonitor.cpp index 6256e83..e2d313e 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifinwmonitor.cpp +++ b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifinwmonitor.cpp @@ -18,7 +18,7 @@ * ******************************************************************/ -#include "cawifiinterface.h" +#include "cawifiinterface_singlethread.h" #include #include @@ -29,7 +29,7 @@ #include #include "logger.h" #include "caadapterutils.h" -#include "cawifiadapter.h" +#include "cawifiadapter_singlethread.h" #define WIFI_MONITOR_TAG "WIFI_MONITOR" diff --git a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiserver.cpp b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiserver.cpp index 59906b0..951af15 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiserver.cpp +++ b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiserver.cpp @@ -18,7 +18,7 @@ * ******************************************************************/ -#include "cawifiinterface.h" +#include "cawifiinterface_singlethread.h" #include #include @@ -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; diff --git a/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c b/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c index ebba6be..9c5fd96 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c +++ b/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c @@ -35,14 +35,14 @@ #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) { diff --git a/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter_singlethread.c b/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter_singlethread.c index 3c4771d..e4797ee 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter_singlethread.c +++ b/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter_singlethread.c @@ -17,7 +17,7 @@ * limitations under the License. * ******************************************************************/ -#include "cawifiadapter.h" +#include "cawifiadapter_singlethread.h" #include #include @@ -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; } diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c index 24d337d..8cdbf3e 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c +++ b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c @@ -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"); diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c index a62d74f..9538e03 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c +++ b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c @@ -48,6 +48,12 @@ #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"); diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c index f3bd0b0..b288ed2 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c @@ -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; diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c index c7afc02..9538e03 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c @@ -30,6 +30,9 @@ #include "pdu.h" #include "caadapterutils.h" +#ifdef __WITH_DTLS__ +#include "caadapternetdtls.h" +#endif #include "umutex.h" /** @@ -45,6 +48,12 @@ #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, -- 2.7.4