From a9408c7d2d4a18bf9ac00b12f84499dee524484b Mon Sep 17 00:00:00 2001 From: "bg.chun" Date: Tue, 8 Nov 2016 21:00:56 +0900 Subject: [PATCH] [IOT-1531]PAL API for get link-local zone id from ifindex PAL API for get IPv6 link-local zone id from ifindex. This changes need for mapping zone-id with IPv6 link-local Address on Endpoint and CAGetNetworkInfo(). Change-Id: Ib5043d3de5747f3e461de775dba2d04e804297dd Signed-off-by: bg.chun Reviewed-on: https://gerrit.iotivity.org/gerrit/14123 Tested-by: jenkins-iotivity Reviewed-by: Ashok Babu Channa --- resource/csdk/connectivity/api/cainterface.h | 10 ++ resource/csdk/connectivity/api/cautilinterface.h | 9 + resource/csdk/connectivity/inc/caadapterutils.h | 8 + resource/csdk/connectivity/inc/caipnwmonitor.h | 10 ++ .../connectivity/src/adapter_util/caadapterutils.c | 50 ++++++ .../src/ip_adapter/android/caipnwmonitor.c | 26 +++ .../csdk/connectivity/src/ip_adapter/caipserver.c | 5 + .../src/ip_adapter/linux/caipnwmonitor.c | 26 +++ .../src/ip_adapter/tizen/caipnwmonitor.c | 26 +++ .../src/ip_adapter/windows/caipnwmonitor.c | 46 +++++ .../csdk/connectivity/test/ca_api_unittest.cpp | 192 +++++++++++++++++++++ .../csdk/connectivity/util/src/cautilinterface.c | 5 + resource/csdk/stack/include/ocstack.h | 10 ++ resource/csdk/stack/octbstack_product.def | 1 + resource/csdk/stack/src/ocstack.c | 6 + resource/csdk/stack/test/stacktests.cpp | 25 +++ 16 files changed, 455 insertions(+) diff --git a/resource/csdk/connectivity/api/cainterface.h b/resource/csdk/connectivity/api/cainterface.h index 6a4916d..1531ebf 100644 --- a/resource/csdk/connectivity/api/cainterface.h +++ b/resource/csdk/connectivity/api/cainterface.h @@ -250,6 +250,16 @@ CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo); */ CAResult_t CASetProxyUri(const char *uri); +/** + * This function return zone id related from ifindex and address. + * + * @param ifindex[in] interface index. + * @param zoneId[out] pointer of zoneId string. + * + * @return ::CA_STATUS_OK or ::CA_STATUS_INVALID_PARAM + */ +CAResult_t CAGetLinkLocalZoneId(uint32_t ifindex, char **zoneId); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/resource/csdk/connectivity/api/cautilinterface.h b/resource/csdk/connectivity/api/cautilinterface.h index c29d486..4b90ff8 100644 --- a/resource/csdk/connectivity/api/cautilinterface.h +++ b/resource/csdk/connectivity/api/cautilinterface.h @@ -224,6 +224,15 @@ CAResult_t CAUtilStopLEAdvertising(); * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h). */ CAResult_t CAUtilSetBTConfigure(CAUtilConfig_t config); + +/** + * return scope level of given ip address. + * @param[in] address remote address. + * @param[out] scope level of given ip address. + * @return ::CA_STATUS_OK or Appropriate error code. + */ +CAResult_t CAGetIpv6AddrScope(const char *addr, CATransportFlags_t *scopeLevel); + #ifdef __cplusplus } /* extern "C" */ #endif //__cplusplus diff --git a/resource/csdk/connectivity/inc/caadapterutils.h b/resource/csdk/connectivity/inc/caadapterutils.h index b3f1f0a..b91581a 100644 --- a/resource/csdk/connectivity/inc/caadapterutils.h +++ b/resource/csdk/connectivity/inc/caadapterutils.h @@ -320,6 +320,14 @@ void CALogAdapterStateInfo(CATransportAdapter_t adapter, CANetworkStatus_t state * @param[in] adapter transport adapter type. */ void CALogAdapterTypeInfo(CATransportAdapter_t adapter); + +/** + * return scope level of given ip address. + * @param[in] address remote address. + * @param[out] scopeLevel scope level of given ip address. + * @return ::CA_STATUS_OK or Appropriate error code. + */ +CAResult_t CAGetIpv6AddrScopeInternal(const char *addr, CATransportFlags_t *scopeLevel); #endif #ifdef __cplusplus diff --git a/resource/csdk/connectivity/inc/caipnwmonitor.h b/resource/csdk/connectivity/inc/caipnwmonitor.h index b5a4e29..f484792 100644 --- a/resource/csdk/connectivity/inc/caipnwmonitor.h +++ b/resource/csdk/connectivity/inc/caipnwmonitor.h @@ -126,6 +126,16 @@ CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter); */ void CAProcessNewInterface(CAInterface_t *ifchanged); +/** + * This function return link local zone id related from ifindex. + * + * @param ifindex[in] interface index. + * @param zoneId[out] pointer of zoneId string, caller should free + * zoneId using OICFree() when it returned CA_STATUS_OK. + * @return ::CA_STATUS_OK or ::CA_STATUS_INVALID_PARAM + */ +CAResult_t CAGetLinkLocalZoneIdInternal(uint32_t ifindex, char **zoneId); + #ifdef __cplusplus } #endif diff --git a/resource/csdk/connectivity/src/adapter_util/caadapterutils.c b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c index 37a20bc..8c332f5 100644 --- a/resource/csdk/connectivity/src/adapter_util/caadapterutils.c +++ b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c @@ -43,6 +43,12 @@ #ifdef HAVE_NETDB_H #include #endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_IN6ADDR_H +#include +#endif #ifdef __JAVA__ #include @@ -403,4 +409,48 @@ void CALogAdapterTypeInfo(CATransportAdapter_t adapter) break; } } + +CAResult_t CAGetIpv6AddrScopeInternal(const char *addr, CATransportFlags_t *scopeLevel) +{ + if (!addr || !scopeLevel) + { + return CA_STATUS_INVALID_PARAM; + } + // check addr is ipv6 + struct in6_addr inAddr6; + if (1 == inet_pton(AF_INET6, addr, &inAddr6)) + { + // check addr is multicast + if (IN6_IS_ADDR_MULTICAST(&inAddr6)) + { + *scopeLevel = (CATransportFlags_t)(inAddr6.s6_addr[1] & 0xf); + return CA_STATUS_OK; + } + else + { + // check addr is linklocal or loopback + if (IN6_IS_ADDR_LINKLOCAL(&inAddr6) || IN6_IS_ADDR_LOOPBACK(&inAddr6)) + { + *scopeLevel = CA_SCOPE_LINK; + return CA_STATUS_OK; + } + // check addr is sitelocal + else if (IN6_IS_ADDR_SITELOCAL(&inAddr6)) + { + *scopeLevel = CA_SCOPE_SITE; + return CA_STATUS_OK; + } + else + { + *scopeLevel = CA_SCOPE_GLOBAL; + return CA_STATUS_OK; + } + } + } + else + { + OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Failed at parse ipv6 address using inet_pton"); + return CA_STATUS_FAILED; + } +} #endif diff --git a/resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c index 2042826..44965c7 100644 --- a/resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c @@ -515,3 +515,29 @@ Java_org_iotivity_ca_CaIpInterface_caIpStateDisabled(JNIEnv *env, jclass class) OIC_LOG(DEBUG, TAG, "Wifi is in Deactivated State"); CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN); } + +CAResult_t CAGetLinkLocalZoneIdInternal(uint32_t ifindex, char **zoneId) +{ + if (!zoneId || (*zoneId != NULL)) + { + return CA_STATUS_INVALID_PARAM; + } + + *zoneId = (char *)OICCalloc(IF_NAMESIZE, sizeof(char)); + if (!(*zoneId)) + { + OIC_LOG(ERROR, TAG, "OICCalloc failed in CAGetLinkLocalZoneIdInternal"); + return CA_MEMORY_ALLOC_FAILED; + } + + if (!if_indextoname(ifindex, *zoneId)) + { + OIC_LOG(ERROR, TAG, "if_indextoname failed in CAGetLinkLocalZoneIdInternal"); + OICFree(*zoneId); + *zoneId = NULL; + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, TAG, "Given ifindex is %d parsed zoneId is %s", ifindex, *zoneId); + return CA_STATUS_OK; +} diff --git a/resource/csdk/connectivity/src/ip_adapter/caipserver.c b/resource/csdk/connectivity/src/ip_adapter/caipserver.c index afa874c..cde643b 100644 --- a/resource/csdk/connectivity/src/ip_adapter/caipserver.c +++ b/resource/csdk/connectivity/src/ip_adapter/caipserver.c @@ -1590,3 +1590,8 @@ void CAIPSetErrorHandler(CAIPErrorHandleCallback errorHandleCallback) { g_ipErrorHandler = errorHandleCallback; } + +CAResult_t CAGetLinkLocalZoneId(uint32_t ifindex, char **zoneId) +{ + return CAGetLinkLocalZoneIdInternal(ifindex, zoneId); +} diff --git a/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c index 26fbef8..d86a854 100644 --- a/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c @@ -484,3 +484,29 @@ exit: u_arraylist_destroy(iflist); return NULL; } + +CAResult_t CAGetLinkLocalZoneIdInternal(uint32_t ifindex, char **zoneId) +{ + if (!zoneId || (*zoneId != NULL)) + { + return CA_STATUS_INVALID_PARAM; + } + + *zoneId = (char *)OICCalloc(IF_NAMESIZE, sizeof(char)); + if (!(*zoneId)) + { + OIC_LOG(ERROR, TAG, "OICCalloc failed in CAGetLinkLocalZoneIdInternal"); + return CA_MEMORY_ALLOC_FAILED; + } + + if (!if_indextoname(ifindex, *zoneId)) + { + OIC_LOG(ERROR, TAG, "if_indextoname failed in CAGetLinkLocalZoneIdInternal"); + OICFree(*zoneId); + *zoneId = NULL; + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, TAG, "Given ifindex is %d parsed zoneId is %s", ifindex, *zoneId); + return CA_STATUS_OK; +} diff --git a/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c index 3fb48f6..7f37f78 100644 --- a/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c @@ -409,3 +409,29 @@ void CAIPConnectionStateChangedCb(connection_type_e type, void* userData) break; } } + +CAResult_t CAGetLinkLocalZoneIdInternal(uint32_t ifindex, char **zoneId) +{ + if (!zoneId || (*zoneId != NULL)) + { + return CA_STATUS_INVALID_PARAM; + } + + *zoneId = (char *)OICCalloc(IF_NAMESIZE, sizeof(char)); + if (!(*zoneId)) + { + OIC_LOG(ERROR, TAG, "OICCalloc failed in CAGetLinkLocalZoneIdInternal"); + return CA_MEMORY_ALLOC_FAILED; + } + + if (!if_indextoname(ifindex, *zoneId)) + { + OIC_LOG(ERROR, TAG, "if_indextoname failed in CAGetLinkLocalZoneIdInternal"); + OICFree(*zoneId); + *zoneId = NULL; + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, TAG, "Given ifindex is %d parsed zoneId is %s", ifindex, *zoneId); + return CA_STATUS_OK; +} diff --git a/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c index 8f7322c..c0cf28a 100644 --- a/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c @@ -50,6 +50,11 @@ #define USE_SOCKET_ADDRESS_CHANGE_EVENT /** +* Buffer size for PIP_ADAPTER_ADDRESSES +*/ +#define WORKING_BUFFER_SIZE 15000 + +/** * Mutex for synchronizing access to cached address information. */ static oc_mutex g_CAIPNetworkMonitorMutex = NULL; @@ -912,3 +917,44 @@ u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex) return iflist; } + +CAResult_t CAGetLinkLocalZoneIdInternal(uint32_t ifindex, char **zoneId) +{ + if (!zoneId || (*zoneId != NULL)) + { + return CA_STATUS_INVALID_PARAM; + } + + PIP_ADAPTER_ADDRESSES pAdapters = GetAdapters(); + + if (!pAdapters) + { + OICFree(pAdapters); + return CA_STATUS_FAILED; + } + + PIP_ADAPTER_ADDRESSES pCurrAdapter = NULL; + pCurrAdapter = pAdapters; + + while (pCurrAdapter) + { + if (ifindex == pCurrAdapter->IfIndex) + { + OIC_LOG_V(DEBUG, TAG, "Given ifindex is %d parsed zoneId is %d", + ifindex, pCurrAdapter->ZoneIndices[ScopeLevelLink]); + *zoneId = (char *)OICCalloc(IF_NAMESIZE, sizeof(char)); + _ultoa(pCurrAdapter->ZoneIndices[ScopeLevelLink], *zoneId, 10); + break; + } + pCurrAdapter = pCurrAdapter->Next; + } + + OICFree(pAdapters); + + if (!*zoneId) + { + return CA_STATUS_FAILED; + } + + return CA_STATUS_OK; +} diff --git a/resource/csdk/connectivity/test/ca_api_unittest.cpp b/resource/csdk/connectivity/test/ca_api_unittest.cpp index 791108e..cfbe602 100755 --- a/resource/csdk/connectivity/test/ca_api_unittest.cpp +++ b/resource/csdk/connectivity/test/ca_api_unittest.cpp @@ -678,3 +678,195 @@ TEST(CAfragmentationTest, DefragmentTest) free(data); #endif } + +TEST(Ipv6ScopeLevel, getMulticastScope) +{ + + const char interfaceLocalStart[] = "ff01::"; + const char linkLocalStart[] = "ff02::"; + const char realmLocalStart[] = "ff03::"; + const char adminLocalStart[] = "ff04::"; + const char siteLocalStart[] = "ff05::"; + const char orgLocalStart[] = "ff08::"; + const char globalStart[] = "ff0e::"; + + const char interfaceLocalMid[] = "ff81:0000:0000:f000:0000:0000:0000:0000"; + const char linkLocalMid[] = "ff82:0000:0000:f000:0000:0000:0000:0000"; + const char realmLocalMid[] = "ff83:0000:0000:f000:0000:0000:0000:0000"; + const char adminLocalMid[] = "ff84:0000:0000:f000:0000:0000:0000:0000"; + const char siteLocalMid[] = "ff85:0000:0000:f000:0000:0000:0000:0000"; + const char orgLocalMid[] = "ff88:0000:0000:f000:0000:0000:0000:0000"; + const char globalMid[] = "ff8e:0000:0000:f000:0000:0000:0000:0000"; + + const char interfaceLocalEnd[] = "fff1:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + const char linkLocalEnd[] = "fff2:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + const char realmLocalEnd[] = "fff3:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + const char adminLocalEnd[] = "fff4:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + const char siteLocalEnd[] = "fff5:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + const char orgLocalEnd[] = "fff8:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + const char globalEnd[] = "fffe:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + + // range start + CATransportFlags_t scopeLevel = CA_DEFAULT_FLAGS; + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(interfaceLocalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_INTERFACE, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(linkLocalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_LINK, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(realmLocalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_REALM, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(adminLocalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_ADMIN, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(siteLocalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_SITE, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(orgLocalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_ORG, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(globalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_GLOBAL, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + // range mid + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(interfaceLocalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_INTERFACE, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(linkLocalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_LINK, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(realmLocalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_REALM, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(adminLocalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_ADMIN, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(siteLocalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_SITE, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(orgLocalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_ORG, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(globalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_GLOBAL, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + // range end + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(interfaceLocalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_INTERFACE, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(linkLocalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_LINK, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(realmLocalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_REALM, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(adminLocalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_ADMIN, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(siteLocalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_SITE, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(orgLocalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_ORG, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(globalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_GLOBAL, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; +} + +TEST(Ipv6ScopeLevel, getUnicastScope) +{ + const char linkLocalLoopBack[] = "::1"; + + const char linkLocalStart[] = "fe80::"; + const char linkLocalMid[] = "fe80:0000:0000:0000:0f00:0000:0000:0000"; + const char linkLocalEnd[] = "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + + const char siteLocalStart[] = "fec0::"; + const char siteLocalMid[] = "fec0:0000:0000:0000:0f00:0000:0000:0000"; + const char siteLocalEnd[] = "feff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + + const char globalStart[] = "2000:0000:0000:0000:0000:0000:0000:0000"; + const char globalMid[] = "2000:0000:0000:0f00:0000:0000:0000:0000"; + const char globalEnd[] = "3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + + // loopback + CATransportFlags_t scopeLevel = CA_DEFAULT_FLAGS; + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(linkLocalLoopBack, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_LINK, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + // linklocal + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(linkLocalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_LINK, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(linkLocalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_LINK, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(linkLocalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_LINK, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + // sitelocal + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(siteLocalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_SITE, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(siteLocalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_SITE, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(siteLocalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_SITE, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + // global + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(globalStart, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_GLOBAL, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(globalMid, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_GLOBAL, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; + + EXPECT_EQ(CA_STATUS_OK, CAGetIpv6AddrScope(globalEnd, &scopeLevel)); + EXPECT_EQ(CA_SCOPE_GLOBAL, scopeLevel); + scopeLevel = CA_DEFAULT_FLAGS; +} + +TEST(Ipv6ScopeLevel, invalidAddressTest) +{ + const char invalidAddr1[] = "qqqq"; + const char invalidAddr2[] = "ffx7:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + const char invalidAddr3[] = "ffx7::::::::::dsds"; + const char invalidAddr4[] = "ffx7:ffff:ffff:ff@f:ffff:ffff:ffff:ffff"; + + CATransportFlags_t scopeLevel = CA_DEFAULT_FLAGS; + EXPECT_EQ(CA_STATUS_FAILED, CAGetIpv6AddrScope(invalidAddr1, &scopeLevel)); + EXPECT_EQ(CA_STATUS_FAILED, CAGetIpv6AddrScope(invalidAddr2, &scopeLevel)); + EXPECT_EQ(CA_STATUS_FAILED, CAGetIpv6AddrScope(invalidAddr3, &scopeLevel)); + EXPECT_EQ(CA_STATUS_FAILED, CAGetIpv6AddrScope(invalidAddr4, &scopeLevel)); +} \ No newline at end of file diff --git a/resource/csdk/connectivity/util/src/cautilinterface.c b/resource/csdk/connectivity/util/src/cautilinterface.c index 2a56b5c..afcf64c 100644 --- a/resource/csdk/connectivity/util/src/cautilinterface.c +++ b/resource/csdk/connectivity/util/src/cautilinterface.c @@ -349,3 +349,8 @@ CAResult_t CAUtilSetBTConfigure(CAUtilConfig_t config) return CA_NOT_SUPPORTED; #endif } + +CAResult_t CAGetIpv6AddrScope(const char *addr, CATransportFlags_t *scopeLevel) +{ + return CAGetIpv6AddrScopeInternal(addr, scopeLevel); +} diff --git a/resource/csdk/stack/include/ocstack.h b/resource/csdk/stack/include/ocstack.h index fa8258d..f82ffe5 100644 --- a/resource/csdk/stack/include/ocstack.h +++ b/resource/csdk/stack/include/ocstack.h @@ -878,6 +878,16 @@ OCStackResult OCGetPropertyValue(OCPayloadType type, const char *propName, void */ OCPersistentStorage *OCGetPersistentStorageHandler(); +/** +* This function return link local zone id related from ifindex. +* +* @param ifindex[in] interface index. +* @param zoneId[out] pointer of zoneId string, caller should free +* zoneId using OICFree() when it returned CA_STATUS_OK. +* @return Returns ::OC_STACK_OK if success. +*/ +OCStackResult OCGetLinkLocalZoneId(uint32_t ifindex, char **zoneId); + #ifdef __cplusplus } #endif // __cplusplus diff --git a/resource/csdk/stack/octbstack_product.def b/resource/csdk/stack/octbstack_product.def index ea8cda7..f1a0831 100644 --- a/resource/csdk/stack/octbstack_product.def +++ b/resource/csdk/stack/octbstack_product.def @@ -57,6 +57,7 @@ OCGetHeaderOption OCGetNumberOfResources OCGetNumberOfResourceInterfaces OCGetNumberOfResourceTypes +OCGetLinkLocalZoneId OCGetPropertyValue OCGetResourceHandle OCGetResourceHandleAtUri diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index bf99983..7744dc2 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -60,6 +60,7 @@ #include "ocpayload.h" #include "ocpayloadcbor.h" #include "cautilinterface.h" +#include "cainterface.h" #include "oicgroup.h" #include "ocendpoint.h" @@ -5576,3 +5577,8 @@ OCStackResult OCGetDeviceOwnedState(bool *isOwned) } return ret; } + +OCStackResult OCGetLinkLocalZoneId(uint32_t ifindex, char **zoneId) +{ + return CAResultToOCResult(CAGetLinkLocalZoneId(ifindex, zoneId)); +} diff --git a/resource/csdk/stack/test/stacktests.cpp b/resource/csdk/stack/test/stacktests.cpp index fac2637..15ecd31 100644 --- a/resource/csdk/stack/test/stacktests.cpp +++ b/resource/csdk/stack/test/stacktests.cpp @@ -2564,3 +2564,28 @@ TEST_F(OCDiscoverTests, DiscoverResourceWithInvalidQueries) OC_HIGH_QOS, discoverUnicastRTEmptyCB, NULL, 0)); discoverUnicastRTEmptyCB.Wait(10); } + +TEST(StackZoneId, getZoneId) +{ + uint32_t tempSize = 0; + CAEndpoint_t *tempInfo = NULL; + CAGetNetworkInformation(&tempInfo, &tempSize); + + for (uint32_t i = 0; i < tempSize; i++) + { + char *zoneId = NULL; + EXPECT_EQ(OC_STACK_OK, OCGetLinkLocalZoneId(tempInfo[i].ifindex, &zoneId)); + OICFree(zoneId); + zoneId = NULL; + } + + OICFree(tempInfo); +} + +TEST(StackZoneId, getZoneIdWithInvalidParams) +{ + char *zoneId = NULL; + EXPECT_EQ(OC_STACK_INVALID_PARAM, OCGetLinkLocalZoneId(0, NULL)); + EXPECT_EQ(OC_STACK_ERROR, OCGetLinkLocalZoneId(9999, &zoneId)); + EXPECT_EQ(OC_STACK_ERROR, OCGetLinkLocalZoneId(-1, &zoneId)); +} -- 2.7.4