[Win32] Add win32-specific networking APIs
[platform/upstream/iotivity.git] / resource / src / OCResource.cpp
index 52fdfa8..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 {
 
@@ -126,7 +132,6 @@ void OCResource::setHost(const std::string& host)
     else if (host.compare(0, sizeof(COAP_TCP) - 1, COAP_TCP) == 0)
     {
         prefix_len = sizeof(COAP_TCP) - 1;
-        m_devAddr.adapter = static_cast<OCTransportAdapter>(m_devAddr.adapter & OC_ADAPTER_TCP);
     }
     else
     {
@@ -134,158 +139,54 @@ void OCResource::setHost(const std::string& host)
             m_interfaces.empty(), m_clientWrapper.expired(), false, false);
     }
 
-    // removed 'coap://' or 'coaps://' or 'coap+tcp://'
+    // remove 'coap://' or 'coaps://' or 'coap+tcp://'
     std::string host_token = host.substr(prefix_len);
 
-    if (host_token[0] == '[') // ipv6 address
+    if(host_token[0] == '[') // IPv6
     {
-        m_devAddr.flags = static_cast< OCTransportFlags >(m_devAddr.flags & OC_IP_USE_V6);
-
-        size_t found = host_token.find(']');
+        size_t bracket = host_token.find(']');
 
-        if (found == std::string::npos || found == 0)
+        if(bracket == std::string::npos || bracket == 0)
         {
             throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                        m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                        false);
+                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
         }
         // extract the ipv6 address
-        std::string ip6Addr = host_token.substr(1, found - 1);
-
-        size_t addrLength = ip6Addr.length();
-
-        if (MAX_ADDR_STR_SIZE <= addrLength)
-        {
-            throw std::length_error("host address is too long.");
-        }
+        std::string ip6Addr = host_token.substr(1, bracket - 1);
 
         // address validity check
-        size_t colon = ip6Addr.find(':');
-
-        if (std::string::npos == colon)
+        struct in6_addr buf;
+        const char *cAddr = ip6Addr.c_str();
+        if(0 == inet_pton(AF_INET6, cAddr, &buf))
         {
             throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                        m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                        false);
-        }
-
-        size_t colonCnt = 1;
-        int omittedColon = -2;
-
-        while (std::string::npos != colon)
-        {
-            size_t nextColon = ip6Addr.find(':', colon + 1);
-
-            if (nextColon == colon + 1)
-            {
-                if (0 < omittedColon)
-                {
-                    throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                                m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                                false);
-                }
-                omittedColon = colon;
-            }
-
-            colon = nextColon;
-
-            if (7 < colonCnt++)
-            {
-                throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                            m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                            false);
-            }
-        }
-
-        if (7 >= colonCnt && 0 > omittedColon)
-        {
-            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                        m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                        false);
-        }
-
-        size_t startPoint = 0;
-
-        if (0 == omittedColon)
-        {
-            startPoint = 2;
-        }
-
-        while (1)
-        {
-            std::string block;
-            colon = ip6Addr.find(':', startPoint);
-
-            if (std::string::npos != colon)
-            {
-                block = ip6Addr.substr(startPoint, colon - startPoint);
-
-                if (4 < block.length() ||
-                       std::string::npos != block.find_first_not_of("0123456789ABCDEFabcdef") ||
-                       0 == block.length())
-                {
-                    throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                                m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                                false);
-                }
-
-                startPoint = colon + 1;
-            }
-            else
-            {
-                block = ip6Addr.substr(startPoint);
-
-                if (4 < block.length() ||
-                        std::string::npos != block.find_first_not_of("0123456789ABCDEFabcdef") ||
-                        0 == block.length())
-                {
-                    throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                                m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                                false);
-                }
-
-                break;
-            }
-
-            if ((int)colon == omittedColon)
-            {
-                if (colon == addrLength - 2)
-                {
-                    break;
-                }
-                startPoint = colon + 2;
-                continue;
-            }
-
+                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
         }
-        // end of address validity check
 
-        ip6Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
-        m_devAddr.addr[ip6Addr.length()] = '\0';
         //skip ']' and ':' characters in host string
-        host_token = host_token.substr(found + 2);
-
+        host_token = host_token.substr(bracket + 2);
         int port = std::stoi(host_token);
 
         if (0 > port || UINT16_MAX < port)
         {
             throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                        m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                        false);
+                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
         }
 
-        m_devAddr.port = static_cast< uint16_t >(port);
+        ip6Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
+        m_devAddr.addr[ip6Addr.length()] = '\0';
+        m_devAddr.port = static_cast<uint16_t>(port);
+        m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags & OC_IP_USE_V6);
     }
     else if (host_token[0] == ':')
     {
         throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                    m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                    false);
+            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
     }
     else
     {
         size_t dot = host_token.find('.');
-        if (dot == std::string::npos) // MAC address
+        if (std::string::npos == dot) // MAC
         {
             std::string macAddr = host_token;
 
@@ -293,121 +194,69 @@ void OCResource::setHost(const std::string& host)
             if (MAC_ADDR_STR_SIZE != macAddr.length())
             {
                 throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                            m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                            false);
+                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
             }
 
-            for (size_t blockCnt = 0; blockCnt < 6; blockCnt++)
+            for (size_t blockCnt = 0; blockCnt < MAC_ADDR_BLOCKS; blockCnt++)
             {
                 std::string block = macAddr.substr(blockCnt * 3, 2);
 
                 if (std::string::npos != block.find_first_not_of("0123456789ABCDEFabcdef"))
                 {
                     throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                                m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                                false);
+                        m_interfaces.empty(), m_clientWrapper.expired(), false, false);
                 }
 
-                if (5 > blockCnt)
+                if (MAC_ADDR_BLOCKS - 1 > blockCnt)
                 {
                     char delimiter = macAddr[blockCnt * 3 + 2];
 
-                    if (':' != delimiter || '-' != delimiter)
+                    if (':' != delimiter)
                     {
                         throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                                    m_interfaces.empty(), m_clientWrapper.expired(),
-                                                    false, false);
+                            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
                     }
                 }
             }
-            // end of address validity check
 
             macAddr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
-            m_devAddr.addr[macAddr.length()] = '\0';
+            m_devAddr.addr[MAC_ADDR_STR_SIZE] = '\0';
         }
-        else // ipv4 address
+        else // IPv4
         {
             size_t colon = host_token.find(':');
 
-            if (colon == std::string::npos)
+            if (colon == std::string::npos || colon == 0)
             {
                 throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                            m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                            false);
+                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
             }
 
+            // extract the ipv4 address
             std::string ip4Addr = host_token.substr(0, colon);
-            size_t addrLength = ip4Addr.length();
-
-            if (MAX_ADDR_STR_SIZE <= addrLength)
-            {
-                throw std::length_error("host address is too long.");
-            }
 
             // address validity check
-            size_t startPoint = 0;
-
-            for (size_t blockCnt = 1; blockCnt <= 4; blockCnt++)
+            struct in_addr buf;
+            const char *cAddr = ip4Addr.c_str();
+            if(0 == inet_pton(AF_INET, cAddr, &buf))
             {
-                size_t dot = ip4Addr.find('.', startPoint);
-                std::string addrBlock;
-
-                if (4 > blockCnt)
-                {
-                    if (std::string::npos == dot || dot <= startPoint)
-                    {
-                        throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                                    m_interfaces.empty(), m_clientWrapper.expired(),
-                                                    false, false);
-                    }
-                    addrBlock = ip4Addr.substr(startPoint, dot - startPoint);
-                }
-                else
-                {
-                    if (std::string::npos != dot)
-                    {
-                        throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                                    m_interfaces.empty(), m_clientWrapper.expired(),
-                                                    false, false);
-                    }
-                    addrBlock = ip4Addr.substr(startPoint, colon - startPoint);
-                }
-
-                int i_addrBlock = std::stoi(addrBlock);
-
-                if (std::string::npos != addrBlock.find_first_not_of("0123456789") ||
-                    0 > i_addrBlock || 255 < i_addrBlock)
-                {
-                    throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                                m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                                false);
-                }
-                startPoint = dot + 1;
-
-                if (addrLength <= startPoint)
-                {
-                    throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                                m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                                false);
-                }
+                throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
             }
-            // end of address validity check
 
-            ip4Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
-            m_devAddr.addr[ip4Addr.length()] = '\0';
-            //skip ':' character in host string
+            //skip ':' characters in host string
             host_token = host_token.substr(colon + 1);
-
             int port = std::stoi(host_token);
 
             if (0 > port || UINT16_MAX < port)
             {
                 throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                                            m_interfaces.empty(), m_clientWrapper.expired(), false,
-                                            false);
+                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
             }
 
-            m_devAddr.port = static_cast< uint16_t >(port);
+            ip4Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
+            m_devAddr.addr[ip4Addr.length()] = '\0';
+            m_devAddr.port = static_cast<uint16_t>(port);
         }
     }
 }
@@ -639,7 +488,9 @@ std::string OCResource::host() const
     {
         ss << COAPS;
     }
-    else if (m_devAddr.adapter & OC_ADAPTER_TCP)
+    else if ((m_devAddr.adapter & OC_ADAPTER_TCP)
+            || (m_devAddr.adapter & OC_ADAPTER_GATT_BTLE)
+            || (m_devAddr.adapter & OC_ADAPTER_RFCOMM_BTEDR))
     {
         ss << COAP_TCP;
     }