X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fconnectivity%2Fsrc%2Fip_adapter%2Fcaipadapter.c;h=d6b1b89944aacf07e2af684ed4ba4a5b92250c06;hb=bdec944c51c8e0063b6ee0890170e828ac8f2b96;hp=43ca8fa76c500ba451ab42f3fd8bc748fb8a1a8f;hpb=643ee9800bea92cfba6d22e70189ffe829cfaf61;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/connectivity/src/ip_adapter/caipadapter.c b/resource/csdk/connectivity/src/ip_adapter/caipadapter.c index 43ca8fa..d6b1b89 100644 --- a/resource/csdk/connectivity/src/ip_adapter/caipadapter.c +++ b/resource/csdk/connectivity/src/ip_adapter/caipadapter.c @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -24,13 +24,18 @@ #include #include +#include "caipnwmonitor.h" #include "caipinterface.h" #include "caqueueingthread.h" #include "caadapterutils.h" #ifdef __WITH_DTLS__ -#include "caadapternetdtls.h" +#include "ca_adapter_net_ssl.h" +#ifdef WITH_TCP +#include "catcpinterface.h" #endif -#include "camutex.h" +#endif + +#include "octhread.h" #include "uarraylist.h" #include "caremotehandler.h" #include "logger.h" @@ -38,43 +43,13 @@ #include "oic_string.h" /** - * @def IP_ADAPTER_TAG - * @brief Logging tag for module name - */ -#define IP_ADAPTER_TAG "IPAD" - -/** - * @def CA_PORT - * @brief Port to listen for incoming data - */ -#ifdef ARDUINO -#define CA_PORT 55555 -#else -#define CA_PORT 0 -#endif - -/** - * @def CA_SECURE_PORT - * @brief Secured (unicast) port number as defined in COAP Specification, RFC-7252. - */ -#define CA_SECURE_PORT 5684 - -/** - * @def CA_MCAST_PORT - * @brief Multicast port number as defined in COAP Specification, RFC-7252. - */ -#define CA_MCAST_PORT 5683 - -/** - * @def CA_MULTICAST_IP - * @brief Multicast IP Address as defined in COAP Specification, RFC-7252. + * Logging tag for module name. */ -#define CA_MULTICAST_IP "224.0.1.187" +#define TAG "OIC_CA_IP_ADAP" #ifndef SINGLE_THREAD /** - * @var CAIPData - * @brief Holds inter thread ip data information. + * Holds inter thread ip data information. */ typedef struct { @@ -82,55 +57,36 @@ typedef struct void *data; uint32_t dataLen; bool isMulticast; -} CAIPData; +} CAIPData_t; /** - * @var g_sendQueueHandle - * @brief Queue handle for Send Data + * Queue handle for Send Data. */ static CAQueueingThread_t *g_sendQueueHandle = NULL; #endif /** - * @var g_networkPacketCallback - * @brief Network Packet Received Callback to CA + * Network Packet Received Callback to CA. */ static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL; /** - * @var g_networkChangeCallback - * @brief Network Changed Callback to CA + * Network Changed Callback to CA. */ -static CANetworkChangeCallback g_networkChangeCallback = NULL; +static CAAdapterChangeCallback g_networkChangeCallback = NULL; /** - * @var g_errorCallback - * @brief error Callback to CA adapter + * error Callback to CA adapter. */ static CAErrorHandleCallback g_errorCallback = NULL; -/** - * @var g_threadPool - * @brief ThreadPool for storing ca_thread_pool_t handle passed from CA - */ -static ca_thread_pool_t g_threadPool = NULL; - -static void CAIPNotifyNetworkChange(const char *address, uint16_t port, - CANetworkStatus_t status); - -static void CAIPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status); - -static void CAIPPacketReceivedCB(const CAEndpoint_t *endpoint, - const void *data, uint32_t dataLength); -static void CAIPErrorHandler(const CAEndpoint_t *endpoint, const void *data, - uint32_t dataLength, CAResult_t result); +static CAResult_t CAIPPacketReceivedCB(const CASecureEndpoint_t *endpoint, + const void *data, size_t dataLength); #ifdef __WITH_DTLS__ -static uint32_t CAIPPacketSendCB(const CAEndpoint_t *endpoint, - const void *data, uint32_t dataLength); +static ssize_t CAIPPacketSendCB(CAEndpoint_t *endpoint, + const void *data, size_t dataLength); #endif -static CAResult_t CAIPStopServers(); - #ifndef SINGLE_THREAD static CAResult_t CAIPInitializeQueueHandles(); @@ -139,20 +95,20 @@ static void CAIPDeinitializeQueueHandles(); static void CAIPSendDataThread(void *threadData); -static CAIPData *CACreateIPData(const CAEndpoint_t *remoteEndpoint, - const void *data, uint32_t dataLength, bool isMulticast); -void CAFreeIPData(CAIPData *ipData); +static CAIPData_t *CACreateIPData(const CAEndpoint_t *remoteEndpoint, + const void *data, uint32_t dataLength, + bool isMulticast); + +void CAFreeIPData(CAIPData_t *ipData); static void CADataDestroyer(void *data, uint32_t size); CAResult_t CAIPInitializeQueueHandles() { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - // Check if the message queue is already initialized if (g_sendQueueHandle) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "send queue handle is already initialized!"); + OIC_LOG(DEBUG, TAG, "send queue handle is already initialized!"); return CA_STATUS_OK; } @@ -160,752 +116,446 @@ CAResult_t CAIPInitializeQueueHandles() g_sendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t)); if (!g_sendQueueHandle) { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory allocation failed!"); + OIC_LOG(ERROR, TAG, "Memory allocation failed!"); return CA_MEMORY_ALLOC_FAILED; } - if (CA_STATUS_OK != CAQueueingThreadInitialize(g_sendQueueHandle, g_threadPool, - CAIPSendDataThread, CADataDestroyer)) + if (CA_STATUS_OK != CAQueueingThreadInitialize(g_sendQueueHandle, + (const ca_thread_pool_t)caglobals.ip.threadpool, + CAIPSendDataThread, CADataDestroyer)) { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Initialize send queue thread"); + OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread"); OICFree(g_sendQueueHandle); g_sendQueueHandle = NULL; return CA_STATUS_FAILED; } - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); return CA_STATUS_OK; } void CAIPDeinitializeQueueHandles() { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - CAQueueingThreadDestroy(g_sendQueueHandle); OICFree(g_sendQueueHandle); g_sendQueueHandle = NULL; - - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); } -void CAIPSendDataThread(void *threadData) -{ - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - - CAIPData *ipData = (CAIPData *) threadData; - uint32_t sentData = -1; - - if (!ipData) - { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "Invalid ip data!"); - return; - } - - if (ipData->isMulticast) - { - //Processing for sending multicast - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "Send Multicast Data is called"); - strncpy(ipData->remoteEndpoint->addr, CA_MULTICAST_IP, MAX_ADDR_STR_SIZE_CA); - ipData->remoteEndpoint->port = CA_MCAST_PORT; - sentData = CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, true); - } - else - { - //Processing for sending unicast -#ifdef __WITH_DTLS__ - if (ipData->remoteEndpoint->flags & CA_SECURE) - { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt called!"); - CAResult_t result = CAAdapterNetDtlsEncrypt(ipData->remoteEndpoint, - ipData->data, ipData->dataLen); - if (CA_STATUS_OK != result) - { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt failed!"); - sentData = 0; - } - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, - "CAAdapterNetDtlsEncrypt returned with result[%d]", result); - } - else - { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "Send Unicast Data is called"); - sentData = CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, false); - } -#else - sentData = CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, false); -#endif - } - - if (0 == sentData) - { - g_errorCallback(ipData->remoteEndpoint, ipData->data, ipData->dataLen, - CA_SEND_FAILED); - } - - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); -} - -CAIPData *CACreateIPData(const CAEndpoint_t *remoteEndpoint, const void *data, - uint32_t dataLength, bool isMulticast) -{ - VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "IPData is NULL", NULL); - - CAIPData *ipData = (CAIPData *) OICMalloc(sizeof(CAIPData)); - if (!ipData) - { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory allocation failed!"); - return NULL; - } - - ipData->remoteEndpoint = CACloneEndpoint(remoteEndpoint); - ipData->data = (void *) OICMalloc(dataLength); - if (!ipData->data) - { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory allocation failed!"); - CAFreeIPData(ipData); - return NULL; - } - - memcpy(ipData->data, data, dataLength); - ipData->dataLen = dataLength; - - ipData->isMulticast = isMulticast; - - return ipData; -} - -void CAFreeIPData(CAIPData *ipData) -{ - VERIFY_NON_NULL_VOID(ipData, IP_ADAPTER_TAG, "ipData is NULL"); - - CAFreeEndpoint(ipData->remoteEndpoint); - OICFree(ipData->data); - OICFree(ipData); -} - -void CADataDestroyer(void *data, uint32_t size) -{ - CAIPData *etdata = (CAIPData *) data; - - CAFreeIPData(etdata); -} -#endif +#endif // SINGLE_THREAD -void CAIPNotifyNetworkChange(const char *address, uint16_t port, CANetworkStatus_t status) +void CAIPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - - VERIFY_NON_NULL_VOID(address, IP_ADAPTER_TAG, "address is NULL"); - - CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS, - CA_ADAPTER_IP, - address, port); - if (!localEndpoint) - { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "localEndpoint creation failed!"); - return; - } - if (g_networkChangeCallback) { - g_networkChangeCallback(localEndpoint, status); + g_networkChangeCallback(adapter, status); } else { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "g_networkChangeCallback is NULL"); + OIC_LOG(ERROR, TAG, "g_networkChangeCallback is NULL"); } - CAFreeEndpoint(localEndpoint); - - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); -} - -void CAIPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status) -{ - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - - VERIFY_NON_NULL_VOID(ipAddress, IP_ADAPTER_TAG, "ipAddress is NULL"); - - if (CA_INTERFACE_UP == status) + if (CA_INTERFACE_DOWN == status) { - uint16_t port = CA_PORT; - CAResult_t ret = CAIPStartUnicastServer(ipAddress, &port, false); - if (CA_STATUS_OK == ret) - { - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Unicast server started on %d port", port); - } - else + OIC_LOG(DEBUG, TAG, "Network status for IP is down"); + + CAResult_t res = CAQueueingThreadClearData(g_sendQueueHandle); + if (res != CA_STATUS_OK) { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to start Unicast server port[%d]", ret); + OIC_LOG_V(ERROR, TAG, "CAQueueingThreadClearData failed[%d]", res); } #ifdef __WITH_DTLS__ - port = CA_SECURE_PORT; - ret = CAIPStartUnicastServer(ipAddress, &port, true); - if (CA_STATUS_OK == ret) - { - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Secure Unicast server started on %d", port); - } - else - { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to start secure Unicast server [%d]", - ret); - } +#ifdef WITH_TCP + CATCPCloseInProgressConnections(); +#endif + OIC_LOG(DEBUG, TAG, "close all ssl session"); + CAcloseSslConnectionAll(CA_ADAPTER_IP); #endif - ret = CAIPStartMulticastServer(ipAddress, CA_MULTICAST_IP, CA_MCAST_PORT); - if (CA_STATUS_OK == ret) - { - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Multicast server started on port[%d]", - CA_MCAST_PORT); - } - else - { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to start Multicast server port[%d]", - ret); - } - - // Notify network change to CA - CAIPNotifyNetworkChange(ipAddress, port, status); - } - else - { - CAIPNotifyNetworkChange(ipAddress, 0, status); - - // Stop Unicast, Secured unicast and Multicast servers - CAIPStopServer(ipAddress); } - - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); } #ifdef __WITH_DTLS__ -uint32_t CAIPPacketSendCB(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength) +static ssize_t CAIPPacketSendCB(CAEndpoint_t *endpoint, const void *data, size_t dataLength) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - - VERIFY_NON_NULL_RET(endpoint, IP_ADAPTER_TAG, "endpoint is NULL", 0); - VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "data is NULL", 0); - - uint32_t sentLength = CAIPSendData(endpoint, data, dataLength, false); + VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint is NULL", -1); + VERIFY_NON_NULL_RET(data, TAG, "data is NULL", -1); - if (sentLength == 0) - { - g_errorCallback(endpoint, data, dataLength, CA_SEND_FAILED); - } - - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Successfully sent %d of encrypted data!", sentLength); - - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - - return sentLength; + CAIPSendData(endpoint, data, dataLength, false); + return dataLength; } #endif -void CAIPPacketReceivedCB(const CAEndpoint_t *endpoint, const void *data, - uint32_t dataLength) -{ - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - - VERIFY_NON_NULL_VOID(endpoint, IP_ADAPTER_TAG, "ipAddress is NULL"); - VERIFY_NON_NULL_VOID(data, IP_ADAPTER_TAG, "data is NULL"); - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Address: %s, port:%d", endpoint->addr, endpoint->port); +CAResult_t CAIPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data, + size_t dataLength) +{ + VERIFY_NON_NULL(sep, TAG, "sep is NULL"); + VERIFY_NON_NULL(data, TAG, "data is NULL"); - void *buf = OICCalloc(dataLength + 1, sizeof (char)); - if (!buf) - { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory Allocation failed!"); - return; - } - memcpy(buf, data, dataLength); + OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", sep->endpoint.addr, sep->endpoint.port); + CAResult_t res = CA_STATUS_OK; if (g_networkPacketCallback) { - g_networkPacketCallback(endpoint, buf, dataLength); - } - else - { - OICFree(buf); + res = g_networkPacketCallback(sep, data, dataLength); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "Error parsing CoAP data"); + } } - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); + return res; } -void CAIPErrorHandler (const CAEndpoint_t *endpoint, const void *data, - uint32_t dataLength, CAResult_t result) +void CAIPErrorHandler(const CAEndpoint_t *endpoint, const void *data, + uint32_t dataLength, CAResult_t result) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - - VERIFY_NON_NULL_VOID(endpoint, IP_ADAPTER_TAG, "endpoint is NULL"); + VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL"); + VERIFY_NON_NULL_VOID(data, TAG, "data is NULL"); - VERIFY_NON_NULL_VOID(data, IP_ADAPTER_TAG, "data is NULL"); - - void *buf = (void*)OICMalloc(sizeof(char) * dataLength); - if (!buf) - { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory Allocation failed!"); - return; - } - memcpy(buf, data, dataLength); if (g_errorCallback) { - g_errorCallback(endpoint, buf, dataLength, result); - } - else - { - OICFree(buf); + g_errorCallback(endpoint, data, dataLength, result); } - - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - - return; } -int32_t CAIPSendDataInternal(const CAEndpoint_t *remoteEndpoint, const void *data, - uint32_t dataLength, bool isMulticast) +static void CAInitializeIPGlobals() { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); -#ifdef SINGLE_THREAD - - // If remoteEndpoint is NULL, its Multicast, else its Unicast. - if(!isMulticast) - { - CAIPSendData(remoteEndpoint, data, dataLength, false); - } - else - { - CAEndpoint_t ep = { 0 }; - strcpy(ep.addr, CA_MULTICAST_IP); - ep.port = CA_MCAST_PORT; - CAIPSendData(&ep, data, dataLength, true); - } -#else - VERIFY_NON_NULL_RET(g_sendQueueHandle, IP_ADAPTER_TAG, "sendQueueHandle", -1); - - // Create IPData to add to queue - CAIPData *ipData = CACreateIPData(remoteEndpoint, data, dataLength, isMulticast); - - if (!ipData) - { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to create ipData!"); - return -1; - } - else - { - // Add message to send queue - CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData)); - } + caglobals.ip.u6.fd = -1; + caglobals.ip.u6s.fd = -1; + caglobals.ip.u4.fd = -1; + caglobals.ip.u4s.fd = -1; + caglobals.ip.m6.fd = -1; + caglobals.ip.m6s.fd = -1; + caglobals.ip.m4.fd = -1; + caglobals.ip.m4s.fd = -1; + caglobals.ip.u6.port = 0; + caglobals.ip.u6s.port = 0; + caglobals.ip.u4.port = 0; + caglobals.ip.u4s.port = 0; + caglobals.ip.m6.port = CA_COAP; + caglobals.ip.m6s.port = CA_SECURE_COAP; + caglobals.ip.m4.port = CA_COAP; + caglobals.ip.m4s.port = CA_SECURE_COAP; + + CATransportFlags_t flags = 0; + if (caglobals.client) + { + flags |= caglobals.clientFlags; + } + if (caglobals.server) + { + flags |= caglobals.serverFlags; + } +//TODO Enable once TizenRT supports IPv6 +#ifndef __TIZENRT__ + caglobals.ip.ipv6enabled = flags & CA_IPV6; #endif - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - return dataLength; + caglobals.ip.ipv4enabled = flags & CA_IPV4; + caglobals.ip.dualstack = caglobals.ip.ipv6enabled && caglobals.ip.ipv4enabled; } CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback, CANetworkPacketReceivedCallback networkPacketCallback, - CANetworkChangeCallback netCallback, + CAAdapterChangeCallback netCallback, CAErrorHandleCallback errorCallback, ca_thread_pool_t handle) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - VERIFY_NON_NULL(registerCallback, IP_ADAPTER_TAG, "registerCallback"); - VERIFY_NON_NULL(networkPacketCallback, IP_ADAPTER_TAG, "networkPacketCallback"); - VERIFY_NON_NULL(netCallback, IP_ADAPTER_TAG, "netCallback"); + OIC_LOG(DEBUG, TAG, "IN"); + VERIFY_NON_NULL(registerCallback, TAG, "registerCallback"); + VERIFY_NON_NULL(networkPacketCallback, TAG, "networkPacketCallback"); + VERIFY_NON_NULL(netCallback, TAG, "netCallback"); #ifndef SINGLE_THREAD - VERIFY_NON_NULL(handle, IP_ADAPTER_TAG, "thread pool handle"); + VERIFY_NON_NULL(handle, TAG, "thread pool handle"); #endif - g_threadPool = handle; g_networkChangeCallback = netCallback; g_networkPacketCallback = networkPacketCallback; g_errorCallback = errorCallback; - CAResult_t ret = CAIPInitializeNetworkMonitor(g_threadPool); - if (CA_STATUS_OK != ret) - { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to initialize n/w monitor[%d]", ret); - return ret; - } - CAIPSetConnectionStateChangeCallback(CAIPConnectionStateCB); - - ret = CAIPInitializeServer(g_threadPool); - if (CA_STATUS_OK != ret) - { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to initialize server![%d]", ret); - CATerminateIP(); - return ret; - } + CAInitializeIPGlobals(); + caglobals.ip.threadpool = handle; + CAIPSetErrorHandler(CAIPErrorHandler); CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB); - CAIPSetErrorHandleCallback(CAIPErrorHandler); -#ifdef __WITH_DTLS__ - CAAdapterNetDtlsInit(); - CADTLSSetAdapterCallbacks(CAIPPacketReceivedCB, CAIPPacketSendCB, 0); +#ifdef __WITH_DTLS__ + CAsetSslAdapterCallbacks(CAIPPacketReceivedCB, CAIPPacketSendCB, CA_ADAPTER_IP); #endif - CAConnectivityHandler_t ipHandler; - ipHandler.startAdapter = CAStartIP; - ipHandler.startListenServer = CAStartIPListeningServer; - ipHandler.startDiscoveryServer = CAStartIPDiscoveryServer; - ipHandler.sendData = CASendIPUnicastData; - ipHandler.sendDataToAll = CASendIPMulticastData; - ipHandler.GetnetInfo = CAGetIPInterfaceInformation; - ipHandler.readData = CAReadIPData; - ipHandler.stopAdapter = CAStopIP; - ipHandler.terminate = CATerminateIP; - registerCallback(ipHandler, CA_ADAPTER_IP); - -#ifndef SINGLE_THREAD - if (CA_STATUS_OK != CAIPInitializeQueueHandles()) - { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Initialize Queue Handle"); - CATerminateIP(); - return CA_STATUS_FAILED; - } -#endif - OIC_LOG(INFO, IP_ADAPTER_TAG, "OUT"); + static const CAConnectivityHandler_t ipHandler = + { + .startAdapter = CAStartIP, + .stopAdapter = CAStopIP, + .startListenServer = CAStartIPListeningServer, + .stopListenServer = CAStopIPListeningServer, + .startDiscoveryServer = CAStartIPDiscoveryServer, + .sendData = CASendIPUnicastData, + .sendDataToAll = CASendIPMulticastData, + .GetnetInfo = CAGetIPInterfaceInformation, + .readData = CAReadIPData, + .terminate = CATerminateIP, + .cType = CA_ADAPTER_IP + }; + registerCallback(ipHandler); + + OIC_LOG(INFO, TAG, "OUT IntializeIP is Success"); return CA_STATUS_OK; } CAResult_t CAStartIP() { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); + // Specific the port number received from application. + caglobals.ip.u6.port = caglobals.ports.udp.u6; + caglobals.ip.u6s.port = caglobals.ports.udp.u6s; + caglobals.ip.u4.port = caglobals.ports.udp.u4; + caglobals.ip.u4s.port = caglobals.ports.udp.u4s; - // Start monitoring IP network - CAResult_t ret = CAIPStartNetworkMonitor(); + CAIPStartNetworkMonitor(CAIPAdapterHandler, CA_ADAPTER_IP); +#ifdef SINGLE_THREAD + uint16_t unicastPort = 55555; + // Address is hardcoded as we are using Single Interface + CAResult_t ret = CAIPStartServer(); if (CA_STATUS_OK != ret) { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Start n/w monitor"); + OIC_LOG_V(DEBUG, TAG, "CAIPStartServer failed[%d]", ret); return ret; } - -#ifndef SINGLE_THREAD - // Start send queue thread - if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle)) +#else + if (CA_STATUS_OK != CAIPInitializeQueueHandles()) { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Start Send Data Thread"); + OIC_LOG(ERROR, TAG, "Failed to Initialize Queue Handle"); + CATerminateIP(); return CA_STATUS_FAILED; } -#endif - - bool retVal = CAIPIsConnected(); - if (false == retVal) - { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IP is not Connected"); - return CA_STATUS_OK; - } -#ifdef ARDUINO - uint16_t unicastPort = CA_PORT; - // Address is hardcoded as we are using Single Interface - ret = CAIPStartUnicastServer("0.0.0.0", &unicastPort, false); - if (CA_STATUS_OK != ret) + // Start send queue thread +#ifndef __TIZENRT__ + if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle)) +#else + if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle, "IoT_IPSendQueue")) +#endif { - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Start unicast serv failed[%d]", ret); - + OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread"); + return CA_STATUS_FAILED; } -#else - u_arraylist_t *netInterfaceList = u_arraylist_create(); - - VERIFY_NON_NULL(netInterfaceList, IP_ADAPTER_TAG, "netInterfaceList is NULL"); - ret = CAIPGetInterfaceInfo(&netInterfaceList); + CAResult_t ret = CAIPStartServer((const ca_thread_pool_t)caglobals.ip.threadpool); if (CA_STATUS_OK != ret) { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to get IP interface info [%d]", ret); - CAClearNetInterfaceInfoList(netInterfaceList); + OIC_LOG_V(ERROR, TAG, "Failed to start server![%d]", ret); return ret; } - uint32_t listIndex = 0; - uint32_t listLength = u_arraylist_length(netInterfaceList); - for (listIndex = 0; listIndex < listLength; listIndex++) - { - CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex); - if (!netInfo) - { - continue; - } - uint16_t unicastPort = CA_PORT; - ret = CAIPStartUnicastServer(netInfo->ipAddress, &unicastPort, false); - if (CA_STATUS_OK == ret) - { - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Unicast server started on %d port", - unicastPort); - } - -#ifdef __WITH_DTLS__ - unicastPort = CA_SECURE_PORT; - ret = CAIPStartUnicastServer(netInfo->ipAddress, &unicastPort, true); - - if (CA_STATUS_OK == ret) - { - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, - "Secure Unicast server started on %d port", unicastPort); - } #endif - } - CAClearNetInterfaceInfoList(netInterfaceList); -#endif - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - return ret; + + return CA_STATUS_OK; } CAResult_t CAStartIPListeningServer() { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - - CAResult_t ret = CA_STATUS_OK; - bool retVal = CAIPIsConnected(); - if (false == retVal) - { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IP not Connected"); - return ret; - } - -#ifdef ARDUINO - //uint16_t multicastPort = CA_MCAST_PORT; - ret = CAIPStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, CA_MCAST_PORT); + CAResult_t ret = CAIPStartListenServer(); if (CA_STATUS_OK != ret) { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Start multicast failed[%d]", ret); + OIC_LOG_V(ERROR, TAG, "Failed to start listening server![%d]", ret); + return ret; } -#else - u_arraylist_t *netInterfaceList = u_arraylist_create(); - VERIFY_NON_NULL(netInterfaceList, IP_ADAPTER_TAG, "netInterfaceList is NULL"); + return CA_STATUS_OK; +} - ret = CAIPGetInterfaceInfo(&netInterfaceList); +CAResult_t CAStopIPListeningServer() +{ + CAResult_t ret = CAIPStopListenServer(); if (CA_STATUS_OK != ret) { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to get IP interface info [%d]", ret); - CAClearNetInterfaceInfoList(netInterfaceList); - return ret; - } - - uint32_t listIndex = 0; - uint32_t listLength = u_arraylist_length(netInterfaceList); - for (listIndex = 0; listIndex < listLength; listIndex++) - { - - CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex); - if (!netInfo) - { - continue; - } - - OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Ip address for multicast interface %s", - netInfo->ipAddress); - ret = CAIPStartMulticastServer(netInfo->ipAddress, CA_MULTICAST_IP, CA_MCAST_PORT); - if (CA_STATUS_OK == ret) - { - OIC_LOG(INFO, IP_ADAPTER_TAG, "Multicast Server is Started Successfully"); - } + OIC_LOG_V(ERROR, TAG, "Failed to stop listening server![%d]", ret); } - CAClearNetInterfaceInfoList(netInterfaceList); -#endif - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); return ret; } CAResult_t CAStartIPDiscoveryServer() { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - /* Both listening and discovery server are same */ - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); return CAStartIPListeningServer(); } -int32_t CASendIPUnicastData(const CAEndpoint_t *remoteEndpoint, - const void *data, uint32_t dataLength) +static int32_t CAQueueIPData(bool isMulticast, const CAEndpoint_t *endpoint, + const void *data, uint32_t dataLength) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); + VERIFY_NON_NULL_RET(endpoint, TAG, "remoteEndpoint", -1); + VERIFY_NON_NULL_RET(data, TAG, "data", -1); - VERIFY_NON_NULL_RET(remoteEndpoint, IP_ADAPTER_TAG, "remoteEndpoint", -1); - VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "data", -1); if (0 == dataLength) { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Invalid Data Length"); + OIC_LOG(ERROR, TAG, "Invalid Data Length"); return -1; } - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - return CAIPSendDataInternal(remoteEndpoint, data, dataLength, false); -} +#ifdef SINGLE_THREAD -int32_t CASendIPMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength) -{ - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); + CAIPSendData(endpoint, data, dataLength, isMulticast); + return dataLength; - VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "data", -1); - if (0 == dataLength) +#else + + VERIFY_NON_NULL_RET(g_sendQueueHandle, TAG, "sendQueueHandle", -1); + // Create IPData to add to queue + CAIPData_t *ipData = CACreateIPData(endpoint, data, dataLength, isMulticast); + if (!ipData) { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Invalid Data Length"); + OIC_LOG(ERROR, TAG, "Failed to create ipData!"); return -1; } + // Add message to send queue + CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData_t)); + +#endif // SINGLE_THREAD - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - return CAIPSendDataInternal(endpoint, data, dataLength, true); + return dataLength; } -CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size) +int32_t CASendIPUnicastData(const CAEndpoint_t *endpoint, + const void *data, uint32_t dataLength, + CADataType_t dataType) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); + (void)dataType; + return CAQueueIPData(false, endpoint, data, dataLength); +} - VERIFY_NON_NULL(info, IP_ADAPTER_TAG, "info is NULL"); - VERIFY_NON_NULL(size, IP_ADAPTER_TAG, "size is NULL"); +int32_t CASendIPMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength, + CADataType_t dataType) +{ + (void)dataType; + return CAQueueIPData(true, endpoint, data, dataLength); +} - bool retVal = CAIPIsConnected(); - if (false == retVal) +CAResult_t CAReadIPData() +{ + CAIPPullData(); + return CA_STATUS_OK; +} + +CAResult_t CAStopIP() +{ +#ifndef SINGLE_THREAD + if (g_sendQueueHandle && g_sendQueueHandle->threadMutex) { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "IP not Connected"); - return CA_ADAPTER_NOT_ENABLED; + CAQueueingThreadStop(g_sendQueueHandle); } +#endif - u_arraylist_t *netInterfaceList = u_arraylist_create(); + CAIPStopNetworkMonitor(CA_ADAPTER_IP); + CAIPStopServer(); + //Re-initializing the Globals to start them again + CAInitializeIPGlobals(); - VERIFY_NON_NULL(netInterfaceList, IP_ADAPTER_TAG, "netInterfaceList is NULL"); + return CA_STATUS_OK; +} - CAResult_t ret = CAIPGetInterfaceInfo(&netInterfaceList); - if (CA_STATUS_OK != ret) - { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "CAIPGetInterfaceInfo failed:%d", ret); - CAClearNetInterfaceInfoList(netInterfaceList); - return ret; - } +void CATerminateIP() +{ +#ifdef __WITH_DTLS__ + CAsetSslAdapterCallbacks(NULL, NULL, CA_ADAPTER_IP); +#endif - uint32_t listLength = u_arraylist_length(netInterfaceList); - uint32_t netInfoSize = listLength; + CAIPSetPacketReceiveCallback(NULL); -#ifdef __WITH_DTLS__ - if (listLength) - { - netInfoSize = listLength * 2; - } +#ifndef SINGLE_THREAD + CAIPDeinitializeQueueHandles(); #endif +} - CAEndpoint_t *conInfo = (CAEndpoint_t *)OICCalloc(netInfoSize, sizeof (CAEndpoint_t)); - if (!conInfo) +#ifndef SINGLE_THREAD + +void CAIPSendDataThread(void *threadData) +{ + CAIPData_t *ipData = (CAIPData_t *) threadData; + if (!ipData) { - OIC_LOG(ERROR, IP_ADAPTER_TAG, "Malloc Failed"); - CAClearNetInterfaceInfoList(netInterfaceList); - return CA_MEMORY_ALLOC_FAILED; + OIC_LOG(DEBUG, TAG, "Invalid ip data!"); + return; } - uint32_t listIndex = 0; - uint32_t count = 0; - for (listIndex = 0; listIndex < listLength; listIndex++) + if (ipData->isMulticast) { - CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex); - if (!netInfo) + //Processing for sending multicast + OIC_LOG(DEBUG, TAG, "Send Multicast Data is called"); + CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, true); + } + else + { + //Processing for sending unicast +#ifdef __WITH_DTLS__ + if (ipData->remoteEndpoint && ipData->remoteEndpoint->flags & CA_SECURE) { - continue; + OIC_LOG(INFO, TAG, "DTLS encrypt called"); + CAResult_t result = CAencryptSsl(ipData->remoteEndpoint, ipData->data, ipData->dataLen); + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, TAG, "CAencryptSsl failed!"); + } + OIC_LOG_V(INFO, TAG, "CAencryptSsl returned with result[%d]", result); } - - conInfo[count].adapter = CA_ADAPTER_IP; - conInfo[count].flags = 0; - conInfo[count].port = CAGetServerPortNum(netInfo->ipAddress, false); - OICStrcpy(conInfo[count].addr, - sizeof(conInfo[count].addr), - netInfo->ipAddress); - -#ifdef __WITH_DTLS__ - // copy secure unicast server information + else { - count ++; - conInfo[count].adapter = CA_ADAPTER_IP; - conInfo[count].flags = CA_SECURE; - conInfo[count].port = CAGetServerPortNum(netInfo->ipAddress, true); - OICStrcpy(conInfo[count].addr, - sizeof(conInfo[count].addr), - netInfo->ipAddress); + OIC_LOG(DEBUG, TAG, "Send Unicast Data is called"); + CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, false); } +#else + CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, false); #endif - count ++; } - *size = count; - *info = conInfo; - CAClearNetInterfaceInfoList(netInterfaceList); - - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - return CA_STATUS_OK; } -CAResult_t CAReadIPData() -{ - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - CAIPPullData(); - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - return CA_STATUS_OK; -} +#endif -CAResult_t CAIPStopServers() +#ifndef SINGLE_THREAD +CAIPData_t *CACreateIPData(const CAEndpoint_t *remoteEndpoint, const void *data, + uint32_t dataLength, bool isMulticast) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); + VERIFY_NON_NULL_RET(remoteEndpoint, TAG, "remoteEndpoint is NULL", NULL); + VERIFY_NON_NULL_RET(data, TAG, "IPData is NULL", NULL); - // Stop all unicast and multicast servers. - if (CA_STATUS_OK == CAIPStopAllServers()) + CAIPData_t *ipData = (CAIPData_t *) OICMalloc(sizeof(*ipData)); + if (!ipData) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "CAIPStopAllServers success"); + OIC_LOG(ERROR, TAG, "Memory allocation failed!"); + return NULL; } - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - return CA_STATUS_OK; -} - -CAResult_t CAStopIP() -{ - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - -#ifdef __WITH_DTLS__ - CAAdapterNetDtlsDeInit(); -#endif - - // Stop IP network monitor - CAIPStopNetworkMonitor(); - -#ifdef MULTI_THREAD - // Stop send queue thread - if (g_sendQueueHandle) + ipData->remoteEndpoint = CACloneEndpoint(remoteEndpoint); + ipData->data = (void *) OICMalloc(dataLength); + if (!ipData->data) { - CAQueueingThreadStop(g_sendQueueHandle); + OIC_LOG(ERROR, TAG, "Memory allocation failed!"); + CAFreeIPData(ipData); + return NULL; } -#endif - // Stop Unicast, Secured unicast and Multicast servers running - CAResult_t result = CAIPStopServers(); - if (CA_STATUS_OK != result) - { - OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "stop srv fail:%d", result); - } + memcpy(ipData->data, data, dataLength); + ipData->dataLen = dataLength; - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); - return result; + ipData->isMulticast = isMulticast; + + return ipData; } -void CATerminateIP() +void CAFreeIPData(CAIPData_t *ipData) { - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN"); - - // Stop IP adapter - CAStopIP(); - -#ifdef __WITH_DTLS__ - CADTLSSetAdapterCallbacks(NULL, NULL, 0); -#endif - - CAIPSetPacketReceiveCallback(NULL); + VERIFY_NON_NULL_VOID(ipData, TAG, "ipData is NULL"); - // Terminate IP server - CAIPTerminateServer(); - - // Terminate network monitor - CAIPSetConnectionStateChangeCallback(NULL); - CAIPTerminateNetworkMonitor(); + CAFreeEndpoint(ipData->remoteEndpoint); + OICFree(ipData->data); + OICFree(ipData); +} -#ifndef SINGLE_THREAD - // Terminate message queue handler - CAIPDeinitializeQueueHandles(); -#endif +void CADataDestroyer(void *data, uint32_t size) +{ + if (size < sizeof(CAIPData_t)) + { + OIC_LOG_V(ERROR, TAG, "Destroy data too small %p %d", data, size); + } + CAIPData_t *etdata = (CAIPData_t *) data; - OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT"); + CAFreeIPData(etdata); } + +#endif // SINGLE_THREAD