Implement ServerID parsing and sample app
[platform/upstream/iotivity.git] / resource / src / InProcClientWrapper.cpp
index bc11721..9fd3153 100644 (file)
@@ -58,7 +58,12 @@ namespace OC
             m_listeningThread.join();
         }
 
-        OCStop();
+        // only stop if we are the ones who actually called 'init'.  We are counting
+        // on the server to do the stop.
+        if(m_cfg.mode == ModeType::Client)
+        {
+            OCStop();
+        }
     }
 
     void InProcClientWrapper::listeningFunc()
@@ -87,6 +92,33 @@ namespace OC
         }
     }
 
+    OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
+    {
+        if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
+        {
+            throw OCException(OC::Exception::STR_NULL_RESPONSE, OC_STACK_ERROR);
+        }
+
+        MessageContainer oc;
+        oc.setJSONRepresentation(clientResponse->resJSONPayload);
+
+        std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
+        if(it == oc.representations().end())
+        {
+            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_ERROR);
+        }
+
+        // first one is considered the root, everything else is considered a child of this one.
+        OCRepresentation root = *it;
+        ++it;
+
+        std::for_each(it, oc.representations().end(),
+                [&root](const OCRepresentation& repItr)
+                {root.addChild(repItr);});
+        return root;
+
+    }
+
     OCStackApplicationResult listenCallback(void* ctx, OCDoHandle handle,
         OCClientResponse* clientResponse)
     {
@@ -102,12 +134,21 @@ namespace OC
             return OC_STACK_KEEP_TRANSACTION;
         }
 
+        auto clientWrapper = context->clientWrapper.lock();
+
+        if(!clientWrapper)
+        {
+            oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
+                    << std::flush;
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
         std::stringstream requestStream;
         requestStream << clientResponse->resJSONPayload;
 
         try
         {
-            ListenOCContainer container(context->clientWrapper, *clientResponse->addr,
+            ListenOCContainer container(clientWrapper, *clientResponse->addr,
                     requestStream);
 
             // loop to ensure valid construction of all resources
@@ -122,18 +163,25 @@ namespace OC
         {
             oclog() << "listenCallback failed to parse a malformed message: "
                     << e.what()
-                    << std::endl <<std::endl
+                    << std::endl
+                    << clientResponse->resJSONPayload
+                    << std::endl
                     << clientResponse->result
                     << std::flush;
             return OC_STACK_KEEP_TRANSACTION;
         }
 
         return OC_STACK_KEEP_TRANSACTION;
-
     }
 
+#ifdef CA_INT
+    OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
+        const std::string& resourceType, uint8_t connectivityType,
+        FindCallback& callback, QualityOfService QoS)
+#else
     OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
         const std::string& resourceType, FindCallback& callback, QualityOfService QoS)
+#endif
     {
         OCStackResult result;
 
@@ -152,45 +200,91 @@ namespace OC
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCDoHandle handle;
+#ifdef CA_INT
+            result = OCDoResource(&handle, OC_REST_GET,
+                                  resourceType.c_str(),
+                                  nullptr, nullptr, connectivityType,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  NULL, 0);
+#else
             result = OCDoResource(&handle, OC_REST_GET,
                                   resourceType.c_str(),
                                   nullptr, nullptr,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   NULL, 0);
+#endif
         }
         else
         {
+            delete context;
             result = OC_STACK_ERROR;
         }
         return result;
     }
 
-    OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
+    OCStackApplicationResult listenDeviceCallback(void* ctx, OCDoHandle handle,
+            OCClientResponse* clientResponse)
     {
-        if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
-        {
-            return OCRepresentation();
-        }
+        ClientCallbackContext::DeviceListenContext* context =
+            static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
 
-        MessageContainer oc;
-        oc.setJSONRepresentation(clientResponse->resJSONPayload);
+        OCRepresentation rep = parseGetSetCallback(clientResponse);
+        std::thread exec(context->callback, rep);
+        exec.detach();
 
-        std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
-        if(it == oc.representations().end())
-        {
-            return OCRepresentation();
-        }
+        return OC_STACK_KEEP_TRANSACTION;
+    }
 
-        // first one is considered the root, everything else is considered a child of this one.
-        OCRepresentation root = *it;
-        ++it;
+#ifdef CA_INT
+    OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
+        const std::string& deviceURI, uint8_t connectivityType,
+        FindDeviceCallback& callback, QualityOfService QoS)
+#else
+    OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
+        const std::string& deviceURI, FindDeviceCallback& callback, QualityOfService QoS)
+#endif
+    {
+        OCStackResult result;
 
-        std::for_each(it, oc.representations().end(),
-                [&root](const OCRepresentation& repItr)
-                {root.addChild(repItr);});
-        return root;
+        OCCallbackData cbdata = {0};
 
+        ClientCallbackContext::DeviceListenContext* context =
+            new ClientCallbackContext::DeviceListenContext();
+        context->callback = callback;
+        context->clientWrapper = shared_from_this();
+
+        cbdata.context =  static_cast<void*>(context);
+        cbdata.cb = listenDeviceCallback;
+        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeviceListenContext*>(c);};
+
+        auto cLock = m_csdkLock.lock();
+        if(cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCDoHandle handle;
+#ifdef CA_INT
+            result = OCDoResource(&handle, OC_REST_GET,
+                                  deviceURI.c_str(),
+                                  nullptr, nullptr, connectivityType,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  NULL, 0);
+#else
+            result = OCDoResource(&handle, OC_REST_GET,
+                                  deviceURI.c_str(),
+                                  nullptr, nullptr,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  NULL, 0);
+#endif
+        }
+        else
+        {
+            result = OC_STACK_ERROR;
+        }
+        return result;
     }
 
     void parseServerHeaderOptions(OCClientResponse* clientResponse,
@@ -238,10 +332,17 @@ namespace OC
         return OC_STACK_DELETE_TRANSACTION;
     }
 
+#ifdef CA_INT
+    OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
+        const std::string& uri, uint8_t connectivityType, const QueryParamsMap& queryParams,
+        const HeaderOptions& headerOptions, GetCallback& callback,
+        QualityOfService QoS)
+#else
     OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
         const std::string& uri, const QueryParamsMap& queryParams,
         const HeaderOptions& headerOptions, GetCallback& callback,
         QualityOfService QoS)
+#endif
     {
         OCStackResult result;
         OCCallbackData cbdata = {0};
@@ -264,14 +365,23 @@ namespace OC
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
             assembleHeaderOptions(options, headerOptions);
+#ifdef CA_INT
+            result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
+                                  nullptr, nullptr, connectivityType,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  options, headerOptions.size());
+#else
             result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
                                   nullptr, nullptr,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   options, headerOptions.size());
+#endif
         }
         else
         {
+            delete ctx;
             result = OC_STACK_ERROR;
         }
         return result;
@@ -335,10 +445,17 @@ namespace OC
         return ocInfo.getJSONRepresentation(OCInfoFormat::IncludeOC);
     }
 
+#ifdef CA_INT
+    OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
+        const std::string& uri, uint8_t connectivityType, const OCRepresentation& rep,
+        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+        PostCallback& callback, QualityOfService QoS)
+#else
     OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
         const std::string& uri, const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PostCallback& callback, QualityOfService QoS)
+#endif
     {
         OCStackResult result;
         OCCallbackData cbdata = {0};
@@ -363,25 +480,40 @@ namespace OC
             OCDoHandle handle;
 
             assembleHeaderOptions(options, headerOptions);
+#ifdef CA_INT
+            result = OCDoResource(&handle, OC_REST_POST,
+                                  os.str().c_str(), nullptr,
+                                  assembleSetResourcePayload(rep).c_str(), connectivityType,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata, options, headerOptions.size());
+#else
             result = OCDoResource(&handle, OC_REST_POST,
                                   os.str().c_str(), nullptr,
                                   assembleSetResourcePayload(rep).c_str(),
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata, options, headerOptions.size());
+#endif
         }
         else
         {
+            delete ctx;
             result = OC_STACK_ERROR;
         }
 
         return result;
     }
 
-
+#ifdef CA_INT
+    OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
+        const std::string& uri, uint8_t connectivityType, const OCRepresentation& rep,
+        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+        PutCallback& callback, QualityOfService QoS)
+#else
     OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
         const std::string& uri, const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PutCallback& callback, QualityOfService QoS)
+#endif
     {
         OCStackResult result;
         OCCallbackData cbdata = {0};
@@ -406,15 +538,25 @@ namespace OC
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
             assembleHeaderOptions(options, headerOptions);
+#ifdef CA_INT
+            result = OCDoResource(&handle, OC_REST_PUT,
+                                  os.str().c_str(), nullptr,
+                                  assembleSetResourcePayload(rep).c_str(), connectivityType,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  options, headerOptions.size());
+#else
             result = OCDoResource(&handle, OC_REST_PUT,
                                   os.str().c_str(), nullptr,
                                   assembleSetResourcePayload(rep).c_str(),
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   options, headerOptions.size());
+#endif
         }
         else
         {
+            delete ctx;
             result = OC_STACK_ERROR;
         }
 
@@ -437,9 +579,15 @@ namespace OC
         return OC_STACK_DELETE_TRANSACTION;
     }
 
+#ifdef CA_INT
+    OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
+        const std::string& uri, uint8_t connectivityType, const HeaderOptions& headerOptions,
+         DeleteCallback& callback, QualityOfService QoS)
+#else
     OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
         const std::string& uri, const HeaderOptions& headerOptions,
          DeleteCallback& callback, QualityOfService QoS)
+#endif
     {
         OCStackResult result;
         OCCallbackData cbdata = {0};
@@ -463,14 +611,22 @@ namespace OC
             assembleHeaderOptions(options, headerOptions);
 
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-
+#ifdef CA_INT
+            result = OCDoResource(&handle, OC_REST_DELETE,
+                                  os.str().c_str(), nullptr,
+                                  nullptr, connectivityType,
+                                  static_cast<OCQualityOfService>(m_cfg.QoS),
+                                  &cbdata, options, headerOptions.size());
+#else
             result = OCDoResource(&handle, OC_REST_DELETE,
                                   os.str().c_str(), nullptr,
                                   nullptr, static_cast<OCQualityOfService>(m_cfg.QoS),
                                   &cbdata, options, headerOptions.size());
+#endif
         }
         else
         {
+            delete ctx;
             result = OC_STACK_ERROR;
         }
 
@@ -497,9 +653,16 @@ namespace OC
         return OC_STACK_KEEP_TRANSACTION;
     }
 
+#ifdef CA_INT
+    OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
+        const std::string& host, const std::string& uri, uint8_t connectivityType,
+        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+        ObserveCallback& callback, QualityOfService QoS)
+#else
     OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
         const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
         const HeaderOptions& headerOptions, ObserveCallback& callback, QualityOfService QoS)
+#endif
     {
         OCStackResult result;
         OCCallbackData cbdata = {0};
@@ -535,15 +698,25 @@ namespace OC
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
             assembleHeaderOptions(options, headerOptions);
+#ifdef CA_INT
+            result = OCDoResource(handle, method,
+                                  os.str().c_str(), nullptr,
+                                  nullptr, connectivityType,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  options, headerOptions.size());
+#else
             result = OCDoResource(handle, method,
                                   os.str().c_str(), nullptr,
                                   nullptr,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   options, headerOptions.size());
+#endif
         }
         else
         {
+            delete ctx;
             return OC_STACK_ERROR;
         }
 
@@ -602,9 +775,15 @@ namespace OC
         return OC_STACK_KEEP_TRANSACTION;
     }
 
+#ifdef CA_INT
+    OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
+        const std::string& host, const std::string& resourceType, uint8_t connectivityType,
+        SubscribeCallback& presenceHandler)
+#else
     OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
         const std::string& host, const std::string& resourceType,
         SubscribeCallback& presenceHandler)
+#endif
     {
         OCCallbackData cbdata = {0};
 
@@ -626,10 +805,18 @@ namespace OC
         }
 
         if(!cLock)
+        {
+            delete ctx;
             return OC_STACK_ERROR;
+        }
 
+#ifdef CA_INT
+        return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
+                            connectivityType, OC_LOW_QOS, &cbdata, NULL, 0);
+#else
         return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
                             OC_LOW_QOS, &cbdata, NULL, 0);
+#endif
     }
 
     OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)