RD client features in base layer
[platform/upstream/iotivity.git] / resource / src / InProcServerWrapper.cpp
index 2fd1c19..bd7639d 100644 (file)
 #include <OCPlatform.h>
 #include <OCUtilities.h>
 
+#ifdef RD_CLIENT
+#include <oicresourcedirectory.h>
+#endif
+
 using namespace std;
 using namespace OC;
 
@@ -595,7 +599,149 @@ namespace OC
             return result;
         }
     }
+#ifdef RD_CLIENT
+    OCRepresentation parseRDResponseCallback(OCClientResponse* clientResponse)
+    {
+        if (nullptr == clientResponse->payload ||
+                    PAYLOAD_TYPE_RD != clientResponse->payload->type)
+        {
+            return OCRepresentation();
+        }
+
+        MessageContainer oc;
+        oc.setPayload(clientResponse->payload);
+
+        std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
+        if (it == oc.representations().end())
+        {
+            return OCRepresentation();
+        }
 
+        // first one is considered the root, everything else is considered a child of this one.
+        OCRepresentation root = *it;
+        root.setDevAddr(clientResponse->devAddr);
+        root.setUri(clientResponse->resourceUri);
+        ++it;
+
+        std::for_each(it, oc.representations().end(),
+                [&root](const OCRepresentation& repItr)
+                {root.addChild(repItr);});
+        return root;
+
+    }
+
+    OCStackApplicationResult publishResourceToRDCallback(void* ctx, OCDoHandle /*handle*/,
+                                                         OCClientResponse* clientResponse)
+    {
+        ServerCallbackContext::PublishContext* context =
+        static_cast<ServerCallbackContext::PublishContext*>(ctx);
+
+        try
+        {
+            // Update resource unique id in stack.
+            if (clientResponse)
+            {
+                if (clientResponse->payload)
+                {
+                    OCRDPayload *rdPayload = (OCRDPayload *) clientResponse->payload;
+                    OCLinksPayload *links = rdPayload->rdPublish->setLinks;
+
+                    while (links)
+                    {
+                        OCResourceHandle handle = OCGetResourceHandleAtUri(links->href);
+                        OCBindResourceInsToResource(handle, links->ins);
+                        links = links->next;
+                    }
+
+                }
+            }
+
+            OCRepresentation rep = parseRDResponseCallback(clientResponse);
+            std::thread exec(context->callback, rep, clientResponse->result);
+            exec.detach();
+        }
+        catch (OC::OCException& e)
+        {
+            oclog() <<"Exception in publishResourceToRDCallback, ignoring response: "
+                <<e.what() <<std::flush;
+        }
+
+        return OC_STACK_KEEP_TRANSACTION;
+    }
+
+    OCStackResult InProcServerWrapper::publishResourceToRD(const std::string& host,
+                                                           OCConnectivityType connectivityType,
+                                                           ResourceHandles& resourceHandles,
+                                                           PublishResourceCallback& callback,
+                                                           OCQualityOfService qos)
+    {
+        ServerCallbackContext::PublishContext* ctx =
+            new ServerCallbackContext::PublishContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                publishResourceToRDCallback,
+                [](void* c)
+                {delete static_cast<ServerCallbackContext::PublishContext*>(c);}
+                );
+
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCRDPublish(host.c_str(), connectivityType, &resourceHandles[0],
+                                 resourceHandles.size(), &cbdata, qos);
+        }
+
+        if (OC_STACK_OK != result)
+        {
+            throw OCException(OC::Exception::PUBLISH_RESOURCE_FAILED, result);
+        }
+        return result;
+    }
+
+    OCStackApplicationResult deleteResourceFromRDCallback(void* ctx, OCDoHandle /*handle*/,
+                                                          OCClientResponse* clientResponse)
+    {
+        ServerCallbackContext::DeleteContext* context =
+        static_cast<ServerCallbackContext::DeleteContext*>(ctx);
+
+        std::thread exec(context->callback, clientResponse->result);
+        exec.detach();
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OCStackResult InProcServerWrapper::deleteResourceFromRD(const std::string& host,
+                                                            OCConnectivityType connectivityType,
+                                                            ResourceHandles& resourceHandles,
+                                                            DeleteResourceCallback& callback,
+                                                            OCQualityOfService qos)
+    {
+        ServerCallbackContext::DeleteContext* ctx =
+            new ServerCallbackContext::DeleteContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                deleteResourceFromRDCallback,
+                [](void* c)
+                {delete static_cast<ServerCallbackContext::DeleteContext*>(c);}
+                );
+
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCRDDelete(host.c_str(), connectivityType, &resourceHandles[0],
+                                resourceHandles.size(), &cbdata, qos);
+        }
+
+        if (OC_STACK_OK != result)
+        {
+            throw OCException(OC::Exception::PUBLISH_RESOURCE_FAILED, result);
+        }
+        return result;
+    }
+#endif
     InProcServerWrapper::~InProcServerWrapper()
     {
         if(m_processThread.joinable())