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**********)
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)
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
name=cmsample
-sudo rm -rf $name-$version
+rm -rf $name-$version
builddir=`pwd`
sourcedir=`pwd`
#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
#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.
*/
{
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.
*/
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} addr;
- uint8_t ifindex;
+ uint8_t ifIndex;
} stCADtlsAddrInfo_t;
/**
* @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
const uint32_t port,
const void *data,
uint32_t dataLen,
- uint8_t *cacheFlag);
+ uint8_t *cacheFlag,
+ eDtlsAdapterType_t type);
/**
* @fn CAAdapterNetDtlsDecrypt
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
#ifndef _CA_ADAPTER_UTILS_H_
#define _CA_ADAPTER_UTILS_H_
+#include <stdbool.h>
+
#include "cacommon.h"
#include "logger.h"
#include "oic_malloc.h"
*/
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
**/
#include "cacommon.h"
#include "caadapterinterface.h"
-#ifndef ARDUINO
#include "uthreadpool.h" /* for thread pool */
-#endif //ARDUINO
#ifdef __cplusplus
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
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+/**
+ * @file caedradapter_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_
#include "cacommon.h"
#include "caadapterinterface.h"
-#ifndef ARDUINO
#include "uthreadpool.h" /* for thread pool */
-#endif //ARDUINO
#ifdef __cplusplus
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.
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file 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__
* @brief This file provides APIs ethernet client/server/network monitor modules
*/
-#ifndef _CA_ETHERNET_INTERFACE_
-#define _CA_ETHERNET_INTERFACE_
+#ifndef _CA_ETHERNET_INTERFACE_H_
+#define _CA_ETHERNET_INTERFACE_H_
#include <stdbool.h>
#include "cacommon.h"
-#ifndef ARDUINO
#include "uthreadpool.h" /* for thread pool */
-#endif //ARDUINO
#ifdef __cplusplus
extern "C"
* @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
* @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
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
*/
CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
const bool forceStart, const bool secured, int32_t *serverFD);
-#endif //ARDUINO
/**
* @fn CAEthernetStopMulticastServer
*/
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.
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.
*/
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.
*/
void CAEthernetSetUnicastPort(const int32_t port);
+#ifdef __WITH_DTLS__
/**
* @fn CAEthernetSetSecureUnicastSocket
* @brief API to set socket description for sending secured (encrypted) unicast UDP data
*
*/
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
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.
* @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
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.
*
}
#endif
-#endif //_CA_ETHERNET_INTERFACE_
+#endif //_CA_ETHERNET_INTERFACE_H_
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+/**
+ * @file caethernetinterface_singlethread.h
+ * @brief This file provides APIs ethernet client/server/network monitor modules
+ */
+
+#ifndef _CA_ETHERNET_INTERFACE_SINGLETHREAD_H_
+#define _CA_ETHERNET_INTERFACE_SINGLETHREAD_H_
+
+#include <stdbool.h>
+
+#include "cacommon.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @enum CAAdapterServerType_t
+ * @brief Enum for defining different server types.
+ */
+typedef enum
+{
+ CA_UNICAST_SERVER = 0,
+ CA_MULTICAST_SERVER,
+ CA_SECURED_UNICAST_SERVER
+} CAAdapterServerType_t;
+
+/**
+ * @fn CAEthernetPacketReceivedCallback
+ * @brief Callback to be notified on receival of any data from remote OIC devices.
+ *
+ * @param[in] ipAddress IP address of remote OIC device.
+ * @param[in] port Port number on which data is received.
+ * @param[in] data Data received from remote OIC device.
+ * @param[in] dataLength Length of data in bytes.
+ * @param[in] secure Indicates the data is secure or not.
+ *
+ * @pre Callback must be registered using CAEthernetSetPacketReceiveCallback()
+ */
+typedef void (*CAEthernetPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength);
+
+/**
+ * @fn CAEthernetExceptionCallback
+ * @brief Callback to be notified when exception occures on multicast/unicast server.
+ *
+ * @param[in] type Type of server either #CA_UNICAST_SERVER or $CA_MULTICAST_SERVER
+ *
+ * @pre Callback must be registered using CAEthernetSetExceptionCallback()
+ */
+typedef void (*CAEthernetExceptionCallback)(CAAdapterServerType_t type);
+
+/**
+ * @fn CAEthernetInitializeServer
+ * @brief API to initialize Ethernet server
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAEthernetInitializeServer(void);
+
+/**
+ * @fn CAEthernetTerminateServer
+ * @brief API to terminate Ethernet server
+ */
+void CAEthernetTerminateServer(void);
+
+/**
+ * @fn CAEthernetStartMulticastServer
+ * @brief API to start multicast server for specified multicast address and port
+ *
+ * @param[in] localAddress Local adapter address to which server to be binded.
+ * @param[in] multicastAddress Multicast group address.
+ * @param[in] multicastPort Port number on which server to be running.
+ * @param[out] serverFD Multicast server socket FD.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_SERVER_STARTED_ALREADY Multicast server is already started and running.
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
+ const int16_t multicastPort, int32_t *serverFD);
+
+/**
+ * @fn CAEthernetStartUnicastServer
+ * @brief API to start unicast server for specified local address and port
+ *
+ * @param[in] localAddress Local adapter address to which server to be binded.
+ * @param[in][out] port Port number on which server to be running.
+ * Port number on which server actually started will be returned.
+ * @param[in] forceStart Indicate whether to start server forcesfully on specified port or not.
+ * @param[in] secured true if the secure server to be started, otherwise false.
+ * @param[out] serverFD Unicast server socket FD.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, int32_t *serverFD);
+
+/**
+ * @fn CAEthernetStopMulticastServer
+ * @brief API to stop multicast server.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopMulticastServer(void);
+
+/**
+ * @fn CAEthernetStopUnicastServer
+ * @brief API to stop unicast server.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopUnicastServer();
+
+/**
+ * @fn CAEthernetStopSecureUnicastServer
+ * @brief API to stop secured unicast server.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopSecureUnicastServer();
+
+/**
+ * @fn CAEthernetGetUnicastServerInfo
+ * @brief API to get running unicast server information.
+ * @remarks @ipAddress must be freed using free().
+ *
+ * @param[in] secure true if the secure server information needed, otherwise false.
+ * @param[in] ipAddress IP address on which server is binded and running.
+ * @param[out] port Port number on which server is running
+ * @param[out] serverFD Server socket fd.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+
+CAResult_t CAEthernetGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
+
+/**
+ * @fn CAEthernetSetPacketReceiveCallback
+ * @brief API to set callback for receiving data packets from peer devices.
+ *
+ * @param[in] callback Callback to be notified on receival of unicast/multicast data packets.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback);
+
+/**
+ * @fn CAEthernetReadData
+ * @brief API to pull data
+ */
+void CAEthernetPullData();
+
+/**
+ * @fn CAEthernetSetExceptionCallback
+ * @brief API to set callback for receiving exception notifications.
+ *
+ * @param[in] callback Callback to be notified on occurance of exception running servers.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback);
+
+/**
+ * @fn CAEthernetSetUnicastSocket
+ * @brief API to set socket description for sending unicast UDP data
+ *
+ * @param[in] socketFD Socket descriptor used for sending UDP data.
+ *
+ */
+void CAEthernetSetUnicastSocket(const int32_t socketFD);
+
+/**
+ * @fn CAEthernetSetUnicastPort
+ * @brief API to set port description for sending unicast UDP data
+ *
+ * @param[in] port Port descriptor used for sending UDP data.
+ *
+ */
+void CAEthernetSetUnicastPort(const int32_t port);
+
+/**
+ * @fn CAEthernetSetSecureUnicastSocket
+ * @brief API to set socket description for sending secured (encrypted) unicast UDP data
+ *
+ * @param[in] socketFD Socket descriptor used for sending secured (encrypted) UDP data.
+ *
+ */
+void CAEthernetSetSecureUnicastSocket(const int32_t socketFD);
+
+/**
+ * @fn CAEthernetSendUnicastData
+ * @brief API to send unicast UDP data
+ *
+ * @param[in] remoteAddress IP address to which data needs to be send.
+ * @param[in] port Port to which data needs to be send.
+ * @param[in] data Data to be send.
+ * @param[in] dataLength Length of data in bytes
+ * @param[in] isMulticast whether data needs to be sent to multicast ip
+ * @param[in] isSecure Indicate the whether data needs to be send on secure channel.
+ * @isSecure will be ignored when @isMulticast is true.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+
+uint32_t CAEthernetSendData(const char *remoteAddress, const int16_t port,
+ const char *buf, const uint32_t bufLen, bool isMulticast);
+
+/**
+ * @fn CAEthernetConnectionStateChangeCallback
+ * @brief Callback to be notified when ethernet adapter connection state changes.
+ *
+ * @param[in] ipAddress IP address of remote OIC device.
+ * @param[in] status Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN.
+ *
+ * @pre Callback must be registered using CAEthernetSetConnectionStateChangeCallback()
+ */
+typedef void (*CAEthernetConnectionStateChangeCallback)(const char *ipAddress,
+ const CANetworkStatus_t status);
+
+ /**
+ * @fn CAEthernetInitializeServer
+ * @brief API to initialize Ethernet server
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAEthernetInitializeNetworkMonitor(void);
+
+/**
+ * @fn CAEthernetTerminateNetworkMonitor
+ * @brief API to terminate Ethernet network monitor
+ */
+void CAEthernetTerminateNetworkMonitor(void);
+
+/**
+ * @fn CAEthernetStartNetworkMonitor
+ * @brief API to start network monitoring process.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartNetworkMonitor(void);
+
+/**
+ * @fn CAEthernetStopNetworkMonitor
+ * @brief API to stop network monitoring process.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopNetworkMonitor(void);
+
+/**
+ * @fn CAEthernetGetInterfaceInfo
+ * @brief API to get local adapter network information.
+ * @remarks @interfaceName and @ipAddress must be freed using free().
+ *
+ * @param[out] interfaceName Local adapter interface name
+ * @param[out] ipAddress IP address
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetGetInterfaceInfo(char **interfaceName, char **ipAddress);
+
+/**
+ * @fn CAEthernetIsConnected
+ * @brief API to get ethernet adapter connection state.
+ *
+ * @return true if ethernet adapter is connected, otherwise false
+ */
+bool CAEthernetIsConnected(void);
+
+/**
+ * @fn CAEthernetSetConnectionStateChangeCallback
+ * @brief API to set callback for receiving local ethernet adapter connection status.
+ *
+ * @param[in] callback Callback to be notified when local ethernet adapter connection state changes.
+ *
+ */
+void CAEthernetSetConnectionStateChangeCallback(CAEthernetConnectionStateChangeCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CA_ETHERNET_INTERFACE_SINGLETHREAD_H_
#include "cacommon.h"
#include "caadapterinterface.h"
-#ifndef ARDUINO
#include "uthreadpool.h" /* for thread pool */
-#endif //ARDUINO
/**
* BLE Interface APIs.
* @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 . \
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file 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_
* @brief This file provides APIs for BLE modules
*/
-#ifndef _CA_LE_INTERFACE_
-#define _CA_LE_INTERFACE_
+#ifndef _CA_LE_INTERFACE_H_
+#define _CA_LE_INTERFACE_H_
#include <stdbool.h>
}
#endif
-#endif //_CA_LE_INTERFACE_
+#endif //_CA_LE_INTERFACE_H_
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+/**
+ * @file caleinterface_singlethread.h
+ * @brief This file provides APIs for BLE modules
+ */
+
+#ifndef _CA_LE_INTERFACE_SINGLETHREAD_H_
+#define _CA_LE_INTERFACE_SINGLETHREAD_H_
+
+#include <stdbool.h>
+
+#include "cacommon.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @ENUM TRANSFER_TYPE
+ * @brief Provide info about different mode of data transfer
+ *
+ * This enum is used to differentiate between unicast and multicast data transfer.
+ */
+typedef enum
+{
+ MULTICAST, /**< When this enum is selected, data will be updated to all OIC servers. */
+ UNICAST /**< When this enum is selected, data will be updated to desired OIC Server. */
+} TRANSFER_TYPE;
+
+/**
+* @fn CAStartBleGattServer
+* @brief Used to start Gatt Server thread for service creation and advertise ble service.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAStartBleGattServer();
+
+/**
+* @fn CAStopBleGattServer
+* @brief Used to terminate BLE Gatt Service.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAStopBleGattServer();
+
+/**
+* @fn CASetBLEReqRespServerCallback
+* @brief used to store upper layer callback locally which will be used to send the data
+* to application
+* @param[in] CANetworkPacketReceivedCallback - upper layer callback function
+* to pass the data to CA layer.
+* @return void
+*/
+void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback);
+
+/**
+* @fn CAUpdateCharacteristicsInGattServer
+* @brief Used to update characteristics(Read/Write) value that we want to send to particular client.
+* Both unicast and multicast will use the same api. In mulicast, we will be sending in loop to all clients.
+*
+* @param[in] charValue - data that we want to send to client(unicast)/clients(multicast)
+* @param[in] charValueLen - length of the data.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, const uint32_t charValueLen);
+
+/**
+* @fn CAStartBLEGattClient
+* @brief Used to start CAStartBleGattClientThread for initializing Gatt Client
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAStartBLEGattClient();
+
+/**
+* @fn CAStopBLEGattClient
+* @brief Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient function.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+void CAStopBLEGattClient();
+
+/**
+* @fn CATerminateBLEGattClient
+* @brief Used to unset all the callbacks and stop service discovery
+*
+* @return void
+*/
+void CATerminateBLEGattClient();
+
+/**
+* @fn CAUpdateCharacteristicsToGattServer
+* @brief Sets the value of characteristic and update the value to GATTServer(unicast).
+*
+* @param[in] remoteAddress The address of the remote device
+* @param[in] data The value of characteristic (byte array)
+* @param[in] dataLen The length of value
+* @param[in] TRANSFER_TYPE (UNICAST/MULTICAST)
+* @param[in] position The unique index of each ble server. Used for multicast feature.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data,
+ const int32_t dataLen, TRANSFER_TYPE type, const int32_t position);
+
+/**
+ * @fn CAUpdateCharacteristicsToAllGattServers
+ * @brief Sets the value of characteristic and update the value to All registered GATTServer -> Multicast
+ *
+ * @param[in] data The value of characteristic (byte array)
+ * @param[in] dataLen The length of value
+ *
+ * @return 0 on success otherwise a positive error value.
+ * @retval CA_STATUS_OK Successful
+ * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, const int32_t dataLen);
+
+/**
+ * @fn CASetBLEReqRespClientCallback
+ * @brief used to store upper layer callback locally which will be used to send the data to application
+ *
+ * @param[in] CANetworkPacketReceivedCallback - upper layer callback function to pass the data to CA layer.
+ *
+ * @return void
+ */
+void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CA_LE_INTERFACE_SINGLETHREAD_H_
* @brief This file contains message functionality.
*/
-#ifndef __CA_MESSAGE_HANDLER_H_
-#define __CA_MESSAGE_HANDLER_H_
+#ifndef __CA_MESSAGE_HANDLER_SINGLETHREAD_H_
+#define __CA_MESSAGE_HANDLER_SINGLETHREAD_H_
#include <stdint.h>
#include "cacommon.h"
} /* extern "C" */
#endif
-#endif //#ifndef __CA_MESSAGE_HANDLER_H_
+#endif //#ifndef __CA_MESSAGE_HANDLER_SINGLETHREAD_H_
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+/**
+ * @file 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_
*
******************************************************************/
/**
- * @file caretransmission.h
+ * @file caretransmission_singlethread.h
* @brief
*/
-#ifndef __CA_RETRANSMISSION_H_
-#define __CA_RETRANSMISSION_H_
+#ifndef __CA_RETRANSMISSION_SINGLETHREAD_H_
+#define __CA_RETRANSMISSION_SINGLETHREAD_H_
#include <stdint.h>
} /* extern "C" */
#endif
-#endif // __CA_RETRANSMISSION_H_
+#endif // __CA_RETRANSMISSION_SINGLETHREAD_H_
#include "cacommon.h"
#include "caadapterinterface.h"
-#ifndef ARDUINO
#include "uthreadpool.h" /* for thread pool */
-#endif //ARDUINO
#ifdef __cplusplus
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.
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file 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__
* @brief This file provides APIs wifi client/server/network monitor modules
*/
-#ifndef _CA_WIFI_INTERFACE_
-#define _CA_WIFI_INTERFACE_
+#ifndef _CA_WIFI_INTERFACE_H_
+#define _CA_WIFI_INTERFACE_H_
#include <stdbool.h>
#include "cacommon.h"
-#ifndef ARDUINO
#include "uthreadpool.h"
-#endif //ARDUINO
#ifdef __cplusplus
extern "C"
*
* @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.
* @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
* @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
* @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
*/
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.
* @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.
* @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
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.
*
}
#endif
-#endif //_CA_WIFI_INTERFACE_
+#endif //_CA_WIFI_INTERFACE_H_
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+/**
+ * @file cawifiinterface.h
+ * @brief This file provides APIs wifi client/server/network monitor modules
+ */
+
+#ifndef _CA_WIFI_INTERFACE_SINGLETHREAD_H_
+#define _CA_WIFI_INTERFACE_SINGLETHREAD_H_
+
+#include <stdbool.h>
+
+#include "cacommon.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @enum CAAdapterServerType_t
+ * @brief Enum for defining different server types.
+ */
+typedef enum
+{
+ CA_UNICAST_SERVER = 0,
+ CA_MULTICAST_SERVER,
+ CA_SECURED_UNICAST_SERVER
+} CAAdapterServerType_t;
+
+/**
+ * @fn CAWiFiPacketReceivedCallback
+ * @brief Callback to be notified on receival of any data from remote OIC devices.
+ *
+ * @param[in] ipAddress IP address of remote OIC device.
+ * @param[in] port Port number on which data is received.
+ * @param[in] data Data received from remote OIC device.
+ * @param[in] dataLength Length of data in bytes.
+ * @param[in] secure Indicates the data is secure or not.
+ *
+ * @pre Callback must be registered using CAWiFiSetPacketReceiveCallback()
+ */
+typedef void (*CAWiFiPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength);
+
+/**
+ * @fn CAWiFiExceptionCallback
+ * @brief Callback to be notified when exception occures on multicast/unicast server.
+ *
+ * @param[in] type Type of server either #CA_UNICAST_SERVER or $CA_MULTICAST_SERVER
+ *
+ * @pre Callback must be registered using CAWiFiSetExceptionCallback()
+ */
+typedef void (*CAWiFiExceptionCallback)(CAAdapterServerType_t type);
+
+/**
+ * @fn CAWiFiInitializeServer
+ * @brief API to initialize Wifi server
+ *
+ * @param[in] threadPool Thread pool for managing Unicast/Multicast server threads.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeServer(void);
+
+/**
+ * @fn CAWiFiTerminateServer
+ * @brief API to terminate Wifi server
+ */
+void CAWiFiTerminateServer(void);
+
+/**
+ * @fn CAWiFiStartMulticastServer
+ * @brief API to start multicast server for specified multicast address and port
+ *
+ * @param[in] localAddress Local adapter address to which server to be binded.
+ * @param[in] multicastAddress Multicast group address.
+ * @param[in] multicastPort Port number on which server to be running.
+ * @param[out] serverFD Multicast server socket FD.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_SERVER_STARTED_ALREADY Multicast server is already started and running.
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
+ const int16_t multicastPort, int32_t *serverFD);
+
+/**
+ * @fn CAWiFiStartUnicastServer
+ * @brief API to start unicast server for specified local address and port
+ *
+ * @param[in] localAddress Local adapter address to which server to be binded.
+ * @param[in][out] port Port number on which server to be running.
+ * Port number on which server actually started will be returned.
+ * @param[in] forceStart Indicate whether to start server forcesfully on specified port or not.
+ * @param[in] secured true if the secure server to be started, otherwise false.
+ * @param[out] serverFD Unicast server socket FD.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, int32_t *serverFD);
+
+/**
+ * @fn CAWiFiStopMulticastServer
+ * @brief API to stop multicast server.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopMulticastServer(void);
+
+/**
+ * @fn CAWiFiStopUnicastServer
+ * @brief API to stop unicast server.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopUnicastServer();
+
+#ifdef __WITH_DTLS__
+/**
+ * @fn CAWiFiStopSecureUnicastServer
+ * @brief API to stop secured unicast server.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopSecureUnicastServer();
+#endif
+
+/**
+ * @fn CAWiFiGetUnicastServerInfo
+ * @brief API to get running unicast server information.
+ * @remarks @ipAddress must be freed using free().
+ *
+ * @param[in] secure true if the secure server information needed, otherwise false.
+ * @param[in] ipAddress IP address on which server is binded and running.
+ * @param[out] port Port number on which server is running
+ * @param[out] serverFD Server socket fd.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
+
+/**
+ * @fn CAWiFiSetPacketReceiveCallback
+ * @brief API to set callback for receiving data packets from peer devices.
+ *
+ * @param[in] callback Callback to be notified on receival of unicast/multicast data packets.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback);
+
+/**
+ * @fn CAWiFiReadData
+ * @brief API to pull data
+ */
+void CAWiFiPullData();
+
+/**
+ * @fn CAWiFiSetExceptionCallback
+ * @brief API to set callback for receiving exception notifications.
+ *
+ * @param[in] callback Callback to be notified on occurance of exception running servers.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback);
+
+/**
+ * @fn CAWiFiSetUnicastSocket
+ * @brief API to set socket description for sending unicast UDP data
+ *
+ * @param[in] socketFD Socket descriptor used for sending UDP data.
+ *
+ */
+void CAWiFiSetUnicastSocket(const int32_t socketFD);
+
+#ifdef __WITH_DTLS__
+/**
+ * @fn CAWiFiSetSecureUnicastSocket
+ * @brief API to set socket description for sending secured (encrypted) unicast UDP data
+ *
+ * @param[in] socketFD Socket descriptor used for sending secured (encrypted) UDP data.
+ *
+ */
+void CAWiFiSetSecureUnicastSocket(const int32_t socketFD);
+#endif
+
+/**
+ * @fn CAWiFiSendUnicastData
+ * @brief API to send unicast UDP data
+ *
+ * @param[in] remoteAddress IP address to which data needs to be send.
+ * @param[in] port Port to which data needs to be send.
+ * @param[in] data Data to be send.
+ * @param[in] dataLength Length of data in bytes
+ * @param[in] isMulticast whether data needs to be sent to multicast ip
+ * @param[in] isSecure Indicate the whether data needs to be send on secure channel.
+ * @isSecure will be ignored when @isMulticast is true.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength, bool isMulticast);
+
+/**
+ * @fn CAWiFiConnectionStateChangeCallback
+ * @brief Callback to be notified when wifi adapter connection state changes.
+ *
+ * @param[in] ipAddress IP address of remote OIC device.
+ * @param[in] status Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN.
+ *
+ * @pre Callback must be registered using CAWiFiSetConnectionStateChangeCallback()
+ */
+typedef void (*CAWiFiConnectionStateChangeCallback)(const char *ipAddress,
+ const CANetworkStatus_t status);
+
+/**
+ * @fn CAWiFiInitializeNetworkMonitor
+ * @brief API to initialize Wifi network monitor
+ *
+ * @param[in] threadPool Thread pool for managing network monitor thread.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeNetworkMonitor(void);
+
+/**
+ * @fn CAWiFiInitializeServer
+ * @brief API to initialize Wifi server
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeNetworkMonitor(void);
+
+/**
+ * @fn CAWiFiTerminateNetworkMonitor
+ * @brief API to terminate Wifi network monitor
+ */
+void CAWiFiTerminateNetworkMonitor(void);
+
+/**
+ * @fn CAWiFiStartNetworkMonitor
+ * @brief API to start network monitoring process.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStartNetworkMonitor(void);
+
+/**
+ * @fn CAWiFiStopNetworkMonitor
+ * @brief API to stop network monitoring process.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopNetworkMonitor(void);
+
+/**
+ * @fn CAWiFiGetInterfaceInfo
+ * @brief API to get local adapter network information.
+ * @remarks @interfaceName and @ipAddress must be freed using free().
+ *
+ * @param[out] interfaceName Local adapter interface name
+ * @param[out] ipAddress IP address
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress);
+
+/**
+ * @fn CAWiFiIsConnected
+ * @brief API to get wifi adapter connection state.
+ *
+ * @return true if wifi adapter is connected, otherwise false
+ */
+bool CAWiFiIsConnected(void);
+
+/**
+ * @fn CAWiFiSetConnectionStateChangeCallback
+ * @brief API to set callback for receiving local wifi adapter connection status.
+ *
+ * @param[in] callback Callback to be notified when local wifi adapter connection state changes.
+ *
+ */
+void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CA_WIFI_INTERFACE_SINGLETHREAD_H_
#include "Arduino.h"
#include "caadapterinterface.h"
#include "cacommon.h"
-#include "caleadapter.h"
+#include "caleadapter_singlethread.h"
#include <TimedAction.h>
#include <logger.h>
#include "Arduino.h"
-#include "cawifiadapter.h"
+#include "cawifiadapter_singlethread.h"
#include <logger.h>
#include "caadapterinterface.h"
# *
#******************************************************************/
-cd ../../lib/libcoap-4.1.1
-make clean
-make
-
cd ../../build/linux
make clean
if echo $1 | grep -q -i "WITH_DTLS"
* @brief
*/
#define IDENTITY ("1111111111111111")
-
-/**
- * @def RS_CLIENT_PSK
+/* @def RS_CLIENT_PSK
* @brief
*/
#define RS_CLIENT_PSK ("AAAAAAAAAAAAAAAA")
int gReceived;
CABool_t gLocalUnicastPort;
CABool_t gLocalSecurePort;
+CAConnectivityType_t gSelectedNwType = CA_ETHERNET;
char get_menu();
void process();
return 0;
}
+#if 0
// network enable
// default
printf("select default network(WIFI)\n");
printf("CASelectNetwork fail\n");
return 0;
}
+#endif
// set handler.
res = CARegisterHandler(request_handler, response_handler);
return;
}
+ endpoint->connectivityType = gSelectedNwType;
+
char buf[MAX_BUF_LEN];
memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
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
{
printf("Failed to create duplicate of remote endpoint!\n");
return;
}
+ endpoint->connectivityType = object->connectivityType;
endpoint->isSecured = CA_TRUE;
object = endpoint;
}
===============================
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:
#include "cawifiinterface.h"
#include "dtls.h"
+
/**
* @def NET_DTLS_TAG
* @brief Logging tag for module name
{
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)
{
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)
{
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;
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;
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!");
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;
}
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);
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");
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)
{
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");
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);
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");
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);
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);
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);
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)
}
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;
}
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;
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);
}
gCaDtlsContext->callbacks.write = CASendSecureData;
- gCaDtlsContext->callbacks.read = CAReadDecryptedPayload;
+ gCaDtlsContext->callbacks.read = CAReadDecryptedPayload;
gCaDtlsContext->callbacks.event = CAHandleSecureEvent;
gCaDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
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)
{
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));
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!");
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!");
message->data = buf;
message->dataLen = dataLen;
- message->destSession = addrInfo;
+ message->destSession = addrInfo;
CAResult_t result = CADtlsCacheMsg(message);
if (CA_STATUS_OK == result)
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));
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!");
}
}
+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
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);
if (gServerState == TRUE)
{
CABTManagerStartServer();
- gServerState == FALSE;
+ gServerState = FALSE;
}
}
//Notity to upper layer
* limitations under the License.
*
******************************************************************/
-#include "caleadapter.h"
+#include "caleadapter_singlethread.h"
#include <TimedAction.h>
-#include "caleinterface.h"
+#include "caleinterface_singlethread.h"
#include "caleserver.h"
#include "logger.h"
#include "caadapterutils.h"
{
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 !");
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);
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;
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gReqRespCallback is NULL!");
u_mutex_unlock(gBleReqRespCbMutex);
+ OICFree(data);
return;
}
#include "cainterface.h"
#include "caremotehandler.h"
-#include "caprotocolmessage.h"
+#include "caprotocolmessage_singlethread.h"
#include "canetworkconfigurator.h"
#include "logger.h"
#include <stdint.h>
#include "cainterfacecontroller.h"
-#include "cawifiadapter.h"
#include "caethernetadapter.h"
#include "caedradapter.h"
#include "caleadapter.h"
#include "cawifiadapter.h"
-#include "caethernetadapter.h"
#include "canetworkconfigurator.h"
#include "caremotehandler.h"
#include "oic_malloc.h"
#include <string.h>
#include <stdint.h>
-#include "cawifiadapter.h"
-#include "caethernetadapter.h"
-#include "caedradapter.h"
-#include "caleadapter.h"
+#include "cawifiadapter_singlethread.h"
+#include "caethernetadapter_singlethread.h"
+#include "caedradapter_singlethread.h"
+#include "caleadapter_singlethread.h"
#include "canetworkconfigurator.h"
#include "oic_malloc.h"
if (!list)
{
- OIC_LOG(DEBUG, TAG, "No selected network");
return CA_STATUS_FAILED;
}
void *ptrType = NULL;
#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"
#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
{
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);
#define CA_BUFSIZE 128\r
#define CA_COAP_MESSAGE_CON 0\r
\r
-#ifdef __ARDUINO__\r
-#include "util.h"\r
-#else\r
#include <time.h>\r
-#endif //#ifdef __ARDUINO__\r
+\r
\r
uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo,\r
char *outUri)\r
// set random byte\r
uint32_t index;\r
\r
-#ifndef __ARDUINO__\r
srand(time(NULL));\r
-#endif //#ifndef __ARDUINO__\r
for (index = 0; index < CA_MAX_TOKEN_LEN; index++)\r
{\r
// use valid characters\r
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "caprotocolmessage_singlethread.h"
+#include "logger.h"
+#include "oic_malloc.h"
+
+#define TAG "CA"
+
+#define CA_MAX_TOKEN_LEN (8)
+#define CA_FLAGS_BLOCK 0x01
+#define CA_BUFSIZE 128
+#define CA_COAP_MESSAGE_CON 0
+
+#include "util.h"
+
+uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo,
+ char *outUri)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ if (NULL == pdu)
+ return 0;
+
+ uint32_t code = CA_NOT_FOUND;
+ CAGetRequestPDUInfo(pdu, &code, &(outReqInfo->info), outUri);
+ outReqInfo->method = code;
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return 1;
+}
+
+uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo,
+ char *outUri)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ if (NULL == pdu)
+ return 0;
+
+ uint32_t code = CA_NOT_FOUND;
+ CAGetRequestPDUInfo(pdu, &code, &(outResInfo->info), outUri);
+ outResInfo->result = code;
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return 1;
+}
+
+coap_pdu_t *CAGeneratePdu(const char *uri, const uint32_t code, const CAInfo_t info)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ coap_pdu_t *pdu;
+ char *coapUri = NULL;
+ uint32_t coapHeaderLength = 12;
+ uint32_t length;
+ coap_list_t *optlist = NULL;
+
+ if (NULL == uri)
+ return NULL;
+
+ length = strlen(uri);
+ if (CA_MAX_URI_LENGTH < length)
+ {
+ OIC_LOG(DEBUG, TAG, "URI len err");
+ return NULL;
+ }
+
+ coapUri = (char *) OICMalloc(length + coapHeaderLength + 1);
+ if (coapUri == NULL)
+ {
+ OIC_LOG(ERROR, TAG, "Mem alloc failed");
+ return NULL;
+ }
+ memset(coapUri, 0, length + coapHeaderLength + 1);
+
+ if (NULL != coapUri)
+ {
+ memcpy(coapUri, "coap://[::]/", coapHeaderLength);
+ memcpy(coapUri + coapHeaderLength, uri, length);
+
+ // parsing options in URI
+ CAParseURI(coapUri, &optlist);
+
+ // parsing options in HeadOption
+ CAParseHeadOption(code, info, &optlist);
+
+ OICFree(coapUri);
+ }
+
+ if (NULL != info.payload) // payload is include in request / response
+ {
+ if (!(pdu = CACreatePDUforRequestWithPayload((code_t) code, optlist, info.payload, info)))
+ return NULL;
+ }
+ else // payload is not include in request / response
+ {
+ if (!(pdu = CACreatePDUforRequest((code_t) code, optlist, info)))
+ return NULL;
+ }
+
+ // pdu print method : coap_show_pdu(pdu);
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return pdu;
+}
+
+coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ coap_pdu_t *outpdu = coap_new_pdu();
+
+ coap_pdu_parse((unsigned char *) data, length, outpdu);
+ (*outCode) = (uint32_t) outpdu->hdr->code;
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return outpdu;
+}
+
+coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *options,
+ const char *payload, const CAInfo_t info)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ coap_pdu_t *pdu;
+ coap_list_t *opt;
+
+ uint32_t CAFlags = 0;
+ coap_block_t CABlock =
+ { .num = 0, .m = 0, .szx = 6 };
+
+ if (!(pdu = coap_new_pdu()))
+ return NULL;
+
+ unsigned short message_id;
+
+ if (info.messageId == 0)
+ {
+ /* initialize message id */
+ prng((unsigned char * )&message_id, sizeof(unsigned short));
+ ++message_id;
+
+ OIC_LOG_V(DEBUG, TAG, "gen msg id(%d)", message_id);
+ }
+ else
+ {
+ /* use saved message id */
+ message_id = info.messageId;
+ }
+
+ pdu->hdr->type = info.type;
+ pdu->hdr->id = htons(message_id);
+ pdu->hdr->code = code;
+
+ if (info.token)
+ {
+ pdu->hdr->token_length = CA_MAX_TOKEN_LEN;
+ if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char *) info.token))
+ {
+ OIC_LOG(DEBUG, TAG, "cant add token");
+ }
+ }
+ for (opt = options; opt; opt = opt->next)
+ {
+ coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option * )opt->data),
+ COAP_OPTION_LENGTH(*(coap_option * )opt->data),
+ COAP_OPTION_DATA(*(coap_option * )opt->data));
+ }
+
+ if (NULL != payload)
+ {
+ uint32_t len = strlen(payload);
+ if ((CAFlags & CA_FLAGS_BLOCK) == 0)
+ {
+ OIC_LOG_V(DEBUG, TAG, "add data, payload: %s", payload);
+ coap_add_data(pdu, len, (const unsigned char *) payload);
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, TAG, "add block, payload: %s", payload);
+ coap_add_block(pdu, len, (const unsigned char *) payload, CABlock.num, CABlock.szx);
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return pdu;
+}
+
+coap_pdu_t *CACreatePDUforRequest(const code_t code, coap_list_t *options,
+ const CAInfo_t info)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ coap_pdu_t *pdu;
+ coap_list_t *opt;
+
+ if (!(pdu = coap_new_pdu()))
+ {
+ OIC_LOG(ERROR, TAG, "mem alloc failed");
+ return NULL;
+ }
+
+ unsigned short message_id;
+
+ if (info.messageId == 0)
+ {
+ /* initialize message id */
+ prng((unsigned char * )&message_id, sizeof(unsigned short));
+ ++message_id;
+
+ OIC_LOG_V(DEBUG, TAG, "gen msg id(%d)", message_id);
+ }
+ else
+ {
+ /* use saved message id */
+ message_id = info.messageId;
+ }
+
+ pdu->hdr->type = info.type;
+ pdu->hdr->id = htons(message_id);
+ pdu->hdr->code = code;
+
+ OIC_LOG_V(DEBUG, TAG, "token info : %s, %d", info.token, strlen(info.token));
+ pdu->hdr->token_length = CA_MAX_TOKEN_LEN;
+
+ if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char *) info.token))
+ {
+ OIC_LOG(DEBUG, TAG, "cant add data");
+ }
+
+ for (opt = options; opt; opt = opt->next)
+ {
+ coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option * )opt->data),
+ COAP_OPTION_LENGTH(*(coap_option * )opt->data),
+ COAP_OPTION_DATA(*(coap_option * )opt->data));
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return pdu;
+}
+
+void CAParseURI(const char *uriInfo, coap_list_t **optlist)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ unsigned char portbuf[2];
+ unsigned char _buf[CA_BUFSIZE];
+ unsigned char *buf = _buf;
+ coap_uri_t uri;
+ size_t buflen;
+ uint32_t res;
+
+ OIC_LOG_V(DEBUG, TAG, "url : %s", uriInfo);
+
+ /* split arg into Uri-* options */
+ coap_split_uri((unsigned char *) uriInfo, strlen(uriInfo), &uri);
+
+ if (uri.port != COAP_DEFAULT_PORT)
+ {
+ coap_insert(optlist,
+ CACreateNewOptionNode(COAP_OPTION_URI_PORT,
+ coap_encode_var_bytes(portbuf, uri.port), portbuf),
+ CAOrderOpts);
+ }
+
+ if (uri.path.length)
+ {
+ buflen = CA_BUFSIZE;
+ res = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
+
+ while (res--)
+ {
+ coap_insert(optlist,
+ CACreateNewOptionNode(COAP_OPTION_URI_PATH, COAP_OPT_LENGTH(buf),
+ COAP_OPT_VALUE(buf)), CAOrderOpts);
+ buf += COAP_OPT_SIZE(buf);
+ }
+ }
+
+ if (uri.query.length)
+ {
+ buflen = CA_BUFSIZE;
+ buf = _buf;
+ res = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);
+
+ while (res--)
+ {
+ coap_insert(optlist,
+ CACreateNewOptionNode(COAP_OPTION_URI_QUERY, COAP_OPT_LENGTH(buf),
+ COAP_OPT_VALUE(buf)), CAOrderOpts);
+
+ buf += COAP_OPT_SIZE(buf);
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ OIC_LOG_V(DEBUG, TAG, "parse Head Opt: %d", info.numOptions);
+
+ uint32_t i;
+ for (i = 0; i < info.numOptions; i++)
+ {
+ uint32_t id = info.options[i].optionID;
+ if (COAP_OPTION_URI_PATH == id || COAP_OPTION_URI_QUERY == id)
+ {
+ OIC_LOG_V(DEBUG, TAG, "not Header Opt: %d", id);
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, TAG, "Head Opt ID: %d", info.options[i].optionID);
+ OIC_LOG_V(DEBUG, TAG, "Head Opt data: %s", info.options[i].optionData);
+ OIC_LOG_V(DEBUG, TAG, "Head Opt len: %d", info.options[i].optionLength);
+
+ coap_insert(optlist,
+ CACreateNewOptionNode(info.options[i].optionID,
+ info.options[i].optionLength,
+ info.options[i].optionData), CAOrderOpts);
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length,
+ const uint8_t *data)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ coap_option *option;
+ coap_list_t *node;
+
+ option = coap_malloc(sizeof(coap_option) + length);
+ if (!option)
+ {
+ OIC_LOG(ERROR, TAG, "mem alloc failed");
+ return NULL;
+ }
+ memset(option, 0, sizeof(coap_option) + length);
+
+ COAP_OPTION_KEY(*option) = key;
+ COAP_OPTION_LENGTH(*option) = length;
+ memcpy(COAP_OPTION_DATA(*option), data, length);
+
+ /* we can pass NULL here as delete function since option is released automatically */
+ node = coap_new_listnode(option, NULL);
+
+ if (!node)
+ {
+ OIC_LOG(DEBUG, TAG, "new_listnode rets NULL");
+ coap_free(option);
+ return NULL;
+ }
+ //coap_free(option);
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return node;
+}
+
+int CAOrderOpts(void *a, void *b)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ if (!a || !b)
+ {
+ return a < b ? -1 : 1;
+ }
+
+ if (COAP_OPTION_KEY(*(coap_option *)a) < COAP_OPTION_KEY(*(coap_option * )b))
+ {
+ return -1;
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return COAP_OPTION_KEY(*(coap_option *)a) == COAP_OPTION_KEY(*(coap_option * )b);
+}
+
+uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ uint32_t count = 0;
+ coap_opt_t *option;
+
+ while ((option = coap_option_next(&opt_iter)))
+ {
+ if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)
+ {
+
+ }
+ else
+ {
+ count++;
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return count;
+}
+
+void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo,
+ char *outUri)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */
+ uint32_t encode = 0;
+ coap_opt_iterator_t opt_iter;
+ coap_opt_t *option;
+ char optionResult[CA_MAX_URI_LENGTH] =
+ { 0, };
+ uint32_t count = 0, idx = 0;
+ uint32_t optionLength = 0;
+ uint32_t isfirstsetflag = 0;
+
+ coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL);
+
+ memset(optionResult, 0, sizeof(optionResult));
+
+ // set code
+ (*outCode) = (uint32_t) pdu->hdr->code;
+
+ // init HeaderOption list
+ count = CAGetOptionCount(opt_iter);
+
+ memset(outInfo, 0, sizeof(CAInfo_t));
+ outInfo->numOptions = count;
+ // set type
+ outInfo->type = pdu->hdr->type;
+
+ // set message id
+ outInfo->messageId = ntohs(pdu->hdr->id);
+
+ if (count > 0)
+ {
+ outInfo->options = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * count);
+ if (outInfo->options == NULL)
+ {
+ OIC_LOG(DEBUG, TAG, "Mem alloc failed");
+ return;
+ }
+ memset(outInfo->options, 0, sizeof(CAHeaderOption_t) * count);
+ }
+
+ while ((option = coap_option_next(&opt_iter)))
+ {
+
+ if (CAGetOptionData((uint8_t *)(COAP_OPT_VALUE(option)),
+ COAP_OPT_LENGTH(option), (uint8_t *)buf, sizeof(buf),
+ encode))
+ {
+ if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)
+ {
+ if (0 == isfirstsetflag)
+ {
+ isfirstsetflag = 1;
+ memcpy(optionResult + optionLength, buf, strlen((const char *) buf));
+ optionLength += strlen((const char *) buf);
+
+ }
+ else
+ {
+ if (COAP_OPTION_URI_PATH == opt_iter.type)
+ {
+ memcpy(optionResult + optionLength, "/", 1);
+ optionLength++;
+ }
+ else if (COAP_OPTION_URI_QUERY == opt_iter.type)
+ {
+ memcpy(optionResult + optionLength, "?", 1);
+ optionLength++;
+ }
+ memcpy(optionResult + optionLength, buf, strlen((const char *) buf));
+ optionLength += strlen((const char *) buf);
+ }
+ }
+ else
+ {
+
+ if (idx < count)
+ {
+ uint32_t length = (uint32_t) strlen((const char *) buf);
+
+ if (length <= CA_MAX_HEADER_OPTION_DATA_LENGTH)
+ {
+ outInfo->options[idx].optionID = opt_iter.type;
+ outInfo->options[idx].optionLength = length;
+ outInfo->options[idx].protocolID = CA_COAP_ID;
+ memcpy(outInfo->options[idx].optionData, buf, length);
+ idx++;
+ }
+ }
+ }
+ }
+ }
+
+ // set token data
+ if (pdu->hdr->token_length > 0)
+ {
+ OIC_LOG(DEBUG, TAG, "pdu->hdr->token_length>0");
+ outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN);
+ if (outInfo->token == NULL)
+ {
+ OIC_LOG(DEBUG, TAG, "Mem alloc failed");
+ OICFree(outInfo->options);
+ return;
+ }
+ memcpy(outInfo->token, pdu->hdr->token, CA_MAX_TOKEN_LEN);
+ }
+
+ // set payload data
+ if (NULL != pdu->data)
+ {
+ OIC_LOG(DEBUG, TAG, "inside pdu->data");
+ outInfo->payload = (char *) OICMalloc(strlen((const char *) pdu->data) + 1);
+ if (outInfo->payload == NULL)
+ {
+ OIC_LOG(DEBUG, TAG, "Mem alloc failed");
+ OICFree(outInfo->options);
+ OICFree(outInfo->token);
+ return;
+ }
+ memcpy(outInfo->payload, pdu->data, strlen((const char *) pdu->data) + 1);
+ }
+
+
+ memcpy(outUri, optionResult, strlen(optionResult));
+ OIC_LOG_V(DEBUG, TAG, "made URL:%s\n", optionResult);
+ OIC_LOG(DEBUG, TAG, "OUT");
+
+}
+
+CAResult_t CAGenerateTokenInternal(CAToken_t *token)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ if (token == NULL)
+ {
+ return CA_STATUS_FAILED;
+ }
+
+ // memory allocation
+ char *temp = (char *) OICMalloc(sizeof(char) * (CA_MAX_TOKEN_LEN + 1));
+ if (temp == NULL)
+ {
+ OIC_LOG(DEBUG, TAG, "Mem alloc failed");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ memset(temp, 0, sizeof(char) * (CA_MAX_TOKEN_LEN + 1));
+
+ // set random byte
+ uint32_t index;
+
+ for (index = 0; index < CA_MAX_TOKEN_LEN; index++)
+ {
+ // use valid characters
+ temp[index] = (rand() % 94 + 33) & 0xFF;
+ }
+
+ temp[index] = '\0';
+ // save token
+ *token = temp;
+
+ OIC_LOG_V(DEBUG, TAG, "gen token(%s)", *token);
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CADestroyTokenInternal(CAToken_t token)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ if (token != NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "destroy token(%s)!!", token);
+
+ OICFree(token);
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CADeinitialize(CAInfo_t *info)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ if (NULL != info)
+ {
+ if (NULL != info->options)
+ {
+ OIC_LOG(DEBUG, TAG, "free opt");
+ OICFree(info->options);
+ }
+
+ if (NULL != info->token)
+ {
+ OIC_LOG(DEBUG, TAG, "free tok");
+ OICFree(info->token);
+ }
+
+ if (NULL != info->payload)
+ {
+ OIC_LOG(DEBUG, TAG, "free payld");
+ OICFree(info->payload);
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result,
+ uint32_t buflen, uint32_t encode_always)
+{
+ const unsigned char hex[] = "0123456789ABCDEF";
+ uint32_t cnt = 0;
+ assert(data || len == 0);
+
+ if (buflen == 0 || len == 0)
+ return 0;
+
+ while (len)
+ {
+ if (!encode_always)
+ {
+ if (cnt == buflen)
+ break;
+ *result++ = *data;
+ ++cnt;
+ }
+ else
+ {
+ if (cnt + 4 < buflen)
+ {
+ *result++ = '\\';
+ *result++ = 'x';
+ *result++ = hex[(*data & 0xf0) >> 4];
+ *result++ = hex[*data & 0x0f];
+ cnt += 4;
+ }
+ else
+ break;
+ }
+
+ ++data;
+ --len;
+ }
+
+ *result = '\0';
+ return cnt;
+}
+
+CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void* pdu, uint32_t size)
+{
+ // pdu minimum size is 4 byte.
+ if (size < 4)
+ return CA_MSG_NONCONFIRM;
+
+ coap_hdr_t* hdr = (coap_hdr_t*) pdu;
+
+ return (CAMessageType_t) hdr->type;
+}
+
+uint16_t CAGetMessageIdFromPduBinaryData(const void* pdu, uint32_t size)
+{
+ // pdu minimum size is 4 byte.
+ if (size < 4)
+ return 0;
+
+ coap_hdr_t* hdr = (coap_hdr_t*) pdu;
+
+ return ntohs(hdr->id);
+}
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);
#include <TimedAction.h>
#include "caremotehandler.h"
-#include "caprotocolmessage.h"
+#include "caprotocolmessage_singlethread.h"
#include "oic_malloc.h"
#include "logger.h"
-#define TAG "RET"
+#define TAG "RT"
typedef struct
{
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;
}
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)
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);
}
// #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);
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;
// Enable TimedAction for CACheckRetransmissionList API
gRetransmissionPtr = context;
gRcvAction.enable();
-
+ OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
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");
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));
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);
// #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;
}
// 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)
// #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;
}
#include "logger.h"
#include "cacommon.h"
#include "caadapterinterface.h"
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
#include "caadapterutils.h"
#define MOD_NAME "EU"
#include "logger.h"
#include "cacommon.h"
#include "caadapterinterface.h"
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
#include "caadapterutils.h"
#ifdef __cplusplus
* limitations under the License.
*
******************************************************************/
-#include "caethernetinterface.h"
+#include "caethernetinterface_singlethread.h"
#include <Arduino.h>
#include <Ethernet.h>
#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"
*
******************************************************************/
-#include "caethernetinterface.h"
+#include "caethernetinterface_singlethread.h"
#include <Arduino.h>
#include <Ethernet.h>
#include <IPAddress.h>
#include "logger.h"
#include "caadapterutils.h"
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
#define ETHERNET_MONITOR_TAG "ETHERNET_MONITOR"
*
******************************************************************/
-#include "caethernetinterface.h"
+#include "caethernetinterface_singlethread.h"
#include <Arduino.h>
#include <Ethernet.h>
#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"
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 };
#include "caethernetinterface.h"
#include "caqueueingthread.h"
#include "caadapterutils.h"
+#ifdef __WITH_DTLS__
+#include "caadapternetdtls.h"
+#endif
#include "umutex.h"
#include "logger.h"
#include "oic_malloc.h"
/**
- * @def WIFI_ETHERNET_ADAPTER_TAG
+ * @def ETHERNET_ADAPTER_TAG
* @brief Logging tag for module name
*/
#define ETHERNET_ADAPTER_TAG "ETHERNET_ADAP"
* @def CA_PORT
* @brief Port to listen for incoming data
*/
-#define CA_PORT 5283
+#define CA_PORT 5683
+
+/**
+ * @def CA_PORT
+ * @brief Port to listen for incoming data
+ */
+#define CA_SECURE_PORT 5684
/**
* @def CA_MCAST_PORT
* @var gEthernetNetworkChangeCallback
* @brief Network Changed Callback to CA
*/
-CANetworkChangeCallback gEthernetNetworkChangeCallback = NULL;
+static CANetworkChangeCallback gNetworkChangeCallback = NULL;
/**
* @var gIsMulticastServerStarted
*/
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.
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,
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)
{
}
localEndpoint->addressInfo.IP.port = port;
- if (NULL != gEthernetNetworkChangeCallback)
+ if (NULL != gNetworkChangeCallback)
{
- gEthernetNetworkChangeCallback(localEndpoint, status);
+ gNetworkChangeCallback(localEndpoint, status);
}
CAAdapterFreeLocalEndpoint(localEndpoint);
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);
{
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;
}
}
- 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)
{
return;
}
endPoint->addressInfo.IP.port = port;
+ endPoint->isSecured = isSecured;
void *buf = OICMalloc(dataLength + 1);
if (NULL == buf)
{
gNetworkPacketCallback(endPoint, buf, dataLength);
}
+
OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
}
VERIFY_NON_NULL(handle, ETHERNET_ADAPTER_TAG, "thread pool handle");
gThreadPool = handle;
- gEthernetNetworkChangeCallback = netCallback;
+ gNetworkChangeCallback = netCallback;
gNetworkPacketCallback = networkPacketCallback;
CAResult_t ret = CAEthernetInitializeNetworkMonitor(gThreadPool);
CATerminateEthernet();
return ret;
}
+
CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCB);
+#ifdef __WITH_DTLS__
+ CAAdapterNetDtlsInit();
+ CADTLSSetAdapterCallbacks(CAEthernetPacketReceivedCB, CAEthernetPacketSendCB, DTLS_ETHERNET);
+#endif
CAConnectivityHandler_t ethernetHandler;
ethernetHandler.startAdapter = CAStartEthernet;
}
OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "IntializeEthernet is Success");
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
{
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;
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);
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;
}
{
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;
}
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();
}
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)
{
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;
}
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()
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;
}
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,
CAFreeEthernetData(ethernetData);
return NULL;
}
+
memcpy(ethernetData->data, data, dataLength);
ethernetData->dataLen = dataLength;
void CAFreeEthernetData(CAEthernetData *ethernetData)
{
if (!ethernetData)
+ {
return;
+ }
CAAdapterFreeRemoteEndpoint(ethernetData->remoteEndpoint);
OICFree(ethernetData->data);
*
******************************************************************/
-#include "caethernetadapter.h"
+#include "caethernetadapter_singlethread.h"
#include <stdio.h>
#include <stdint.h>
#include "caadapterutils.h"
#include "logger.h"
#include "oic_malloc.h"
-#include "caethernetinterface.h"
+#include "caethernetinterface_singlethread.h"
/**
* @def ETHERNET_ADAPTER_TAG
/**
* @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
CAAdapterFreeLocalEndpoint(localEndpoint);
}
-void CAEthernetConnectionStateCB(const char *ipAddress,
+void CAEthernetConnectionStateCB(const char *ipAddr,
const CANetworkStatus_t status)
{
OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
CAResult_t CAReadEthernetData()
{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
CAEthernetPullData();
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
*/
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;
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;
+}
+
#include "caethernetinterface.h"
-#include <string.h>
+#include <sys/types.h>
#include <ifaddrs.h>
+#include <net/if.h>
+#include <sys/socket.h>
#include <netdb.h>
+#include <string.h>
+#include <errno.h>
#include "caadapterutils.h"
#include "umutex.h"
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
*/
* @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);
}
u_mutex_lock(gEthernetNetInfoMutex);
- CAEthernetGetInterfaceInformation(&gEthernetInterfaceName, &gEthernetIPAddress);
+ CAEthernetGetInterfaceInformation(&gEthernetInterfaceName, &gEthernetIPAddress, &gEthernetSubnetMask);
u_mutex_unlock(gEthernetNetInfoMutex);
nwConnectivityStatus = (gEthernetIPAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
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,
if (gStopNetworkMonitor)
{
- OIC_LOG(DEBUG, ETHERNET_MONITOR_TAG, "CAEthernetStopNetworkMonitor, already stopped");
-
+ OIC_LOG(DEBUG, ETHERNET_MONITOR_TAG, "CAEthernetStopNetworkMonitor, already stopped!");
return CA_STATUS_OK;
}
{
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");
{
OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
- if (nwConnectivityStatus == CA_INTERFACE_DOWN)
+ if (CA_INTERFACE_DOWN == nwConnectivityStatus)
return false;
return true;
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);
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;
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);
}
OICFree(interfaceName);
OICFree(ipAddress);
+ OICFree(subnetMask);
}
+
+ OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "OUT");
}
#include "pdu.h"
#include "caadapterutils.h"
+#ifdef __WITH_DTLS__
+#include "caadapternetdtls.h"
+#endif
#include "umutex.h"
/**
#define CA_UDP_BIND_RETRY_COUNT 10
/**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @def IPNAMESIZE
+ * @brief max length for ip
*/
-static int32_t gUnicastServerSocketDescriptor = -1;
+#define IPNAMESIZE 16
/**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gUnicastServerSocketFD
+ * @brief Unicast server socket descriptor
*/
-static char *gUnicastServerAddress = NULL;
+static int32_t gUnicastServerSocketFD = -1;
/**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gMutexUnicastServer
+ * @brief Mutex to synchronize unicast server
*/
-static int16_t gUnicastServerPort = -1;
-
-/**
- * @var gMutexUnicastServerSocketDescriptor
- * @brief Mutex for socket descriptor for unicast server
- */
-static u_mutex gMutexUnicastServerSocketDescriptor = NULL;
-/**
- * @var gMulticastServerSocketDescriptor
- * @brief socket descriptor for multicast server
- */
-static int32_t gMulticastServerSocketDescriptor = -1;
-
-/**
- * @var gMutexMulticastServerSocketDescriptor
- * @brief Mutex for socket descriptor for Multicast server
- */
-static u_mutex gMutexMulticastServerSocketDescriptor = NULL;
-
-/**
- * @var gThreadPool
- * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
- */
-static u_thread_pool_t gThreadPool = NULL;
-
-/**
- * @var gMReq
- * @brief ip_mreq structure passed to join a multicast group
- */
-static struct ip_mreq gMReq;
+static u_mutex gMutexUnicastServer = NULL;
/**
* @var gStopUnicast
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
*/
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;
}
}
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
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;
}
/**
* 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;
+}
* limitations under the License.
*
******************************************************************/
-#include "cawifiinterface.h"
+#include "cawifiinterface_singlethread.h"
#include <Arduino.h>
#include <WiFi.h>
#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
*
******************************************************************/
-#include "cawifiinterface.h"
+#include "cawifiinterface_singlethread.h"
#include <Arduino.h>
#include <WiFi.h>
#include <IPAddress.h>
#include "logger.h"
#include "caadapterutils.h"
-#include "cawifiadapter.h"
+#include "cawifiadapter_singlethread.h"
#define WIFI_MONITOR_TAG "WIFI_MONITOR"
*
******************************************************************/
-#include "cawifiinterface.h"
+#include "cawifiinterface_singlethread.h"
#include <Arduino.h>
#include <WiFi.h>
#include "cacommon.h"
#include "cainterface.h"
#include "caadapterinterface.h"
-#include "cawifiadapter.h"
+#include "cawifiadapter_singlethread.h"
#include "caadapterutils.h"
#include "oic_malloc.h"
{
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;
#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
* @var gNetworkChangeCb
* @brief Network Changed Callback to CA
*/
-CANetworkChangeCallback gNetworkChangeCallback = NULL;
+static CANetworkChangeCallback gNetworkChangeCallback = NULL;
/**
* @var gIsMulticastServerStarted
*/
static int16_t gSecureUnicastServerport = 0;
#endif
+
/**
* @var gIsStartServerCalled
* @brief Flag to check if server start requested by CA.
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,
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)
{
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;
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)
{
CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
#ifdef __WITH_DTLS__
CAAdapterNetDtlsInit();
- CADTLSSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
+ CADTLSSetAdapterCallbacks(CAWiFiPacketReceivedCB, CAWiFiPacketSendCB, DTLS_WIFI);
#endif
CAConnectivityHandler_t wifiHandler;
}
OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi is Success");
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
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);
#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);
gSecureUnicastServerport = unicastPort;
}
#endif
-
+ OICFree(ifcName);
+ OICFree(ifcAdrs);
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
return ret;;
}
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;
}
// Stop wifi network monitor
CAWiFiStopNetworkMonitor();
- //Stop send queue thread
+ // Stop send queue thread
if (gSendQueueHandle && CA_FALSE == gSendQueueHandle->isStop)
{
CAQueueingThreadStop(gSendQueueHandle);
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
#ifdef __WITH_DTLS__
- CADTLSSetPacketReceiveCallback(NULL);
+ CADTLSSetAdapterCallbacks(NULL, NULL, DTLS_WIFI);
CAAdapterNetDtlsDeInit();
#endif
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)
{
* limitations under the License.
*
******************************************************************/
-#include "cawifiadapter.h"
+#include "cawifiadapter_singlethread.h"
#include <stdio.h>
#include <stdlib.h>
#include "caadapterutils.h"
#include "logger.h"
#include "oic_malloc.h"
-#include "cawifiinterface.h"
+#include "cawifiinterface_singlethread.h"
/**
* @def WIFI_ETHERNET_ADAPTER_TAG
/**
* @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
CAAdapterFreeLocalEndpoint(localEndpoint);
}
-void CAWiFiConnectionStateCB(const char *ipAddress,
+void CAWiFiConnectionStateCB(const char *ipAddr,
const CANetworkStatus_t status)
{
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
CAResult_t CAReadWIFIData()
{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
CAWiFiPullData();
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
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
*/
* @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);
}
u_mutex_lock(gWifiNetInfoMutex);
- CAWiFiGetInterfaceInformation(&gWifiInterfaceName, &gWifiIPAddress);
+ CAWiFiGetInterfaceInformation(&gWifiInterfaceName, &gWifiIPAddress, &gWifiSubnetMask);
u_mutex_unlock(gWifiNetInfoMutex);
nwConnectivityStatus = (gWifiIPAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
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;
// 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))
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");
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;
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
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");
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;
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);
}
OICFree(interfaceName);
OICFree(ipAddress);
+ OICFree(subnetMask);
}
OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
#define CA_UDP_BIND_RETRY_COUNT 10
/**
+ * @def IPNAMESIZE
+ * @brief max length for ip
+ */
+#define IPNAMESIZE 16
+
+/**
* @var gUnicastServerSocketFD
* @brief Unicast server socket descriptor
*/
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
*/
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;
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:
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;
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
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++)
{
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;
if (!gMutexSecureUnicastServer)
{
OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+ CAWiFiServerDestroyMutex();
return CA_STATUS_FAILED;
}
#endif
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");
// 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,
}
*serverFD = gMulticastServerSocketFD;
+ strncpy(gMulticastServerInterface, localAddress, sizeof(gMulticastServerInterface));
u_mutex_unlock(gMutexMulticastServer);
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
static char *gWifiIPAddress = NULL;
/**
+ * @var gWifiSubnetMask
+ * @brief Maintains interface subnetmask.
+ */
+static char *gWifiSubnetMask = NULL;
+
+/**
* @var gNetworkChangeCb
* @brief Maintains network connection state change callback.
*/
* @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)
{
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");
// 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);
}
return;
}
-void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
+void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress, char **subnetMask)
{
OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
}
}
+ // 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;
#include "pdu.h"
#include "caadapterutils.h"
+#ifdef __WITH_DTLS__
+#include "caadapternetdtls.h"
+#endif
#include "umutex.h"
/**
#define CA_UDP_BIND_RETRY_COUNT 10
/**
+ * @def IPNAMESIZE
+ * @brief max length for ip
+ */
+#define IPNAMESIZE 16
+
+/**
* @var gUnicastServerSocketFD
* @brief Unicast server socket descriptor
*/
static int32_t gSecureUnicastServerSocketFD = -1;
/**
- * @var gMutexUnicastServer
+ * @var gMutexSecureUnicastServer
* @brief Mutex to synchronize secure unicast server
*/
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
/**
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
*/
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));
}
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;
}
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));
}
// 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;
}
}
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
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;
}
if (!gMutexSecureUnicastServer)
{
OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+ CAWiFiServerDestroyMutex();
return CA_STATUS_FAILED;
}
#endif
}
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;
}
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;
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;
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,
* 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!");
}
*serverFD = gMulticastServerSocketFD;
+ strncpy(gMulticastServerInterface, localAddress, sizeof(gMulticastServerInterface));
u_mutex_unlock(gMutexMulticastServer);
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
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__
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
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,