X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fconnectivity%2Fsrc%2Fip_adapter%2Fcaipserver.c;h=87afa900c84974ad2a97cc8b3949bdce513bf63e;hb=55283efd23d570e22010e2a403adea20d16210b9;hp=62efe49412c8c1e7146a1d85f9686175b9a17d28;hpb=1bb09598dc3a52d97d0f6709afdfafd3fa2cbfc5;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 62efe49..87afa90 100644 --- a/resource/csdk/connectivity/src/ip_adapter/caipserver.c +++ b/resource/csdk/connectivity/src/ip_adapter/caipserver.c @@ -25,6 +25,11 @@ #define _GNU_SOURCE // for in6_pktinfo #endif +#ifdef __TIZENRT__ +#include +#include +#endif + #include "iotivity_config.h" #include #if !defined(_WIN32) @@ -40,6 +45,7 @@ #endif #include +#include #if !defined(_MSC_VER) #include #endif //!defined(_MSC_VER) @@ -57,6 +63,11 @@ #include #endif +#ifdef __TIZENRT__ +#include +#include +#endif + #include #include "caipinterface.h" #include "caipnwmonitor.h" @@ -64,7 +75,7 @@ #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" @@ -73,17 +84,31 @@ #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 MOBILE_INTERFACES 2 #define IPv6_MULTICAST_INT "ff01::158" static struct in6_addr IPv6MulticastAddressInt; #define IPv6_MULTICAST_LNK "ff02::158" @@ -99,6 +124,11 @@ static struct in6_addr IPv6MulticastAddressOrg; #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, @@ -118,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) @@ -147,15 +212,58 @@ static void CAEventReturned(CASocketFd_t socket); 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) @@ -198,11 +306,12 @@ 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); } +#endif if (caglobals.ip.netlinkFd != OC_INVALID_SOCKET) { FD_SET(caglobals.ip.netlinkFd, &readFds); @@ -212,20 +321,33 @@ 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) @@ -246,6 +368,7 @@ static void CASelectReturned(fd_set *readFds, int ret) else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE) else if ((caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && FD_ISSET(caglobals.ip.netlinkFd, readFds)) { +#ifndef __TIZENRT__ u_arraylist_t *iflist = CAFindInterfaceChange(); if (iflist) { @@ -261,7 +384,9 @@ static void CASelectReturned(fd_set *readFds, int ret) u_arraylist_destroy(iflist); } break; +#endif } +#ifndef __TIZENRT__ else if (FD_ISSET(caglobals.ip.shutdownFds[0], readFds)) { char buf[10] = {0}; @@ -272,6 +397,7 @@ static void CASelectReturned(fd_set *readFds, int ret) } break; } +#endif else { break; @@ -470,14 +596,7 @@ static void CAEventReturned(CASocketFd_t socket) 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 != OC_INVALID_SOCKET) { @@ -492,7 +611,8 @@ void CADeInitializeIPGlobals() static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags) { - char recvBuffer[COAP_MAX_PDU_SIZE] = {0}; + OIC_LOG(DEBUG, TAG, "IN - CAReceiveMessage"); + char recvBuffer[RECV_MSG_BUF_LEN] = {0}; size_t len = 0; int level = 0; @@ -537,6 +657,7 @@ static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags) 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) { @@ -599,6 +720,7 @@ static CAResult_t CAReceiveMessage(CASocketFd_t 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.*/ @@ -613,6 +735,7 @@ static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags) } } else +#endif { if ((flags & CA_MULTICAST) && pktinfo) { @@ -632,7 +755,7 @@ static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags) { #ifdef __WITH_DTLS__ int ret = CAdecryptSsl(&sep, (uint8_t *)recvBuffer, recvLen); - OIC_LOG_V(DEBUG, TAG, "CAdecryptSsl returns [%d]", ret); + OIC_LOG_V(INFO, TAG, "CAdecryptSsl returns [%d]", ret); #else OIC_LOG(ERROR, TAG, "Encrypted message but no DTLS"); #endif @@ -641,10 +764,12 @@ static CAResult_t CAReceiveMessage(CASocketFd_t 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; } @@ -769,20 +894,64 @@ static CASocketFd_t CACreateSocket(int family, uint16_t *port, bool isMulticast) if (FD > caglobals.ip.maxfd) \ caglobals.ip.maxfd = FD; #define NEWSOCKET(FAMILY, NAME, MULTICAST) \ - 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); \ + 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) \ } \ - 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 = 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 == OC_INVALID_SOCKET) @@ -803,6 +972,17 @@ static void CAInitializeNetlink() 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 } @@ -817,10 +997,13 @@ static void CAInitializeFastShutdownMechanism() 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) { @@ -848,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); @@ -891,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, 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); - } + 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, @@ -946,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; @@ -963,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]); @@ -973,6 +1151,7 @@ void CAIPStopServer() { // receive thread will stop in SELECT_TIMEOUT seconds. } +#endif #else // receive thread will stop immediately. if (!WSASetEvent(caglobals.ip.shutdownEvent)) @@ -980,29 +1159,8 @@ void CAIPStopServer() 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 - 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) @@ -1049,7 +1207,8 @@ static void applyMulticastToInterface4(uint32_t ifindex) static void applyMulticast6(int fd, struct in6_addr *addr, uint32_t ifindex) { - struct ipv6_mreq mreq = {.ipv6mr_multiaddr = {0}, +#ifndef __TIZENRT__ + struct ipv6_mreq mreq = {.ipv6mr_multiaddr = {{{0}}}, .ipv6mr_interface = ifindex }; // VS2013 has problems with struct copies inside struct initializers, so copy separately. @@ -1067,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) @@ -1118,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); } } @@ -1183,10 +1343,12 @@ 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); } } @@ -1242,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; @@ -1272,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 { @@ -1325,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"); } } @@ -1369,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 @@ -1379,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"); } } @@ -1524,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; +}