From: Lomtev Dmytro Date: Tue, 15 Aug 2017 08:54:36 +0000 (+0300) Subject: Changed: now multiple hubs can be connected to one account. Refactored: ResportHandle... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c027472b2069e92abe4d0f981a643d1911406a31;p=platform%2Fcore%2Fsecurity%2Fsuspicious-activity-monitor.git Changed: now multiple hubs can be connected to one account. Refactored: ResportHandler implementations moved to separate files. --- diff --git a/device_core/ctrl_app_lib/inc/hub_client.h b/device_core/ctrl_app_lib/inc/hub_client.h index edcdee5..075602f 100644 --- a/device_core/ctrl_app_lib/inc/hub_client.h +++ b/device_core/ctrl_app_lib/inc/hub_client.h @@ -27,6 +27,8 @@ class HubClient: public std::enable_shared_from_this public: static const std::string RESOURCE_TYPE; + typedef std::shared_ptr Ptr; + /** * @brief Constructor * @param host [in] IoT Cloud host address @@ -34,6 +36,21 @@ public: HubClient(const std::string& host); /** + * @brief Constructor + * @param hub_resource [in] resource tied wiith hub device + */ + HubClient(std::shared_ptr hub_resource) : resource(hub_resource) + { + } + + /** + * @brief Copy constructor + */ + HubClient(const HubClient& host) : resource(host.resource) + { + } + + /** * @brief true if resource found and false otherwise */ operator bool() const; diff --git a/device_core/ctrl_app_lib/inc/securitycontext.h b/device_core/ctrl_app_lib/inc/securitycontext.h index ac2fb87..4f1fd82 100644 --- a/device_core/ctrl_app_lib/inc/securitycontext.h +++ b/device_core/ctrl_app_lib/inc/securitycontext.h @@ -123,11 +123,7 @@ private: IoTDevicesMap unowned; PresenceHook presence_hook; std::mutex instance_mutex; - std::shared_ptr notificationResource; - std::shared_ptr reportClient; - std::shared_ptr policyClient; - std::shared_ptr hubClient; - std::mutex notificationMtx; + std::vector hubs; std::string dsm_address; std::string user_login; diff --git a/device_core/ctrl_app_lib/src/securitycontext.cpp b/device_core/ctrl_app_lib/src/securitycontext.cpp index e57b2a6..f5d2285 100644 --- a/device_core/ctrl_app_lib/src/securitycontext.cpp +++ b/device_core/ctrl_app_lib/src/securitycontext.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "nmlib.h" #include "report_client.h" #include "policy_client.h" @@ -42,63 +43,6 @@ const std::string NOTIF_FIND = "Notification findResource()"; const std::string NOTIF_REQUEST = string(OC_RSRVD_WELL_KNOWN_URI) + "?rt=" + NetworkManager::NOTIFICATION_TYPE; const std::string POLICY_TOPIC{"/srv/policy"}; -/** - * @brief Check if resource client created and resource found - */ -template -void checkResource(std::shared_ptr& sptr, const std::string& host) -{ - FN_VISIT - if (!sptr) - { - sptr = std::make_shared(host); - } - - if (!bool(*(sptr))) - { - std::string error = ResourceClass::RESOURCE_TYPE + " resource not found."; - LOG_E(TAG, "%s", error.c_str()); - sptr.reset(); - throw NetworkManager::IoTInternalError(error); - } -} - -/** - * @brief Wrapper function to perform resource operations, if operation fails reource reseted. - */ -template -void callResourceWithResetNonReturn(Callable fn, std::shared_ptr& obj, Args&&... params) -{ - try - { - (obj.get()->*fn)(std::forward(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 -auto callResourceWithResetReturn(Callable fn, std::shared_ptr& obj, Args&&... params) -> decltype((std::declval().*fn)(params...)) -{ - try - { - return (obj.get()->*fn)(std::forward(params)...); - } - catch(std::exception& e) - { - NetworkManager::IoTivity::getInstance()->signIn(); - obj.reset(); - throw e; - } -} - } // namespace namespace NetworkManager @@ -163,6 +107,14 @@ std::string SecurityContext::getAuthCode() const IoTDevicesMap& SecurityContext::getOwnedDevices() { FN_VISIT + auto hubs_finder = std::async( + std::launch::async, + &IoTivity::findResourceList, + iotivity, + true, + HubClient::RESOURCE_TYPE, + OC_RSRVD_WELL_KNOWN_URI, + CT_DEFAULT); RestService rest_service(dsm_address); owned = rest_service.getOwnedDevices(m_uid); @@ -192,12 +144,20 @@ const IoTDevicesMap& SecurityContext::getOwnedDevices() try { - checkResource(hubClient, iotivity->host()); - hubClient->getOwnedDevices(owned); + std::vector> hub_resources = hubs_finder.get(); + hubs.clear(); + for (auto hub_resource: hub_resources) + { + hubs.emplace_back(std::make_shared(hub_resource)); + } + + for (auto hub: hubs) + { + hub->getOwnedDevices(owned); + } } catch (std::exception& e) { - hubClient.reset(); iotivity->signIn(); LOG_E(TAG, "getOwnedDevices from Hub exception: %s", e.what()); } @@ -210,6 +170,15 @@ const IoTDevicesMap& SecurityContext::getUnOwnedDevices() FN_VISIT unowned.clear(); + auto hubs_finder = std::async( + std::launch::async, + &IoTivity::findResourceList, + iotivity, + true, + HubClient::RESOURCE_TYPE, + OC_RSRVD_WELL_KNOWN_URI, + CT_DEFAULT); + std::vector found_devices = iotivity->findDevices(false, CT_ADAPTER_IP); for (auto found_device : found_devices) @@ -232,13 +201,22 @@ const IoTDevicesMap& SecurityContext::getUnOwnedDevices() try { - LOG_D(TAG, "Request unowned devices from Hub"); - checkResource(hubClient, iotivity->host()); - hubClient->getUnownedDevices(unowned); + LOG_D(TAG, "Request unowned devices from Hubs"); + + std::vector> hub_resources = hubs_finder.get(); + hubs.clear(); + for (auto hub_resource: hub_resources) + { + hubs.emplace_back(std::make_shared(hub_resource)); + } + + for (auto hub: hubs) + { + hub->getUnownedDevices(unowned); + } } catch (std::exception& e) { - hubClient.reset(); iotivity->signIn(); LOG_E(TAG, "getUnOwnedDevices from Hub exception: %s", e.what()); } @@ -339,12 +317,6 @@ std::string SecurityContext::getDeviceReport(const std::string& uuid) RestService rest_service(dsm_address); return rest_service.getReports(uuid); - -// FN_VISIT -// checkResource(reportClient, iotivity->host()); -// QueryParamsMap qp{{"did", uuid}}; - -// return callResourceWithResetReturn(&ReportClient::getReport, reportClient, qp); } void SecurityContext::postReport(const std::string& report) @@ -367,18 +339,11 @@ std::string SecurityContext::getPolicy(const std::string& uuid, const std::strin } return rest_service.getPolicy(uuid, agent); -// FN_VISIT -// checkResource(policyClient, iotivity->host()); -// auto it = getIoTDevice(uuid); -// auto route = it->getRouting(); - -// return callResourceWithResetReturn(&PolicyClient::getPolicy, policyClient, route, agent); } void SecurityContext::postPolicy(const std::string& uuid, const std::string& policy) { FN_VISIT -// checkResource(policyClient, iotivity->host()); auto it = getIoTDevice(uuid); auto route = it->getRouting(); @@ -389,7 +354,6 @@ void SecurityContext::postPolicy(const std::string& uuid, const std::string& pol LOG_D(TAG, "Save policy for: %s with route %s", uuid.c_str(), route.c_str()); iotivity->getMqHandler()->publish(POLICY_TOPIC, repr); -// callResourceWithResetNonReturn(&PolicyClient::postPolicy, policyClient, route, "", policy); } std::string SecurityContext::getAgentsList(const std::string& uuid) @@ -404,13 +368,6 @@ std::string SecurityContext::getAgentsList(const std::string& uuid) RestService rest_service(dsm_address); return rest_service.getAgents(uuid); - -// FN_VISIT -// checkResource(policyClient, iotivity->host()); -// auto it = getIoTDevice(uuid); -// auto route = it->getRouting(); - -// return callResourceWithResetReturn(&PolicyClient::getPolicy, policyClient, route, "list"); } IoTDevicePtr SecurityContext::getIoTDevice(const std::string& uuid) diff --git a/device_core/iotivity_lib/inc/iotivity.h b/device_core/iotivity_lib/inc/iotivity.h index bcafa22..4f830c9 100644 --- a/device_core/iotivity_lib/inc/iotivity.h +++ b/device_core/iotivity_lib/inc/iotivity.h @@ -87,6 +87,11 @@ public: void signOut(); /** + * @brief delete device from IoTivity cloud + */ + void deleteFromAccount(); + + /** * @brief cleanUp free memory occupied by IoTivity singletone instance */ static void cleanUp(); diff --git a/device_core/iotivity_lib/inc/resource_callbacks.h b/device_core/iotivity_lib/inc/resource_callbacks.h index f339817..6c026c3 100644 --- a/device_core/iotivity_lib/inc/resource_callbacks.h +++ b/device_core/iotivity_lib/inc/resource_callbacks.h @@ -95,6 +95,7 @@ struct FindResourceListCallback : public CallbackBase std::vector>& resources; OCConnectivityType conn_type; + std::string type; /** * @brief FindResourceListCallback constructor @@ -103,8 +104,9 @@ struct FindResourceListCallback : public CallbackBase */ FindResourceListCallback( std::vector>& resources, - const OCConnectivityType ct = OCConnectivityType::CT_DEFAULT) - : CallbackBase(), resources(resources), conn_type(ct) {} + const OCConnectivityType ct = OCConnectivityType::CT_DEFAULT, + const std::string& type = "") + : CallbackBase(), resources(resources), conn_type(ct), type(type) {} /** * @brief call - callback routine, called from iotivity framework diff --git a/device_core/iotivity_lib/src/iotivity.cpp b/device_core/iotivity_lib/src/iotivity.cpp index de80934..88f18a2 100644 --- a/device_core/iotivity_lib/src/iotivity.cpp +++ b/device_core/iotivity_lib/src/iotivity.cpp @@ -208,7 +208,7 @@ std::shared_ptr IoTivity::findResource(bool cloud, const std::st std::vector> IoTivity::findResourceList(bool cloud, const std::string& type, const std::string& uri, OCConnectivityType con_type) { std::vector> resources; - FindResourceListCallback::Sptr callback = std::make_shared(resources, con_type); + FindResourceListCallback::Sptr callback = std::make_shared(resources, con_type, type); OCPlatform::findResourceList(cloud ? cloud_host : "", uri, con_type, bind_callback(callback, PH::_1)); callback->wait_timeout(); @@ -427,6 +427,50 @@ void IoTivity::signOut() guardPostErrorCode(signOutCb->resultCode, SIGNOUT); } +void IoTivity::deleteFromAccount() +{ + FN_VISIT + if (!signed_in) + { + return; + } + signed_in = false; + + if (cloud_host.empty() || cloud_access_token.empty()) + { + LOG_W(TAG, "SignOut without SignIn"); + return; + } + + if (!account_mgr) + throw IoTInternalError("No account manager", EC_IOTIVITY_ERROR); + + auto deleteMutex = std::make_shared(); + weak_ptr deleteMutexWptr(deleteMutex); + std::unique_lock lock(*deleteMutex); + std::condition_variable cv; + bool called = false; + int code = OC_STACK_ERROR; + + auto deleteCallback = [deleteMutexWptr, &cv, &called, &code] (const HeaderOptions&, const int ecode) { + if (auto mtx = deleteMutexWptr.lock()) + { + called = true; + code = ecode; + cv.notify_all(); + } + }; + + account_mgr->deleteDevice(cloud_access_token, getDeviceID(), deleteCallback); + + cv.wait_for(lock, std::chrono::seconds(DEFAULT_TIMEOUT), [&called] { return called; }); + + if (!called || code > OC_STACK_RESOURCE_CHANGED) + { + throw IoTInternalError("Failed to delete device from account", EC_IOTIVITY_ERROR); + } +} + void IoTivity::devicePresenceHandle( const HeaderOptions& hOptions, const OCRepresentation& rep, diff --git a/device_core/iotivity_lib/src/resource_callbacks.cpp b/device_core/iotivity_lib/src/resource_callbacks.cpp index 1606af6..2e8fc0a 100644 --- a/device_core/iotivity_lib/src/resource_callbacks.cpp +++ b/device_core/iotivity_lib/src/resource_callbacks.cpp @@ -51,6 +51,22 @@ void FindResourceListCallback::call(std::weak_ptr ctx, for (auto resource : found_resource) { + if (!p->type.empty()) + { + auto res_types = resource->getResourceTypes(); + bool found = false; + for (auto rt: res_types) + { + if (p->type == rt) + { + found = true; + break; + } + } + + if (!found) continue; + } + if (p->conn_type == CT_DEFAULT || (resource->connectivityType() & p->conn_type)) { p->resources.push_back(resource); diff --git a/device_core/nmdaemon/commandhandler.cpp b/device_core/nmdaemon/commandhandler.cpp index 2e870c3..5979bec 100644 --- a/device_core/nmdaemon/commandhandler.cpp +++ b/device_core/nmdaemon/commandhandler.cpp @@ -2,6 +2,9 @@ #include "registration_mq.h" #include "device_commands.h" #include "application_service.h" +#include "logging.h" + +#define TAG "nmdaemon" namespace NMD { @@ -14,6 +17,7 @@ CommandHandler::CommandHandler(NetworkManager::IoTivity* iotivity, WorkingMode wmode, ThreadBase* main_thread) : m_iotivity(iotivity) + , m_hub(hub) , m_report_handler(report_handler) , m_policy_handler(policy_handler) , m_proxy_thread(proxy_thread) @@ -76,16 +80,29 @@ void CommandHandler::unOwnTask() delete_config(); - if (g_working_mode == WorkingMode::Hub) + try + { + + if (g_working_mode == WorkingMode::Hub) + { + // disable hub to send found devices list + assert(m_hub); + m_hub->setEnabled(false); + clear_hub_cache(); + m_report_handler->disable(); + m_policy_handler->disable(); + m_iotivity->unPublishAllResources(); + m_hub->unownAll(); + } + + if (m_wmode != WorkingMode::Primitive) + { + m_iotivity->deleteFromAccount(); + } + } + catch (std::exception& e) { - // disable hub to send found devices list - assert(m_hub); - m_hub->setEnabled(false); - clear_hub_cache(); - m_report_handler->disable(); - m_policy_handler->disable(); - m_proxy_thread->addAction(std::async(std::launch::deferred, &NetworkManager::IoTivity::unPublishAllResources, m_iotivity)); - m_proxy_thread->addAction(std::async(std::launch::deferred, &HubResource::unownAll, m_hub.get())); + LOG_E(TAG, "Unpairing failed with exception: %s", e.what()); } m_main_thread->stop(); diff --git a/device_core/nmdaemon/hub_policy_resource.cpp b/device_core/nmdaemon/hub_policy_resource.cpp index 223074e..4dd27c1 100644 --- a/device_core/nmdaemon/hub_policy_resource.cpp +++ b/device_core/nmdaemon/hub_policy_resource.cpp @@ -207,7 +207,7 @@ void PolicyResource::observHandler(const HeaderOptions& /*head_options*/, const std::string policy; std::string value; - if (rep.getValue("did", value)) + if (rep.getValue("duid", value)) { did = value; } diff --git a/device_core/nmdaemon/main_thread.cpp b/device_core/nmdaemon/main_thread.cpp index 5c1b7d5..d6d0d8d 100644 --- a/device_core/nmdaemon/main_thread.cpp +++ b/device_core/nmdaemon/main_thread.cpp @@ -238,41 +238,4 @@ void MainThread::routine() g_running = false; } -void MainThread::unregister_proc(IoTivity* iotivity, - std::shared_ptr hub, - std::shared_ptr report_handler, - std::shared_ptr policy_handler, - std::shared_ptr notification_handler, - std::shared_ptr proxy_thread) -{ - assert(iotivity); - assert(report_handler); - assert(policy_handler); - assert(notification_handler); - assert(proxy_thread); - - // Device unregistration - if (g_working_mode != WorkingMode::Primitive) - { - RegistrationMQ::unreg(iotivity->getMqHandler(), iotivity->getDeviceID()); - } - - delete_config(); - - if (g_working_mode == WorkingMode::Hub) - { - // disable hub to send found devices list - assert(hub); - hub->setEnabled(false); - clear_hub_cache(); - report_handler->disable(); - policy_handler->disable(); - notification_handler->disable(); - proxy_thread->addAction(std::async(std::launch::deferred, &IoTivity::unPublishAllResources, iotivity)); - proxy_thread->addAction(std::async(std::launch::deferred, &HubResource::unownAll, hub.get())); - } - - this->stop(); -} - } // namespace NMD diff --git a/device_core/nmdaemon/main_thread.h b/device_core/nmdaemon/main_thread.h index 9b82675..7bf413e 100644 --- a/device_core/nmdaemon/main_thread.h +++ b/device_core/nmdaemon/main_thread.h @@ -37,13 +37,6 @@ public: virtual void routine(); - void unregister_proc(NetworkManager::IoTivity* iotivity, - std::shared_ptr hub, - std::shared_ptr report_handler, - std::shared_ptr policy_handler, - std::shared_ptr notification_handler, - std::shared_ptr proxy_thread); - private: std::string m_device_name; std::string m_device_model; diff --git a/device_core/nmdaemon/reporthandler.h b/device_core/nmdaemon/reporthandler.h index ac3b9b8..20e4a53 100644 --- a/device_core/nmdaemon/reporthandler.h +++ b/device_core/nmdaemon/reporthandler.h @@ -2,9 +2,6 @@ #define REPORTHANDLER_H #include -#include -#include "iotivity.h" -#include class ReportHandler { @@ -31,36 +28,4 @@ protected: bool disabled; }; -class ReportHandlerRes: public ReportHandler -{ -public: - /** - * @brief ReportHandlerRes constructor - * @param iotivity pointer to IoTivity instance - */ - ReportHandlerRes(const std::string& server_id = ""); - - void pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) override; - -private: - std::shared_ptr resource; - NetworkManager::IoTivity* iotivity; - std::string server_id; - void findResource(); - std::mutex handler_mutex; -}; - -class ReportHandlerMQ: public ReportHandler -{ -public: - void pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) override; - -private: - std::shared_ptr resource; - NetworkManager::IoTivity* iotivity; - std::string server_id; - void findResource(); - std::mutex handler_mutex; -}; - #endif // REPORTHANDLER_H diff --git a/device_core/nmdaemon/reporthandler.cpp b/device_core/nmdaemon/reporthandler_res.cpp similarity index 81% rename from device_core/nmdaemon/reporthandler.cpp rename to device_core/nmdaemon/reporthandler_res.cpp index 779e437..104f5a9 100644 --- a/device_core/nmdaemon/reporthandler.cpp +++ b/device_core/nmdaemon/reporthandler_res.cpp @@ -1,8 +1,6 @@ -#include "reporthandler.h" -#include #include "logging.h" #include "iot_resource.h" -#include "OCPlatform.h" +#include "reporthandler_res.h" #define TAG "nmdaemon" @@ -14,8 +12,7 @@ namespace const std::string REPORT_RESOURCE_TYPE{"core.security"}; } -ReportHandlerRes::ReportHandlerRes(const std::string& server_id) - : server_id(server_id) +ReportHandlerRes::ReportHandlerRes(const std::string& server_id) : server_id(server_id) { iotivity = NetworkManager::IoTivity::getInstance(); } @@ -64,7 +61,3 @@ void ReportHandlerRes::findResource() } } -void ReportHandlerMQ::pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) { - if (disabled) return; - NetworkManager::IoTivity::getInstance()->getMqHandler()->publish("/srv/report", rep); -} diff --git a/device_core/nmdaemon/reporthandler_res.h b/device_core/nmdaemon/reporthandler_res.h new file mode 100644 index 0000000..aad5938 --- /dev/null +++ b/device_core/nmdaemon/reporthandler_res.h @@ -0,0 +1,29 @@ +#ifndef REPORTHANDLERRES_H +#define REPORTHANDLERRES_H + +#include +#include "iotivity.h" +#include "reporthandler.h" + +class ReportHandlerRes: public ReportHandler +{ +public: + /** + * @brief ReportHandlerRes constructor + * @param iotivity pointer to IoTivity instance + */ + ReportHandlerRes(const std::string& server_id = ""); + + void pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) override; + +private: + + void findResource(); + + std::shared_ptr resource; + NetworkManager::IoTivity* iotivity; + std::string server_id; + std::mutex handler_mutex; +}; + +#endif // REPORTHANDLERRES_H diff --git a/device_core/nmdaemon/reporthandlerfactory.cpp b/device_core/nmdaemon/reporthandlerfactory.cpp index 5f2ff88..87796bc 100644 --- a/device_core/nmdaemon/reporthandlerfactory.cpp +++ b/device_core/nmdaemon/reporthandlerfactory.cpp @@ -1,4 +1,6 @@ #include "reporthandler.h" +#include "reporthandler_res.h" +#include "reporthandlermq.h" #include "reporthandlerfactory.h" std::shared_ptr ReportHandlerFactory::createWithResource(const std::string& sid) diff --git a/device_core/nmdaemon/reporthandlermq.cpp b/device_core/nmdaemon/reporthandlermq.cpp new file mode 100644 index 0000000..990aba7 --- /dev/null +++ b/device_core/nmdaemon/reporthandlermq.cpp @@ -0,0 +1,15 @@ +#include "reporthandlermq.h" +#include "logging.h" + +#define TAG "nmdaemon" + +namespace +{ +const std::string POST_REPORT_MQ{"/srv/report"}; +} + +void ReportHandlerMQ::pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& /*params*/) { + if (disabled) return; + + NetworkManager::IoTivity::getInstance()->getMqHandler()->publish(POST_REPORT_MQ, rep); +} diff --git a/device_core/nmdaemon/reporthandlermq.h b/device_core/nmdaemon/reporthandlermq.h new file mode 100644 index 0000000..2b0ac96 --- /dev/null +++ b/device_core/nmdaemon/reporthandlermq.h @@ -0,0 +1,23 @@ +#ifndef REPORTHANDLERMQ_H +#define REPORTHANDLERMQ_H + +#include +#include "iotivity.h" +#include "reporthandler.h" + +class ReportHandlerMQ: public ReportHandler +{ +public: + void pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) override; + +private: + + void findResource(); + + OC::OCResource::Ptr resource; + NetworkManager::IoTivity* iotivity; + std::string server_id; + std::mutex handler_mutex; +}; + +#endif // REPORTHANDLERMQ_H