Fixed: resources searched againt when connection lost and reestablished.
authorLomtev Dmytro <d.lomtev@samsung.com>
Thu, 6 Jul 2017 12:15:33 +0000 (15:15 +0300)
committerLomtev Dmytro <d.lomtev@samsung.com>
Thu, 6 Jul 2017 12:28:05 +0000 (15:28 +0300)
15 files changed:
device_core/agent_lib/rmi/src/rmi/service.cpp
device_core/ctrl_app_lib/src/hub_client.cpp
device_core/ctrl_app_lib/src/policy_client.cpp
device_core/ctrl_app_lib/src/report_client.cpp
device_core/ctrl_app_lib/src/securitycontext.cpp
device_core/iotivity_lib/inc/resource_callbacks.h
device_core/iotivity_lib/src/IOT_Resource.cpp
device_core/iotivity_lib/src/iotivity.cpp
device_core/iotivity_lib/src/resource_callbacks.cpp
device_core/nmdaemon/agentpolicyservice.cpp
device_core/nmdaemon/agentpolicyservice.h
device_core/nmdaemon/main.cpp
device_core/nmdaemon/main_thread.cpp
device_core/nmdaemon/policyhandler.cpp
device_core/nmdaemon/reporthandler.cpp

index 01fb49d..42f8e59 100644 (file)
@@ -55,6 +55,7 @@ void Service::start()
 
 void Service::stop()
 {
+    mainloop.stop();
 }
 
 Service::ConnectionRegistry::iterator Service::getConnectionIterator(const int id)
index 52632d2..aafca7b 100644 (file)
@@ -71,10 +71,13 @@ void HubClient::getPrimitiveDevices(const OC::QueryParamsMap& query, IoTDevicesM
         {
             throw IoTInternalError("HubClient::getPrimitiveDevices callback not called", EC_UNAUTHORIZED);
         }
-        else
+
+        if (callback->errorCode > OC_STACK_RESOURCE_CHANGED)
         {
-            callback->representation.getValue("devices", devices);
+            throw IoTInternalError("HubClient::getPrimitiveDevices error", callback->errorCode);
         }
+
+        callback->representation.getValue("devices", devices);
     }
 
     Json::Reader reader;
index 9fa2936..4830b37 100644 (file)
@@ -69,10 +69,13 @@ std::string PolicyClient::getPolicy(OC::QueryParamsMap& route, const std::string
         {
             throw IoTInternalError("PolicyClient::getPolicy callback not called", EC_UNAUTHORIZED);
         }
-        else
+
+        if (callback->errorCode > OC_STACK_RESOURCE_CHANGED)
         {
-            callback->representation.getValue("policy", policy);
+            throw IoTInternalError("PolicyClient::getPolicy callback error", callback->errorCode);
         }
+
+        callback->representation.getValue("policy", policy);
     }
 
     return policy;
@@ -107,6 +110,11 @@ void PolicyClient::postPolicy(OC::QueryParamsMap& route, const std::string& agen
     {
         throw IoTInternalError("PolicyClient::postPolicy callback not called", EC_UNAUTHORIZED);
     }
+
+    if (callback->errorCode > OC_STACK_RESOURCE_CHANGED)
+    {
+        throw IoTInternalError("PolicyClient::postPolicy callback error", callback->errorCode);
+    }
 }
 
 } // namespace NetworkManager
index 177c8ca..4930ae2 100644 (file)
@@ -68,10 +68,13 @@ std::string ReportClient::getReport(const QueryParamsMap& query)
         {
             throw IoTInternalError("ReportClient::getReport callback not called", EC_UNAUTHORIZED);
         }
-        else
+
+        if (callback->errorCode > OC_STACK_RESOURCE_CHANGED)
         {
-            callback->representation.getValue("report", report);
+            throw IoTInternalError("ReportClient::getReport callback error", callback->errorCode);
         }
+
+        callback->representation.getValue("report", report);
     }
 
     return report;
@@ -107,6 +110,11 @@ void ReportClient::postReport(const std::string& report)
     {
         throw IoTInternalError("ReportClient::postReport callback not called", EC_UNAUTHORIZED);
     }
+
+    if (callback->errorCode > OC_STACK_RESOURCE_CHANGED)
+    {
+        throw IoTInternalError("ReportClient::postReport callback error", callback->errorCode);
+    }
 }
 
 } // namespace NetworkManager
index def2d54..ecc4300 100644 (file)
@@ -41,6 +41,9 @@ namespace
 const std::string NOTIF_FIND = "Notification findResource()";
 const std::string NOTIF_REQUEST = string(OC_RSRVD_WELL_KNOWN_URI) + "?rt=" + NetworkManager::NOTIFICATION_TYPE;
 
+/**
+ * @brief Check if resource client created and resource found
+ */
 template<class ResourceClass>
 void checkResource(std::shared_ptr<ResourceClass>& sptr, const std::string& host)
 {
@@ -59,6 +62,42 @@ void checkResource(std::shared_ptr<ResourceClass>& sptr, const std::string& host
     }
 }
 
+/**
+ * @brief Wrapper function to perform resource operations, if operation fails reource reseted.
+ */
+template<class Callable, class Obj, typename... Args>
+void callResourceWithResetNonReturn(Callable fn, std::shared_ptr<Obj>& obj, Args&&... params)
+{
+    try
+    {
+        (obj.get()->*fn)(std::forward<Args>(params)...);
+    }
+    catch(std::exception& e)
+    {
+        NetworkManager::IoTivity::getInstance()->signIn();
+        obj.reset();
+        throw e;
+    }
+}
+
+/**
+ * @brief Wrapper function to perform resource operations, if operation fails reource reseted.
+ */
+template<class Callable, class Obj, typename... Args>
+auto callResourceWithResetReturn(Callable fn, std::shared_ptr<Obj>& obj, Args&&... params) -> decltype((std::declval<Obj>().*fn)(params...))
+{
+    try
+    {
+        return (obj.get()->*fn)(std::forward<Args>(params)...);
+    }
+    catch(std::exception& e)
+    {
+        NetworkManager::IoTivity::getInstance()->signIn();
+        obj.reset();
+        throw e;
+    }
+}
+
 } // namespace
 
 namespace NetworkManager
@@ -116,11 +155,7 @@ const IoTDevicesMap& SecurityContext::getOwnedDevices()
 
         if (it != owned.end())
         {
-//            if (dev->getHost().compare(0, COAP_IF.length(), COAP_IF) == 0)
-            {
-                it->second = found_device;
-            }
-
+            it->second = found_device;
         }
         else
         {
@@ -141,6 +176,7 @@ const IoTDevicesMap& SecurityContext::getOwnedDevices()
     catch (std::exception& e)
     {
         hubClient.reset();
+        iotivity->signIn();
         LOG_E(TAG, "getOwnedDevices from Hub exception: %s", e.what());
     }
 
@@ -181,6 +217,7 @@ const IoTDevicesMap& SecurityContext::getUnOwnedDevices()
     catch (std::exception& e)
     {
         hubClient.reset();
+        iotivity->signIn();
         LOG_E(TAG, "getUnOwnedDevices from Hub exception: %s", e.what());
     }
 
@@ -306,14 +343,14 @@ std::string SecurityContext::getDeviceReport(const std::string& uuid)
     checkResource(reportClient, iotivity->host());
     QueryParamsMap qp{{"did", uuid}};
 
-    return reportClient->getReport(qp);
+    return callResourceWithResetReturn(&ReportClient::getReport, reportClient, qp);
 }
 
 void SecurityContext::postReport(const std::string& report)
 {
     FN_VISIT
     checkResource(reportClient, iotivity->host());
-    reportClient->postReport(report);
+    callResourceWithResetNonReturn(&ReportClient::postReport, reportClient, report);
 }
 
 std::string SecurityContext::getPolicy(const std::string& uuid, const std::string& agent)
@@ -323,7 +360,7 @@ std::string SecurityContext::getPolicy(const std::string& uuid, const std::strin
     auto it = getIoTDevice(uuid);
     auto route = it->getRouting();
 
-    return policyClient->getPolicy(route, agent);
+    return callResourceWithResetReturn(&PolicyClient::getPolicy, policyClient, route, agent);
 }
 
 void SecurityContext::postPolicy(const std::string& uuid, const std::string& policy)
@@ -332,8 +369,7 @@ void SecurityContext::postPolicy(const std::string& uuid, const std::string& pol
     checkResource(policyClient, iotivity->host());
     auto it = getIoTDevice(uuid);
     auto route = it->getRouting();
-
-    policyClient->postPolicy(route, "", policy);
+    callResourceWithResetNonReturn(&PolicyClient::postPolicy, policyClient, route, "", policy);
 }
 
 std::string SecurityContext::getAgentsList(const std::string& uuid)
@@ -343,7 +379,7 @@ std::string SecurityContext::getAgentsList(const std::string& uuid)
     auto it = getIoTDevice(uuid);
     auto route = it->getRouting();
 
-    return policyClient->getPolicy(route, "list");
+    return callResourceWithResetReturn(&PolicyClient::getPolicy, policyClient, route, "list");
 }
 
 IoTDevicePtr SecurityContext::getIoTDevice(const std::string& uuid)
index f3da899..75d29e5 100644 (file)
@@ -30,6 +30,7 @@ struct CallbackBase
     std::condition_variable signal;
     std::mutex mtx;
     std::unique_lock<std::mutex> lock;
+    int errorCode = OC_STACK_ERROR;
 
     CallbackBase() : mtx(), lock(mtx) {}
 
@@ -184,7 +185,6 @@ struct GetConfigurationStatusCallback : public CallbackBase
 struct ResourcePublishCallback : public CallbackBase
 {
     typedef std::shared_ptr<ResourcePublishCallback> Sptr;
-    int ecode;
 
     /**
      * @brief call - callback routine, called from iotivity framework
@@ -199,7 +199,6 @@ struct MqCreateTopicCallback : public CallbackBase
 {
     typedef std::shared_ptr<MqCreateTopicCallback> Sptr;
     std::shared_ptr<OC::OCResource> resource;
-    int errorCode = OC_STACK_ERROR;
 
     /**
      * @brief call - callback routine, called from iotivity framework
index d221077..30e99b2 100644 (file)
@@ -269,25 +269,26 @@ OCStackResult IOT_Resource::post(const std::shared_ptr<OC::OCResource> _resource
         std::unique_lock<std::mutex> lck(mtx);
         std::condition_variable cvar;
         bool fired = false;
-        res = _resource->post(  /*_type,
-                                _interface,*/
-                                _representation,
-                                _query_params,
-                                [&](const HeaderOptions&, const OCRepresentation & _rep, const int _ecode)
+        res = _resource->post(
+                _representation,
+                _query_params,
+                [&](const HeaderOptions&, const OCRepresentation & _rep, const int _ecode)
         {
-            if(_ecode != 4)
+            if(_ecode > 4)
+            {
+                // Fail codes have numbers bigger than 4
                 res = static_cast<OCStackResult>(_ecode);
+            }
+
             fired = true;
             cvar.notify_all();
-        }   );
+        });
+
         cvar.wait_for(lck, std::chrono::seconds(3), [&fired] { return fired; });
+
         if (!fired)
         {
-            std::cout << "Post timeout" << std::endl;
-        }
-        else
-        {
-            std::cout << "Post code " << res << std::endl;
+            res = OC_STACK_TIMEOUT;
         }
     }
 
index eab2a0a..ef4a01d 100644 (file)
@@ -86,8 +86,10 @@ void IoTivity::connectionChangedCallback(const std::string& conn, /*OCConnectivi
             if (!state)
             {
                 LOG_D(TAG, "Connection losts.");
-                instance->connected = false;
+//                instance->connected = false;
             }
+
+            instance->connected = state;
         }
     }
 }
@@ -174,7 +176,6 @@ std::vector<IoTDevicePtr> IoTivity::findDevices(bool cloud, OCConnectivityType c
     OC::OCPlatform::findResourceList(cloud ? cloud_host : "", uri, con_type, bind_callback(callback, PH::_1), OC::QualityOfService::HighQos);
     callback->wait_timeout(std::chrono::seconds(DEFAULT_TIMEOUT));
 
-
     return devices;
 }
 
@@ -499,9 +500,9 @@ void IoTivity::publishResources(OC::ResourceHandles& handles)
 
     bool ok = callback->wait();
 
-    if(!ok || callback->ecode > OC_STACK_RESOURCE_CHANGED)
+    if(!ok || callback->errorCode > OC_STACK_RESOURCE_CHANGED)
     {
-        throw IoTInternalError("Failed to publish resources", callback->ecode);
+        throw IoTInternalError("Failed to publish resources", callback->errorCode);
     }
 }
 
index 25c9e34..a2395db 100644 (file)
@@ -91,7 +91,6 @@ void PostResourceCallback::call(std::weak_ptr<PostResourceCallback> ctx,
     if (auto p = ctx.lock())
     {
         p->errorCode = errorCode;
-
         p->signalize();
     }
 }
@@ -102,6 +101,8 @@ void GetResourceCallback::call(std::weak_ptr<GetResourceCallback> ctx, const OC:
     {
         try
         {
+            p->errorCode = eCode;
+
             if(eCode == OC_STACK_OK)
             {
                 p->representation = rep;
@@ -132,7 +133,7 @@ void ResourcePublishCallback::call(std::weak_ptr<ResourcePublishCallback> ctx, c
 {
     if (auto p = ctx.lock())
     {
-        p->ecode = code;
+        p->errorCode = code;
         p->signalize();
     }
 }
index 42727c8..13733f4 100644 (file)
@@ -27,6 +27,11 @@ void AgentPolicyService::run()
     service->start();
 }
 
+void AgentPolicyService::stop()
+{
+    service->stop();
+}
+
 pid_t AgentPolicyService::getServicePid()
 {
     return getpid();
index efc2adb..93d586d 100644 (file)
@@ -54,6 +54,11 @@ public:
      */
     void run();
 
+    /**
+     * @brief stop method stop service
+     */
+    void stop();
+
 private:
     EnforcePolicyHandler m_enforcePolicyHandler;
     std::unique_ptr<rmi::Service> service;
index 4bfe31b..6b9dff1 100644 (file)
@@ -86,22 +86,21 @@ int main(int argc, char** argv)
         }
     }
 
-    std::cout << TAG "Running as ";
+    const char* mode = "unknown";
+
     switch (g_working_mode) {
     case WorkingMode::Standard:
-        std::cout << "standard";
+        mode = "standard";
         break;
     case WorkingMode::Hub:
-        std::cout << "hub";
+        mode = "hub";
         break;
     case WorkingMode::Primitive:
-        std::cout << "primitive";
-        break;
-    default:
-        std::cout << "unknown";
+        mode = "primitive";
         break;
     }
-    std::cout << " device" <<std::endl;
+
+    write_log(TAG "Running as %s device\n", mode);
 
     auto res = signal(SIGSEGV, sig_handler);
 
index 4e84897..e6a25fc 100644 (file)
@@ -221,6 +221,7 @@ void main_thread::routine()
             }
         }
 
+        agent_policy_service.stop();
 //        rmithread.stop();
 
     }
index dbb7544..531e620 100644 (file)
@@ -35,7 +35,7 @@ void PolicyHandler::pass(const OC::OCRepresentation& rep, const OC::QueryParamsM
 {
     if (!resource)
     {
-        std::cout << "[RMI_THREADS] Search for policy resource" << std::endl;
+        LOG_D(TAG, "[RMI_THREADS] Search for policy resource");
         findResource();
     }
 
@@ -81,13 +81,11 @@ void PolicyHandler::enforceCallback(const std::string& agentId, const std::strin
 
 bool PolicyHandler::findResource()
 {
-    try
-    {
-        resource = iotivity->findResource(iotivity->host(), POLICY_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, sid);
-    }
-    catch (std::exception& e)
+    resource = iotivity->findResource(iotivity->host(), POLICY_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, sid);
+
+    if (!resource)
     {
-        if (iotivity->isSignedIn())
+        if (iotivity->isConnected())
         {
 
             try
@@ -102,6 +100,27 @@ bool PolicyHandler::findResource()
         }
     }
 
+//    try
+//    {
+//        resource = iotivity->findResource(iotivity->host(), POLICY_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, sid);
+//    }
+//    catch (std::exception& e)
+//    {
+//        if (iotivity->isConnected())
+//        {
+
+//            try
+//            {
+//                iotivity->signIn();
+//                resource = iotivity->findResource(iotivity->host(), POLICY_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, sid);
+//            }
+//            catch(...)
+//            {
+
+//            }
+//        }
+//    }
+
     if(resource)
     {
         QueryParamsMap query{{"did", device_id}};
index 5d40d8e..b2a98c2 100644 (file)
@@ -35,14 +35,13 @@ void ReportHandler::pass(const OC::OCRepresentation& rep, const OC::QueryParamsM
 
 void ReportHandler::findResource()
 {
-    try
-    {
-        resource = iotivity->findResource(iotivity->host(), REPORT_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, server_id);
-    }
-    catch (std::exception& e)
+    resource = iotivity->findResource(iotivity->host(), REPORT_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, server_id);
+
+    if (!resource)
     {
-        if (iotivity->isSignedIn())
+        if (iotivity->isConnected())
         {
+            std::cout << "!!! Try to signIn" << std::endl;
             iotivity->signIn();
             try
             {
@@ -52,5 +51,33 @@ void ReportHandler::findResource()
             {
             }
         }
+        else
+        {
+            std::cout << "Not connected don't try to signIn" << std::endl;
+        }
     }
+
+//    try
+//    {
+//        resource = iotivity->findResource(iotivity->host(), REPORT_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, server_id);
+//    }
+//    catch (std::exception& e)
+//    {
+//        if (iotivity->isConnected())
+//        {
+//            std::cout << "!!! Try to signIn" << std::endl;
+//            iotivity->signIn();
+//            try
+//            {
+//                resource = iotivity->findResource(iotivity->host(), REPORT_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, server_id);
+//            }
+//            catch(...)
+//            {
+//            }
+//        }
+//        else
+//        {
+//            std::cout << "Not connected don't try to signIn" << std::endl;
+//        }
+//    }
 }