From 1a2a7c36fdf4469b481d7c0a61a23ebb6bebd367 Mon Sep 17 00:00:00 2001 From: Sijae Kim Date: Mon, 15 Aug 2016 20:04:59 +0900 Subject: [PATCH] Add PMSingleDiscovery function for discover owned/unowned devices in specified endpoint this function will return when found one or more device even though timeout is not exceeded Change-Id: Ib03a775bb4142466274bb38517433803971a4213 Signed-off-by: Sijae Kim Reviewed-on: https://gerrit.iotivity.org/gerrit/10461 Reviewed-by: Jongmin Choi Tested-by: jenkins-iotivity Reviewed-by: Jongho Park Reviewed-by: dongik Lee Reviewed-by: Randeep Singh --- .../provisioning/include/ocprovisioningmanager.h | 14 +++ .../csdk/security/provisioning/include/pmutility.h | 17 ++- .../provisioning/src/ocprovisioningmanager.c | 22 ++++ .../csdk/security/provisioning/src/pmutility.c | 115 ++++++++++++++++++++- .../security/provisioning/unittest/otmunittest.cpp | 20 ++++ resource/include/OCProvisioningManager.h | 16 +++ .../provisioning/src/OCProvisioningManager.cpp | 41 ++++++++ .../provisioning/unittests/OCProvisioningTest.cpp | 12 +++ 8 files changed, 255 insertions(+), 2 deletions(-) mode change 100644 => 100755 resource/csdk/security/provisioning/include/ocprovisioningmanager.h mode change 100644 => 100755 resource/csdk/security/provisioning/include/pmutility.h mode change 100644 => 100755 resource/csdk/security/provisioning/src/ocprovisioningmanager.c mode change 100644 => 100755 resource/csdk/security/provisioning/src/pmutility.c mode change 100644 => 100755 resource/csdk/security/provisioning/unittest/otmunittest.cpp mode change 100644 => 100755 resource/include/OCProvisioningManager.h mode change 100644 => 100755 resource/provisioning/src/OCProvisioningManager.cpp mode change 100644 => 100755 resource/provisioning/unittests/OCProvisioningTest.cpp diff --git a/resource/csdk/security/provisioning/include/ocprovisioningmanager.h b/resource/csdk/security/provisioning/include/ocprovisioningmanager.h old mode 100644 new mode 100755 index dd6ac1d..1ab0f10 --- a/resource/csdk/security/provisioning/include/ocprovisioningmanager.h +++ b/resource/csdk/security/provisioning/include/ocprovisioningmanager.h @@ -42,6 +42,20 @@ extern "C" { OCStackResult OCInitPM(const char* dbPath); /** + * The function is responsible for discovery of owned/unowned device is specified endpoint. + * It will return when found one or more device even though timeout is not exceeded + * + * @param[in] timeout Timeout in seconds, value till which function will listen to responses from + * server before returning the list of devices. + * @param[in] host address of target endpoint + * @param[in] connType connectivity type of endpoint + * @param[out] ppList List of device. + * @return OTM_SUCCESS in case of success and other value otherwise. + */ +OCStackResult OCDiscoverSecureResource(unsigned short timeout, const char* host, + OCConnectivityType connType, OCProvisionDev_t **ppList); + +/** * The function is responsible for discovery of device is current subnet. It will list * all the device in subnet which are not yet owned. Please call OCInit with OC_CLIENT_SERVER as * OCMode. diff --git a/resource/csdk/security/provisioning/include/pmutility.h b/resource/csdk/security/provisioning/include/pmutility.h old mode 100644 new mode 100755 index ddb2968..d3947b1 --- a/resource/csdk/security/provisioning/include/pmutility.h +++ b/resource/csdk/security/provisioning/include/pmutility.h @@ -39,7 +39,22 @@ extern "C" #define COAP_TCP_PREFIX "coap+tcp://" #define COAPS_TCP_PREFIX "coaps+tcp://" - /** + +/** + * Discover owned/unowned devices in the specified endpoint. + * It will return when found one or more device even though timeout is not exceeded + * + * @param[in] waittime Timeout in seconds + * @param[in] host address of target endpoint + * @param[in] connType connectivity type of endpoint + * @param[out] ppDevicesList List of OCProvisionDev_t + * + * @return OC_STACK_OK on success otherwise error. + */ +OCStackResult PMSingleDeviceDiscovery(unsigned short waittime, const char* host, + OCConnectivityType connType, OCProvisionDev_t **ppDevicesList); + +/** * Discover owned/unowned devices in the same IP subnet. . * * @param[in] waittime Timeout in seconds. diff --git a/resource/csdk/security/provisioning/src/ocprovisioningmanager.c b/resource/csdk/security/provisioning/src/ocprovisioningmanager.c old mode 100644 new mode 100755 index ae2f054..67f859a --- a/resource/csdk/security/provisioning/src/ocprovisioningmanager.c +++ b/resource/csdk/security/provisioning/src/ocprovisioningmanager.c @@ -66,6 +66,28 @@ OCStackResult OCInitPM(const char* dbPath) } /** + * The function is responsible for discovery of owned/unowned device is specified endpoint. + * It will return when found one or more device even though timeout is not exceeded + * + * @param[in] timeout Timeout in seconds, value till which function will listen to responses from + * server before returning the list of devices. + * @param[in] host address of target endpoint + * @param[in] connType connectivity type of endpoint + * @param[out] ppList List of device. + * @return OTM_SUCCESS in case of success and other value otherwise. + */ +OCStackResult OCDiscoverSecureResource(unsigned short timeout, const char* host, + OCConnectivityType connType, OCProvisionDev_t **ppList) +{ + if( ppList == NULL || *ppList != NULL || 0 == timeout || host == NULL) + { + return OC_STACK_INVALID_PARAM; + } + + return PMSingleDeviceDiscovery(timeout, host, connType, ppList); +} + +/** * The function is responsible for discovery of device is current subnet. It will list * all the device in subnet which are not yet owned. Please call OCInit with OC_CLIENT_SERVER as * OCMode. diff --git a/resource/csdk/security/provisioning/src/pmutility.c b/resource/csdk/security/provisioning/src/pmutility.c old mode 100644 new mode 100755 index bda2270..f679388 --- a/resource/csdk/security/provisioning/src/pmutility.c +++ b/resource/csdk/security/provisioning/src/pmutility.c @@ -53,6 +53,8 @@ typedef struct _DiscoveryInfo{ OCProvisionDev_t **ppDevicesList; bool isOwnedDiscovery; + bool isSingleDiscovery; + bool isFound; } DiscoveryInfo; /* @@ -538,6 +540,10 @@ static OCStackApplicationResult SecurityVersionDiscoveryHandler(void *ctx, OCDoH OIC_LOG(INFO, TAG, "Exiting SecVersionDiscoveryHandler."); DeleteVerBinData(ptrVer); + if(pDInfo->isSingleDiscovery) + { + pDInfo->isFound = true; + } } } } @@ -717,7 +723,7 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU return OC_STACK_KEEP_TRANSACTION; } //if this is owned discovery and this is PT's reply, discard it - if((pDInfo->isOwnedDiscovery) && + if(((pDInfo->isSingleDiscovery) || (pDInfo->isOwnedDiscovery)) && (0 == memcmp(&ptrDoxm->deviceID.id, &myId.id, sizeof(myId.id))) ) { OIC_LOG(DEBUG, TAG, "discarding provision tool's reply"); @@ -743,6 +749,10 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU } OIC_LOG(INFO, TAG, "Exiting ProvisionDiscoveryHandler."); + if(pDInfo->isSingleDiscovery) + { + return OC_STACK_DELETE_TRANSACTION; + } } return OC_STACK_KEEP_TRANSACTION; @@ -757,6 +767,108 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU return OC_STACK_DELETE_TRANSACTION; } + +/** + * Discover owned/unowned devices in the specified endpoint. + * It will return when found one or more device even though timeout is not exceeded + * + * @param[in] waittime Timeout in seconds + * @param[in] host address of target endpoint + * @param[in] connType connectivity type of endpoint + * @param[out] ppDevicesList List of OCProvisionDev_t + * + * @return OC_STACK_OK on success otherwise error. + */ +OCStackResult PMSingleDeviceDiscovery(unsigned short waittime, const char* host, + OCConnectivityType connType, OCProvisionDev_t **ppDevicesList) +{ + OIC_LOG(DEBUG, TAG, "IN PMSingleDeviceDiscovery"); + + if (NULL != *ppDevicesList) + { + OIC_LOG(ERROR, TAG, "List is not null can cause memory leak"); + return OC_STACK_INVALID_PARAM; + } + + DiscoveryInfo *pDInfo = OICCalloc(1, sizeof(DiscoveryInfo)); + if(NULL == pDInfo) + { + OIC_LOG(ERROR, TAG, "PMSingleDeviceDiscovery : Memory allocation failed."); + return OC_STACK_NO_MEMORY; + } + + pDInfo->ppDevicesList = ppDevicesList; + pDInfo->isOwnedDiscovery = false; + pDInfo->isSingleDiscovery = true; + pDInfo->isFound = false; + + OCCallbackData cbData; + cbData.cb = &DeviceDiscoveryHandler; + cbData.context = (void *)pDInfo; + cbData.cd = NULL; + OCStackResult res = OC_STACK_ERROR; + + char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH + 1] = { '\0' }; + if(host == NULL) + { + host = ""; + } + snprintf(query, MAX_URI_LENGTH + MAX_QUERY_LENGTH + 1, "%s/oic/sec/doxm", host); + + OCDoHandle handle = NULL; + res = OCDoResource(&handle, OC_REST_DISCOVER, query, 0, 0, + connType, OC_HIGH_QOS, &cbData, NULL, 0); + if (res != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStack resource error"); + OICFree(pDInfo); + return res; + } + + //Waiting for each response. + res = OC_STACK_OK; + uint64_t startTime = OICGetCurrentTime(TIME_IN_MS); + while (OC_STACK_OK == res && pDInfo->isFound == false) + { + uint64_t currTime = OICGetCurrentTime(TIME_IN_MS); + + long elapsed = (long)((currTime - startTime) / MS_PER_SEC); + if (elapsed > waittime) + { + break; + } + res = OCProcess(); + } + + if(OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "Failed to wait response for secure discovery."); + OICFree(pDInfo); + OCStackResult resCancel = OCCancel(handle, OC_HIGH_QOS, NULL, 0); + if(OC_STACK_OK != resCancel) + { + OIC_LOG(ERROR, TAG, "Failed to remove registered callback"); + } + return res; + } + + if(*ppDevicesList == NULL) + { + res = OCCancel(handle,OC_HIGH_QOS,NULL,0); + } + + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "Failed to remove registered callback"); + OICFree(pDInfo); + return res; + } + OIC_LOG(DEBUG, TAG, "OUT PMSingleDeviceDiscovery"); + OICFree(pDInfo); + return res; +} + + /** * Discover owned/unowned devices in the same IP subnet. . * @@ -788,6 +900,7 @@ OCStackResult PMDeviceDiscovery(unsigned short waittime, bool isOwned, OCProvisi pDInfo->ppDevicesList = ppDevicesList; pDInfo->isOwnedDiscovery = isOwned; + pDInfo->isSingleDiscovery = false; OCCallbackData cbData; cbData.cb = &DeviceDiscoveryHandler; diff --git a/resource/csdk/security/provisioning/unittest/otmunittest.cpp b/resource/csdk/security/provisioning/unittest/otmunittest.cpp old mode 100644 new mode 100755 index 40eac29..4d97057 --- a/resource/csdk/security/provisioning/unittest/otmunittest.cpp +++ b/resource/csdk/security/provisioning/unittest/otmunittest.cpp @@ -413,6 +413,26 @@ TEST(InitForOTM, NullParam) g_callbackResult = false; } +TEST(PerformSecureResourceDiscovery, NullParam) +{ + OCStackResult result = OC_STACK_ERROR; + OCProvisionDev_t* foundDevice = NULL; + + OIC_LOG(INFO, TAG, "Discovering Owned/Unowned Device using multicast\n"); + result = OCDiscoverSecureResource(DISCOVERY_TIMEOUT, "", CT_DEFAULT, &foundDevice); + EXPECT_EQ(OC_STACK_OK, result); + + int NumOfFoundDevice = 0; + OCProvisionDev_t* tempDev = foundDevice; + while(tempDev) + { + NumOfFoundDevice++; + tempDev = tempDev->next; + } + PMDeleteDeviceList(foundDevice); + + EXPECT_EQ(true, NumOfFoundDevice > 0); +} TEST(PerformUnownedDeviceDiscovery, NullParam) { diff --git a/resource/include/OCProvisioningManager.h b/resource/include/OCProvisioningManager.h old mode 100644 new mode 100755 index 3602cd8..add8105 --- a/resource/include/OCProvisioningManager.h +++ b/resource/include/OCProvisioningManager.h @@ -144,6 +144,22 @@ namespace OC DeviceList_t &list); /** + * API is responsible for discovery of devices in specified endpoint. + * It will return when found one or more device even though timeout is not exceeded + * + * @param timeout Timeout in seconds, time until which function will listen to + * responses from server before returning the list of devices. + * @param host address of target endpoint + * @param connType connectivity type of endpoint + * @param list List of devices. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult discoverSecureResource(unsigned short timeout, + const std::string& host, + OCConnectivityType connType, + DeviceList_t &list); + + /** * API for registering Ownership transfer methods for a particular transfer Type. * * @param oxm Ownership transfer method. diff --git a/resource/provisioning/src/OCProvisioningManager.cpp b/resource/provisioning/src/OCProvisioningManager.cpp old mode 100644 new mode 100755 index cb13e67..822297a --- a/resource/provisioning/src/OCProvisioningManager.cpp +++ b/resource/provisioning/src/OCProvisioningManager.cpp @@ -121,6 +121,47 @@ namespace OC return result; } + OCStackResult OCSecure::discoverSecureResource(unsigned short timeout, + const std::string& host, + OCConnectivityType connType, + DeviceList_t &list) + { + OCStackResult result; + OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr; + auto csdkLock = OCPlatform_impl::Instance().csdkLock(); + auto cLock = csdkLock.lock(); + + if (cLock) + { + std::lock_guard lock(*cLock); + result = OCDiscoverSecureResource(timeout, host.c_str(), connType, &pDevList); + if (result == OC_STACK_OK) + { + pCurDev = pDevList; + while (pCurDev) + { + tmp = pCurDev; + list.push_back(std::shared_ptr( + new OCSecureResource(csdkLock, pCurDev))); + pCurDev = pCurDev->next; + tmp->next = nullptr; + } + } + else + { + oclog() <<"Secure resource discovery failed!"; + result = OC_STACK_ERROR; + } + } + else + { + oclog() <<"Mutex not found"; + result = OC_STACK_ERROR; + } + + return result; + } + OCStackResult OCSecure::setOwnerTransferCallbackData(OicSecOxm_t oxm, OTMCallbackData_t* callbackData, InputPinCallback inputPin) { diff --git a/resource/provisioning/unittests/OCProvisioningTest.cpp b/resource/provisioning/unittests/OCProvisioningTest.cpp old mode 100644 new mode 100755 index 9e44e06..1a9dac6 --- a/resource/provisioning/unittests/OCProvisioningTest.cpp +++ b/resource/provisioning/unittests/OCProvisioningTest.cpp @@ -51,6 +51,18 @@ namespace OCProvisioningTest EXPECT_EQ(OC_STACK_OK, OCSecure::provisionInit(dbPath)); } + TEST(DiscoveryTest, SecureResource) + { + DeviceList_t list; + EXPECT_EQ(OC_STACK_OK, OCSecure::discoverSecureResource(TIMEOUT, "", CT_DEFAULT, list)); + } + + TEST(DiscoveryTest, SecureResourceZeroTimeout) + { + DeviceList_t list; + EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::discoverSecureResource(0, "", CT_DEFAULT, list)); + } + TEST(DiscoveryTest, UnownedDevices) { DeviceList_t list; -- 2.7.4