[Win32] Add win32-specific networking APIs
authorDaniel Ferguson <daniel.j.ferguson@intel.com>
Thu, 14 Jan 2016 08:31:49 +0000 (00:31 -0800)
committerDavid Antler <david.a.antler@intel.com>
Wed, 25 May 2016 22:07:53 +0000 (22:07 +0000)
* Network Interface Monitor using GetAdaptersAddresses()
* WSARecvMsg() instead of recvmsg()
* WSARecvMsg() requires the use of WSAIoctl()
* Added function pointer to caglobals
* CAIPServer.c:sendData() supports partial sends

Change-Id: Icc0c38fa34fa8d50f8b4253990d83be5ae3cdd5c
Signed-off-by: Daniel Ferguson <daniel.j.ferguson@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/5509
Reviewed-by: Dave Thaler <dthaler@microsoft.com>
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: David Antler <david.a.antler@intel.com>
12 files changed:
build_common/msys_nt/SConscript
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/src/SConscript
resource/csdk/connectivity/src/adapter_util/caadapterutils.c
resource/csdk/connectivity/src/ip_adapter/SConscript
resource/csdk/connectivity/src/ip_adapter/caipserver.c
resource/csdk/connectivity/src/ip_adapter/windows/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c [new file with mode: 0644]
resource/csdk/logger/include/logger.h
resource/csdk/stack/include/octypes.h
resource/src/OCResource.cpp
resource/src/SConscript

index d6bf08b..140f54b 100644 (file)
@@ -22,8 +22,8 @@ if env['CC'] == 'gcc':
        env.AppendUnique(CFLAGS = ['-std=c99'])
        env.AppendUnique(CXXFLAGS = ['-std=c++11'])
        env.AppendUnique(CCFLAGS = ['-Wall', '-Wextra', '-Wa,-mbig-obj'])
-       env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '_GNU_SOURCE', '__msys_nt__'])
-
+       env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '_GNU_SOURCE', '__msys_nt__', '_WIN32_WINNT=0x0600'])
+       
        # Set arch flags
        if target_arch in ['x86']:
                env.AppendUnique(CCFLAGS = ['-m32'])
index ca41063..fcf8328 100644 (file)
 #include <sys/poll.h>
 #endif
 
+#if defined(_WIN32)
+#include <mswsock.h>
+#endif
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -128,13 +132,19 @@ typedef char *CAURI_t;
  */
 typedef char *CAToken_t;
 
-// The following flags are the same as the equivalent OIC values in
-// octypes.h, allowing direct copying with slight fixup.
-// The CA layer should used the OC types when build allows that.
+/** The following flags are the same as the equivalent OIC values in
+ * octypes.h, allowing direct copying with slight fixup.
+ * The CA layer should used the OC types when build allows that.
+ */
 #ifdef RA_ADAPTER
 #define MAX_ADDR_STR_SIZE_CA (256)
 #else
-#define MAX_ADDR_STR_SIZE_CA (40)
+/** Max Address could be "coap+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:yyy.yyy.yyy.yyy]:xxxxx"
+ * Which is 64, +1 for null terminator => 65
+ * OCDevAddr (defined in OCTypes.h) must be the same
+ * as CAEndpoint_t (defined here)
+ */
+#define MAX_ADDR_STR_SIZE_CA (65)
 #endif
 
 typedef enum
@@ -250,7 +260,7 @@ typedef struct
     CATransportFlags_t      flags;      // transport modifiers
     uint16_t                port;       // for IP
     char                    addr[MAX_ADDR_STR_SIZE_CA]; // address for all
-    uint32_t                ifindex;  // usually zero for default interface
+    uint32_t                ifindex;    // usually zero for default interface
 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
     char                    routeData[MAX_ADDR_STR_SIZE_CA]; /**< GatewayId:ClientId of
                                                                     destination. **/
@@ -477,24 +487,27 @@ typedef struct
 
     struct sockets
     {
-        void *threadpool;   /**< threadpool between Initialize and Start */
-        CASocket_t u6;      /**< unicast   IPv6 */
-        CASocket_t u6s;     /**< unicast   IPv6 secure */
-        CASocket_t u4;      /**< unicast   IPv4 */
-        CASocket_t u4s;     /**< unicast   IPv4 secure */
-        CASocket_t m6;      /**< multicast IPv6 */
-        CASocket_t m6s;     /**< multicast IPv6 secure */
-        CASocket_t m4;      /**< multicast IPv4 */
-        CASocket_t m4s;     /**< multicast IPv4 secure */
-        int netlinkFd;      /**< netlink */
-        int shutdownFds[2]; /**< shutdown pipe */
-        int selectTimeout;  /**< in seconds */
-        int maxfd;          /**< highest fd (for select) */
-        bool started;       /**< the IP adapter has started */
-        bool terminate;     /**< the IP adapter needs to stop */
-        bool ipv6enabled;   /**< IPv6 enabled by OCInit flags */
-        bool ipv4enabled;   /**< IPv4 enabled by OCInit flags */
-        bool dualstack;     /**< IPv6 and IPv4 enabled */
+        void *threadpool;           /**< threadpool between Initialize and Start */
+        CASocket_t u6;              /**< unicast   IPv6 */
+        CASocket_t u6s;             /**< unicast   IPv6 secure */
+        CASocket_t u4;              /**< unicast   IPv4 */
+        CASocket_t u4s;             /**< unicast   IPv4 secure */
+        CASocket_t m6;              /**< multicast IPv6 */
+        CASocket_t m6s;             /**< multicast IPv6 secure */
+        CASocket_t m4;              /**< multicast IPv4 */
+        CASocket_t m4s;             /**< multicast IPv4 secure */
+        int netlinkFd;              /**< netlink */
+        int shutdownFds[2];         /**< shutdown pipe */
+        int selectTimeout;          /**< in seconds */
+        int maxfd;                  /**< highest fd (for select) */
+        bool started;               /**< the IP adapter has started */
+        bool terminate;             /**< the IP adapter needs to stop */
+        bool ipv6enabled;           /**< IPv6 enabled by OCInit flags */
+        bool ipv4enabled;           /**< IPv4 enabled by OCInit flags */
+        bool dualstack;             /**< IPv6 and IPv4 enabled */
+#if defined (_WIN32)
+        LPFN_WSARECVMSG wsaRecvMsg; /**< Win32 function pointer to WSARecvMsg() */
+#endif
 
         struct networkmonitors
         {
index 74535a2..a948641 100644 (file)
@@ -157,11 +157,14 @@ if ca_os in ['linux', 'tizen', 'android', 'arduino', 'ios']:
 
 print "Include path is %s" % env.get('CPPPATH')
 print "Files path is %s" % env.get('CA_SRC')
-               
+
 lib_env = env.Clone()
 
+if env.get('LOGGING'):
+       lib_env.AppendUnique(CPPDEFINES=['TB_LOG'])
+
 if ca_os == 'android':
-    lib_env.AppendUnique(LINKFLAGS = ['-Wl,-soname,libconnectivity_abstraction.so'])
+       lib_env.AppendUnique(LINKFLAGS = ['-Wl,-soname,libconnectivity_abstraction.so'])
 
 if ca_os in ['android', 'tizen']:
        lib_env.AppendUnique(LIBS = ['coap'])
index 5d71b54..4aec40b 100644 (file)
@@ -153,12 +153,12 @@ void CAConvertAddrToName(const struct sockaddr_storage *sockAddr, socklen_t sock
             OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
                             "getnameinfo failed: %s", gai_strerror(r));
         }
-#elif defined(__msys_nt__) || defined(_WIN32)
+#elif defined(_WIN32)
         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
                             "getnameinfo failed: errno %i", WSAGetLastError());
 #else
         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
-                        "getnameinfo failed: %s", gai_strerror(r));
+                            "getnameinfo failed: %s", gai_strerror(r));
 #endif
         return;
     }
@@ -189,12 +189,12 @@ void CAConvertNameToAddr(const char *host, uint16_t port, struct sockaddr_storag
             OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
                             "getaddrinfo failed: %s", gai_strerror(r));
         }
-#elif defined(__msys_nt__) || defined(_WIN32)
+#elif defined(_WIN32)
         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
                             "getaddrinfo failed: errno %i", WSAGetLastError());
 #else
         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
-                        "getaddrinfo failed: %s", gai_strerror(r));
+                            "getaddrinfo failed: %s", gai_strerror(r));
 #endif
         return;
     }
index 5cc3798..4d45917 100644 (file)
@@ -48,6 +48,9 @@ if target_os in ['linux','darwin','ios']:
     target_files += [ os.path.join(src_dir,
                                    'linux/caipnwmonitor.c') ]
 
+if target_os in ['windows', 'msys_nt']:
+       target_files += [ os.path.join(src_dir, 'windows/caipnwmonitor.c') ]
+
 # The list of BLE adapter source files is a combination of both the
 # common and target-specific source file lists.
 env.AppendUnique(CA_SRC = common_files + target_files)
index 837940b..cacf7b0 100644 (file)
@@ -1,4 +1,4 @@
-/*****************************************************************j
+/* ****************************************************************
  *
  * Copyright 2014 Samsung Electronics All Rights Reserved.
  *
 #include "oic_malloc.h"
 #include "oic_string.h"
 
+#define USE_IP_MREQN
+#if defined(_WIN32)
+#undef USE_IP_MREQN
+#endif
+
 /*
  * Logging tag for module name
  */
@@ -108,17 +113,21 @@ static char *ipv6mcnames[IPv6_DOMAINS] = {
     NULL
 };
 
-#if defined (__msys_nt__)
-    char* _caips_get_error(){
+#if defined (_WIN32)
+#define IFF_UP_RUNNING_FLAGS  (IFF_UP)
+
+    char* caips_get_error(){
         static char buffer[32];
         snprintf(buffer, 32, "%i", WSAGetLastError());
         return buffer;
     }
-    #define CAIPS_GET_ERROR \
-        _caips_get_error()
+#define CAIPS_GET_ERROR \
+    caips_get_error()
 #else
-    #define CAIPS_GET_ERROR \
-        strerror(errno)
+#define IFF_UP_RUNNING_FLAGS  (IFF_UP|IFF_RUNNING)
+
+#define CAIPS_GET_ERROR \
+    strerror(errno)
 #endif
 static CAIPExceptionCallback g_exceptionCallback;
 
@@ -197,7 +206,7 @@ static void CAFindReadyMessage()
     SET(m4,  &readFds)
     SET(m4s, &readFds)
 
-#if !defined(__msys_nt__)
+#if !defined(_WIN32)
     if (caglobals.ip.shutdownFds[0] != -1)
     {
         FD_SET(caglobals.ip.shutdownFds[0], &readFds);
@@ -243,7 +252,7 @@ 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)
-#if !defined(__msys_nt__)
+#if !defined(_WIN32)
         else if (FD_ISSET(caglobals.ip.netlinkFd, readFds))
         {
             CAInterface_t *ifchanged = CAFindInterfaceChange();
@@ -287,9 +296,9 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags)
     int level, type, namelen;
     struct sockaddr_storage srcAddr;
     unsigned char *pktinfo = NULL;
-#if !defined(__msys_nt__)
+#if !defined(WSA_CMSG_DATA)
     struct cmsghdr *cmp = NULL;
-    struct iovec iov = { recvBuffer, sizeof (recvBuffer) };
+    struct iovec iov = { .iov_base = recvBuffer, .iov_len = sizeof (recvBuffer) };
     union control
     {
         struct cmsghdr cmsg;
@@ -335,16 +344,60 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags)
             }
         }
     }
-#else // if defined(__msys_nt__)
+#else // if defined(WSA_CMSG_DATA)
+    union control
+    {
+        WSACMSGHDR cmsg;
+        uint8_t data[WSA_CMSG_SPACE(sizeof (IN6_PKTINFO))];
+    } cmsg;
+    memset(&cmsg, 0, sizeof(cmsg));
 
-#endif // !defined(__msys_nt__)
+    if (flags & CA_IPV6)
+    {
+        namelen  = sizeof (struct sockaddr_in6);
+        level = IPPROTO_IPV6;
+        type = IPV6_PKTINFO;
+    }
+    else
+    {
+        namelen = sizeof (struct sockaddr_in);
+        level = IPPROTO_IP;
+        type = IP_PKTINFO;
+    }
+
+    WSABUF iov = {.len = sizeof (recvBuffer), .buf = recvBuffer};
+    WSAMSG msg = {.name = &srcAddr,
+                  .namelen = namelen,
+                  .lpBuffers = &iov,
+                  .dwBufferCount = 1,
+                  .Control = {.buf = cmsg.data, .len = sizeof (cmsg)}
+                 };
+
+    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)
+    {
+        OIC_LOG_V(ERROR, TAG, "WSARecvMsg failed %i", WSAGetLastError());
+    }
+
+    if (flags & CA_MULTICAST)
+    {
+        for (WSACMSGHDR *cmp = WSA_CMSG_FIRSTHDR(&msg); cmp != NULL;
+             cmp = WSA_CMSG_NXTHDR(&msg, cmp))
+        {
+            if (cmp->cmsg_level == level && cmp->cmsg_type == type)
+            {
+                pktinfo = WSA_CMSG_DATA(cmp);
+            }
+        }
+    }
+#endif // !defined(WSA_CMSG_DATA)
     CASecureEndpoint_t sep = {.endpoint = {.adapter = CA_ADAPTER_IP, .flags = flags}};
 
     if (flags & CA_IPV6)
     {
-        sep.endpoint.ifindex = ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id;
-        ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id = 0;
-
+        /** @todo figure out correct usage for ifindex, and sin6_scope_id.*/
         if ((flags & CA_MULTICAST) && pktinfo)
         {
             struct in6_addr *addr = &(((struct in6_pktinfo *)pktinfo)->ipi6_addr);
@@ -368,11 +421,9 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags)
             }
         }
     }
-#if !defined(__msys_nt__)
-    CAConvertAddrToName(&srcAddr, msg.msg_namelen, sep.endpoint.addr, &sep.endpoint.port);
-#else
 
-#endif
+    CAConvertAddrToName(&srcAddr, namelen, sep.endpoint.addr, &sep.endpoint.port);
+
     if (flags & CA_SECURE)
     {
 #ifdef __WITH_DTLS__
@@ -392,7 +443,6 @@ static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags)
 
     return CA_STATUS_OK;
 
-
 }
 
 void CAIPPullData()
@@ -403,7 +453,6 @@ void CAIPPullData()
 
 static int CACreateSocket(int family, uint16_t *port)
 {
-#if !defined(__msys_nt__)
     int socktype = SOCK_DGRAM;
 #ifdef SOCK_CLOEXEC
     socktype |= SOCK_CLOEXEC;
@@ -411,11 +460,11 @@ static int CACreateSocket(int family, uint16_t *port)
     int fd = socket(family, socktype, IPPROTO_UDP);
     if (-1 == fd)
     {
-        OIC_LOG_V(ERROR, TAG, "create socket failed: %s", strerror(errno));
+        OIC_LOG_V(ERROR, TAG, "create socket failed: %s", CAIPS_GET_ERROR);
         return -1;
     }
 
-#ifndef SOCK_CLOEXEC
+#if !defined(SOCK_CLOEXEC) && defined(FD_CLOEXEC)
     int fl = fcntl(fd, F_GETFD);
     if (-1 == fl || -1 == fcntl(fd, F_SETFD, fl|FD_CLOEXEC))
     {
@@ -424,9 +473,6 @@ static int CACreateSocket(int family, uint16_t *port)
         return -1;
     }
 #endif
-#else // defined(__msys_nt__)
-
-#endif
     struct sockaddr_storage sa = { .ss_family = family };
     socklen_t socklen;
 
@@ -436,15 +482,15 @@ static int CACreateSocket(int family, uint16_t *port)
 
         if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)))
         {
-            OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", strerror(errno));
+            OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", CAIPS_GET_ERROR);
         }
 
-        if (*port)      // only do this for multicast ports
+        if (*port) // only do this for multicast ports
         {
-#if !defined(__msys_nt__)
+#if defined(IPV6_RECVPKTINFO)
             if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof (on)))
 #else
-
+            if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof (on)))
 #endif
             {
                 OIC_LOG_V(ERROR, TAG, "IPV6_RECVPKTINFO failed: %s",CAIPS_GET_ERROR);
@@ -456,7 +502,7 @@ static int CACreateSocket(int family, uint16_t *port)
     }
     else
     {
-        if (*port)      // only do this for multicast ports
+        if (*port) // only do this for multicast ports
         {
             int on = 1;
             if (-1 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &on, sizeof (on)))
@@ -469,7 +515,7 @@ static int CACreateSocket(int family, uint16_t *port)
         socklen = sizeof (struct sockaddr_in);
     }
 
-    if (*port)  // use the given port
+    if (*port) // use the given port
     {
         int on = 1;
         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)))
@@ -487,7 +533,7 @@ static int CACreateSocket(int family, uint16_t *port)
         return -1;
     }
 
-    if (!*port)  // return the assigned port
+    if (!*port) // return the assigned port
     {
         if (-1 == getsockname(fd, (struct sockaddr *)&sa, &socklen))
         {
@@ -540,7 +586,7 @@ static void CAInitializeNetlink()
 
 static void CAInitializePipe()
 {
-#if !defined(__msys_nt__)
+#if !defined(_WIN32)
     caglobals.ip.selectTimeout = -1;
 #ifdef HAVE_PIPE2
     int ret = pipe2(caglobals.ip.shutdownFds, O_CLOEXEC);
@@ -576,7 +622,7 @@ static void CAInitializePipe()
         caglobals.ip.selectTimeout = SELECT_TIMEOUT; //poll needed for shutdown
     }
 #else
-    //msys stuff here
+    /** @todo Refactor to support Windows-specific inter-thread communication code. */
 #endif
 }
 
@@ -588,7 +634,17 @@ CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool)
     {
         return res;
     }
-
+#if defined (_WIN32)
+    WORD wVersionRequested = MAKEWORD(2, 2);
+    WSADATA wsaData ={.wVersion = 0};
+    int err = WSAStartup(wVersionRequested, &wsaData);
+    if (err != 0)
+    {
+        OIC_LOG_V(ERROR, TAG, "WSAStartup failed: %i", err);
+        return CA_STATUS_FAILED;
+    }
+    OIC_LOG(DEBUG, TAG, "WSAStartup Succeeded");
+#endif
     if (!IPv4MulticastAddress.s_addr)
     {
         (void)inet_pton(AF_INET, IPv4_MULTICAST, &IPv4MulticastAddress);
@@ -634,6 +690,17 @@ CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool)
               caglobals.ip.u6.port, caglobals.ip.u6s.port, caglobals.ip.u4.port,
               caglobals.ip.u4s.port, caglobals.ip.m6.port, caglobals.ip.m6s.port,
               caglobals.ip.m4.port, caglobals.ip.m4s.port);
+#if defined (_WIN32)
+    caglobals.ip.wsaRecvMsg = NULL;
+    GUID GuidWSARecvMsg = WSAID_WSARECVMSG;
+    DWORD copied = 0;
+    err = WSAIoctl(caglobals.ip.u4.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidWSARecvMsg, sizeof(GuidWSARecvMsg), &(caglobals.ip.wsaRecvMsg), sizeof(caglobals.ip.wsaRecvMsg), &copied, 0, 0);
+    if (0 != err)
+    {
+        OIC_LOG_V(ERROR, TAG, "WSAIoctl failed %i", WSAGetLastError());
+        return CA_STATUS_FAILED;
+    }
+#endif
     // create pipe for fast shutdown
     CAInitializePipe();
     CHECKFD(caglobals.ip.shutdownFds[0]);
@@ -668,7 +735,7 @@ void CAIPStopServer()
 {
     caglobals.ip.started = false;
     caglobals.ip.terminate = true;
-#if !defined(__msys_nt__)
+#if !defined(_WIN32)
 
     if (caglobals.ip.shutdownFds[1] != -1)
     {
@@ -680,13 +747,13 @@ void CAIPStopServer()
         // receive thread will stop in SELECT_TIMEOUT seconds.
     }
 #else
-    //msys stuff here
+    /** @todo Refactor to support Windows-specific inter-thread communication code. */
 #endif
 }
 
 void CAWakeUpForChange()
 {
-#if !defined(__msys_nt__)
+#if !defined(_WIN32)
     if (caglobals.ip.shutdownFds[1] != -1)
     {
         ssize_t len = 0;
@@ -700,44 +767,66 @@ void CAWakeUpForChange()
         }
     }
 #else
-    //msys stuff here
+    /** @todo Refactor to support Windows-specific inter-thread communication code. */
 #endif
 }
 
-static void applyMulticastToInterface4(struct in_addr inaddr)
+static void applyMulticastToInterface4(uint32_t ifindex)
 {
     if (!caglobals.ip.ipv4enabled)
     {
         return;
     }
 
+#if defined(USE_IP_MREQN)
     struct ip_mreqn mreq = { .imr_multiaddr = IPv4MulticastAddress,
-                             .imr_address = inaddr,
-                             .imr_ifindex = 0 };
-    if (setsockopt(caglobals.ip.m4.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq)))
+                             .imr_address.s_addr = htonl(INADDR_ANY),
+                             .imr_ifindex = ifindex };
+#else
+    struct ip_mreq mreq  = { .imr_multiaddr = IPv4MulticastAddress,
+                             .imr_interface.s_addr = htonl(ifindex) };
+#endif
+
+    int ret = setsockopt(caglobals.ip.m4.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq));
+    if (-1 == ret)
     {
+#if !defined(WSAEINVAL)
         if (EADDRINUSE != errno)
+#else
+        if (WSAEINVAL != WSAGetLastError()) // Joining multicast group more than once (IPv4 Flavor)
+#endif
         {
-            OIC_LOG_V(ERROR, TAG, "IPv4 IP_ADD_MEMBERSHIP failed: %s", CAIPS_GET_ERROR);
+            OIC_LOG_V(ERROR, TAG, "       IPv4 IP_ADD_MEMBERSHIP failed: %s", CAIPS_GET_ERROR);
         }
     }
-    if (setsockopt(caglobals.ip.m4s.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq)))
+    ret = setsockopt(caglobals.ip.m4s.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq));
+    if (-1 == ret)
     {
+#if !defined(WSAEINVAL)
         if (EADDRINUSE != errno)
+#else
+        if (WSAEINVAL != WSAGetLastError()) // Joining multicast group more than once (IPv4 Flavor)
+#endif
         {
-            OIC_LOG_V(ERROR, TAG, "secure IPv4 IP_ADD_MEMBERSHIP failed: %s", CAIPS_GET_ERROR);
+            OIC_LOG_V(ERROR, TAG, "SECURE IPv4 IP_ADD_MEMBERSHIP failed: %s", CAIPS_GET_ERROR);
         }
     }
 }
 
 static void applyMulticast6(int fd, struct in6_addr *addr, uint32_t ifindex)
 {
-    struct ipv6_mreq mreq = {.ipv6mr_multiaddr = *addr, .ipv6mr_interface = ifindex};
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof (mreq)))
+    struct ipv6_mreq mreq = {.ipv6mr_multiaddr = *addr,
+                             .ipv6mr_interface = ifindex };
+    int ret = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof (mreq));
+    if (-1 == ret)
     {
-        if (EADDRINUSE != errno)
+#if !defined(_WIN32)
+                if (EADDRINUSE != errno)
+#else
+                if (WSAEINVAL != WSAGetLastError()) // Joining multicast group more than once (IPv6 Flavor)
+#endif
         {
-            OIC_LOG_V(ERROR, TAG, "IPv6 IP_ADD_MEMBERSHIP failed: %s", CAIPS_GET_ERROR);
+            OIC_LOG_V(ERROR, TAG, "IPv6 IPV6_JOIN_GROUP failed: %s", CAIPS_GET_ERROR);
         }
     }
 }
@@ -770,7 +859,7 @@ CAResult_t CAIPStartListenServer()
     u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
     if (!iflist)
     {
-        OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
+        OIC_LOG_V(ERROR, TAG, "CAIPGetInterfaceInformation() failed: %s", strerror(errno));
         return CA_STATUS_FAILED;
     }
 
@@ -785,25 +874,19 @@ CAResult_t CAIPStartListenServer()
         {
             continue;
         }
-#if !defined(__msys_nt__)
-        if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
-#else
-    //IFF_RUNNING is not on msys or win32
-#endif
+        if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS)
         {
             continue;
         }
         if (ifitem->family == AF_INET)
         {
-            struct in_addr inaddr;
-            inaddr.s_addr = ifitem->ipv4addr;
-            applyMulticastToInterface4(inaddr);
-            OIC_LOG_V(DEBUG, TAG, "IPv4 network interface: %s", ifitem->name);
+            OIC_LOG_V(DEBUG, TAG, "Adding IPv4 interface %i 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);
             applyMulticastToInterface6(ifitem->index);
-            OIC_LOG_V(DEBUG, TAG, "IPv6 network interface: %s", ifitem->name);
         }
     }
 
@@ -831,11 +914,7 @@ CAResult_t CAIPStopListenServer()
         {
             continue;
         }
-#if !defined(__msys_nt__)
-        if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
-#else
-    //IFF_RUNNING is not on msys or win32
-#endif
+        if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS)
         {
             continue;
         }
@@ -867,14 +946,14 @@ static void CAProcessNewInterface(CAInterface_t *ifitem)
         OIC_LOG(DEBUG, TAG, "ifitem is null");
         return;
     }
+
     if (ifitem->family == AF_INET6)
     {
         applyMulticastToInterface6(ifitem->index);
     }
     if (ifitem->family == AF_INET)
     {
-        struct in_addr inaddr = { .s_addr = ifitem->ipv4addr };
-        applyMulticastToInterface4(inaddr);
+        applyMulticastToInterface4(ifitem->index);
     }
 }
 
@@ -906,31 +985,28 @@ static void sendData(int fd, const CAEndpoint_t *endpoint,
     }
 
     char *secure = (endpoint->flags & CA_SECURE) ? "secure " : "";
+
     (void)secure;   // eliminates release warning
+    (void)cast;
+    (void)fam;
+
     struct sockaddr_storage sock;
     CAConvertNameToAddr(endpoint->addr, endpoint->port, &sock);
 
     socklen_t socklen;
     if (sock.ss_family == AF_INET6)
     {
-        struct sockaddr_in6 *sock6 = (struct sockaddr_in6 *)&sock;
-        if (!sock6->sin6_scope_id)
-        {
-            sock6->sin6_scope_id = endpoint->ifindex;
-        }
+        /** @todo figure out correct usage for ifindex, and sin6_scope_id */
         socklen = sizeof(struct sockaddr_in6);
     }
     else
     {
         socklen = sizeof(struct sockaddr_in);
     }
-#if !defined(__msys_nt__)
+#if !defined(_WIN32)
     ssize_t len = sendto(fd, data, dlen, 0, (struct sockaddr *)&sock, socklen);
     if (-1 == len)
     {
-         // If logging is not defined/enabled.
-         (void)cast;
-         (void)fam;
         OIC_LOG_V(ERROR, TAG, "%s%s %s sendTo failed: %s", secure, cast, fam, strerror(errno));
     }
     else
@@ -938,7 +1014,37 @@ static void sendData(int fd, const CAEndpoint_t *endpoint,
         OIC_LOG_V(INFO, TAG, "%s%s %s sendTo is successful: %zd bytes", secure, cast, fam, len);
     }
 #else
-
+    int err = 0;
+    int len = 0;
+    int sent = 0;
+    do {
+        len = sendto(fd, ((char*)data) + sent, dlen - sent, 0, (struct sockaddr *)&sock, socklen);
+        if (SOCKET_ERROR == len)
+        {
+            err = WSAGetLastError();
+            if ((WSAEWOULDBLOCK != err) && (WSAENOBUFS != err))
+            {
+                OIC_LOG_V(ERROR, TAG, "%s%s %s sendTo failed: %i", secure, cast, fam, err);
+            }
+        }
+        else
+        {
+            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);
+            }
+            else
+            {
+                OIC_LOG_V(INFO, TAG, "%s%s %s sendTo is successful: %ld bytes", 
+                                     secure, cast, fam, len);
+            }
+        }
+    } while ((SOCKET_ERROR == len) && ((WSAEWOULDBLOCK == err) || (WSAENOBUFS == err)) || (sent < dlen));
 #endif
 }
 
@@ -970,11 +1076,7 @@ static void sendMulticastData6(const u_arraylist_t *iflist,
         {
             continue;
         }
-#if !defined(__msys_nt__)
-        if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
-#else
-
-#endif
+        if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS)
         {
             continue;
         }
@@ -987,7 +1089,6 @@ static void sendMulticastData6(const u_arraylist_t *iflist,
         if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &index, sizeof (index)))
         {
             OIC_LOG_V(ERROR, TAG, "setsockopt6 failed: %s", CAIPS_GET_ERROR);
-
             return;
         }
         sendData(fd, endpoint, data, datalen, "multicast", "ipv6");
@@ -1000,8 +1101,15 @@ static void sendMulticastData4(const u_arraylist_t *iflist,
 {
     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");
 
+#if defined(USE_IP_MREQN)
     struct ip_mreqn mreq = { .imr_multiaddr = IPv4MulticastAddress,
-                             .imr_ifindex = 0 };
+                             .imr_address.s_addr = htonl(INADDR_ANY),
+                             .imr_ifindex = 0};
+#else
+    struct ip_mreq mreq  = { .imr_multiaddr = IPv4MulticastAddress,
+                             .imr_interface = {0}};
+#endif
+
     OICStrcpy(endpoint->addr, sizeof(endpoint->addr), IPv4_MULTICAST);
     int fd = caglobals.ip.u4.fd;
 
@@ -1013,11 +1121,7 @@ static void sendMulticastData4(const u_arraylist_t *iflist,
         {
             continue;
         }
-#if !defined(__msys_nt__)
-        if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
-#else
-
-#endif
+        if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS)
         {
             continue;
         }
@@ -1025,10 +1129,11 @@ static void sendMulticastData4(const u_arraylist_t *iflist,
         {
             continue;
         }
-
-        struct in_addr inaddr;
-        inaddr.s_addr = ifitem->ipv4addr;
-        mreq.imr_address = inaddr;
+#if defined(USE_IP_MREQN)
+        mreq.imr_ifindex = ifitem->index;
+#else
+        mreq.imr_interface.s_addr = htonl(ifitem->index);
+#endif
         if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof (mreq)))
         {
             OIC_LOG_V(ERROR, TAG, "send IP_MULTICAST_IF failed: %s (using defualt)",
@@ -1143,8 +1248,9 @@ CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
         {
             eps[j].flags = CA_IPV4;
             eps[j].port = caglobals.ip.u4.port;
-
-            inet_ntop(AF_INET, &(ifitem->ipv4addr), eps[j].addr, MAX_ADDR_STR_SIZE_CA);
+            /** @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*/
         }
 
 #ifdef __WITH_DTLS__
diff --git a/resource/csdk/connectivity/src/ip_adapter/windows/SConscript b/resource/csdk/connectivity/src/ip_adapter/windows/SConscript
new file mode 100644 (file)
index 0000000..f10999f
--- /dev/null
@@ -0,0 +1,12 @@
+#######################################################
+#       Build IP adapter for MSYS2
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+target_os = env.get('TARGET_OS')
+env.AppendUnique(CPPPATH = [ os.path.join(src_dir, target_os) ])
+
+src_files = [ 'caipnwmonitor.c' ]
+
+Return('src_files')
diff --git a/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c
new file mode 100644 (file)
index 0000000..4720e18
--- /dev/null
@@ -0,0 +1,273 @@
+/* *****************************************************************
+*
+* Copyright 2016 Intel Corporation
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+#include "caipinterface.h"
+
+#include <sys/types.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <winsock2.h>
+#include <iptypes.h>
+#include <stdbool.h>
+#include "caadapterutils.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+
+#define TAG "IP_MONITOR"
+
+/** @todo Implement network interface monitoring in case the IP changes.
+ * Not critical for win32 bring-up.
+ */
+CAResult_t CAIPStartNetworkMonitor()
+{
+    return CA_STATUS_OK;
+}
+
+/** @todo Implement network interface monitoring in case the IP changes.
+ * Not critical for win32 bring-up.
+ */
+CAResult_t CAIPStopNetworkMonitor()
+{
+    return CA_STATUS_OK;
+}
+
+/** @todo Implement network interface monitoring.
+ *  Not used in win32, but caipserver currently requires this function
+ *  be defined. not critical.
+ */
+int CAGetPollingInterval(int interval)
+{
+    return interval;
+}
+
+/** @todo Implement network interface monitoring.
+ * Not critical for win32 bring-up.
+ */
+void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+{
+    return;
+}
+
+bool IsValidAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex, uint16_t family)
+{
+    bool valid = true;
+
+    // If desiredIndex is non-zero, then only retrieve adapter corresponding to desiredIndex.
+    // If desiredIndex is zero, then retrieve all adapters.
+    if (desiredIndex && (pAdapterAddr->IfIndex != desiredIndex))
+    {
+        OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i not interesting.", pAdapterAddr->IfIndex);
+        valid = false;
+    }
+
+    if (pAdapterAddr->IfType & IF_TYPE_SOFTWARE_LOOPBACK)
+    {
+        OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i is loopback.", pAdapterAddr->IfIndex);
+        valid = false;
+    }
+
+    // If the adapter must support the requested family
+    if ((family == AF_INET6) && ((pAdapterAddr->Flags & IP_ADAPTER_IPV6_ENABLED) == 0))
+    {
+        OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i does not support IPv6", pAdapterAddr->IfIndex);
+        valid = false;
+    }
+    else if ((family == AF_INET) && ((pAdapterAddr->Flags & IP_ADAPTER_IPV4_ENABLED) == 0))
+    {
+        OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i does not support IPv4", pAdapterAddr->IfIndex);
+        valid = false;
+    }
+
+    if ((pAdapterAddr->OperStatus & IfOperStatusUp) == 0)
+    {
+        OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i is not operational.", pAdapterAddr->IfIndex);
+        valid = false;
+    }
+    return valid;
+
+}
+
+
+bool AddCAInterface(u_arraylist_t *iflist, const char * name, uint32_t index, uint16_t family)
+{
+    bool bSucceeded = false;
+    CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(*ifitem));
+    if (ifitem)
+    {
+        OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, name);
+        ifitem->index = index;
+        ifitem->family = family;
+        ifitem->flags |= IFF_UP;// IsValidAddress() will have filtered out non-operational addresses already.
+
+        if (u_arraylist_add(iflist, ifitem))
+        {
+            bSucceeded = true;
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "u_arraylist_add failed");
+            OICFree(ifitem);
+        }
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "Allocating memory for a CAInterface_t failed");
+    }
+    return bSucceeded;
+}
+
+bool AddInterfaces(PIP_ADAPTER_ADDRESSES pAdapterAddr, u_arraylist_t *iflist, int desiredIndex)
+{
+    bool bSucceeded = false;
+    for (PIP_ADAPTER_ADDRESSES pCurAdapterAddr = pAdapterAddr;
+         pCurAdapterAddr != NULL; pCurAdapterAddr = pCurAdapterAddr->Next)
+    {
+        OIC_LOG_V(DEBUG, TAG, "\tInterface Index: %u", pCurAdapterAddr->IfIndex);
+        OIC_LOG_V(DEBUG, TAG, "\tInterface  name: %s", pCurAdapterAddr->AdapterName);
+
+        // Prefer IPv6 over IPv4.
+        if (pCurAdapterAddr->Flags & IP_ADAPTER_IPV6_ENABLED)
+        {
+            // Do not add loopback, duplicate, or non-operational adapters
+            if (IsValidAdapter(pCurAdapterAddr, desiredIndex, AF_INET6))
+            {
+                if (AddCAInterface(iflist, pCurAdapterAddr->AdapterName, pCurAdapterAddr->IfIndex, AF_INET6))
+                {
+                    OIC_LOG_V(DEBUG, TAG, "\t\tAdded IPv6 interface %i", pCurAdapterAddr->IfIndex);
+                    bSucceeded = true;
+                }
+                else
+                {
+                    OIC_LOG_V(ERROR, TAG, "\tAdding IPv6 interface %i failed", pCurAdapterAddr->IfIndex);
+                    break;
+                }
+            }
+            else
+            {
+                OIC_LOG_V(DEBUG, TAG, "\t\tIPv6 interface %i not valid, skipping...", pCurAdapterAddr->IfIndex);
+            }
+        }
+        else if (pCurAdapterAddr->Flags & IP_ADAPTER_IPV4_ENABLED)
+        {
+            // Do not add loopback, duplicate, or non-operational adapters
+            if (IsValidAdapter(pCurAdapterAddr, desiredIndex, AF_INET))
+            {
+                if (AddCAInterface(iflist, pCurAdapterAddr->AdapterName, pCurAdapterAddr->IfIndex, AF_INET))
+                {
+                    OIC_LOG_V(DEBUG, TAG, "\t\tAdded IPv4 interface %i", pCurAdapterAddr->IfIndex);
+                    bSucceeded = true;
+                }
+                else
+                {
+                    OIC_LOG_V(ERROR, TAG, "\tAdding IPv4 interface %i failed", pCurAdapterAddr->IfIndex);
+                    break;
+                }
+            }
+            else
+            {
+                OIC_LOG_V(DEBUG, TAG, "\t\tIPv6 interface %i not valid, skipping...", pCurAdapterAddr->IfIndex);
+            }
+
+        }
+    }
+    return bSucceeded;
+}
+
+PIP_ADAPTER_ADDRESSES GetAdapters()
+{
+    ULONG ulOutBufLen = sizeof(IP_ADAPTER_ADDRESSES);
+    PIP_ADAPTER_ADDRESSES pAdapterAddr = (IP_ADAPTER_ADDRESSES *) OICMalloc(ulOutBufLen);
+    if (pAdapterAddr != NULL)
+    {
+        ULONG flags = 0;
+        ULONG ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapterAddr, &ulOutBufLen);
+        if (ERROR_BUFFER_OVERFLOW == ret)
+        {
+            // Redo with updated length
+            OICFree(pAdapterAddr);
+            pAdapterAddr = (PIP_ADAPTER_ADDRESSES) OICMalloc(ulOutBufLen);
+            if (pAdapterAddr != NULL) {
+                ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapterAddr, &ulOutBufLen);
+                if (NO_ERROR != ret)
+                {
+                    OIC_LOG(ERROR, TAG, "GetAdaptersAddresses() failed");
+                    OICFree(pAdapterAddr);
+                    pAdapterAddr = NULL;
+                }
+                else
+                {
+                    // Succeeded getting adapters
+                }
+            }
+            else
+            {
+                OIC_LOG(ERROR, TAG, "Second time allocating memory for GetAdaptersAddresses() failed");
+            }
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "Expected GetAdaptersAddresses() to fail on first try, but it didn't.");
+        }
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "First time allocating memory for GetAdaptersAddresses() failed");
+    }
+    return pAdapterAddr;
+}
+
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
+{
+    u_arraylist_t *iflist = u_arraylist_create();
+    if (iflist)
+    {
+        PIP_ADAPTER_ADDRESSES pAdapterAddr = NULL;
+        pAdapterAddr = GetAdapters();
+        if (pAdapterAddr)
+        {
+            // Cycle through adapters
+            // Add valid adapters to the interface list.
+            bool ret = AddInterfaces(pAdapterAddr, iflist, desiredIndex);
+            if (false == ret)
+            {
+                OIC_LOG(ERROR, TAG, "AddInterfaces() failed");
+                u_arraylist_destroy(iflist);
+                iflist = NULL;
+            }
+
+            // Finished with Adapter List
+            OICFree(pAdapterAddr);
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "Enumerating Adapters failed");
+            u_arraylist_destroy(iflist);
+            iflist = NULL;
+        }
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "Failed to create iflist");
+    }
+    return iflist;
+}
index cbd7bbf..28b8308 100644 (file)
@@ -67,6 +67,12 @@ typedef enum {
     FATAL = DLOG_ERROR
 } LogLevel;
 #else
+
+/** @todo temporary work-around until better names with prefixes are used for the enum values. */
+#ifdef ERROR
+#undef ERROR
+#endif
+
 typedef enum {
     DEBUG = 0,
     INFO,
index e83bb82..659748c 100644 (file)
@@ -281,8 +281,11 @@ extern "C" {
 #ifdef RA_ADAPTER
 #define MAX_ADDR_STR_SIZE (256)
 #else
-/** Max Address could be "coap+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:xxxxx" */
-#define MAX_ADDR_STR_SIZE (59)
+/** Max Address could be
+ * "coap+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:yyy.yyy.yyy.yyy]:xxxxx"
+ * +1 for null terminator.
+ */
+#define MAX_ADDR_STR_SIZE (65)
 #endif
 
 /** Length of MAC address */
index a3c8ec8..3e86fae 100644 (file)
 
 #include <boost/lexical_cast.hpp>
 #include <sstream>
+#if !defined(_WIN32)
 #include <arpa/inet.h>
+#else
+#include <ws2tcpip.h>
+#include <in6addr.h>
+#endif
 
 namespace OC {
 
index 1416c44..f6d045d 100644 (file)
 ##
 Import('env')
 
+import os
+
 # Add third party libraries
 lib_env = env.Clone()
 SConscript(env.get('SRC_DIR') + '/resource/third_party_libs.scons', 'lib_env')
 
 oclib_env = lib_env.Clone()
+secured = lib_env.get('SECURED')
 ######################################################################
 # Build flags
 ######################################################################
@@ -66,8 +69,16 @@ if target_os == 'tizen':
 
 if target_os in ['linux'] and env.get('SIMULATOR', False):
     oclib_env.Append( RPATH = env.Literal('\\$$ORIGIN'))
+
+
 if target_os in ['msys_nt']:
-       oclib_env.AppendUnique(LIBS = ['ws2_32', 'iphlpapi'])
+       oclib_env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource', 'oc_logger')])
+       oclib_env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource', 'csdk')])
+       oclib_env.AppendUnique(LIBS=['octbstack', 'logger', 'oc_logger','connectivity_abstraction', 'ocsrm', 'c_common', 'routingmanager'])
+       if oclib_env.get('SECURED') == '1':
+               oclib_env.AppendUnique(LIBS=['tinydtls'])
+       oclib_env.AppendUnique(LIBS=[ 'coap', 'ws2_32' ,'iphlpapi'])
+
 
 ######################################################################
 # Source files and Targets