iotivity_lib multithreading fixes for PolicyClient and ReportClient classes.
authorLomtev Dmytro <d.lomtev@samsung.com>
Thu, 1 Jun 2017 08:52:14 +0000 (11:52 +0300)
committerLomtev Dmytro <d.lomtev@samsung.com>
Thu, 1 Jun 2017 09:40:34 +0000 (12:40 +0300)
device_core/common/inc/network_manager_tag.h [new file with mode: 0644]
device_core/iotivity_lib/inc/policy_client.h
device_core/iotivity_lib/inc/report_client.h
device_core/iotivity_lib/inc/resource_callbacks.h [new file with mode: 0644]
device_core/iotivity_lib/src/policy_client.cpp
device_core/iotivity_lib/src/report_client.cpp
device_core/iotivity_lib/src/resource_callbacks.cpp [new file with mode: 0644]

diff --git a/device_core/common/inc/network_manager_tag.h b/device_core/common/inc/network_manager_tag.h
new file mode 100644 (file)
index 0000000..57cbecb
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef NETWORK_MANAGER_TAG_H
+#define NETWORK_MANAGER_TAG_H
+
+#ifndef TAG
+#   define TAG "NetworkManager"
+#endif
+
+#endif // NETWORK_MANAGER_TAG_H
index 8e8dcf6..4b0a196 100644 (file)
@@ -1,3 +1,12 @@
+/**
+ * @brief  Policy resource client
+ * @date   Created 18.05.2017
+ * @author Created 2017 in Samsung Ukraine R&D Center (SURC) under a contract
+ *         between LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
+ *         and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea).
+ *         Copyright: (c) Samsung Electronics Co, Ltd 2017. All rights reserved.
+ * @author Mail to: <A HREF="mailto:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
 #ifndef POLICY_CLIENT_H
 #define POLICY_CLIENT_H
 
@@ -15,12 +24,9 @@ namespace NetworkManager
  */
 class PolicyClient
 {
+    static const std::string POLICY_RESOURCE_TYPE;
     std::shared_ptr<OC::OCResource> resource;
-    std::mutex report_mutex;
-    std::condition_variable signal;
-    std::string policy;
-    bool fired;
-    OCStackResult lastResult;
+
 public:
     /**
      * @brief Constructor
index cb8c55e..ab1a3f5 100644 (file)
@@ -1,10 +1,17 @@
+/**
+ * @brief  Report resource client
+ * @date   Created 18.05.2017
+ * @author Created 2017 in Samsung Ukraine R&D Center (SURC) under a contract
+ *         between LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
+ *         and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea).
+ *         Copyright: (c) Samsung Electronics Co, Ltd 2017. All rights reserved.
+ * @author Mail to: <A HREF="mailto:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
 #ifndef REPORT_CLIENT_H
 #define REPORT_CLIENT_H
 
 #include <string>
 #include <memory>
-#include <mutex>
-#include <condition_variable>
 #include <OCApi.h>
 #include <OCPlatform.h>
 
@@ -15,11 +22,8 @@ namespace NetworkManager
  */
 class ReportClient
 {
+    static const std::string REPORT_RESOURCE_TYPE;
     std::shared_ptr<OC::OCResource> resource;
-    std::mutex report_mutex;
-    std::condition_variable signal;
-    std::string report;
-    bool fired;
 public:
     /**
      * @brief Constructor
@@ -44,12 +48,6 @@ public:
      * @param report [in] report in JSON format
      */
     void postReport(const std::string& report);
-private:
-    /**
-     * @brief foundResourceCb callback processing resource found events
-     * @param found_resource [in] found resource
-     */
-    void foundResourceCb(std::shared_ptr<OC::OCResource> found_resource);
 };
 
 } // namespace NetworkManager
diff --git a/device_core/iotivity_lib/inc/resource_callbacks.h b/device_core/iotivity_lib/inc/resource_callbacks.h
new file mode 100644 (file)
index 0000000..acbce1b
--- /dev/null
@@ -0,0 +1,113 @@
+/**
+ * @brief  Safe iotivity resource callbacks implementation
+ * @date   Created 01.06.2017
+ * @author Created 2017 in Samsung Ukraine R&D Center (SURC) under a contract
+ *         between LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
+ *         and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea).
+ *         Copyright: (c) Samsung Electronics Co, Ltd 2017. All rights reserved.
+ * @author Mail to: <A HREF="mailto:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
+#ifndef RESOURCE_CALLBACKS_H
+#define RESOURCE_CALLBACKS_H
+
+#include <mutex>
+#include <condition_variable>
+#include <memory>
+#include <OCApi.h>
+#include <OCPlatform.h>
+
+namespace NetworkManager
+{
+
+// Callback wait to finish default time
+const auto DEFAULT_TIMEOUT{std::chrono::seconds(3)};
+
+struct CallbackBase
+{
+    bool fired = false;
+    std::condition_variable signal;
+    std::mutex mtx;
+    std::unique_lock<std::mutex> lock;
+
+    CallbackBase() : mtx(), lock(mtx) {}
+
+    /**
+     * @brief signalize to those who waits for signal
+     */
+    void signalize()
+    {
+        fired = true;
+        signal.notify_one();
+    }
+
+    /**
+     * @brief wait for signal
+     * @return true if callback successfully completed or false if callback not called
+     */
+    bool wait()
+    {
+        signal.wait_for(lock, DEFAULT_TIMEOUT, [this] { return fired; });
+        return fired;
+    }
+};
+
+struct FindResourceCallback : public CallbackBase
+{
+    typedef std::shared_ptr<FindResourceCallback> Sptr;
+
+    std::shared_ptr<OC::OCResource> resource;
+    std::string search_type;
+
+    /**
+     * @brief FindResourceCallback constructor
+     * @param type [in] iotivity resource type to search for
+     */
+    FindResourceCallback(const std::string& type) : CallbackBase(), search_type(type) {}
+
+    /**
+     * @brief call - callback routine, called from iotivity framework
+     * @param ctx [in] this struct self weak reference
+     * @param found_resource [in] resource founded by iotivity
+     */
+    static void call(std::weak_ptr<FindResourceCallback> ctx, std::shared_ptr<OC::OCResource> found_resource);
+};
+
+struct PostResourceCallback : public CallbackBase
+{
+    typedef std::shared_ptr<PostResourceCallback> Sptr;
+
+    /**
+     * @brief call - callback routine, called from iotivity framework
+     * @param ctx [in] this struct self weak reference
+     * @param eCode [in] iotivity callback result code
+     */
+    static void call(std::weak_ptr<PostResourceCallback> ctx, const OC::HeaderOptions & /*ho*/, const OC::OCRepresentation& /*rep*/, const int eCode);
+};
+
+struct GetResourceCallback : public CallbackBase
+{
+    typedef std::shared_ptr<GetResourceCallback> Sptr;
+    OC::OCRepresentation representation;
+
+    /**
+     * @brief call - callback routine, called from iotivity framework
+     * @param ctx [in] this struct self weak reference
+     * @param eCode [in] iotivity callback result code
+     */
+    static void call(std::weak_ptr<GetResourceCallback> ctx, const OC::HeaderOptions & /*ho*/, const OC::OCRepresentation &rep, const int eCode);
+};
+
+/**
+ * @brief bind_callback - helper function to simplify callback binding
+ * @param ptr [in] weak reference to callback struct
+ * @param args [in] arguments to bind
+ */
+template<class Callback, typename... Params>
+auto bind_callback(std::shared_ptr<Callback> ptr, Params&&... args) -> decltype(std::bind(&Callback::call, std::weak_ptr<Callback>(ptr), args...))
+{
+    return std::bind(&Callback::call, std::weak_ptr<Callback>(ptr), args...);
+}
+
+} // namespace NetworkManager
+
+#endif // RESOURCE_CALLBACKS_H
index 9792cab..8581334 100644 (file)
@@ -1,9 +1,18 @@
-#if 1
+/**
+ * @brief  Policy resource client
+ * @date   Created 18.05.2017
+ * @author Created 2017 in Samsung Ukraine R&D Center (SURC) under a contract
+ *         between LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
+ *         and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea).
+ *         Copyright: (c) Samsung Electronics Co, Ltd 2017. All rights reserved.
+ * @author Mail to: <A HREF="mailto:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
 #include "policy_client.h"
 #include "logging.h"
 #include <functional>
 #include <chrono>
 #include "iotivity.h"
+#include "resource_callbacks.h"
 
 using namespace OC;
 
@@ -14,77 +23,17 @@ namespace PH = std::placeholders;
 namespace NetworkManager
 {
 
-struct FindPolicyCallback
-{
-    std::shared_ptr<OCResource> resource;
-    bool fired = false;
-    std::condition_variable signal;
-    std::mutex mtx;
-
-    void signalize()
-    {
-        fired = true;
-        signal.notify_one();
-    }
-
-    static void call(std::weak_ptr<FindPolicyCallback> ctx, std::shared_ptr<OCResource> found_resource)
-    {
-        if (auto p = ctx.lock())
-        {
-            std::unique_lock<std::mutex> lock(p->mtx);
-
-            if(!p->resource && found_resource)
-            {
-                for(auto &resource_type : found_resource->getResourceTypes())
-                {
-                    if(resource_type == "core.policy")
-                    {
-                        if (found_resource->connectivityType() & OCConnectivityType::CT_ADAPTER_TCP)
-                        {
-                            p->resource = found_resource;
-                            LOG_I(TAG, "Address of selected policy resource: %s", found_resource->host().c_str());
-                            p->signalize();
-                        }
-                    }
-                }
-            }
-        }
-    }
-};
-
-struct PostPolicyCallback
-{
-    bool fired = false;
-    std::condition_variable signal;
-    int ecode = 0;
-
-    void signalize()
-    {
-        fired = true;
-        signal.notify_one();
-    }
-
-    static void call(std::weak_ptr<PostPolicyCallback> ctx, const HeaderOptions& hopts, const OCRepresentation& rep, const int eCode)
-    {
-        if (auto p = ctx.lock())
-        {
-            LOG_I(TAG, "Post policy return code=%d", eCode);
-            p->ecode = eCode;
-            p->signalize();
-        }
-    }
-};
+const std::string PolicyClient::POLICY_RESOURCE_TYPE{"core.policy"};
 
 PolicyClient::PolicyClient(const std::string& host)
 {
     std::string requestURI{OC_RSRVD_WELL_KNOWN_URI};
-    std::shared_ptr<FindPolicyCallback> callback = std::make_shared<FindPolicyCallback>();
-    std::unique_lock<std::mutex> lock(callback->mtx);
-    OCPlatform::findResource(host, requestURI, CT_DEFAULT, std::bind(&FindPolicyCallback::call, std::weak_ptr<FindPolicyCallback>(callback), PH::_1));
-    callback->signal.wait_for(lock, std::chrono::seconds(3));
-    if (!callback->fired)
+    FindResourceCallback::Sptr callback = std::make_shared<FindResourceCallback>(POLICY_RESOURCE_TYPE);
+    OCPlatform::findResource(host, requestURI, CT_DEFAULT, bind_callback(callback, PH::_1));
+
+    if (!callback->wait())
     {
-        LOG_E(TAG, "PolicyClient found callback not called.");
+        LOG_E(TAG, "ReportClient found callback not called.");
     }
     else
     {
@@ -97,78 +46,31 @@ PolicyClient::operator bool() const
     return (bool)resource;
 }
 
-struct GetPolicyCallback
-{
-    std::string policy;
-    bool fired = false;
-    std::condition_variable signal;
-    std::mutex mtx;
-    int ecode = OC_STACK_OK;
-
-    void signalize()
-    {
-        fired = true;
-        signal.notify_one();
-    }
-
-    static void call(std::weak_ptr<GetPolicyCallback> ctx, const HeaderOptions& hopts, const OCRepresentation& rep, const int eCode)
-    {
-        if (auto p = ctx.lock())
-        {
-            std::unique_lock<std::mutex> lock(p->mtx);
-
-            try
-            {
-                if(eCode == OC_STACK_OK)
-                {
-                    rep.getValue("policy", p->policy);
-                }
-                else
-                {
-                    LOG_E(TAG, "Error (PolicyClient::getPolicy): code=%d", eCode);
-                    p->ecode = eCode;
-                }
-            }
-            catch(std::exception& e)
-            {
-                LOG_E(TAG, "Exception (PolicyClient::getPolicy): %s", e.what());
-            }
-
-            p->signalize();
-        }
-    }
-};
-
 std::string PolicyClient::getPolicy(const std::string& did, const std::string& agent)
 {
     LOG_I(TAG, "PolicyClient::getPolicy(%s, %s)", did.c_str(), agent.c_str());
+    std::string policy;
 
     if(resource)
     {
         QueryParamsMap query{{"did", did}, {"agent", agent}};
-        std::shared_ptr<GetPolicyCallback> callback = std::make_shared<GetPolicyCallback>();
-        std::unique_lock<std::mutex> lock(callback->mtx);
+        GetResourceCallback::Sptr callback = std::make_shared<GetResourceCallback>();
 
-        auto result = resource->get(query, std::bind(&GetPolicyCallback::call, std::weak_ptr<GetPolicyCallback>(callback), PH::_1, PH::_2, PH::_3));
+        auto result = resource->get(query, bind_callback(callback, PH::_1, PH::_2, PH::_3));
 
         if (OC_STACK_OK != result)
         {
             throw IoTInternalError("PolicyClient::getPolicy error", result);
         }
 
-        callback->signal.wait_for(lock, std::chrono::seconds(3), [&callback] { return callback->fired; });
-
-        if (!callback->fired)
+        if (!callback->wait())
         {
             throw IoTInternalError("PolicyClient::getPolicy callback not called", EC_UNAUTHORIZED);
         }
-
-        if (callback->ecode !=OC_STACK_OK)
+        else
         {
-            throw IoTInternalError("PolicyClient::getPolicy callback error", callback->ecode);
+            callback->representation.getValue("policy", policy);
         }
-
-        policy = callback->policy;
     }
 
     return policy;
@@ -186,34 +88,23 @@ void PolicyClient::postPolicy(const std::string& did, const std::string& agent,
     repr.setValue("policy", policy);
 
     QueryParamsMap query{{"did", did}, {"agent", agent}};
+    PostResourceCallback::Sptr callback = std::make_shared<PostResourceCallback>();
 
-    std::shared_ptr<PostPolicyCallback> callback = std::make_shared<PostPolicyCallback>();
-    std::mutex mtx;
-    std::unique_lock<std::mutex> lock(mtx);
-
-    auto result = resource->post("core.policy",
+    auto result = resource->post(POLICY_RESOURCE_TYPE,
                                  DEFAULT_INTERFACE,
                                  repr,
                                  query,
-                                 std::bind(&PostPolicyCallback::call, std::weak_ptr<PostPolicyCallback>(callback), PH::_1, PH::_2, PH::_3));
+                                 bind_callback(callback, PH::_1, PH::_2, PH::_3));
 
     if (OC_STACK_OK != result)
     {
-        throw IoTInternalError("PolicyClient::postPolicy error", result);
+        throw IoTInternalError("PolicyClient::postPolicy", result);
     }
 
-    callback->signal.wait_for(lock, std::chrono::seconds(3), [&callback] { return callback->fired; });
-
-    if (!callback->fired)
+    if (!callback->wait())
     {
         throw IoTInternalError("PolicyClient::postPolicy callback not called", EC_UNAUTHORIZED);
     }
-    if (OC_STACK_OK != callback->ecode && OC_STACK_RESOURCE_CHANGED != callback->ecode)
-    {
-        throw IoTInternalError("PolicyClient::postPolicy callback error", callback->ecode);
-    }
 }
 
 } // namespace NetworkManager
-
-#endif
index 792260a..800eda4 100644 (file)
@@ -1,25 +1,45 @@
-
+/**
+ * @brief  Report resource client
+ * @date   Created 18.05.2017
+ * @author Created 2017 in Samsung Ukraine R&D Center (SURC) under a contract
+ *         between LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
+ *         and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea).
+ *         Copyright: (c) Samsung Electronics Co, Ltd 2017. All rights reserved.
+ * @author Mail to: <A HREF="mailto:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
 #include "report_client.h"
+#include "network_manager_tag.h"
 #include "logging.h"
 #include <functional>
 #include <chrono>
 #include "iotivity.h"
+#include "report_client.h"
+#include "resource_callbacks.h"
 
 using namespace OC;
 
 namespace PH = std::placeholders;
 
-#define TAG "NetworkManager"
-
 namespace NetworkManager
 {
 
+const std::string ReportClient::REPORT_RESOURCE_TYPE{"core.security"};
+
 ReportClient::ReportClient(const std::string& host)
 {
     std::string requestURI{OC_RSRVD_WELL_KNOWN_URI};
-    std::unique_lock<std::mutex> lock(report_mutex);
-    OCPlatform::findResource(host, requestURI, CT_DEFAULT, std::bind(&ReportClient::foundResourceCb, this, PH::_1));
-    signal.wait_for(lock, std::chrono::seconds(3));
+    FindResourceCallback::Sptr callback = std::make_shared<FindResourceCallback>(REPORT_RESOURCE_TYPE);
+
+    OCPlatform::findResource(host, requestURI, CT_DEFAULT, bind_callback(callback, PH::_1));
+
+    if (!callback->wait())
+    {
+        LOG_E(TAG, "ReportClient found callback not called.");
+    }
+    else
+    {
+        resource = callback->resource;
+    }
 }
 
 ReportClient::operator bool() const
@@ -30,45 +50,26 @@ ReportClient::operator bool() const
 std::string ReportClient::getReport(const QueryParamsMap& query)
 {
     std::string report;
-    std::unique_lock<std::mutex> lock(report_mutex);
 
     if(resource)
     {
-        fired = false;
-
-        auto result = resource->get(query, [this, &report](const HeaderOptions& hopts, const OCRepresentation& rep, const int eCode)
-            {
-                try
-                {
-                    if(eCode == OC_STACK_OK)
-                    {
-                        rep.getValue("report", report);
-                    }
-                    else
-                    {
-                        LOG_E(TAG, "Error (ReportClient::getReport): code=%d", eCode);
-                    }
-                }
-                catch(std::exception& e)
-                {
-                    LOG_E(TAG, "Exception (ReportClient::getReport): %s", e.what());
-                }
-
-                fired = true;
-                signal.notify_one();
-            });
+        GetResourceCallback::Sptr callback = std::make_shared<GetResourceCallback>();
+
+        auto result = resource->get(query, bind_callback(callback, PH::_1, PH::_2, PH::_3));
 
         if (OC_STACK_OK != result)
         {
             throw IoTInternalError("ReportClient::getReport error", result);
         }
 
-        signal.wait_for(lock, std::chrono::seconds(3), [this] { return fired; });
-
-        if (!fired)
+        if (!callback->wait())
         {
             throw IoTInternalError("ReportClient::getReport callback not called", EC_UNAUTHORIZED);
         }
+        else
+        {
+            callback->representation.getValue("report", report);
+        }
     }
 
     return report;
@@ -87,58 +88,23 @@ void ReportClient::postReport(const std::string& report)
 
     QueryParamsMap query{{"did", IoTivity::getInstance()->getDeviceID()}};
 
-    std::unique_lock<std::mutex> lock(report_mutex);
+    PostResourceCallback::Sptr callback = std::make_shared<PostResourceCallback>();
 
-    fired = false;
-    auto result = resource->post("core.security", DEFAULT_INTERFACE, repr, query,
-        [this] (const HeaderOptions & /*ho*/, const OCRepresentation &rep, const int eCode)
-        {
-            LOG_I(TAG, "post report return code=%d", eCode);
-            fired = true;
-            signal.notify_one();
-        }
-    );
+    auto result = resource->post(REPORT_RESOURCE_TYPE,
+                                 DEFAULT_INTERFACE,
+                                 repr,
+                                 query,
+                                 bind_callback(callback, PH::_1, PH::_2, PH::_3));
 
     if (OC_STACK_OK != result)
     {
         throw IoTInternalError("ReportClient::postReport error", result);
     }
 
-    signal.wait_for(lock, std::chrono::seconds(1), [this] { return fired; });
-
-    if (!fired)
+    if (!callback->wait())
     {
         throw IoTInternalError("ReportClient::postReport callback not called", EC_UNAUTHORIZED);
     }
 }
 
-void ReportClient::foundResourceCb(std::shared_ptr<OCResource> found_resource)
-{
-    try
-    {
-        std::unique_lock<std::mutex> lock(report_mutex);
-
-        if(!resource && found_resource)
-        {
-            for(auto &resource_type : found_resource->getResourceTypes())
-            {
-                if(resource_type == "core.security")
-                {
-                    if (found_resource->connectivityType() & OCConnectivityType::CT_ADAPTER_TCP)
-                    {
-                        resource = found_resource;
-                        LOG_I(TAG, "Address of selected report resource: %s", found_resource->host().c_str());
-                        signal.notify_one();
-                    }
-                }
-            }
-        }
-
-    }
-    catch(std::exception& e)
-    {
-        LOG_E(TAG, "Exception in foundResource: %s", e.what());
-    }
-}
-
 } // namespace NetworkManager
diff --git a/device_core/iotivity_lib/src/resource_callbacks.cpp b/device_core/iotivity_lib/src/resource_callbacks.cpp
new file mode 100644 (file)
index 0000000..a943620
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * @brief  Safe iotivity resource callbacks implementation
+ * @date   Created 01.06.2017
+ * @author Created 2017 in Samsung Ukraine R&D Center (SURC) under a contract
+ *         between LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
+ *         and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea).
+ *         Copyright: (c) Samsung Electronics Co, Ltd 2017. All rights reserved.
+ * @author Mail to: <A HREF="mailto:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
+#include "resource_callbacks.h"
+#include <chrono>
+#include <functional>
+#include <memory>
+#include "logging.h"
+#include "network_manager_tag.h"
+
+namespace NetworkManager
+{
+
+void FindResourceCallback::call(std::weak_ptr<FindResourceCallback> ctx, std::shared_ptr<OC::OCResource> found_resource)
+{
+    if (auto p = ctx.lock())
+    {
+        std::unique_lock<std::mutex> ilock(p->mtx);
+
+        if(!p->resource && found_resource && (found_resource->connectivityType() & OCConnectivityType::CT_ADAPTER_TCP))
+        {
+            for(auto &resource_type : found_resource->getResourceTypes())
+            {
+                if(resource_type == p->search_type)
+                {
+                    p->resource = found_resource;
+                    LOG_D(TAG, "Address of selected resource of type \"%s\" is %s", p->search_type.c_str(), found_resource->host().c_str());
+                    p->signalize();
+                }
+            }
+        }
+    }
+}
+
+void PostResourceCallback::call(std::weak_ptr<PostResourceCallback> ctx, const OC::HeaderOptions & /*ho*/, const OC::OCRepresentation& /*rep*/, const int eCode)
+{
+    if (auto p = ctx.lock())
+    {
+        LOG_D(TAG, "Post callback return code=%d", eCode);
+        p->signalize();
+    }
+}
+
+void GetResourceCallback::call(std::weak_ptr<GetResourceCallback> ctx, const OC::HeaderOptions & /*ho*/, const OC::OCRepresentation &rep, const int eCode)
+{
+    if (auto p = ctx.lock())
+    {
+        try
+        {
+            if(eCode == OC_STACK_OK)
+            {
+                p->representation = rep;
+            }
+            else
+            {
+                LOG_E(TAG, "GetCallback error: code=%d", eCode);
+            }
+        }
+        catch(std::exception& e)
+        {
+            LOG_E(TAG, "GetCallback exception: %s", e.what());
+        }
+        p->signalize();
+    }
+}
+
+} // namespace NetworkManager
+