Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / resource / src / InProcClientWrapper.cpp
index 83e4ef8..84a8f93 100644 (file)
@@ -96,16 +96,31 @@ namespace OC
     {
         if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
         {
-            throw OCException(OC::Exception::STR_NULL_RESPONSE, OC_STACK_ERROR);
+            return OCRepresentation();
         }
 
         MessageContainer oc;
-        oc.setJSONRepresentation(clientResponse->resJSONPayload);
+        try
+        {
+            oc.setJSONRepresentation(clientResponse->resJSONPayload);
+        }
+        catch (cereal::RapidJSONException& ex)
+        {
+            oclog() <<"RapidJSON Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
+                "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
+            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
+        }
+        catch (cereal::Exception& ex)
+        {
+            oclog() <<"Cereal Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
+                "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
+            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
+        }
 
         std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
         if(it == oc.representations().end())
         {
-            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_ERROR);
+            return OCRepresentation();
         }
 
         // first one is considered the root, everything else is considered a child of this one.
@@ -148,9 +163,9 @@ namespace OC
 
         try
         {
-            ListenOCContainer container(clientWrapper, *clientResponse->addr,
-                    requestStream);
 
+            ListenOCContainer container(clientWrapper, *clientResponse->addr,
+                    clientResponse->connType, requestStream);
             // loop to ensure valid construction of all resources
             for(auto resource : container.Resources())
             {
@@ -163,7 +178,9 @@ 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;
@@ -173,8 +190,14 @@ namespace OC
     }
 
     OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
-        const std::string& resourceType, FindCallback& callback, QualityOfService QoS)
+        const std::string& resourceType, OCConnectivityType connectivityType,
+        FindCallback& callback, QualityOfService QoS)
     {
+        if(!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
+
         OCStackResult result;
 
         OCCallbackData cbdata = {0};
@@ -191,13 +214,12 @@ namespace OC
         if(cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            OCDoHandle handle;
-            result = OCDoResource(&handle, OC_REST_GET,
+            result = OCDoResource(nullptr, OC_REST_GET,
                                   resourceType.c_str(),
-                                  nullptr, nullptr,
+                                  nullptr, nullptr, connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
-                                  NULL, 0);
+                                  nullptr, 0);
         }
         else
         {
@@ -213,25 +235,36 @@ namespace OC
         ClientCallbackContext::DeviceListenContext* context =
             static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
 
-        OCRepresentation rep = parseGetSetCallback(clientResponse);
-        std::thread exec(context->callback, rep);
-        exec.detach();
+        try
+        {
+            OCRepresentation rep = parseGetSetCallback(clientResponse);
+            std::thread exec(context->callback, rep);
+            exec.detach();
+        }
+        catch(OC::OCException& e)
+        {
+            oclog() <<"Exception in listenDeviceCallback, ignoring response: "
+                <<e.what() <<std::flush;
+        }
 
         return OC_STACK_KEEP_TRANSACTION;
     }
 
     OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
-        const std::string& deviceURI, FindDeviceCallback& callback, QualityOfService QoS)
+        const std::string& deviceURI, OCConnectivityType connectivityType,
+        FindDeviceCallback& callback, QualityOfService QoS)
     {
+        if(!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
         OCStackResult result;
 
         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);};
@@ -240,16 +273,16 @@ namespace OC
         if(cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            OCDoHandle handle;
-            result = OCDoResource(&handle, OC_REST_GET,
+            result = OCDoResource(nullptr, OC_REST_GET,
                                   deviceURI.c_str(),
-                                  nullptr, nullptr,
+                                  nullptr, nullptr, connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
-                                  NULL, 0);
+                                  nullptr, 0);
         }
         else
         {
+            delete context;
             result = OC_STACK_ERROR;
         }
         return result;
@@ -289,22 +322,34 @@ namespace OC
 
         OCRepresentation rep;
         HeaderOptions serverHeaderOptions;
-        if(clientResponse->result == OC_STACK_OK)
+        OCStackResult result = clientResponse->result;
+        if(result == OC_STACK_OK)
         {
             parseServerHeaderOptions(clientResponse, serverHeaderOptions);
-            rep = parseGetSetCallback(clientResponse);
+            try
+            {
+                rep = parseGetSetCallback(clientResponse);
+            }
+            catch(OC::OCException& e)
+            {
+                result = e.code();
+            }
         }
 
-        std::thread exec(context->callback, serverHeaderOptions, rep, clientResponse->result);
+        std::thread exec(context->callback, serverHeaderOptions, rep, result);
         exec.detach();
         return OC_STACK_DELETE_TRANSACTION;
     }
 
     OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
-        const std::string& uri, const QueryParamsMap& queryParams,
-        const HeaderOptions& headerOptions, GetCallback& callback,
-        QualityOfService QoS)
+        const std::string& uri, OCConnectivityType connectivityType,
+        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+        GetCallback& callback, QualityOfService QoS)
     {
+        if(!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
         OCStackResult result;
         OCCallbackData cbdata = {0};
 
@@ -322,15 +367,14 @@ namespace OC
             os << host << assembleSetResourceUri(uri, queryParams).c_str();
 
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            OCDoHandle handle;
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
-            assembleHeaderOptions(options, headerOptions);
-            result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
-                                  nullptr, nullptr,
+            result = OCDoResource(nullptr, OC_REST_GET, os.str().c_str(),
+                                  nullptr, nullptr, connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
-                                  options, headerOptions.size());
+                                  assembleHeaderOptions(options, headerOptions),
+                                  headerOptions.size());
         }
         else
         {
@@ -349,15 +393,23 @@ namespace OC
         OCRepresentation attrs;
         HeaderOptions serverHeaderOptions;
 
-        if (OC_STACK_OK               == clientResponse->result ||
-            OC_STACK_RESOURCE_CREATED == clientResponse->result ||
-            OC_STACK_RESOURCE_DELETED == clientResponse->result)
+        OCStackResult result = clientResponse->result;
+        if (OC_STACK_OK               == result ||
+            OC_STACK_RESOURCE_CREATED == result ||
+            OC_STACK_RESOURCE_DELETED == result)
         {
             parseServerHeaderOptions(clientResponse, serverHeaderOptions);
-            attrs = parseGetSetCallback(clientResponse);
+            try
+            {
+                attrs = parseGetSetCallback(clientResponse);
+            }
+            catch(OC::OCException& e)
+            {
+                result = e.code();
+            }
         }
 
-        std::thread exec(context->callback, serverHeaderOptions, attrs, clientResponse->result);
+        std::thread exec(context->callback, serverHeaderOptions, attrs, result);
         exec.detach();
         return OC_STACK_DELETE_TRANSACTION;
     }
@@ -399,10 +451,14 @@ namespace OC
     }
 
     OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
-        const std::string& uri, const OCRepresentation& rep,
+        const std::string& uri, OCConnectivityType connectivityType, const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PostCallback& callback, QualityOfService QoS)
     {
+        if(!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
         OCStackResult result;
         OCCallbackData cbdata = {0};
 
@@ -423,14 +479,14 @@ namespace OC
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
-            OCDoHandle handle;
 
-            assembleHeaderOptions(options, headerOptions);
-            result = OCDoResource(&handle, OC_REST_POST,
+            result = OCDoResource(nullptr, OC_REST_POST,
                                   os.str().c_str(), nullptr,
-                                  assembleSetResourcePayload(rep).c_str(),
+                                  assembleSetResourcePayload(rep).c_str(), connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
-                                  &cbdata, options, headerOptions.size());
+                                  &cbdata,
+                                  assembleHeaderOptions(options, headerOptions),
+                                  headerOptions.size());
         }
         else
         {
@@ -441,12 +497,15 @@ namespace OC
         return result;
     }
 
-
     OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
-        const std::string& uri, const OCRepresentation& rep,
+        const std::string& uri, OCConnectivityType connectivityType, const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PutCallback& callback, QualityOfService QoS)
     {
+        if(!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
         OCStackResult result;
         OCCallbackData cbdata = {0};
 
@@ -469,13 +528,13 @@ namespace OC
             OCDoHandle handle;
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
-            assembleHeaderOptions(options, headerOptions);
             result = OCDoResource(&handle, OC_REST_PUT,
                                   os.str().c_str(), nullptr,
-                                  assembleSetResourcePayload(rep).c_str(),
+                                  assembleSetResourcePayload(rep).c_str(), connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
-                                  options, headerOptions.size());
+                                  assembleHeaderOptions(options, headerOptions),
+                                  headerOptions.size());
         }
         else
         {
@@ -503,9 +562,13 @@ namespace OC
     }
 
     OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
-        const std::string& uri, const HeaderOptions& headerOptions,
-         DeleteCallback& callback, QualityOfService QoS)
+        const std::string& uri, OCConnectivityType connectivityType,
+        const HeaderOptions& headerOptions, DeleteCallback& callback, QualityOfService QoS)
     {
+        if(!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
         OCStackResult result;
         OCCallbackData cbdata = {0};
 
@@ -523,16 +586,16 @@ namespace OC
         if(cLock)
         {
             OCHeaderOption options[MAX_HEADER_OPTIONS];
-            OCDoHandle handle;
-
-            assembleHeaderOptions(options, headerOptions);
 
             std::lock_guard<std::recursive_mutex> lock(*cLock);
 
-            result = OCDoResource(&handle, OC_REST_DELETE,
+            result = OCDoResource(nullptr, OC_REST_DELETE,
                                   os.str().c_str(), nullptr,
-                                  nullptr, static_cast<OCQualityOfService>(m_cfg.QoS),
-                                  &cbdata, options, headerOptions.size());
+                                  nullptr, connectivityType,
+                                  static_cast<OCQualityOfService>(m_cfg.QoS),
+                                  &cbdata,
+                                  assembleHeaderOptions(options, headerOptions),
+                                  headerOptions.size());
         }
         else
         {
@@ -551,22 +614,38 @@ namespace OC
         OCRepresentation attrs;
         HeaderOptions serverHeaderOptions;
         uint32_t sequenceNumber = clientResponse->sequenceNumber;
-
+        OCStackResult result = clientResponse->result;
         if(clientResponse->result == OC_STACK_OK)
         {
             parseServerHeaderOptions(clientResponse, serverHeaderOptions);
-            attrs = parseGetSetCallback(clientResponse);
+            try
+            {
+                attrs = parseGetSetCallback(clientResponse);
+            }
+            catch(OC::OCException& e)
+            {
+                result = e.code();
+            }
         }
         std::thread exec(context->callback, serverHeaderOptions, attrs,
-                    clientResponse->result, sequenceNumber);
+                    result, sequenceNumber);
         exec.detach();
+        if(sequenceNumber == OC_OBSERVE_DEREGISTER)
+        {
+            return OC_STACK_DELETE_TRANSACTION;
+        }
         return OC_STACK_KEEP_TRANSACTION;
     }
 
     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)
+        const std::string& host, const std::string& uri, OCConnectivityType connectivityType,
+        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+        ObserveCallback& callback, QualityOfService QoS)
     {
+        if(!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
         OCStackResult result;
         OCCallbackData cbdata = {0};
 
@@ -600,13 +679,13 @@ namespace OC
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
-            assembleHeaderOptions(options, headerOptions);
             result = OCDoResource(handle, method,
                                   os.str().c_str(), nullptr,
-                                  nullptr,
+                                  nullptr, connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
-                                  options, headerOptions.size());
+                                  assembleHeaderOptions(options, headerOptions),
+                                  headerOptions.size());
         }
         else
         {
@@ -629,8 +708,9 @@ namespace OC
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
-            assembleHeaderOptions(options, headerOptions);
-            result = OCCancel(handle, static_cast<OCQualityOfService>(QoS), options,
+            result = OCCancel(handle,
+                    static_cast<OCQualityOfService>(QoS),
+                    assembleHeaderOptions(options, headerOptions),
                     headerOptions.size());
         }
         else
@@ -644,14 +724,18 @@ namespace OC
     OCStackApplicationResult subscribePresenceCallback(void* ctx, OCDoHandle handle,
             OCClientResponse* clientResponse)
     {
-        char stringAddress[DEV_ADDR_SIZE_MAX];
         ostringstream os;
         uint16_t port;
+        uint8_t a;
+        uint8_t b;
+        uint8_t c;
+        uint8_t d;
 
-        if(OCDevAddrToString(clientResponse->addr, stringAddress) == 0 &&
+        if(OCDevAddrToIPv4Addr(clientResponse->addr, &a, &b, &c, &d) == 0 &&
                 OCDevAddrToPort(clientResponse->addr, &port) == 0)
         {
-            os<<stringAddress<<":"<<port;
+            os<<static_cast<int>(a)<<"."<<static_cast<int>(b)<<"."<<static_cast<int>(c)
+                    <<"."<<static_cast<int>(d)<<":"<<static_cast<int>(port);
 
             ClientCallbackContext::SubscribePresenceContext* context =
                 static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
@@ -663,7 +747,7 @@ namespace OC
         }
         else
         {
-            oclog() << "subscribePresenceCallback(): OCDevAddrToString() or OCDevAddrToPort() "
+            oclog() << "subscribePresenceCallback(): OCDevAddrToIPv4Addr() or OCDevAddrToPort() "
                     <<"failed"<< std::flush;
         }
         return OC_STACK_KEEP_TRANSACTION;
@@ -671,8 +755,12 @@ namespace OC
 
     OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
         const std::string& host, const std::string& resourceType,
-        SubscribeCallback& presenceHandler)
+        OCConnectivityType connectivityType, SubscribeCallback& presenceHandler)
     {
+        if(!presenceHandler)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
         OCCallbackData cbdata = {0};
 
         ClientCallbackContext::SubscribePresenceContext* ctx =
@@ -685,7 +773,7 @@ namespace OC
         auto cLock = m_csdkLock.lock();
 
         std::ostringstream os;
-        os << host << "/oc/presence";
+        os << host << OC_PRESENCE_URI;
 
         if(!resourceType.empty())
         {
@@ -699,7 +787,7 @@ namespace OC
         }
 
         return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
-                            OC_LOW_QOS, &cbdata, NULL, 0);
+                            connectivityType, OC_LOW_QOS, &cbdata, NULL, 0);
     }
 
     OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
@@ -726,11 +814,16 @@ namespace OC
         return OC_STACK_OK;
     }
 
-    void InProcClientWrapper::assembleHeaderOptions(OCHeaderOption options[],
+    OCHeaderOption* InProcClientWrapper::assembleHeaderOptions(OCHeaderOption options[],
            const HeaderOptions& headerOptions)
     {
         int i = 0;
 
+        if( headerOptions.size() == 0)
+        {
+            return nullptr;
+        }
+
         for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
         {
             options[i].protocolID = OC_COAP_ID;
@@ -740,5 +833,7 @@ namespace OC
                     (it->getOptionData()).length() + 1);
             i++;
         }
+
+        return options;
     }
 }