RD Device Presence features in base layer
authorJaehong Jo <jaehong.jo@samsung.com>
Wed, 13 Jul 2016 07:53:56 +0000 (16:53 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Thu, 21 Jul 2016 15:02:43 +0000 (15:02 +0000)
- 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 <jaehong.jo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/9351
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: jihwan seo <jihwan.seo@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
resource/csdk/stack/include/octypes.h
resource/include/IClientWrapper.h
resource/include/InProcClientWrapper.h
resource/include/OCApi.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OutOfProcClientWrapper.h
resource/src/InProcClientWrapper.cpp
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp
resource/unittests/OCPlatformTest.cpp

index 4b521b5..84983fd 100644 (file)
@@ -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)
 
index 849be2d..2bcc0f6 100644 (file)
@@ -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<OCDirectPairing> 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(){}
     };
index c4f0e59..15eac59 100644 (file)
@@ -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);
index d2ac74a..75abb8b 100644 (file)
@@ -221,6 +221,9 @@ namespace OC
     // Typedef for query parameter map
     typedef std::map<std::string, std::string> QueryParamsMap;
 
+    // Typedef for query parameter map with Vector
+    typedef std::map< std::string, std::vector<std::string> > QueryParamsList;
+
     // Typedef for list of observation IDs
     typedef std::vector<OCObservationId> ObservationIds;
 
index a46bb75..c3d540f 100644 (file)
@@ -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
index c9f85ac..2beb4a3 100644 (file)
@@ -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<std::string>& resourceTypes,
index 4b2d24a..ef79c5e 100644 (file)
@@ -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;}
 
index db1178b..68e0330 100644 (file)
@@ -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<void*>(ctx),
+        cbdata.cb      = observeResourceCallback;
+        cbdata.cd      = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
+
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> 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;
index f959239..dd161e4 100644 (file)
@@ -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<OCResourceResponse> pResponse)
         {
             return OCPlatform_impl::Instance().sendResponse(pResponse);
index da48020..f40c14c 100644 (file)
@@ -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<OCResourceResponse> pResponse)
     {
         return checked_guard(m_server, &IServerWrapper::sendResponse,
index 481e453..2a18ad7 100644 (file)
@@ -62,6 +62,10 @@ namespace OCPlatformTest
     {
     }
 
+    void onObserve(const HeaderOptions, const OCRepresentation&, const int&, const int&)
+    {
+    }
+
     void directPairHandler(std::shared_ptr<OCDirectPairing> /*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));