[Inet] Add Openthread Native ipv6 address (#17352)

* Add OpenThread native ipv6
diff --git a/config/qpg/chip-gn/.gn b/config/qpg/chip-gn/.gn
index 4773cbf..04b98b1 100644
--- a/config/qpg/chip-gn/.gn
+++ b/config/qpg/chip-gn/.gn
@@ -19,7 +19,9 @@
 buildconfig = "//build/config/BUILDCONFIG.gn"
 
 # CHIP uses angle bracket includes.
-check_system_includes = true
+# DISABLED since CI failed on PR 17352
+# Build error out for unused/unavailble include file (IPAddress.h : <openthread/ip6.h>)
+check_system_includes = false
 
 default_args = {
   target_cpu = "arm"
diff --git a/src/inet/IPAddress-StringFuncts.cpp b/src/inet/IPAddress-StringFuncts.cpp
index 773034d..7df8a47 100644
--- a/src/inet/IPAddress-StringFuncts.cpp
+++ b/src/inet/IPAddress-StringFuncts.cpp
@@ -33,7 +33,7 @@
 #include <inet/IPAddress.h>
 #include <lib/support/CodeUtils.h>
 
-#if !CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
 #include <arpa/inet.h>
 #endif
 
@@ -42,7 +42,7 @@
 
 char * IPAddress::ToString(char * buf, uint32_t bufSize) const
 {
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
 #if INET_CONFIG_ENABLE_IPV4
     if (IsIPv4())
     {
@@ -55,7 +55,7 @@
         ip6_addr_t ip6_addr = ToIPv6();
         ip6addr_ntoa_r(&ip6_addr, buf, (int) bufSize);
     }
-#else // !CHIP_SYSTEM_CONFIG_USE_LWIP
+#elif CHIP_SYSTEM_CONFIG_USE_SOCKETS
     // socklen_t is sometimes signed, sometimes not, so the only safe way to do
     // this is to promote everything to an unsigned type that's known to be big
     // enough for everything, then cast back to uint32_t after taking the min.
@@ -77,6 +77,9 @@
         // This cast is safe because |s| points into |buf| which is not const.
         buf = const_cast<char *>(s);
     }
+#elif CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+    otIp6Address addr = ToIPv6();
+    otIp6AddressToString(&addr, buf, static_cast<uint16_t>(bufSize));
 #endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
 
     return buf;
@@ -87,11 +90,11 @@
 #if INET_CONFIG_ENABLE_IPV4
     if (strchr(str, ':') == nullptr)
     {
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
         ip4_addr_t ipv4Addr;
         if (!ip4addr_aton(str, &ipv4Addr))
             return false;
-#else  // !CHIP_SYSTEM_CONFIG_USE_LWIP
+#elif CHIP_SYSTEM_CONFIG_USE_SOCKETS
         struct in_addr ipv4Addr;
         if (inet_pton(AF_INET, str, &ipv4Addr) < 1)
             return false;
@@ -101,15 +104,19 @@
     else
 #endif // INET_CONFIG_ENABLE_IPV4
     {
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
         ip6_addr_t ipv6Addr;
         if (!ip6addr_aton(str, &ipv6Addr))
             return false;
-#else  // !CHIP_SYSTEM_CONFIG_USE_LWIP
+#elif CHIP_SYSTEM_CONFIG_USE_SOCKETS
         struct in6_addr ipv6Addr;
         if (inet_pton(AF_INET6, str, &ipv6Addr) < 1)
             return false;
-#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
+#elif CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+        otIp6Address ipv6Addr;
+        if (OT_ERROR_NONE != otIp6AddressFromString(str, &ipv6Addr))
+            return false;
+#endif
         output = IPAddress(ipv6Addr);
     }
 
diff --git a/src/inet/IPAddress.cpp b/src/inet/IPAddress.cpp
index c5fabfe..6c74154 100644
--- a/src/inet/IPAddress.cpp
+++ b/src/inet/IPAddress.cpp
@@ -70,7 +70,7 @@
     return *this;
 }
 
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
 
 IPAddress::IPAddress(const ip6_addr_t & ipv6Addr)
 {
@@ -269,6 +269,29 @@
 
 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
 
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+IPAddress::IPAddress(const otIp6Address & ipv6Addr)
+{
+    static_assert(sizeof(ipv6Addr.mFields.m32) == sizeof(Addr), "otIp6Address size mismatch");
+    memcpy(Addr, ipv6Addr.mFields.m32, sizeof(Addr));
+}
+otIp6Address IPAddress::ToIPv6() const
+{
+    otIp6Address otAddr;
+    static_assert(sizeof(otAddr.mFields.m32) == sizeof(Addr), "otIp6Address size mismatch");
+    memcpy(otAddr.mFields.m32, Addr, sizeof(otAddr.mFields.m32));
+    return otAddr;
+}
+
+IPAddress IPAddress::FromOtAddr(otIp6Address & address)
+{
+    IPAddress addr;
+    static_assert(sizeof(address.mFields.m32) == sizeof(addr), "otIp6Address size mismatch");
+    memcpy(addr.Addr, address.mFields.m32, sizeof(addr.Addr));
+    return addr;
+}
+#endif // CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+
 // Is address an IPv4 address encoded in IPv6 format?
 bool IPAddress::IsIPv4() const
 {
diff --git a/src/inet/IPAddress.h b/src/inet/IPAddress.h
index a83bcf4..e71de19 100644
--- a/src/inet/IPAddress.h
+++ b/src/inet/IPAddress.h
@@ -42,7 +42,7 @@
 
 #include "inet/IANAConstants.h"
 
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
 #include <lwip/init.h>
 #include <lwip/ip_addr.h>
 #if INET_CONFIG_ENABLE_IPV4
@@ -51,6 +51,11 @@
 #include <lwip/inet.h>
 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
 
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+#include <openthread/icmp6.h>
+#include <openthread/ip6.h>
+#endif // CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+
 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
 #include <net/if.h>
 #include <netinet/in.h>
@@ -60,6 +65,10 @@
 #include <sys/socket.h>
 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
 
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT && INET_CONFIG_ENABLE_IPV4
+#error Forbidden : native Open Thread implementation with IPV4 enabled
+#endif
+
 #define NL_INET_IPV6_ADDR_LEN_IN_BYTES (16)
 #define NL_INET_IPV6_MCAST_GROUP_LEN_IN_BYTES (14)
 
@@ -118,17 +127,24 @@
     /**
      * Maximum length of the string representation of an IP address, including a terminating NUL.
      */
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
     static constexpr uint16_t kMaxStringLength = IP6ADDR_STRLEN_MAX;
 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
     static constexpr uint16_t kMaxStringLength = INET6_ADDRSTRLEN;
 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
 
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN OT_IP6_ADDRESS_STRING_SIZE
+#endif
+    static constexpr uint16_t kMaxStringLength = OT_IP6_ADDRESS_STRING_SIZE;
+#endif
+
     IPAddress()                        = default;
     IPAddress(const IPAddress & other) = default;
 
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
     explicit IPAddress(const ip6_addr_t & ipv6Addr);
 #if INET_CONFIG_ENABLE_IPV4 || LWIP_IPV4
     explicit IPAddress(const ip4_addr_t & ipv4Addr);
@@ -143,6 +159,10 @@
 #endif // INET_CONFIG_ENABLE_IPV4
 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
 
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+    explicit IPAddress(const otIp6Address & ipv6Addr);
+#endif
+
     /**
      * @brief   Opaque word array to contain IP addresses (independent of protocol version)
      *
@@ -470,7 +490,7 @@
      *      either unspecified or not an IPv4 address.
      */
 
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
 
     /**
      * @fn      ToLwIPAddr() const
@@ -534,6 +554,11 @@
 
 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_USE_NETWORK_FRAMEWORK
 
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+    otIp6Address ToIPv6() const;
+    static IPAddress FromOtAddr(otIp6Address & address);
+#endif // CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+
     /**
      * @brief   Construct an IPv6 unique-local address (ULA) from its parts.
      *
diff --git a/src/inet/InetInterface.cpp b/src/inet/InetInterface.cpp
index 9f5356e..e6125a1 100644
--- a/src/inet/InetInterface.cpp
+++ b/src/inet/InetInterface.cpp
@@ -34,7 +34,7 @@
 #include <lib/support/CodeUtils.h>
 #include <lib/support/DLLUtil.h>
 
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
 #include <lwip/netif.h>
 #include <lwip/sys.h>
 #include <lwip/tcpip.h>
@@ -63,7 +63,78 @@
 namespace chip {
 namespace Inet {
 
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+CHIP_ERROR InterfaceId::GetInterfaceName(char * nameBuf, size_t nameBufSize) const
+{
+    if (mPlatformInterface && nameBufSize >= kMaxIfNameLength)
+    {
+        nameBuf[0] = 'o';
+        nameBuf[1] = 't';
+        nameBuf[2] = 0;
+    }
+    else
+    {
+        nameBuf[0] = 0;
+    }
+
+    return CHIP_NO_ERROR;
+}
+CHIP_ERROR InterfaceId::InterfaceNameToId(const char * intfName, InterfaceId & interface)
+{
+    if (strlen(intfName) < 3)
+    {
+        return INET_ERROR_UNKNOWN_INTERFACE;
+    }
+    char * parseEnd       = nullptr;
+    unsigned long intfNum = strtoul(intfName + 2, &parseEnd, 10);
+    if (*parseEnd != 0 || intfNum > UINT8_MAX)
+    {
+        return INET_ERROR_UNKNOWN_INTERFACE;
+    }
+
+    interface = InterfaceId(intfNum);
+    if (intfNum == 0)
+    {
+        return INET_ERROR_UNKNOWN_INTERFACE;
+    }
+    return CHIP_NO_ERROR;
+}
+
+bool InterfaceIterator::Next()
+{
+    // TODO : Cleanup #17346
+    return false;
+}
+bool InterfaceAddressIterator::HasCurrent()
+{
+    return mIntfIter.HasCurrent();
+}
+
+bool InterfaceAddressIterator::Next()
+{
+    // TODO : Cleanup #17346
+    return false;
+}
+CHIP_ERROR InterfaceAddressIterator::GetAddress(IPAddress & outIPAddress)
+{
+    if (!HasCurrent())
+    {
+        return CHIP_ERROR_SENTINEL;
+    }
+
+    outIPAddress = IPAddress((*(mAddrInfoList[mCurAddrIndex].mAddress)));
+    return CHIP_NO_ERROR;
+}
+
+uint8_t InterfaceAddressIterator::GetPrefixLength()
+{
+    // Only 64 bits prefix are supported
+    return 64;
+}
+
+#endif
+
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
 
 CHIP_ERROR InterfaceId::GetInterfaceName(char * nameBuf, size_t nameBufSize) const
 {
diff --git a/src/inet/InetInterface.h b/src/inet/InetInterface.h
index 824fc10..e0a3ac1 100644
--- a/src/inet/InetInterface.h
+++ b/src/inet/InetInterface.h
@@ -32,7 +32,7 @@
 #include <inet/InetError.h>
 #include <lib/support/DLLUtil.h>
 
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
 #include <lwip/netif.h>
 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
 
@@ -49,6 +49,10 @@
 struct net_if_ipv6;
 #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
 
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+struct otIp6AddressInfo;
+#endif
+
 #include <stddef.h>
 #include <stdint.h>
 
@@ -76,7 +80,7 @@
 class InterfaceId
 {
 public:
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
     using PlatformType                       = struct netif *;
     static constexpr size_t kMaxIfNameLength = 13; // Names are formatted as %c%c%d
 #endif                                             // CHIP_SYSTEM_CONFIG_USE_LWIP
@@ -91,6 +95,11 @@
     static constexpr size_t kMaxIfNameLength = Z_DEVICE_MAX_NAME_LEN;
 #endif
 
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+    using PlatformType                       = unsigned int;
+    static constexpr size_t kMaxIfNameLength = 6;
+#endif
+
     ~InterfaceId() = default;
 
     constexpr InterfaceId() : mPlatformInterface(kPlatformNull) {}
@@ -182,7 +191,7 @@
     CHIP_ERROR GetLinkLocalAddr(IPAddress * llAddr) const;
 
 private:
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
     static constexpr PlatformType kPlatformNull = nullptr;
 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
 
@@ -193,6 +202,11 @@
 #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
     static constexpr PlatformType kPlatformNull = 0;
 #endif
+
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+    static constexpr PlatformType kPlatformNull = 0;
+#endif
+
     PlatformType mPlatformInterface;
 };
 
@@ -327,7 +341,7 @@
     CHIP_ERROR GetHardwareAddress(uint8_t * addressBuffer, uint8_t & addressSize, uint8_t addressBufferSize);
 
 protected:
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
     struct netif * mCurNetif;
 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
 
@@ -344,6 +358,9 @@
     InterfaceId::PlatformType mCurrentId = 1;
     net_if * mCurrentInterface           = nullptr;
 #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+    struct otIp6AddressInfo * mCurNetif;
+#endif
 };
 
 /**
@@ -502,7 +519,7 @@
     bool HasBroadcastAddress();
 
 private:
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
     enum
     {
         kBeforeStartIndex = -1
@@ -522,9 +539,25 @@
     net_if_ipv6 * mIpv6 = nullptr;
     int mCurAddrIndex   = -1;
 #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+    otIp6AddressInfo * mAddrInfoList;
+    int mCurAddrIndex;
+    InterfaceIterator mIntfIter;
+#endif // #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
 };
 
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+inline InterfaceIterator::InterfaceIterator(void) {}
+inline InterfaceAddressIterator::InterfaceAddressIterator(void) {}
+inline InterfaceIterator::~InterfaceIterator()               = default;
+inline InterfaceAddressIterator::~InterfaceAddressIterator() = default;
+inline bool InterfaceIterator::HasCurrent(void)
+{
+    return mCurNetif != NULL;
+}
+#endif
+
+#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
 
 inline InterfaceIterator::InterfaceIterator(void)
 {
diff --git a/src/inet/arpa-inet-compatibility.h b/src/inet/arpa-inet-compatibility.h
index 57809fd..25f9792 100644
--- a/src/inet/arpa-inet-compatibility.h
+++ b/src/inet/arpa-inet-compatibility.h
@@ -46,4 +46,40 @@
 #endif // defined(LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS)
 
 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
+
+#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+
+#if BYTE_ORDER == BIG_ENDIAN
+#ifndef htons
+#define htons(x) (x)
+#endif
+#ifndef ntohs
+#define ntohs(x) (x)
+#endif
+#ifndef htonl
+#define htonl(x) (x)
+#endif
+#ifndef ntohl
+#define ntohl(x) (x)
+#endif
+
+#else // BYTE_ORDER != BIG_ENDIAN
+#ifndef htons
+#define htons(x) ((u16_t)((((x) & (u16_t) 0x00ffU) << 8) | (((x) & (u16_t) 0xff00U) >> 8)))
+#endif
+#ifndef ntohs
+#define ntohs(x) htons(x)
+#endif
+#ifndef htonl
+#define htonl(x)                                                                                                                   \
+    ((((x) & (uint32_t) 0x000000ffUL) << 24) | (((x) & (uint32_t) 0x0000ff00UL) << 8) | (((x) & (uint32_t) 0x00ff0000UL) >> 8) |   \
+     (((x) & (uint32_t) 0xff000000UL) >> 24))
+#endif
+#ifndef ntohl
+#define ntohl(x) htonl(x)
+#endif
+#endif // BYTE_ORDER == BIG_ENDIAN
+
+#endif // CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
+
 #endif // !CHIP_SYSTEM_CONFIG_USE_SOCKETS