X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fconnectivity%2Fsrc%2Fip_adapter%2Fcaipserver.c;h=87afa900c84974ad2a97cc8b3949bdce513bf63e;hb=refs%2Ftags%2Faccepted%2Ftizen%2F4.0%2Funified%2F20171211.061426;hp=4b47876a1f8a142a31173a90e56e4e715cbb2fbc;hpb=5b285e73548cac989ef00461e1a96bc60b613ae1;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/connectivity/src/ip_adapter/caipserver.c b/resource/csdk/connectivity/src/ip_adapter/caipserver.c index 4b47876..87afa90 100644 --- a/resource/csdk/connectivity/src/ip_adapter/caipserver.c +++ b/resource/csdk/connectivity/src/ip_adapter/caipserver.c @@ -25,6 +25,12 @@ #define _GNU_SOURCE // for in6_pktinfo #endif +#ifdef __TIZENRT__ +#include +#include +#endif + +#include "iotivity_config.h" #include #if !defined(_WIN32) #include @@ -39,6 +45,7 @@ #endif #include +#include #if !defined(_MSC_VER) #include #endif //!defined(_MSC_VER) @@ -56,48 +63,72 @@ #include #endif -#include "pdu.h" +#ifdef __TIZENRT__ +#include +#include +#endif + +#include #include "caipinterface.h" +#include "caipnwmonitor.h" #include "caadapterutils.h" -#ifdef __WITH_DTLS__ -#include "caadapternetdtls.h" +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +#include "ca_adapter_net_ssl.h" #endif -#include "camutex.h" +#include "octhread.h" #include "oic_malloc.h" #include "oic_string.h" -#include "platform_features.h" #define USE_IP_MREQN #if defined(_WIN32) #undef USE_IP_MREQN #endif +#ifdef __TIZEN__ +#include +#endif + /* * Logging tag for module name */ -#define TAG "OIC_CA_IP_SERVER" +//#define TAG "OIC_CA_IP_SERVER" +#define TAG IP_SERVER_TAG +#ifdef __TIZENRT__ +mqd_t g_nwevent_mqfd; +#ifdef CONFIG_NET_LWIP +#define SOCK_CLOEXEC 0 +#else +#define SOCK_CLOEXEC 1 +#endif +#endif #define SELECT_TIMEOUT 1 // select() seconds (and termination latency) #define IPv4_MULTICAST "224.0.1.187" static struct in_addr IPv4MulticastAddress = { 0 }; #define IPv6_DOMAINS 16 -#define IPv6_MULTICAST_INT "ff01::fd" +#define MOBILE_INTERFACES 2 +#define IPv6_MULTICAST_INT "ff01::158" static struct in6_addr IPv6MulticastAddressInt; -#define IPv6_MULTICAST_LNK "ff02::fd" +#define IPv6_MULTICAST_LNK "ff02::158" static struct in6_addr IPv6MulticastAddressLnk; -#define IPv6_MULTICAST_RLM "ff03::fd" +#define IPv6_MULTICAST_RLM "ff03::158" static struct in6_addr IPv6MulticastAddressRlm; -#define IPv6_MULTICAST_ADM "ff04::fd" +#define IPv6_MULTICAST_ADM "ff04::158" static struct in6_addr IPv6MulticastAddressAdm; -#define IPv6_MULTICAST_SIT "ff05::fd" +#define IPv6_MULTICAST_SIT "ff05::158" static struct in6_addr IPv6MulticastAddressSit; -#define IPv6_MULTICAST_ORG "ff08::fd" +#define IPv6_MULTICAST_ORG "ff08::158" static struct in6_addr IPv6MulticastAddressOrg; -#define IPv6_MULTICAST_GLB "ff0e::fd" +#define IPv6_MULTICAST_GLB "ff0e::158" static struct in6_addr IPv6MulticastAddressGlb; +/* + * Buffer size for the receive message buffer + */ +#define RECV_MSG_BUF_LEN 16384 + static char *ipv6mcnames[IPv6_DOMAINS] = { NULL, IPv6_MULTICAST_INT, @@ -117,6 +148,41 @@ static char *ipv6mcnames[IPv6_DOMAINS] = { NULL }; +// Samsung Mobile +static char *mobileinferfaces[MOBILE_INTERFACES] = { + "rmnet", "pdp" +}; + +#ifdef __TIZENRT__ +struct in6_pktinfo { + struct in6_addr ipi6_addr; + int ipi6_ifindex; +}; + +struct in_pktinfo +{ + unsigned int ipi_ifindex; /* Interface index */ + struct in_addr ipi_spec_dst; /* Local address */ + struct in_addr ipi_addr; /* Header Destination + address */ +}; + + +#define RTMGRP_LINK 1 +#define IP_PKTINFO 8 +#define IPV6_PKTINFO 50 +#define IPV6_MULTICAST_IF 9 +#define IPV6_V6ONLY 27 +#define IPV6_RECVPKTINFO 50 +#define IPV6_JOIN_GROUP 12 +#endif + +/** + * By default, IP multicast datagrams are sent with a time-to-live (TTL) of 1. + * An application can choose an initial TTL. + */ +static size_t multicastTTL = 1; + #if defined (_WIN32) #define IFF_UP_RUNNING_FLAGS (IFF_UP) @@ -137,43 +203,85 @@ static CAIPErrorHandleCallback g_ipErrorHandler = NULL; static CAIPPacketReceivedCallback g_packetReceivedCallback = NULL; -static void CAHandleNetlink(); static void CAFindReadyMessage(); #if !defined(WSA_WAIT_EVENT_0) static void CASelectReturned(fd_set *readFds, int ret); #else -static void CAEventReturned(HANDLE); +static void CAEventReturned(CASocketFd_t socket); #endif -static void CAProcessNewInterface(CAInterface_t *ifchanged); -static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags); + +static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags); + +#ifdef __TIZEN__ +static int cleanup_pop_arg = 1; + +static void CAIPCleanupHandler(void *arg) +{ + (void)arg; + + OIC_LOG(DEBUG, TAG, "Called clean-up handler"); + + if (caglobals.ip.shutdownFds[0] != OC_INVALID_SOCKET) + { + close(caglobals.ip.shutdownFds[0]); + caglobals.ip.shutdownFds[0] = OC_INVALID_SOCKET; + } +} static void CAReceiveHandler(void *data) { (void)data; + OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler"); + + pthread_cleanup_push(CAIPCleanupHandler, NULL); while (!caglobals.ip.terminate) { CAFindReadyMessage(); } + + pthread_cleanup_pop(cleanup_pop_arg); + + OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler"); } +#else +static void CAReceiveHandler(void *data) +{ + (void)data; + OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler"); + + while (!caglobals.ip.terminate) + { + CAFindReadyMessage(); + } +#ifndef __TIZENRT__ + if (caglobals.ip.shutdownFds[0] != OC_INVALID_SOCKET) + { + close(caglobals.ip.shutdownFds[0]); + caglobals.ip.shutdownFds[0] = OC_INVALID_SOCKET; + } +#endif + OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler"); +} +#endif #if !defined(WSA_WAIT_EVENT_0) #define CLOSE_SOCKET(TYPE) \ - if (caglobals.ip.TYPE.fd != -1) \ + if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) \ { \ close(caglobals.ip.TYPE.fd); \ - caglobals.ip.TYPE.fd = -1; \ + caglobals.ip.TYPE.fd = OC_INVALID_SOCKET; \ } #define SET(TYPE, FDS) \ - if (caglobals.ip.TYPE.fd != -1) \ + if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) \ { \ FD_SET(caglobals.ip.TYPE.fd, FDS); \ } #define ISSET(TYPE, FDS, FLAGS) \ - if (caglobals.ip.TYPE.fd != -1 && FD_ISSET(caglobals.ip.TYPE.fd, FDS)) \ + if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET && FD_ISSET(caglobals.ip.TYPE.fd, FDS)) \ { \ fd = caglobals.ip.TYPE.fd; \ flags = FLAGS; \ @@ -198,12 +306,13 @@ static void CAFindReadyMessage() SET(m6s, &readFds) SET(m4, &readFds) SET(m4s, &readFds) - +#ifndef __TIZENRT__ if (caglobals.ip.shutdownFds[0] != -1) { FD_SET(caglobals.ip.shutdownFds[0], &readFds); } - if (caglobals.ip.netlinkFd != -1) +#endif + if (caglobals.ip.netlinkFd != OC_INVALID_SOCKET) { FD_SET(caglobals.ip.netlinkFd, &readFds); } @@ -212,26 +321,39 @@ static void CAFindReadyMessage() if (caglobals.ip.terminate) { - OIC_LOG_V(DEBUG, TAG, "Packet receiver Stop request received."); + OIC_LOG_V(INFO, TAG, "Packet receiver Stop request received."); return; } - - if (ret <= 0) +#ifdef __TIZENRT__ + u_arraylist_t *iflist = CAFindInterfaceChange(); + if (iflist) { - if (ret < 0) + uint32_t listLength = u_arraylist_length(iflist); + for (uint32_t i = 0; i < listLength; i++) { - OIC_LOG_V(FATAL, TAG, "select error %s", CAIPS_GET_ERROR); + CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i); + if (ifitem) + { + CAProcessNewInterface(ifitem); + } } - return; + u_arraylist_destroy(iflist); + } +#endif + if (0 < ret) + { + CASelectReturned(&readFds, ret); + } + else if (0 > ret) + { + OIC_LOG_V(FATAL, TAG, "select error %s", CAIPS_GET_ERROR); } - - CASelectReturned(&readFds, ret); } static void CASelectReturned(fd_set *readFds, int ret) { (void)ret; - int fd = -1; + CASocketFd_t fd = OC_INVALID_SOCKET; CATransportFlags_t flags = CA_DEFAULT_FLAGS; while (!caglobals.ip.terminate) @@ -244,16 +366,27 @@ static void CASelectReturned(fd_set *readFds, int ret) else ISSET(m6s, readFds, CA_MULTICAST | CA_IPV6 | CA_SECURE) else ISSET(m4, readFds, CA_MULTICAST | CA_IPV4) else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE) - else if ((caglobals.ip.netlinkFd != -1) && FD_ISSET(caglobals.ip.netlinkFd, readFds)) + else if ((caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && FD_ISSET(caglobals.ip.netlinkFd, readFds)) { - CAInterface_t *ifchanged = CAFindInterfaceChange(); - if (ifchanged) +#ifndef __TIZENRT__ + u_arraylist_t *iflist = CAFindInterfaceChange(); + if (iflist) { - CAProcessNewInterface(ifchanged); - OICFree(ifchanged); + uint32_t listLength = u_arraylist_length(iflist); + for (uint32_t i = 0; i < listLength; i++) + { + CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i); + if (ifitem) + { + CAProcessNewInterface(ifitem); + } + } + u_arraylist_destroy(iflist); } break; +#endif } +#ifndef __TIZENRT__ else if (FD_ISSET(caglobals.ip.shutdownFds[0], readFds)) { char buf[10] = {0}; @@ -264,6 +397,7 @@ static void CASelectReturned(fd_set *readFds, int ret) } break; } +#endif else { break; @@ -276,10 +410,10 @@ static void CASelectReturned(fd_set *readFds, int ret) #else // if defined(WSA_WAIT_EVENT_0) #define CLOSE_SOCKET(TYPE) \ - if (caglobals.ip.TYPE.fd != -1) \ + if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) \ { \ closesocket(caglobals.ip.TYPE.fd); \ - caglobals.ip.TYPE.fd = -1; \ + caglobals.ip.TYPE.fd = OC_INVALID_SOCKET; \ } #define PUSH_HANDLE(HANDLE, ARRAY, INDEX) \ @@ -290,7 +424,7 @@ static void CASelectReturned(fd_set *readFds, int ret) // Turn handle into WSAEvent and push to ARRAY #define PUSH_SOCKET(SOCKET, ARRAY, INDEX) \ - if (SOCKET != -1) \ + if (SOCKET != OC_INVALID_SOCKET) \ { \ WSAEVENT NewEvent; \ NewEvent = WSACreateEvent(); \ @@ -315,27 +449,27 @@ static void CASelectReturned(fd_set *readFds, int ret) }\ } -#define INSERT_FD(FD, ARRAY, INDEX) \ +#define INSERT_SOCKET(FD, ARRAY, INDEX) \ { \ - if (-1 != FD) \ + if (OC_INVALID_SOCKET != FD) \ { \ ARRAY[INDEX] = FD; \ } \ } -// Inserts the FD into the FD_ARRAY and pushes the socket event into ARRAY -#define PUSH_IP_SOCKET(TYPE, ARRAY, FD_ARRAY, INDEX) \ +// Inserts the socket into the SOCKET_ARRAY and pushes the socket event into EVENT_ARRAY +#define PUSH_IP_SOCKET(TYPE, EVENT_ARRAY, SOCKET_ARRAY, INDEX) \ { \ - if (-1 != caglobals.ip.TYPE.fd) \ + if (OC_INVALID_SOCKET != caglobals.ip.TYPE.fd) \ { \ - INSERT_FD(caglobals.ip.TYPE.fd, FD_ARRAY, INDEX); \ - PUSH_SOCKET(caglobals.ip.TYPE.fd, ARRAY, INDEX); \ + INSERT_SOCKET(caglobals.ip.TYPE.fd, SOCKET_ARRAY, INDEX); \ + PUSH_SOCKET(caglobals.ip.TYPE.fd, EVENT_ARRAY, INDEX); \ } \ } -#define IS_MATCHING_IP_HANDLE(TYPE, HANDLE, FLAGS) \ - if ((caglobals.ip.TYPE.fd != -1) && (caglobals.ip.TYPE.fd == HANDLE)) \ +#define IS_MATCHING_IP_SOCKET(TYPE, SOCKET, FLAGS) \ + if ((caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) && (caglobals.ip.TYPE.fd == SOCKET)) \ { \ fd = caglobals.ip.TYPE.fd; \ flags = FLAGS; \ @@ -345,33 +479,33 @@ static void CASelectReturned(fd_set *readFds, int ret) static void CAFindReadyMessage() { - int fdArray[EVENT_ARRAY_SIZE]; + CASocketFd_t socketArray[EVENT_ARRAY_SIZE]; HANDLE eventArray[EVENT_ARRAY_SIZE]; int arraySize = 0; int eventIndex; - // fdArray and eventArray should have same number of elements - OC_STATIC_ASSERT(_countof(fdArray) == _countof(eventArray), "Arrays should have same number of elements"); + // socketArray and eventArray should have same number of elements + OC_STATIC_ASSERT(_countof(socketArray) == _countof(eventArray), "Arrays should have same number of elements"); - PUSH_IP_SOCKET(u6, eventArray, fdArray, arraySize); - PUSH_IP_SOCKET(u6s, eventArray, fdArray, arraySize); - PUSH_IP_SOCKET(u4, eventArray, fdArray, arraySize); - PUSH_IP_SOCKET(u4s, eventArray, fdArray, arraySize); - PUSH_IP_SOCKET(m6, eventArray, fdArray, arraySize); - PUSH_IP_SOCKET(m6s, eventArray, fdArray, arraySize); - PUSH_IP_SOCKET(m4, eventArray, fdArray, arraySize); - PUSH_IP_SOCKET(m4s, eventArray, fdArray, arraySize); + PUSH_IP_SOCKET(u6, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(u6s, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(u4, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(u4s, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(m6, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(m6s, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(m4, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(m4s, eventArray, socketArray, arraySize); - if (-1 != caglobals.ip.shutdownEvent) + if (WSA_INVALID_EVENT != caglobals.ip.shutdownEvent) { - INSERT_FD(caglobals.ip.shutdownEvent, fdArray, arraySize); + INSERT_SOCKET(OC_INVALID_SOCKET, socketArray, arraySize); PUSH_HANDLE(caglobals.ip.shutdownEvent, eventArray, arraySize); } /** @todo Support netlink events */ // Should not have overflowed buffer - assert(arraySize <= (_countof(fdArray))); + assert(arraySize <= (_countof(socketArray))); // Timeout is unnecessary on Windows assert(-1 == caglobals.ip.selectTimeout); @@ -399,7 +533,14 @@ static void CAFindReadyMessage() { OIC_LOG_V(ERROR, TAG, "WSAResetEvent failed 0x%08x", WSAGetLastError()); } - CAEventReturned(fdArray[eventIndex]); + + // Break out if shutdownEvent is triggered. + if ((caglobals.ip.shutdownEvent != WSA_INVALID_EVENT) && + (caglobals.ip.shutdownEvent == eventArray[eventIndex])) + { + break; + } + CAEventReturned(socketArray[eventIndex]); } else { @@ -418,78 +559,66 @@ static void CAFindReadyMessage() OIC_LOG_V(ERROR, TAG, "WSACloseEvent (Index %i) failed 0x%08x", arraySize, WSAGetLastError()); } } + + if (caglobals.ip.terminate) + { + caglobals.ip.shutdownEvent = WSA_INVALID_EVENT; + WSACleanup(); + } } -static void CAEventReturned(HANDLE handle) +static void CAEventReturned(CASocketFd_t socket) { - int fd = -1; + CASocketFd_t fd = OC_INVALID_SOCKET; CATransportFlags_t flags = CA_DEFAULT_FLAGS; while (!caglobals.ip.terminate) { - IS_MATCHING_IP_HANDLE(u6, handle, CA_IPV6) - else IS_MATCHING_IP_HANDLE(u6s, handle, CA_IPV6 | CA_SECURE) - else IS_MATCHING_IP_HANDLE(u4, handle, CA_IPV4) - else IS_MATCHING_IP_HANDLE(u4s, handle, CA_IPV4 | CA_SECURE) - else IS_MATCHING_IP_HANDLE(m6, handle, CA_MULTICAST | CA_IPV6) - else IS_MATCHING_IP_HANDLE(m6s, handle, CA_MULTICAST | CA_IPV6 | CA_SECURE) - else IS_MATCHING_IP_HANDLE(m4, handle, CA_MULTICAST | CA_IPV4) - else IS_MATCHING_IP_HANDLE(m4s, handle, CA_MULTICAST | CA_IPV4 | CA_SECURE) - else if ((caglobals.ip.shutdownEvent != -1) && (caglobals.ip.shutdownEvent == handle)) - { - break; - } + IS_MATCHING_IP_SOCKET(u6, socket, CA_IPV6) + else IS_MATCHING_IP_SOCKET(u6s, socket, CA_IPV6 | CA_SECURE) + else IS_MATCHING_IP_SOCKET(u4, socket, CA_IPV4) + else IS_MATCHING_IP_SOCKET(u4s, socket, CA_IPV4 | CA_SECURE) + else IS_MATCHING_IP_SOCKET(m6, socket, CA_MULTICAST | CA_IPV6) + else IS_MATCHING_IP_SOCKET(m6s, socket, CA_MULTICAST | CA_IPV6 | CA_SECURE) + else IS_MATCHING_IP_SOCKET(m4, socket, CA_MULTICAST | CA_IPV4) + else IS_MATCHING_IP_SOCKET(m4s, socket, CA_MULTICAST | CA_IPV4 | CA_SECURE) else { break; } - (void)CAReceiveMessage(handle, flags); - // We will never get more than one match per handle, so always break. + (void)CAReceiveMessage(socket, flags); + // We will never get more than one match per socket, so always break. break; } - - if (caglobals.ip.terminate) - { - if (-1 != caglobals.ip.shutdownEvent) - { - // We presume the shutdownEvent will be closed in CAFindReadyMessage - caglobals.ip.shutdownEvent = -1; - WSACleanup(); - } - } } #endif void CADeInitializeIPGlobals() { - CLOSE_SOCKET(u6); - CLOSE_SOCKET(u6s); - CLOSE_SOCKET(u4); - CLOSE_SOCKET(u4s); - CLOSE_SOCKET(m6); - CLOSE_SOCKET(m6s); - CLOSE_SOCKET(m4); - CLOSE_SOCKET(m4s); + CloseMulticastSocket(); - if (caglobals.ip.netlinkFd != -1) + if (caglobals.ip.netlinkFd != OC_INVALID_SOCKET) { #ifdef _WIN32 closesocket(caglobals.ip.netlinkFd); #else close(caglobals.ip.netlinkFd); #endif - caglobals.ip.netlinkFd = -1; + caglobals.ip.netlinkFd = OC_INVALID_SOCKET; } } -static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags) +static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags) { - char recvBuffer[COAP_MAX_PDU_SIZE]; - - size_t len; - int level, type, namelen; - struct sockaddr_storage srcAddr; + OIC_LOG(DEBUG, TAG, "IN - CAReceiveMessage"); + char recvBuffer[RECV_MSG_BUF_LEN] = {0}; + + size_t len = 0; + int level = 0; + int type = 0; + int namelen = 0; + struct sockaddr_storage srcAddr = { .ss_family = 0 }; unsigned char *pktinfo = NULL; #if !defined(WSA_CMSG_DATA) struct cmsghdr *cmp = NULL; @@ -523,11 +652,12 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags) .msg_controllen = CMSG_SPACE(len) }; ssize_t recvLen = recvmsg(fd, &msg, flags); - if (-1 == recvLen) + if (OC_SOCKET_ERROR == recvLen) { OIC_LOG_V(ERROR, TAG, "Recvfrom failed %s", strerror(errno)); return CA_STATUS_FAILED; } + OIC_LOG_V(DEBUG, TAG, "recvd %u bytes from recvmsg", recvLen); if (flags & CA_MULTICAST) { @@ -561,7 +691,7 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags) } WSABUF iov = {.len = sizeof (recvBuffer), .buf = recvBuffer}; - WSAMSG msg = {.name = &srcAddr, + WSAMSG msg = {.name = (PSOCKADDR)&srcAddr, .namelen = namelen, .lpBuffers = &iov, .dwBufferCount = 1, @@ -571,7 +701,7 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags) uint32_t recvLen = 0; uint32_t ret = caglobals.ip.wsaRecvMsg(fd, &msg, &recvLen, 0,0); OIC_LOG_V(DEBUG, TAG, "WSARecvMsg recvd %u bytes", recvLen); - if (SOCKET_ERROR == ret) + if (OC_SOCKET_ERROR == ret) { OIC_LOG_V(ERROR, TAG, "WSARecvMsg failed %i", WSAGetLastError()); } @@ -590,6 +720,7 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags) #endif // !defined(WSA_CMSG_DATA) CASecureEndpoint_t sep = {.endpoint = {.adapter = CA_ADAPTER_IP, .flags = flags}}; +#ifndef __TIZENRT__ if (flags & CA_IPV6) { /** @todo figure out correct usage for ifindex, and sin6_scope_id.*/ @@ -604,6 +735,7 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags) } } else +#endif { if ((flags & CA_MULTICAST) && pktinfo) { @@ -622,8 +754,8 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags) if (flags & CA_SECURE) { #ifdef __WITH_DTLS__ - int ret = CAAdapterNetDtlsDecrypt(&sep, (uint8_t *)recvBuffer, recvLen); - OIC_LOG_V(DEBUG, TAG, "CAAdapterNetDtlsDecrypt returns [%d]", ret); + int ret = CAdecryptSsl(&sep, (uint8_t *)recvBuffer, recvLen); + OIC_LOG_V(INFO, TAG, "CAdecryptSsl returns [%d]", ret); #else OIC_LOG(ERROR, TAG, "Encrypted message but no DTLS"); #endif @@ -632,10 +764,12 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags) { if (g_packetReceivedCallback) { + OIC_LOG(DEBUG, TAG, "call receivedCB"); g_packetReceivedCallback(&sep, recvBuffer, recvLen); } } + OIC_LOG(DEBUG, TAG, "OUT - CAReceiveMessage"); return CA_STATUS_OK; } @@ -646,17 +780,17 @@ void CAIPPullData() OIC_LOG(DEBUG, TAG, "OUT"); } -static int CACreateSocket(int family, uint16_t *port) +static CASocketFd_t CACreateSocket(int family, uint16_t *port, bool isMulticast) { int socktype = SOCK_DGRAM; #ifdef SOCK_CLOEXEC socktype |= SOCK_CLOEXEC; #endif - int fd = socket(family, socktype, IPPROTO_UDP); - if (-1 == fd) + CASocketFd_t fd = socket(family, socktype, IPPROTO_UDP); + if (OC_INVALID_SOCKET == fd) { OIC_LOG_V(ERROR, TAG, "create socket failed: %s", CAIPS_GET_ERROR); - return -1; + return OC_INVALID_SOCKET; } #if !defined(SOCK_CLOEXEC) && defined(FD_CLOEXEC) @@ -665,27 +799,27 @@ static int CACreateSocket(int family, uint16_t *port) { OIC_LOG_V(ERROR, TAG, "set FD_CLOEXEC failed: %s", strerror(errno)); close(fd); - return -1; + return OC_INVALID_SOCKET; } #endif struct sockaddr_storage sa = { .ss_family = family }; - socklen_t socklen; + socklen_t socklen = 0; if (family == AF_INET6) { int on = 1; - if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, OPTVAL_T(&on), sizeof (on))) + if (OC_SOCKET_ERROR == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, OPTVAL_T(&on), sizeof (on))) { OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", CAIPS_GET_ERROR); } - if (*port) // only do this for multicast ports + if (isMulticast && *port) // only do this for multicast ports { #if defined(IPV6_RECVPKTINFO) - if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof (on))) + if (OC_SOCKET_ERROR == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof (on))) #else - if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, OPTVAL_T(&on), sizeof (on))) + if (OC_SOCKET_ERROR == setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, OPTVAL_T(&on), sizeof (on))) #endif { OIC_LOG_V(ERROR, TAG, "IPV6_RECVPKTINFO failed: %s",CAIPS_GET_ERROR); @@ -697,10 +831,10 @@ static int CACreateSocket(int family, uint16_t *port) } else { - if (*port) // only do this for multicast ports + if (isMulticast && *port) // only do this for multicast ports { int on = 1; - if (-1 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, OPTVAL_T(&on), sizeof (on))) + if (OC_SOCKET_ERROR == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, OPTVAL_T(&on), sizeof (on))) { OIC_LOG_V(ERROR, TAG, "IP_PKTINFO failed: %s", CAIPS_GET_ERROR); } @@ -710,10 +844,10 @@ static int CACreateSocket(int family, uint16_t *port) socklen = sizeof (struct sockaddr_in); } - if (*port) // use the given port + if (isMulticast && *port) // use the given port { int on = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on))) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on), sizeof (on))) { OIC_LOG_V(ERROR, TAG, "SO_REUSEADDR failed: %s", CAIPS_GET_ERROR); #ifdef _WIN32 @@ -721,11 +855,11 @@ static int CACreateSocket(int family, uint16_t *port) #else close(fd); #endif - return -1; + return OC_INVALID_SOCKET; } } - if (-1 == bind(fd, (struct sockaddr *)&sa, socklen)) + if (OC_SOCKET_ERROR == bind(fd, (struct sockaddr *)&sa, socklen)) { OIC_LOG_V(ERROR, TAG, "bind socket failed: %s", CAIPS_GET_ERROR); #ifdef _WIN32 @@ -733,12 +867,12 @@ static int CACreateSocket(int family, uint16_t *port) #else close(fd); #endif - return -1; + return OC_INVALID_SOCKET; } if (!*port) // return the assigned port { - if (-1 == getsockname(fd, (struct sockaddr *)&sa, &socklen)) + if (OC_SOCKET_ERROR == getsockname(fd, (struct sockaddr *)&sa, &socklen)) { OIC_LOG_V(ERROR, TAG, "getsockname failed: %s", CAIPS_GET_ERROR); #ifdef _WIN32 @@ -746,7 +880,7 @@ static int CACreateSocket(int family, uint16_t *port) #else close(fd); #endif - return -1; + return OC_INVALID_SOCKET; } *port = ntohs(family == AF_INET6 ? ((struct sockaddr_in6 *)&sa)->sin6_port : @@ -759,19 +893,68 @@ static int CACreateSocket(int family, uint16_t *port) #define CHECKFD(FD) \ if (FD > caglobals.ip.maxfd) \ caglobals.ip.maxfd = FD; -#define NEWSOCKET(FAMILY, NAME) \ - caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port); \ - CHECKFD(caglobals.ip.NAME.fd) +#define NEWSOCKET(FAMILY, NAME, MULTICAST) \ + if (caglobals.ip.NAME.fd == OC_INVALID_SOCKET) \ + { \ + caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \ + if (caglobals.ip.NAME.fd == OC_INVALID_SOCKET) \ + { \ + caglobals.ip.NAME.port = 0; \ + caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \ + } \ + CHECKFD(caglobals.ip.NAME.fd) \ + } \ + +void CreateMulticastSocket() +{ + OIC_LOG_V(INFO, TAG, "In %s", __func__); + + if (caglobals.ip.ipv6enabled) + { + NEWSOCKET(AF_INET6, u6, false) + NEWSOCKET(AF_INET6, u6s, false) + NEWSOCKET(AF_INET6, m6, true) + NEWSOCKET(AF_INET6, m6s, true) + OIC_LOG_V(INFO, TAG, "IPv6 unicast port: %u", caglobals.ip.u6.port); + } + if (caglobals.ip.ipv4enabled) + { + NEWSOCKET(AF_INET, u4, false) + NEWSOCKET(AF_INET, u4s, false) + NEWSOCKET(AF_INET, m4, true) + NEWSOCKET(AF_INET, m4s, true) + OIC_LOG_V(INFO, TAG, "IPv4 unicast port: %u", caglobals.ip.u4.port); + } + + OIC_LOG_V(INFO, TAG, "Out %s", __func__); +} + +void CloseMulticastSocket() +{ + OIC_LOG_V(INFO, TAG, "In %s", __func__); + + CLOSE_SOCKET(u6); + CLOSE_SOCKET(u6s); + CLOSE_SOCKET(u4); + CLOSE_SOCKET(u4s); + CLOSE_SOCKET(m6); + CLOSE_SOCKET(m6s); + CLOSE_SOCKET(m4); + CLOSE_SOCKET(m4s); + + OIC_LOG_V(INFO, TAG, "Out %s", __func__); +} static void CAInitializeNetlink() { - caglobals.ip.netlinkFd = -1; + caglobals.ip.netlinkFd = OC_INVALID_SOCKET; #ifdef __linux__ // create NETLINK fd for interface change notifications - struct sockaddr_nl sa = { AF_NETLINK, 0, 0, RTMGRP_LINK }; + struct sockaddr_nl sa = { AF_NETLINK, 0, 0, + RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR }; caglobals.ip.netlinkFd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE); - if (caglobals.ip.netlinkFd == -1) + if (caglobals.ip.netlinkFd == OC_INVALID_SOCKET) { OIC_LOG_V(ERROR, TAG, "netlink socket failed: %s", strerror(errno)); } @@ -782,13 +965,24 @@ static void CAInitializeNetlink() { OIC_LOG_V(ERROR, TAG, "netlink bind failed: %s", strerror(errno)); close(caglobals.ip.netlinkFd); - caglobals.ip.netlinkFd = -1; + caglobals.ip.netlinkFd = OC_INVALID_SOCKET; } else { CHECKFD(caglobals.ip.netlinkFd); } } +#elif defined (__TIZENRT__) // pkmsgq + struct mq_attr lq_attr; + lq_attr.mq_maxmsg = 10; + lq_attr.mq_msgsize = 4; + lq_attr.mq_flags = 0; + g_nwevent_mqfd = mq_open("netlink_evtq", O_RDWR | O_NONBLOCK | O_CREAT, 0666, &lq_attr); + if (g_nwevent_mqfd == (mqd_t) - 1) + { + OIC_LOG_V(ERROR, TAG,"RECV mq_open failed\n"); + return ; + } #endif } @@ -797,22 +991,19 @@ static void CAInitializeFastShutdownMechanism() caglobals.ip.selectTimeout = -1; // don't poll for shutdown int ret = -1; #if defined(WSA_WAIT_EVENT_0) - caglobals.ip.shutdownEvent = -1; caglobals.ip.shutdownEvent = WSACreateEvent(); - - if (caglobals.ip.shutdownEvent == WSA_INVALID_EVENT) - { - caglobals.ip.shutdownEvent = -1; - } - else + if (WSA_INVALID_EVENT != caglobals.ip.shutdownEvent) { ret = 0; } #elif defined(HAVE_PIPE2) +#ifndef __TIZENRT__ ret = pipe2(caglobals.ip.shutdownFds, O_CLOEXEC); CHECKFD(caglobals.ip.shutdownFds[0]); CHECKFD(caglobals.ip.shutdownFds[1]); +#endif #else +#ifndef __TIZENRT__ ret = pipe(caglobals.ip.shutdownFds); if (-1 != ret) { @@ -840,6 +1031,7 @@ static void CAInitializeFastShutdownMechanism() CHECKFD(caglobals.ip.shutdownFds[0]); CHECKFD(caglobals.ip.shutdownFds[1]); #endif +#endif if (-1 == ret) { OIC_LOG_V(ERROR, TAG, "fast shutdown mechanism init failed: %s", CAIPS_GET_ERROR); @@ -883,29 +1075,14 @@ CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool) caglobals.ip.ipv4enabled = true; // only needed to run CA tests } - if (caglobals.ip.ipv6enabled) - { - NEWSOCKET(AF_INET6, u6) - NEWSOCKET(AF_INET6, u6s) - NEWSOCKET(AF_INET6, m6) - NEWSOCKET(AF_INET6, m6s) - OIC_LOG_V(INFO, TAG, "IPv6 unicast port: %u", caglobals.ip.u6.port); - } - if (caglobals.ip.ipv4enabled) - { - NEWSOCKET(AF_INET, u4) - NEWSOCKET(AF_INET, u4s) - NEWSOCKET(AF_INET, m4) - NEWSOCKET(AF_INET, m4s) - OIC_LOG_V(INFO, TAG, "IPv4 unicast port: %u", caglobals.ip.u4.port); - } + CreateMulticastSocket(); - OIC_LOG_V(DEBUG, TAG, + OIC_LOG_V(INFO, TAG, "socket summary: u6=%d, u6s=%d, u4=%d, u4s=%d, m6=%d, m6s=%d, m4=%d, m4s=%d", caglobals.ip.u6.fd, caglobals.ip.u6s.fd, caglobals.ip.u4.fd, caglobals.ip.u4s.fd, caglobals.ip.m6.fd, caglobals.ip.m6s.fd, caglobals.ip.m4.fd, caglobals.ip.m4s.fd); - OIC_LOG_V(DEBUG, TAG, + OIC_LOG_V(INFO, TAG, "port summary: u6 port=%d, u6s port=%d, u4 port=%d, u4s port=%d, m6 port=%d," "m6s port=%d, m4 port=%d, m4s port=%d", caglobals.ip.u6.port, caglobals.ip.u6s.port, caglobals.ip.u4.port, @@ -938,13 +1115,19 @@ CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool) } caglobals.ip.terminate = false; - res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL); +#ifndef __TIZENRT__ + res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL, NULL); +#else + res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL, NULL, "IoT_ReceiveHandler", + CONFIG_IOTIVITY_RECEIVEHANDLER_PTHREAD_STACKSIZE); +#endif if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "thread_pool_add_task failed"); + CAIPStopServer(); return res; } - OIC_LOG(DEBUG, TAG, "CAReceiveHandler thread started successfully."); + OIC_LOG(INFO, TAG, "CAReceiveHandler thread started successfully."); caglobals.ip.started = true; return CA_STATUS_OK; @@ -955,7 +1138,10 @@ void CAIPStopServer() caglobals.ip.started = false; caglobals.ip.terminate = true; + CADeInitializeIPGlobals(); + #if !defined(WSA_WAIT_EVENT_0) +#ifndef __TIZENRT__ if (caglobals.ip.shutdownFds[1] != -1) { close(caglobals.ip.shutdownFds[1]); @@ -965,35 +1151,16 @@ void CAIPStopServer() { // receive thread will stop in SELECT_TIMEOUT seconds. } -#else - if (!WSASetEvent(caglobals.ip.shutdownEvent)) - { - OIC_LOG_V(DEBUG, TAG, "set shutdown event failed: %#08X", GetLastError()); - } #endif -} - -void CAWakeUpForChange() -{ -#if !defined(WSA_WAIT_EVENT_0) - if (caglobals.ip.shutdownFds[1] != -1) - { - ssize_t len = 0; - do - { - len = write(caglobals.ip.shutdownFds[1], "w", 1); - } while ((len == -1) && (errno == EINTR)); - if ((len == -1) && (errno != EINTR) && (errno != EPIPE)) - { - OIC_LOG_V(DEBUG, TAG, "write failed: %s", strerror(errno)); - } - } #else + // receive thread will stop immediately. if (!WSASetEvent(caglobals.ip.shutdownEvent)) { OIC_LOG_V(DEBUG, TAG, "set shutdown event failed: %#08X", GetLastError()); } #endif + + OIC_LOG(INFO, TAG, "Adapter terminated successfully"); } static void applyMulticastToInterface4(uint32_t ifindex) @@ -1008,12 +1175,12 @@ static void applyMulticastToInterface4(uint32_t ifindex) .imr_address.s_addr = htonl(INADDR_ANY), .imr_ifindex = ifindex }; #else - struct ip_mreq mreq = { .imr_multiaddr = IPv4MulticastAddress, + struct ip_mreq mreq = { .imr_multiaddr.s_addr = IPv4MulticastAddress.s_addr, .imr_interface.s_addr = htonl(ifindex) }; #endif int ret = setsockopt(caglobals.ip.m4.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, OPTVAL_T(&mreq), sizeof (mreq)); - if (-1 == ret) + if (OC_SOCKET_ERROR == ret) { #if !defined(WSAEINVAL) if (EADDRINUSE != errno) @@ -1024,8 +1191,8 @@ static void applyMulticastToInterface4(uint32_t ifindex) OIC_LOG_V(ERROR, TAG, " IPv4 IP_ADD_MEMBERSHIP failed: %s", CAIPS_GET_ERROR); } } - ret = setsockopt(caglobals.ip.m4s.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq)); - if (-1 == ret) + ret = setsockopt(caglobals.ip.m4s.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, OPTVAL_T(&mreq), sizeof (mreq)); + if (OC_SOCKET_ERROR == ret) { #if !defined(WSAEINVAL) if (EADDRINUSE != errno) @@ -1040,10 +1207,15 @@ static void applyMulticastToInterface4(uint32_t ifindex) static void applyMulticast6(int fd, struct in6_addr *addr, uint32_t ifindex) { - struct ipv6_mreq mreq = {.ipv6mr_multiaddr = *addr, +#ifndef __TIZENRT__ + struct ipv6_mreq mreq = {.ipv6mr_multiaddr = {{{0}}}, .ipv6mr_interface = ifindex }; - int ret = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof (mreq)); - if (-1 == ret) + + // VS2013 has problems with struct copies inside struct initializers, so copy separately. + mreq.ipv6mr_multiaddr = *addr; + + int ret = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, OPTVAL_T(&mreq), sizeof (mreq)); + if (OC_SOCKET_ERROR == ret) { #if !defined(_WIN32) if (EADDRINUSE != errno) @@ -1054,6 +1226,7 @@ static void applyMulticast6(int fd, struct in6_addr *addr, uint32_t ifindex) OIC_LOG_V(ERROR, TAG, "IPv6 IPV6_JOIN_GROUP failed: %s", CAIPS_GET_ERROR); } } +#endif } static void applyMulticastToInterface6(uint32_t ifindex) @@ -1064,17 +1237,17 @@ static void applyMulticastToInterface6(uint32_t ifindex) } //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressInt, ifindex); applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressLnk, ifindex); - //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressRlm, ifindex); + applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressRlm, ifindex); //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressAdm, ifindex); - //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressSit, ifindex); + applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressSit, ifindex); //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressOrg, ifindex); //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressGlb, ifindex); //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressInt, ifindex); applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressLnk, ifindex); - //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressRlm, ifindex); + applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressRlm, ifindex); //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressAdm, ifindex); - //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressSit, ifindex); + applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressSit, ifindex); //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressOrg, ifindex); //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressGlb, ifindex); } @@ -1105,12 +1278,12 @@ CAResult_t CAIPStartListenServer() } if (ifitem->family == AF_INET) { - OIC_LOG_V(DEBUG, TAG, "Adding IPv4 interface %i to multicast group", ifitem->index); + OIC_LOG_V(DEBUG, TAG, "Adding IPv4 interface(%d) to multicast group", ifitem->index); applyMulticastToInterface4(ifitem->index); } if (ifitem->family == AF_INET6) { - OIC_LOG_V(DEBUG, TAG, "Adding IPv6 interface %i to multicast group", ifitem->index); + OIC_LOG_V(DEBUG, TAG, "Adding IPv6 interface(%d) to multicast group", ifitem->index); applyMulticastToInterface6(ifitem->index); } } @@ -1160,7 +1333,7 @@ CAResult_t CAIPStopListenServer() return CA_STATUS_OK; } -static void CAProcessNewInterface(CAInterface_t *ifitem) +void CAProcessNewInterface(CAInterface_t *ifitem) { if (!ifitem) { @@ -1170,10 +1343,12 @@ static void CAProcessNewInterface(CAInterface_t *ifitem) if (ifitem->family == AF_INET6) { + OIC_LOG_V(DEBUG, TAG, "Adding a new IPv6 interface(%d) to multicast group", ifitem->index); applyMulticastToInterface6(ifitem->index); } if (ifitem->family == AF_INET) { + OIC_LOG_V(DEBUG, TAG, "Adding a new IPv4 interface(%d) to multicast group", ifitem->index); applyMulticastToInterface4(ifitem->index); } } @@ -1183,11 +1358,6 @@ void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback) g_packetReceivedCallback = callback; } -void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback) -{ - CAIPSetNetworkMonitorCallback(callback); -} - static void sendData(int fd, const CAEndpoint_t *endpoint, const void *data, uint32_t dlen, const char *cast, const char *fam) @@ -1204,15 +1374,13 @@ static void sendData(int fd, const CAEndpoint_t *endpoint, return; } - char *secure = (endpoint->flags & CA_SECURE) ? "secure " : ""; - (void)cast; // eliminates release warning (void)fam; - struct sockaddr_storage sock; + struct sockaddr_storage sock = { .ss_family = 0 }; CAConvertNameToAddr(endpoint->addr, endpoint->port, &sock); - socklen_t socklen; + socklen_t socklen = 0; if (sock.ss_family == AF_INET6) { /** @todo figure out correct usage for ifindex, and sin6_scope_id */ @@ -1222,9 +1390,13 @@ static void sendData(int fd, const CAEndpoint_t *endpoint, { socklen = sizeof(struct sockaddr_in); } + +#ifdef TB_LOG + const char *secure = (endpoint->flags & CA_SECURE) ? "secure " : ""; +#endif #if !defined(_WIN32) ssize_t len = sendto(fd, data, dlen, 0, (struct sockaddr *)&sock, socklen); - if (-1 == len) + if (OC_SOCKET_ERROR == len) { // If logging is not defined/enabled. if (g_ipErrorHandler) @@ -1232,10 +1404,14 @@ static void sendData(int fd, const CAEndpoint_t *endpoint, g_ipErrorHandler(endpoint, data, dlen, CA_SEND_FAILED); } OIC_LOG_V(ERROR, TAG, "%s%s %s sendTo failed: %s", secure, cast, fam, strerror(errno)); + CALogSendStateInfo(endpoint->adapter, endpoint->addr, endpoint->port, + len, false, strerror(errno)); } else { OIC_LOG_V(INFO, TAG, "%s%s %s sendTo is successful: %zd bytes", secure, cast, fam, len); + CALogSendStateInfo(endpoint->adapter, endpoint->addr, endpoint->port, + len, true, NULL); } #else int err = 0; @@ -1243,7 +1419,7 @@ static void sendData(int fd, const CAEndpoint_t *endpoint, int sent = 0; do { len = sendto(fd, ((char*)data) + sent, dlen - sent, 0, (struct sockaddr *)&sock, socklen); - if (SOCKET_ERROR == len) + if (OC_SOCKET_ERROR == len) { err = WSAGetLastError(); if ((WSAEWOULDBLOCK != err) && (WSAENOBUFS != err)) @@ -1262,11 +1438,11 @@ static void sendData(int fd, const CAEndpoint_t *endpoint, sent += len; if (sent != len) { - OIC_LOG_V(DEBUG, TAG, "%s%s %s sendTo (Partial Send) is successful: " - "currently sent: %ld bytes, " - "total sent: %ld bytes, " - "remaining: %ld bytes", - secure, cast, fam, len, sent, dlen-sent); + OIC_LOG_V(INFO, TAG, "%s%s %s sendTo (Partial Send) is successful: " + "currently sent: %ld bytes, " + "total sent: %ld bytes, " + "remaining: %ld bytes", + secure, cast, fam, len, sent, dlen-sent); } else { @@ -1274,7 +1450,7 @@ static void sendData(int fd, const CAEndpoint_t *endpoint, secure, cast, fam, len); } } - } while ((SOCKET_ERROR == len) && ((WSAEWOULDBLOCK == err) || (WSAENOBUFS == err)) || (sent < dlen)); + } while ((OC_SOCKET_ERROR == len) && ((WSAEWOULDBLOCK == err) || (WSAENOBUFS == err)) || (sent < dlen)); #endif } @@ -1315,12 +1491,34 @@ static void sendMulticastData6(const u_arraylist_t *iflist, continue; } + bool isMobile = false; + for (uint32_t j = 0; j < MOBILE_INTERFACES; j++) + { + if (strstr(ifitem->name, mobileinferfaces[j])) + { + isMobile = true; + break; + } + } + if (isMobile) + { + continue; + } + int index = ifitem->index; if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, OPTVAL_T(&index), sizeof (index))) { OIC_LOG_V(ERROR, TAG, "setsockopt6 failed: %s", CAIPS_GET_ERROR); return; } + +#ifndef __TIZENRT__ + // Set multicast packet TTL; default TTL is 1 + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &multicastTTL, sizeof(multicastTTL))) + { + OIC_LOG_V(ERROR, TAG, "IPV6_MULTICAST_HOPS failed: %s", CAIPS_GET_ERROR); + } +#endif sendData(fd, endpoint, data, datalen, "multicast", "ipv6"); } } @@ -1336,7 +1534,7 @@ static void sendMulticastData4(const u_arraylist_t *iflist, .imr_address.s_addr = htonl(INADDR_ANY), .imr_ifindex = 0}; #else - struct ip_mreq mreq = { .imr_multiaddr = IPv4MulticastAddress, + struct ip_mreq mreq = { .imr_multiaddr.s_addr = IPv4MulticastAddress.s_addr, .imr_interface = {0}}; #endif @@ -1359,6 +1557,21 @@ static void sendMulticastData4(const u_arraylist_t *iflist, { continue; } + + bool isMobile = false; + for (uint32_t j = 0; j < MOBILE_INTERFACES; j++) + { + if (strstr(ifitem->name, mobileinferfaces[j])) + { + isMobile = true; + break; + } + } + if (isMobile) + { + continue; + } + #if defined(USE_IP_MREQN) mreq.imr_ifindex = ifitem->index; #else @@ -1369,6 +1582,12 @@ static void sendMulticastData4(const u_arraylist_t *iflist, OIC_LOG_V(ERROR, TAG, "send IP_MULTICAST_IF failed: %s (using defualt)", CAIPS_GET_ERROR); } + + // Set multicast packet TTL; default TTL is 1 + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &multicastTTL, sizeof(multicastTTL))) + { + OIC_LOG_V(ERROR, TAG, "IP_MULTICAST_TTL failed: %s", CAIPS_GET_ERROR); + } sendData(fd, endpoint, data, datalen, "multicast", "ipv4"); } } @@ -1410,7 +1629,7 @@ void CAIPSendData(CAEndpoint_t *endpoint, const void *data, uint32_t datalen, endpoint->port = isSecure ? CA_SECURE_COAP : CA_COAP; } - int fd; + CASocketFd_t fd; if (caglobals.ip.ipv6enabled && (endpoint->flags & CA_IPV6)) { fd = isSecure ? caglobals.ip.u6s.fd : caglobals.ip.u6.fd; @@ -1478,10 +1697,8 @@ CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size) { eps[j].flags = CA_IPV4; eps[j].port = caglobals.ip.u4.port; - /** @todo eps[j].addr not populated with IPv4 address string. - * it was using ifitem->ipv4addr to accomplish this. - * Need to understand what ipv4addr means to whom*/ } + OICStrcpy(eps[j].addr, sizeof(eps[j].addr), ifitem->addr); #ifdef __WITH_DTLS__ j++; @@ -1498,14 +1715,14 @@ CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size) { eps[j].flags = CA_IPV4 | CA_SECURE; eps[j].port = caglobals.ip.u4s.port; - inet_ntop(AF_INET, &(ifitem->ipv4addr), eps[j].addr, MAX_ADDR_STR_SIZE_CA); } + OICStrcpy(eps[j].addr, sizeof(eps[j].addr), ifitem->addr); #endif j++; } *info = eps; - *size = len; + *size = length; u_arraylist_destroy(iflist); @@ -1516,3 +1733,17 @@ void CAIPSetErrorHandler(CAIPErrorHandleCallback errorHandleCallback) { g_ipErrorHandler = errorHandleCallback; } + +CAResult_t CAIPSetMulticastTTL(size_t ttl) +{ + multicastTTL = ttl; + return CA_STATUS_OK; +} + +CAResult_t CAIPGetMulticastTTL(size_t *ttl) +{ + VERIFY_NON_NULL(ttl, TAG, "ttl is NULL"); + + *ttl = multicastTTL; + return CA_STATUS_OK; +}