From 4400d1c59ffa755272c8c64b8fb9bd0252723dd4 Mon Sep 17 00:00:00 2001 From: Jaehong Jo Date: Wed, 13 Jul 2016 16:53:56 +0900 Subject: [PATCH] RD Device Presence features in base layer - make consistent with the revised RD spec. - add the RD Device Presence API in base layer. 1. subscribe DevicePresence to resource-directory Change-Id: Ic6635474efdd5797f41e9d8dcdb867747c93f9eb Signed-off-by: Jaehong Jo Reviewed-on: https://gerrit.iotivity.org/gerrit/9351 Tested-by: jenkins-iotivity Reviewed-by: jihwan seo Reviewed-by: Ashok Babu Channa --- resource/csdk/stack/include/octypes.h | 3 ++ resource/include/IClientWrapper.h | 11 +++- resource/include/InProcClientWrapper.h | 9 +++- resource/include/OCApi.h | 3 ++ resource/include/OCPlatform.h | 22 ++++++++ resource/include/OCPlatform_impl.h | 6 +++ resource/include/OutOfProcClientWrapper.h | 8 +++ resource/src/InProcClientWrapper.cpp | 90 +++++++++++++++++++++++++++++++ resource/src/OCPlatform.cpp | 13 +++++ resource/src/OCPlatform_impl.cpp | 10 ++++ resource/unittests/OCPlatformTest.cpp | 45 ++++++++++++++++ 11 files changed, 217 insertions(+), 3 deletions(-) diff --git a/resource/csdk/stack/include/octypes.h b/resource/csdk/stack/include/octypes.h index 4b521b5..84983fd 100644 --- a/resource/csdk/stack/include/octypes.h +++ b/resource/csdk/stack/include/octypes.h @@ -73,6 +73,9 @@ extern "C" { /** Presence URI through which the OIC devices advertise their presence.*/ #define OC_RSRVD_PRESENCE_URI "/oic/ad" +/** Presence URI through which the OCF devices advertise their device presence.*/ +#define OCF_RSRVD_DEVICE_PRESENCE_URI "/.well-known/ocf/prs" + /** Sets the default time to live (TTL) for presence.*/ #define OC_DEFAULT_PRESENCE_TTL_SECONDS (60) diff --git a/resource/include/IClientWrapper.h b/resource/include/IClientWrapper.h index 849be2d..2bcc0f6 100644 --- a/resource/include/IClientWrapper.h +++ b/resource/include/IClientWrapper.h @@ -109,6 +109,12 @@ namespace OC virtual OCStackResult UnsubscribePresence(OCDoHandle handle) =0; + virtual OCStackResult SubscribeDevicePresence(OCDoHandle* handle, + const std::string& host, + const QueryParamsList& queryParams, + OCConnectivityType connectivityType, + ObserveCallback& callback) = 0; + virtual OCStackResult GetDefaultQos(QualityOfService& qos) = 0; virtual OCStackResult FindDirectPairingDevices(unsigned short waittime, @@ -116,8 +122,9 @@ namespace OC virtual OCStackResult GetDirectPairedDevices(GetDirectPairedCallback& callback) = 0; - virtual OCStackResult DoDirectPairing(std::shared_ptr peer, const OCPrm_t& pmSel, - const std::string& pinNumber, DirectPairingCallback& resultCallback) = 0; + virtual OCStackResult DoDirectPairing(std::shared_ptr< OCDirectPairing > peer, + const OCPrm_t& pmSel, const std::string& pinNumber, + DirectPairingCallback& resultCallback) = 0; virtual ~IClientWrapper(){} }; diff --git a/resource/include/InProcClientWrapper.h b/resource/include/InProcClientWrapper.h index c4f0e59..15eac59 100644 --- a/resource/include/InProcClientWrapper.h +++ b/resource/include/InProcClientWrapper.h @@ -168,8 +168,14 @@ namespace OC SubscribeCallback& presenceHandler); virtual OCStackResult UnsubscribePresence(OCDoHandle handle); - OCStackResult GetDefaultQos(QualityOfService& QoS); + virtual OCStackResult SubscribeDevicePresence(OCDoHandle* handle, + const std::string& host, + const QueryParamsList& queryParams, + OCConnectivityType connectivityType, + ObserveCallback& callback); + + OCStackResult GetDefaultQos(QualityOfService& QoS); virtual OCStackResult FindDirectPairingDevices(unsigned short waittime, GetDirectPairedCallback& callback); @@ -182,6 +188,7 @@ namespace OC private: void listeningFunc(); std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams); + std::string assembleSetResourceUri(std::string uri, const QueryParamsList& queryParams); OCPayload* assembleSetResourcePayload(const OCRepresentation& attributes); OCHeaderOption* assembleHeaderOptions(OCHeaderOption options[], const HeaderOptions& headerOptions); diff --git a/resource/include/OCApi.h b/resource/include/OCApi.h index d2ac74a..75abb8b 100644 --- a/resource/include/OCApi.h +++ b/resource/include/OCApi.h @@ -221,6 +221,9 @@ namespace OC // Typedef for query parameter map typedef std::map QueryParamsMap; + // Typedef for query parameter map with Vector + typedef std::map< std::string, std::vector > QueryParamsList; + // Typedef for list of observation IDs typedef std::vector ObservationIds; diff --git a/resource/include/OCPlatform.h b/resource/include/OCPlatform.h index a46bb75..c3d540f 100644 --- a/resource/include/OCPlatform.h +++ b/resource/include/OCPlatform.h @@ -535,6 +535,28 @@ namespace OC OCStackResult unsubscribePresence(OCPresenceHandle presenceHandle); /** + * Subscribes to a server's device presence change events. + * + * @param presenceHandle a handle object that can be used to identify this subscription + * request. It can be used to unsubscribe from these events in the future. + * It will be set upon successful return of this method. + * @param host The IP address/addressable name of the server to subscribe to. + * This should be in the format coap://address:port + * @param queryParams map which can have the query parameter name and list of value. + * @param observeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this observe operation + * This will have error codes + * + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult subscribeDevicePresence(OCPresenceHandle& presenceHandle, + const std::string& host, + const QueryParamsList& queryParams, + OCConnectivityType connectivityType, + ObserveCallback callback); + + /** * Creates a resource proxy object so that get/put/observe functionality * can be used without discovering the object in advance. Note that the * consumer of this method needs to provide all of the details required to diff --git a/resource/include/OCPlatform_impl.h b/resource/include/OCPlatform_impl.h index c9f85ac..2beb4a3 100644 --- a/resource/include/OCPlatform_impl.h +++ b/resource/include/OCPlatform_impl.h @@ -225,6 +225,12 @@ namespace OC SubscribeCallback presenceHandler); OCStackResult unsubscribePresence(OCPresenceHandle presenceHandle); + OCStackResult subscribeDevicePresence(OCPresenceHandle& presenceHandle, + const std::string& host, + const QueryParamsList& queryParams, + OCConnectivityType connectivityType, + ObserveCallback callback); + OCResource::Ptr constructResourceObject(const std::string& host, const std::string& uri, OCConnectivityType connectivityType, bool isObservable, const std::vector& resourceTypes, diff --git a/resource/include/OutOfProcClientWrapper.h b/resource/include/OutOfProcClientWrapper.h index 4b2d24a..ef79c5e 100644 --- a/resource/include/OutOfProcClientWrapper.h +++ b/resource/include/OutOfProcClientWrapper.h @@ -122,6 +122,14 @@ namespace OC virtual OCStackResult UnsubscribePresence(OCDoHandle /*handle*/) {return OC_STACK_NOTIMPL;} + virtual OCStackResult SubscribeDevicePresence( + OCDoHandle* /*handle*/, + const std::string& /*host*/, + const QueryParamsList& /*queryParams*/, + OCConnectivityType /*connectivityType*/, + ObserveCallback& /*callback*/) + {return OC_STACK_NOTIMPL;} + virtual OCStackResult GetDefaultQos(QualityOfService& /*QoS*/) {return OC_STACK_NOTIMPL;} diff --git a/resource/src/InProcClientWrapper.cpp b/resource/src/InProcClientWrapper.cpp index db1178b..68e0330 100644 --- a/resource/src/InProcClientWrapper.cpp +++ b/resource/src/InProcClientWrapper.cpp @@ -559,6 +559,52 @@ namespace OC return ret; } + std::string InProcClientWrapper::assembleSetResourceUri(std::string uri, + const QueryParamsList& queryParams) + { + if (!uri.empty()) + { + if (uri.back() == '/') + { + uri.resize(uri.size() - 1); + } + } + + ostringstream paramsList; + if (queryParams.size() > 0) + { + paramsList << '?'; + } + + for (auto& param : queryParams) + { + for (auto& paramList : param.second) + { + paramsList << param.first << '=' << paramList; + if (paramList != param.second.back()) + { + paramsList << '&'; + } + } + paramsList << ';'; + } + + std::string queryString = paramsList.str(); + + if (queryString.empty()) + { + return uri; + } + + if (queryString.back() == ';') + { + queryString.resize(queryString.size() - 1); + } + + std::string ret = uri + queryString; + return ret; + } + OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep) { MessageContainer ocInfo; @@ -926,6 +972,50 @@ namespace OC return result; } + OCStackResult InProcClientWrapper::SubscribeDevicePresence(OCDoHandle* handle, + const std::string& host, + const QueryParamsList& queryParams, + OCConnectivityType connectivityType, + ObserveCallback& callback) + { + if (!callback) + { + return OC_STACK_INVALID_PARAM; + } + OCStackResult result; + + ClientCallbackContext::ObserveContext* ctx = + new ClientCallbackContext::ObserveContext(callback); + OCCallbackData cbdata; + cbdata.context = static_cast(ctx), + cbdata.cb = observeResourceCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;}; + + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + std::lock_guard lock(*cLock); + + std::ostringstream os; + os << host << OCF_RSRVD_DEVICE_PRESENCE_URI; + std::string url = assembleSetResourceUri(os.str(), queryParams); + + result = OCDoResource(handle, OC_REST_OBSERVE, + url.c_str(), nullptr, + nullptr, connectivityType, + OC_LOW_QOS, &cbdata, + nullptr, 0); + } + else + { + delete ctx; + result = OC_STACK_ERROR; + } + + return result; + } + OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos) { qos = m_cfg.QoS; diff --git a/resource/src/OCPlatform.cpp b/resource/src/OCPlatform.cpp index f959239..dd161e4 100644 --- a/resource/src/OCPlatform.cpp +++ b/resource/src/OCPlatform.cpp @@ -266,6 +266,19 @@ namespace OC return OCPlatform_impl::Instance().unsubscribePresence(presenceHandle); } + OCStackResult subscribeDevicePresence(OCPresenceHandle& presenceHandle, + const std::string& host, + const QueryParamsList& queryParams, + OCConnectivityType connectivityType, + ObserveCallback callback) + { + return OCPlatform_impl::Instance().subscribeDevicePresence(presenceHandle, + host, + queryParams, + connectivityType, + callback); + } + OCStackResult sendResponse(const std::shared_ptr pResponse) { return OCPlatform_impl::Instance().sendResponse(pResponse); diff --git a/resource/src/OCPlatform_impl.cpp b/resource/src/OCPlatform_impl.cpp index da48020..f40c14c 100644 --- a/resource/src/OCPlatform_impl.cpp +++ b/resource/src/OCPlatform_impl.cpp @@ -382,6 +382,16 @@ namespace OC std::ref(presenceHandle)); } + OCStackResult OCPlatform_impl::subscribeDevicePresence(OCPresenceHandle& presenceHandle, + const std::string& host, + const QueryParamsList& queryParams, + OCConnectivityType connectivityType, + ObserveCallback callback) + { + return checked_guard(m_client, &IClientWrapper::SubscribeDevicePresence, + &presenceHandle, host, queryParams, connectivityType, callback); + } + OCStackResult OCPlatform_impl::sendResponse(const std::shared_ptr pResponse) { return checked_guard(m_server, &IServerWrapper::sendResponse, diff --git a/resource/unittests/OCPlatformTest.cpp b/resource/unittests/OCPlatformTest.cpp index 481e453..2a18ad7 100644 --- a/resource/unittests/OCPlatformTest.cpp +++ b/resource/unittests/OCPlatformTest.cpp @@ -62,6 +62,10 @@ namespace OCPlatformTest { } + void onObserve(const HeaderOptions, const OCRepresentation&, const int&, const int&) + { + } + void directPairHandler(std::shared_ptr /*dev*/, OCStackResult /*res*/) { } @@ -833,6 +837,47 @@ namespace OCPlatformTest EXPECT_EQ(OC_STACK_OK, OCPlatform::unsubscribePresence(presenceHandle)); } + //SubscribeDevicePresence Test + TEST(SubscribeDevicePresenceTest, DISABLED_SubscribeDevicePresenceWithValidParameters) + { + std::string hostAddress = "192.168.1.2:5000"; + OCPlatform::OCPresenceHandle presenceHandle = nullptr; + QueryParamsList queryParams = {}; + + EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribeDevicePresence(presenceHandle, + hostAddress, queryParams, CT_DEFAULT, &onObserve)); + } + + TEST(SubscribeDevicePresenceTest, SubscribeDevicePresenceWithNullHost) + { + OCPlatform::OCPresenceHandle presenceHandle = nullptr; + QueryParamsList queryParams = {}; + + EXPECT_ANY_THROW(OCPlatform::subscribeDevicePresence(presenceHandle, + nullptr, queryParams, CT_DEFAULT, &onObserve)); + } + + TEST(SubscribeDevicePresenceTest, SubscribeDevicePresenceWithNullOnObserve) + { + std::string hostAddress = "192.168.1.2:5000"; + OCPlatform::OCPresenceHandle presenceHandle = nullptr; + QueryParamsList queryParams = {}; + + EXPECT_ANY_THROW(OCPlatform::subscribeDevicePresence(presenceHandle, + hostAddress, queryParams, CT_DEFAULT, NULL)); + } + + TEST(SubscribeDevicePresenceTest, DISABLED_UnsubscribePresenceWithValidHandle) + { + std::string hostAddress = "192.168.1.2:5000"; + OCPlatform::OCPresenceHandle presenceHandle = nullptr; + QueryParamsList queryParams = {}; + + EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribeDevicePresence(presenceHandle, + hostAddress, queryParams, CT_DEFAULT, &onObserve)); + EXPECT_EQ(OC_STACK_OK, OCPlatform::unsubscribePresence(presenceHandle)); + } + TEST(FindDirectPairingTest, FindDirectPairingNullCallback) { EXPECT_ANY_THROW(OCPlatform::findDirectPairingDevices(1, nullptr)); -- 2.7.4