From 0749b9bdfb5f2bfbbbd7d5b122eaf3941ed64af0 Mon Sep 17 00:00:00 2001 From: G S Senthil Kumar Date: Tue, 11 Aug 2015 19:06:07 +0530 Subject: [PATCH] Implementation of APIs for managing resource list and callback implementation for attribute update automation feature. 1. Updated linux sample for testing the new APIs. 2. Implemented multi-resource creation and deletion APIs. 3. Added callback feature in automation module to notify the completion of automation to application. Change-Id: I8eb460d2a3d54b6156bdff6d2851d38299a72020 Signed-off-by: G S Senthil Kumar Reviewed-on: https://gerrit.iotivity.org/gerrit/2136 Tested-by: jenkins-iotivity Reviewed-by: Madan Lanka --- .../simulator/examples/server/service_provider.cpp | 147 ++++++++- service/simulator/inc/simulator_manager.h | 23 +- service/simulator/src/resource_manager.cpp | 179 ++++++++--- service/simulator/src/resource_manager.h | 29 +- .../src/simulator_attribute_automation.cpp | 125 ++++++-- .../simulator/src/simulator_attribute_automation.h | 40 ++- service/simulator/src/simulator_manager.cpp | 16 +- service/simulator/src/simulator_resource.cpp | 263 --------------- .../simulator/src/simulator_resource_creator.cpp | 10 +- service/simulator/src/simulator_resource_creator.h | 4 +- service/simulator/src/simulator_resource_model.cpp | 107 +++---- service/simulator/src/simulator_resource_model.h | 28 +- .../simulator/src/simulator_resource_server.cpp | 354 +++++++++++++++++++++ ...ator_resource.h => simulator_resource_server.h} | 73 +++-- 14 files changed, 906 insertions(+), 492 deletions(-) delete mode 100644 service/simulator/src/simulator_resource.cpp create mode 100644 service/simulator/src/simulator_resource_server.cpp rename service/simulator/src/{simulator_resource.h => simulator_resource_server.h} (81%) diff --git a/service/simulator/examples/server/service_provider.cpp b/service/simulator/examples/server/service_provider.cpp index 8f634ca..a15ce05 100644 --- a/service/simulator/examples/server/service_provider.cpp +++ b/service/simulator/examples/server/service_provider.cpp @@ -123,9 +123,9 @@ class SimLightResource void simulateResource() { - SimulatorResource::ResourceModelChangedCB callback = std::bind( + SimulatorResourceServer::ResourceModelChangedCB callback = std::bind( &SimLightResource::onResourceModelChanged, this, std::placeholders::_1, std::placeholders::_2); - SimulatorResourcePtr resource = SimulatorManager::getInstance()->createResource("", callback); + SimulatorResourceServerPtr resource = SimulatorManager::getInstance()->createResource("", callback); if (NULL == resource.get()) std::cout << "Failed to create resource" << std::endl; @@ -135,12 +135,82 @@ class SimLightResource void deleteResource() { - int index = selectResource(); - if (-1 == index) + int choice = -1; + std::cout << "1. Delete single resource" << std::endl; + std::cout << "2. Delete resources on resource types" << std::endl; + std::cout << "3. Delete all resources" << std::endl; + + std::cout << "Enter your choice: "; + std::cin >> choice; + if (choice < 1 || choice > 3) + { + std::cout << "Invalid choice !" << std::endl; return; + } + + switch (choice) + { + case 1: + { + int index = selectResource(); + if (-1 == index) + return; + + if (SIMULATOR_SUCCESS == SimulatorManager::getInstance()->deleteResource(m_resources[index - 1])) + { + std::cout << "Resource deleted successfully! " << std::endl; + m_resources.erase(m_resources.begin() + (index - 1)); + } + else + { + std::cout << "Failed to delete resource!" << std::endl; + } + } break; + case 2: + { + std::string resourceType; + std::cout << "Enter resource type: "; + std::cin >> resourceType; + if (resourceType.empty()) + { + std::cout << "Invalid resource type!" << std::endl; + break; + } + + if (SIMULATOR_SUCCESS == SimulatorManager::getInstance()->deleteResources(resourceType)) + { + std::cout << "Resources of type \"" << resourceType << "\"" << " deleted successfully! " << + std::endl; + std::vector::iterator ite = m_resources.begin(); + while (ite != m_resources.end()) + { + if (!resourceType.compare((*ite)->getResourceType())) + { + ite = m_resources.erase(ite); + continue; + } + ite++; + } + } + else + { + std::cout << "Failed to delete resources of type \"" << resourceType << "\"!" << std::endl; + } + } break; + case 3: + { + if (SIMULATOR_SUCCESS == SimulatorManager::getInstance()->deleteResources()) + { + std::cout << "All resources deleted successfully! " << std::endl; + m_resources.clear(); + } + else + { + std::cout << "Failed to delete all resources!" << std::endl; + } + } break; + } - SimulatorManager::getInstance()->deleteResource(m_resources[index - 1]); - std::cout << "Resource deleted successfully! " << std::endl; } void updateAttributePower() @@ -149,7 +219,7 @@ class SimLightResource if (-1 == index) return; - SimulatorResourcePtr resource = m_resources[index - 1]; + SimulatorResourceServerPtr resource = m_resources[index - 1]; SimulatorResourceModel resModel = resource->getModel(); SimulatorResourceModel::Attribute powerAttribute; resModel.getAttribute("power", powerAttribute); @@ -193,7 +263,7 @@ class SimLightResource if (-1 == index) return; - SimulatorResourcePtr resource = m_resources[index - 1]; + SimulatorResourceServerPtr resource = m_resources[index - 1]; SimulatorResourceModel resModel = resource->getModel(); SimulatorResourceModel::Attribute intensityAttribute; resModel.getAttribute("intensity", intensityAttribute); @@ -237,11 +307,11 @@ class SimLightResource if (-1 == index) return; - SimulatorResourcePtr resource = m_resources[index - 1]; + SimulatorResourceServerPtr resource = m_resources[index - 1]; displayResource(resource); } - void displayResource(SimulatorResourcePtr resource) + void displayResource(SimulatorResourceServerPtr resource) { std::cout << "#############################" << std::endl; std::cout << "Name: " << resource->getName().c_str() << std::endl; @@ -267,14 +337,31 @@ class SimLightResource std::cout << "#############################" << std::endl; } + void onUpdateAutomationCompleted(const std::string &uri, + const int id) + { + std::cout << "Update automation is completed [URI: " << uri.c_str() << " AutomationID: " << + id << "] ###" << std::endl; + } + void automateResourceUpdate() { int index = selectResource(); if (-1 == index) return; + AutomationType type = AutomationType::NORMAL; + int choice = 0; + std::cout << "Press 1 if you want recurrent automation: "; + std::cin >> choice; + if (1 == choice) + type = AutomationType::RECURRENT; + int id; - if (SIMULATOR_SUCCESS != m_resources[index - 1]->startUpdateAutomation(AutomationType::NORMAL, id)) + if (SIMULATOR_SUCCESS != m_resources[index - 1]->startUpdateAutomation(type, + std::bind(&SimLightResource::onUpdateAutomationCompleted, this, std::placeholders::_1, + std::placeholders::_2), + id)) std::cout << "startUpdateAutomation() returned error!" << std::endl; else std::cout << "startUpdateAutomation() returned succces : " << id << std::endl; @@ -286,7 +373,7 @@ class SimLightResource if (-1 == index) return; - SimulatorResourcePtr resource = m_resources[index - 1]; + SimulatorResourceServerPtr resource = m_resources[index - 1]; SimulatorResourceModel resModel = resource->getModel(); std::map attributes = resModel.getAttributes(); int size = 0; @@ -323,9 +410,18 @@ class SimLightResource count++; } + AutomationType type = AutomationType::NORMAL; + std::cout << "Press 1 if you want recurrent automation: "; + std::cin >> choice; + if (1 == choice) + type = AutomationType::RECURRENT; + std::cout << "Requesting attribute automation for " << attributeName.c_str() << std::endl; int id; - if (SIMULATOR_SUCCESS != resource->startUpdateAutomation(attributeName, AutomationType::NORMAL, id)) + if (SIMULATOR_SUCCESS != resource->startUpdateAutomation(attributeName, type, + std::bind(&SimLightResource::onUpdateAutomationCompleted, this, std::placeholders::_1, + std::placeholders::_2), + id)) std::cout << "startUpdateAutomation() returned error!" << std::endl; else std::cout << "startUpdateAutomation() returned succces : " << id << std::endl; @@ -337,15 +433,34 @@ class SimLightResource if (-1 == index) return; - SimulatorResourcePtr resource = m_resources[index - 1]; + SimulatorResourceServerPtr resource = m_resources[index - 1]; + + // Select the automation to stop + std::vector ids; + { + std::vector rids = resource->getResourceAutomationIds(); + std::vector aids = resource->getAttributeAutomationIds(); + ids.insert(ids.end(), rids.begin(), rids.end()); + ids.insert(ids.end(), aids.begin(), aids.end()); + } + + if (!ids.size()) + { + std::cout << "No automation operation is going on this resource right now!" << std::endl; + return; + } + + for (auto & id : ids) + std::cout << id << " "; + int automationid; - std::cout << "Enter automation id: " << std::endl; + std::cout << "\nEnter automation id: " << std::endl; std::cin >> automationid; resource->stopUpdateAutomation(automationid); } private: - std::vector m_resources; + std::vector m_resources; }; void printMainMenu() diff --git a/service/simulator/inc/simulator_manager.h b/service/simulator/inc/simulator_manager.h index b2caf77..f63a6c7 100644 --- a/service/simulator/inc/simulator_manager.h +++ b/service/simulator/inc/simulator_manager.h @@ -29,9 +29,9 @@ #define SIMULATOR_MANAGER_H_ #include +#include "simulator_resource_server.h" #include "simulator_remote_resource.h" #include "simulator_error_codes.h" -#include "simulator_resource.h" #include "simulator_logger.h" /** @@ -52,10 +52,10 @@ class SimulatorManager * @param configPath - RAML configuration file path. * @param callback - Callback method for receive notifications when resource model changes. * - * @return SimulatorResourcePtr - Shared pointer of SimulatorResource on success, otherwise NULL. + * @return SimulatorResourceServerPtr - Shared pointer of SimulatorResourceServer on success, otherwise NULL. */ - SimulatorResourcePtr createResource(const std::string &configPath, - SimulatorResource::ResourceModelChangedCB callback); + SimulatorResourceServerPtr createResource(const std::string &configPath, + SimulatorResourceServer::ResourceModelChangedCB callback); /** * This method is called for creating a collection of resources from RAML configuration file. @@ -64,27 +64,27 @@ class SimulatorManager * @param count - Number of resource to be created. * @param callback - Callback method for receive notifications when resource model changes. * - * @return SimulatorResourcePtr - A vector of Shared pointers of SimulatorResource Objects. + * @return SimulatorResourceServerPtr - A vector of Shared pointers of SimulatorResourceServer Objects. */ - std::vector createResource(const std::string &configPath, + std::vector createResource(const std::string &configPath, const int count, - SimulatorResource::ResourceModelChangedCB callback); + SimulatorResourceServer::ResourceModelChangedCB callback); /** * This method is called for obtaining a list of created resources. * - * @return SimulatorResourcePtr - A vector of Shared pointers of SimulatorResource Objects. + * @return SimulatorResourceServerPtr - A vector of Shared pointers of SimulatorResourceServer Objects. */ - std::vector getResources(void); + std::vector getResources(const std::string &resourceType = ""); /** * This method is called for deleting a single resource. * - * @param resource - Shared pointer of the SimulatorResource to be deleted. + * @param resource - Shared pointer of the SimulatorResourceServer to be deleted. * * @return SimulatorResult */ - SimulatorResult deleteResource(std::shared_ptr &resource); + SimulatorResult deleteResource(SimulatorResourceServerPtr &resource); /** * This method is called for deleting multiple resources. @@ -153,6 +153,7 @@ class SimulatorManager private: SimulatorManager(); + ~SimulatorManager() = default; }; #endif diff --git a/service/simulator/src/resource_manager.cpp b/service/simulator/src/resource_manager.cpp index f10ab7f..3225bd3 100644 --- a/service/simulator/src/resource_manager.cpp +++ b/service/simulator/src/resource_manager.cpp @@ -19,6 +19,7 @@ ******************************************************************/ #include "resource_manager.h" +#include "simulator_logger.h" int ResourceManager::id; ResourceManager *ResourceManager::getInstance() @@ -35,92 +36,184 @@ ResourceManager::~ResourceManager() delete m_resourceCreator; } -SimulatorResourcePtr ResourceManager::createResource(const std::string &configPath, - SimulatorResource::ResourceModelChangedCB callback) +SimulatorResourceServerPtr ResourceManager::createResource(const std::string &configPath, + SimulatorResourceServer::ResourceModelChangedCB callback) { /** * TODO: Temporarily creating the light resource for testing the basic flow * Once the config parser is included this method will simulate the resource based on the config file */ - SimulatorResourcePtr simulatorResource = m_resourceCreator->createLightResoure(); + SimulatorResourceServerPtr simulatorResource = m_resourceCreator->createLightResoure(); simulatorResource->setModelChangeCallback(callback); - - simulatorResource->setURI(getURI(simulatorResource->getURI())); - OC::EntityHandler entityHandler = std::bind(&SimulatorResource::entityHandler, - simulatorResource.get(), std::placeholders::_1); - std::string uri = simulatorResource->getURI(); - OCStackResult result = OC::OCPlatform::registerResource(simulatorResource->m_resourceHandle, - uri, - simulatorResource->getResourceType(), - simulatorResource->getInterfaceType(), - entityHandler, - OC_DISCOVERABLE | OC_OBSERVABLE); - if (OC_STACK_OK != result) + std::string uri = getURI(simulatorResource->getURI()); + if(uri.empty()) { + SIM_LOG(ILogger::ERROR, "Cannot register resource. Resource URI is empty"); + return NULL; + } + simulatorResource->setURI(uri); + SimulatorResult result = simulatorResource->start(); + if (SIMULATOR_SUCCESS != result) + { + SIM_LOG(ILogger::ERROR, "Failed to register resource [" << simulatorResource->getURI() << + "] with platform"); return NULL; } // Add the resource to resource list table + std::lock_guard lock(m_listMutex); m_resourceList[simulatorResource->getResourceType()].insert( - std::pair(simulatorResource->getURI(), simulatorResource)); + std::pair(simulatorResource->getURI(), simulatorResource)); return simulatorResource; } -std::vector ResourceManager::createResource(const std::string &configPath, - const int count, SimulatorResource::ResourceModelChangedCB callback) +std::vector ResourceManager::createResource( + const std::string &configPath, + const int count, SimulatorResourceServer::ResourceModelChangedCB callback) { - std::vector list; - return list; + std::vector resourceList; + for (int i = 0; i < count; i++) + { + /** + * TODO: Temporarily creating the light resource for testing the basic flow + * Once the config parser is included this method will simulate the resource based on the config file + */ + SimulatorResourceServerPtr simulatorResource = m_resourceCreator->createLightResoure(); + simulatorResource->setModelChangeCallback(callback); + std::string uri = getURI(simulatorResource->getURI()); + if(uri.empty()) + { + SIM_LOG(ILogger::ERROR, "Cannot register resource. Resource URI is empty"); + break; + } + simulatorResource->setURI(uri); + SimulatorResult result = simulatorResource->start(); + if (SIMULATOR_SUCCESS != result) + { + resourceList.clear(); + SIM_LOG(ILogger::ERROR, "Failed to register resources!"); + break; + } + else + { + resourceList.push_back(simulatorResource); + } + } + + // Add the resource to resource list table + std::lock_guard lock(m_listMutex); + for (auto & resource : resourceList) + { + m_resourceList[resource->getResourceType()].insert( + std::pair(resource->getURI(), resource)); + } + + return resourceList; } -std::vector ResourceManager::getResources(void) const +std::vector ResourceManager::getResources( + const std::string &resourceType) { - std::vector list; - return list; + std::lock_guard lock(m_listMutex); + + std::vector resourceList; + for (auto resourceTableEntry : m_resourceList) + { + if (!resourceType.empty() && resourceType.compare(resourceTableEntry.first)) + continue; + + for (auto resourceEntry : resourceTableEntry.second) + { + resourceList.push_back(resourceEntry.second); + } + } + + return resourceList; } -SimulatorResult ResourceManager::deleteResource(SimulatorResourcePtr &resource) +SimulatorResult ResourceManager::deleteResource(SimulatorResourceServerPtr &resource) { - if (!resource.get()) - return SIMULATOR_RESOURCE_NOT_FOUND; + std::lock_guard lock(m_listMutex); + + if (nullptr == resource) + return SIMULATOR_BAD_INPUT; + + SimulatorResult result = SIMULATOR_RESOURCE_NOT_FOUND; - auto resourceTableEntry = m_resourceList.find(resource->getResourceType()); - if (m_resourceList.end() != resourceTableEntry) + try { - auto resourceEntry = resourceTableEntry->second.find(resource->getURI()); - if (resourceTableEntry->second.end() != resourceEntry) + auto resourceTableEntry = m_resourceList.find(resource->getResourceType()); + if (m_resourceList.end() != resourceTableEntry) { - if (OC_STACK_OK == OC::OCPlatform::unregisterResource(resource->getHandle())) - resourceTableEntry->second.erase(resourceEntry); + auto resourceEntry = resourceTableEntry->second.find(resource->getURI()); + if (resourceTableEntry->second.end() != resourceEntry) + { + if (SIMULATOR_SUCCESS == resource->stop()) + { + resourceTableEntry->second.erase(resourceEntry); + result = SIMULATOR_SUCCESS; + } + else + { + result = SIMULATOR_ERROR; + } + } } } + catch (OC::OCException &except) + { + SIM_LOG(ILogger::ERROR, except.reason() << except.code()) + result = SIMULATOR_ERROR; + } - return SIMULATOR_SUCCESS; + return result; } SimulatorResult ResourceManager::deleteResources(const std::string &resourceType) { - auto resourceTableEntry = m_resourceList.find(resourceType); - if (m_resourceList.end() != resourceTableEntry) + std::lock_guard lock(m_listMutex); + + SimulatorResult result = SIMULATOR_RESOURCE_NOT_FOUND; + try { - return SIMULATOR_RESOURCE_NOT_FOUND; + for (auto & resourceTableEntry : m_resourceList) + { + if (!resourceType.empty() && resourceType.compare(resourceTableEntry.first)) + continue; + + for (auto & resourceEntry : resourceTableEntry.second) + { + SimulatorResourceServerPtr resource = resourceEntry.second; + if (SIMULATOR_SUCCESS == resource->stop()) + { + resourceTableEntry.second.erase(resourceTableEntry.second.find(resource->getURI())); + result = SIMULATOR_SUCCESS; + } + else + { + return SIMULATOR_ERROR; + } + } + } } - - for (auto resourceEntry : resourceTableEntry->second) + catch (OC::OCException &except) { - SimulatorResourcePtr resource = resourceEntry.second; - if (OC_STACK_OK == OC::OCPlatform::unregisterResource(resource->getHandle())) - resourceTableEntry->second.erase(resourceTableEntry->second.find(resource->getURI())); + SIM_LOG(ILogger::ERROR, except.reason() << except.code()) + result = SIMULATOR_ERROR; } - return SIMULATOR_SUCCESS; + return result; } std::string ResourceManager::getURI(std::string uri) { + if(uri.empty()) + { + return uri; + } std::ostringstream os; os << uri; - if (!uri.empty() && '/' != uri[uri.length() - 1]) + if ('/' != uri[uri.length() - 1]) os << '/'; os << "simulator/" << id++; return os.str(); diff --git a/service/simulator/src/resource_manager.h b/service/simulator/src/resource_manager.h index 9a2a608..4e27d62 100644 --- a/service/simulator/src/resource_manager.h +++ b/service/simulator/src/resource_manager.h @@ -31,7 +31,8 @@ #include #include #include -#include "simulator_resource.h" +#include +#include "simulator_resource_server.h" #include "simulator_resource_creator.h" #include "simulator_error_codes.h" @@ -55,10 +56,10 @@ class ResourceManager * @param configPath - RAML configuration file path. * @param callback - Callback method for receive notifications when resource model changes. * - * @return SimulatorResourcePtr - Shared pointer of SimulatorResource on success, otherwise NULL. + * @return SimulatorResourceServerPtr - Shared pointer of SimulatorResourceServer on success, otherwise NULL. */ - SimulatorResourcePtr createResource(const std::string &configPath, - SimulatorResource::ResourceModelChangedCB callback); + SimulatorResourceServerPtr createResource(const std::string &configPath, + SimulatorResourceServer::ResourceModelChangedCB callback); /** * This method is called for creating a collection of resources from the configuration file. @@ -67,26 +68,27 @@ class ResourceManager * @param count - Number of resource to be created. * @param callback - Callback method for receive notifications when resource model changes. * - * @return SimulatorResourcePtr - A vector of Shared pointers of SimulatorResource Objects. + * @return SimulatorResourceServerPtr - A vector of Shared pointers of SimulatorResourceServer Objects. */ - std::vector createResource(const std::string &configPath, const int count, - SimulatorResource::ResourceModelChangedCB callback); + std::vector createResource(const std::string &configPath, + const int count, + SimulatorResourceServer::ResourceModelChangedCB callback); /** * This method is called for obtaining a list of created resources. * - * @return SimulatorResourcePtr - A vector of Shared pointers of SimulatorResource Objects. + * @return SimulatorResourceServerPtr - A vector of Shared pointers of SimulatorResourceServer Objects. */ - std::vector getResources(void) const; + std::vector getResources(const std::string &resourceType = ""); /** * This method is called for deleting a single resource. * - * @param resource - Shared pointer of the SimulatorResource to be deleted. + * @param resource - Shared pointer of the SimulatorResourceServer to be deleted. * * @return SimulatorResult */ - SimulatorResult deleteResource(SimulatorResourcePtr &resource); + SimulatorResult deleteResource(SimulatorResourceServerPtr &resource); /** * This method is called for deleting multiple resources. @@ -123,9 +125,10 @@ class ResourceManager * This multi-level map organizes the resources in the form of ResourceType as the key * and a set of resources of that resourceType as the value. * The value is another map which has the ResourceURI as the key and the shared pointer - * of the SimulatorResource object as the value. + * of the SimulatorResourceServer object as the value. */ - std::map> m_resourceList; + std::map> m_resourceList; + std::recursive_mutex m_listMutex; }; #endif diff --git a/service/simulator/src/simulator_attribute_automation.cpp b/service/simulator/src/simulator_attribute_automation.cpp index fd732e9..c955b6d 100644 --- a/service/simulator/src/simulator_attribute_automation.cpp +++ b/service/simulator/src/simulator_attribute_automation.cpp @@ -19,19 +19,24 @@ ******************************************************************/ #include "simulator_attribute_automation.h" -#include "simulator_resource.h" +#include "simulator_resource_server.h" #include #define SLEEP_FOR(X) if (X > 0) std::this_thread::sleep_for(std::chrono::milliseconds(X)); AttributeUpdateAutomation::AttributeUpdateAutomation( - SimulatorResource *resource, const std::string &attrName, AutomationType type, int interval) + SimulatorResourceServer *resource, const std::string &attrName, updateCompleteCallback callback, + int automationId, std::function finishedCallback, AutomationType type, + int interval) : m_resource(resource), m_attrName(attrName), m_type(type), + m_id(automationId), m_status(false), m_stopRequested(false), - m_updateInterval(interval) {} + m_updateInterval(interval), + m_callback(callback), + m_finishedCallback(finishedCallback) {} SimulatorResult AttributeUpdateAutomation::start() { @@ -74,6 +79,12 @@ void AttributeUpdateAutomation::updateAttribute() while (AutomationType::RECURRENT == m_type); m_status = false; + + // Notify application through callback + if (m_callback) + m_callback(m_resource->getURI(), m_id); + if (m_finishedCallback && !m_stopRequested) + m_finishedCallback(m_id); } void AttributeUpdateAutomation::setAttributeValue() @@ -85,6 +96,8 @@ void AttributeUpdateAutomation::setAttributeValue() m_attribute.getRange(min, max); for (int value = min; value <= max; value++) { + if (m_stopRequested) + break; m_resource->updateAttribute(m_attribute.getName(), value); SLEEP_FOR(m_updateInterval); } @@ -93,6 +106,8 @@ void AttributeUpdateAutomation::setAttributeValue() { for (int index = 0; index < m_attribute.getAllowedValuesSize(); index++) { + if (m_stopRequested) + break; m_resource->updateAttributeFromAllowedValues(m_attribute.getName(), index); SLEEP_FOR(m_updateInterval); } @@ -101,11 +116,16 @@ void AttributeUpdateAutomation::setAttributeValue() ResourceUpdateAutomation::ResourceUpdateAutomation( - SimulatorResource *resource, AutomationType type, int interval) + SimulatorResourceServer *resource, updateCompleteCallback callback, + int automationId, std::function finishedCallback, AutomationType type, + int interval) : m_resource(resource), m_type(type), + m_id(automationId), m_status(false), - m_updateInterval(interval) {} + m_updateInterval(interval), + m_callback(callback), + m_finishedCallback(finishedCallback) {} SimulatorResult ResourceUpdateAutomation::start() { @@ -120,11 +140,14 @@ SimulatorResult ResourceUpdateAutomation::start() return SIMULATOR_ERROR; } + int id = 0; for (auto & attribute : attributes) { AttributeUpdateAutomationPtr attributeAutomation = std::make_shared - (m_resource, attribute.first, m_type, m_updateInterval); - m_attrUpdationList.push_back(attributeAutomation); + (m_resource, attribute.first, nullptr, id, + std::bind(&ResourceUpdateAutomation::finished, this, std::placeholders::_1), + m_type, m_updateInterval); + m_attrUpdationList[id++] = attributeAutomation; if (SIMULATOR_SUCCESS != attributeAutomation->start()) { m_status = false; @@ -137,12 +160,28 @@ SimulatorResult ResourceUpdateAutomation::start() return SIMULATOR_SUCCESS; } +void ResourceUpdateAutomation::finished(int id) +{ + if (m_attrUpdationList.end() != m_attrUpdationList.find(id)) + { + m_attrUpdationList.erase(m_attrUpdationList.find(id)); + } + + if (!m_attrUpdationList.size()) + { + // Notify application through callback + if (m_callback) + m_callback(m_resource->getURI(), m_id); + if (m_finishedCallback) + m_finishedCallback(m_id); + } +} void ResourceUpdateAutomation::stop() { // Stop all the attributes updation for (auto & attrAutomation : m_attrUpdationList) { - attrAutomation->stop(); + (attrAutomation.second)->stop(); } m_attrUpdationList.clear(); @@ -152,29 +191,37 @@ void ResourceUpdateAutomation::stop() UpdateAutomationManager::UpdateAutomationManager() : m_automationId(0) {} -SimulatorResult UpdateAutomationManager::startResourceAutomation(SimulatorResource *resource, - int &id, AutomationType type, int interval) +SimulatorResult UpdateAutomationManager::startResourceAutomation(SimulatorResourceServer *resource, + int &id, updateCompleteCallback callback, AutomationType type, int interval) { - ResourceUpdateAutomationPtr resoureceAutomation(new ResourceUpdateAutomation(resource, type, - interval)); - SimulatorResult result = resoureceAutomation->start(); + std::lock_guard lock(m_mutex); + + ResourceUpdateAutomationPtr resourceAutomation(new ResourceUpdateAutomation( + resource, callback, m_automationId, + std::bind(&UpdateAutomationManager::automationFinished, this, std::placeholders::_1), + type, interval)); + SimulatorResult result = resourceAutomation->start(); if (SIMULATOR_SUCCESS != result) { id = -1; return result; } - std::lock_guard lock(m_mutex); - m_resourceUpdationList[m_automationId++] = resoureceAutomation; - id = m_automationId - 1; + m_resourceUpdationList[m_automationId] = resourceAutomation; + id = m_automationId++; return result; } -SimulatorResult UpdateAutomationManager::startAttributeAutomation(SimulatorResource *resource, - const std::string &attrName, int &id, AutomationType type, int interval) +SimulatorResult UpdateAutomationManager::startAttributeAutomation(SimulatorResourceServer *resource, + const std::string &attrName, int &id, updateCompleteCallback callback, AutomationType type, + int interval) { - AttributeUpdateAutomationPtr attributeAutomation(new AttributeUpdateAutomation(resource, attrName, - type, interval)); + std::lock_guard lock(m_mutex); + + AttributeUpdateAutomationPtr attributeAutomation(new AttributeUpdateAutomation( + resource, attrName, callback, m_automationId, + std::bind(&UpdateAutomationManager::automationFinished, this, std::placeholders::_1), + type, interval)); SimulatorResult result = attributeAutomation->start(); if (SIMULATOR_SUCCESS != result) { @@ -182,12 +229,31 @@ SimulatorResult UpdateAutomationManager::startAttributeAutomation(SimulatorResou return result; } - std::lock_guard lock(m_mutex); - m_attrUpdationList[m_automationId++] = attributeAutomation; - id = m_automationId - 1; + m_attrUpdationList[m_automationId] = attributeAutomation; + id = m_automationId++; return result; } +std::vector UpdateAutomationManager::getResourceAutomationIds() +{ + std::vector ids; + std::lock_guard lock(m_mutex); + for (auto & automation : m_resourceUpdationList) + ids.push_back(automation.first); + + return ids; +} + +std::vector UpdateAutomationManager::getAttributeAutomationIds() +{ + std::vector ids; + std::lock_guard lock(m_mutex); + for (auto & automation : m_attrUpdationList) + ids.push_back(automation.first); + + return ids; +} + void UpdateAutomationManager::stop(int automationId) { std::lock_guard lock(m_mutex); @@ -220,3 +286,16 @@ void UpdateAutomationManager::stopAll() }); m_attrUpdationList.clear(); } + +void UpdateAutomationManager::automationFinished(int id) +{ + std::lock_guard lock(m_mutex); + if (m_resourceUpdationList.end() != m_resourceUpdationList.find(id)) + { + m_resourceUpdationList.erase(m_resourceUpdationList.find(id)); + } + else if (m_attrUpdationList.end() != m_attrUpdationList.find(id)) + { + m_attrUpdationList.erase(m_attrUpdationList.find(id)); + } +} \ No newline at end of file diff --git a/service/simulator/src/simulator_attribute_automation.h b/service/simulator/src/simulator_attribute_automation.h index a23764a..36717cd 100644 --- a/service/simulator/src/simulator_attribute_automation.h +++ b/service/simulator/src/simulator_attribute_automation.h @@ -24,7 +24,7 @@ #include "simulator_resource_model.h" #include "simulator_error_codes.h" -class SimulatorResource; +class SimulatorResourceServer; enum class AutomationType { @@ -32,11 +32,15 @@ enum class AutomationType RECURRENT }; +typedef std::function updateCompleteCallback; + class AttributeUpdateAutomation { public: - AttributeUpdateAutomation(SimulatorResource *resource, - const std::string &attrName, AutomationType type = AutomationType::NORMAL, int interval = -1); + AttributeUpdateAutomation(SimulatorResourceServer *resource, + const std::string &attrName, updateCompleteCallback callback, int automationId, + std::function finishedCallback, AutomationType type = AutomationType::NORMAL, + int interval = -1); SimulatorResult start(); void stop(); @@ -44,14 +48,17 @@ class AttributeUpdateAutomation void updateAttribute(); void setAttributeValue(); - SimulatorResource *m_resource; + SimulatorResourceServer *m_resource; std::string m_attrName; AutomationType m_type; + int m_id; bool m_status; std::thread *m_thread; bool m_stopRequested; int m_updateInterval; SimulatorResourceModel::Attribute m_attribute; + updateCompleteCallback m_callback; + std::function m_finishedCallback; }; typedef std::shared_ptr AttributeUpdateAutomationPtr; @@ -59,22 +66,27 @@ typedef std::shared_ptr AttributeUpdateAutomationPtr; class ResourceUpdateAutomation { public: - ResourceUpdateAutomation(SimulatorResource *resource, + ResourceUpdateAutomation(SimulatorResourceServer *resource, updateCompleteCallback callback, + int automationId, std::function finishedCallback, AutomationType type = AutomationType::NORMAL, int interval = -1); SimulatorResult start(); void stop(); + void finished(int id); private: void updateAttribute(); void setAttributeValue(); - SimulatorResource *m_resource; + SimulatorResourceServer *m_resource; AutomationType m_type; + int m_id; bool m_status; std::thread *m_thread; int m_updateInterval; SimulatorResourceModel m_resModel; - std::vector m_attrUpdationList; + std::map m_attrUpdationList; + updateCompleteCallback m_callback; + std::function m_finishedCallback; }; typedef std::shared_ptr ResourceUpdateAutomationPtr; @@ -83,13 +95,17 @@ class UpdateAutomationManager { public: UpdateAutomationManager(); - SimulatorResult startResourceAutomation(SimulatorResource *resource, - int &id, AutomationType type = AutomationType::NORMAL, int interval = -1); - SimulatorResult startAttributeAutomation(SimulatorResource *resource, - const std::string &attrName, int &id, AutomationType type = AutomationType::NORMAL, - int interval = -1); + SimulatorResult startResourceAutomation(SimulatorResourceServer *resource, + int &id, updateCompleteCallback callback, + AutomationType type = AutomationType::NORMAL, int interval = -1); + SimulatorResult startAttributeAutomation(SimulatorResourceServer *resource, + const std::string &attrName, int &id, updateCompleteCallback callback, + AutomationType type = AutomationType::NORMAL, int interval = -1); + std::vector getResourceAutomationIds(); + std::vector getAttributeAutomationIds(); void stop(int automationId); void stopAll(); + void automationFinished(int id); private: std::map m_resourceUpdationList; diff --git a/service/simulator/src/simulator_manager.cpp b/service/simulator/src/simulator_manager.cpp index ecba1b7..b641656 100644 --- a/service/simulator/src/simulator_manager.cpp +++ b/service/simulator/src/simulator_manager.cpp @@ -44,24 +44,26 @@ SimulatorManager::SimulatorManager() OC::OCPlatform::Configure(conf); } -SimulatorResourcePtr SimulatorManager::createResource(const std::string &configPath, - SimulatorResource::ResourceModelChangedCB callback) +SimulatorResourceServerPtr SimulatorManager::createResource(const std::string &configPath, + SimulatorResourceServer::ResourceModelChangedCB callback) { return ResourceManager::getInstance()->createResource(configPath, callback); } -std::vector SimulatorManager::createResource(const std::string &configPath, - const int count, SimulatorResource::ResourceModelChangedCB callback) +std::vector SimulatorManager::createResource( + const std::string &configPath, + const int count, SimulatorResourceServer::ResourceModelChangedCB callback) { return ResourceManager::getInstance()->createResource(configPath, count, callback); } -std::vector SimulatorManager::getResources(void) +std::vector SimulatorManager::getResources( + const std::string &resourceType) { - return ResourceManager::getInstance()->getResources(); + return ResourceManager::getInstance()->getResources(resourceType); } -SimulatorResult SimulatorManager::deleteResource(SimulatorResourcePtr &resource) +SimulatorResult SimulatorManager::deleteResource(SimulatorResourceServerPtr &resource) { return ResourceManager::getInstance()->deleteResource(resource); } diff --git a/service/simulator/src/simulator_resource.cpp b/service/simulator/src/simulator_resource.cpp deleted file mode 100644 index a9db65c..0000000 --- a/service/simulator/src/simulator_resource.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************/ - -#include "simulator_resource.h" -#include "simulator_attribute_automation.h" - -void SimulatorResource::setRange(const std::string &attrName, const int min, const int max) -{ - m_resModel.setRange(attrName, min, max); -} - -void SimulatorResource::setUpdateInterval(const std::string &attrName, int interval) -{ - m_resModel.setUpdateInterval(attrName, interval); -} - -void SimulatorResource::removeAttribute(const std::string &attrName) -{ - m_resModel.removeAttribute(attrName); - notifyListOfObservers(); -} - -void SimulatorResource::setURI(const std::string &uri) -{ - m_uri = uri; -} - -std::string SimulatorResource::getURI() const -{ - return m_uri; -} - -void SimulatorResource::setResourceType(const std::string &resourceType) -{ - m_resourceType = resourceType; -} - -std::string SimulatorResource::getResourceType() const -{ - return m_resourceType; -} - -void SimulatorResource::setInterfaceType(const std::string &interfaceType) -{ - m_interfaceType = interfaceType; -} - -std::string SimulatorResource::getInterfaceType() const -{ - return m_interfaceType; -} - -OCResourceHandle SimulatorResource::getHandle() const -{ - return m_resourceHandle; -} - -void SimulatorResource::setName(const std::string &name) -{ - m_name = name; -} - -std::string SimulatorResource::getName() const -{ - return m_name; -} - -void SimulatorResource::updateAttributeFromAllowedValues(const std::string &attrName, - const int allowedValueIndex) -{ - m_resModel.updateAttributeFromAllowedValues(attrName, allowedValueIndex); - notifyListOfObservers(); -} - -SimulatorResourceModel SimulatorResource::getModel() const -{ - return m_resModel; -} - -void SimulatorResource::setModelChangeCallback(ResourceModelChangedCB callback) -{ - m_callback = callback; -} - -SimulatorResult SimulatorResource::startUpdateAutomation(AutomationType type, int &id) -{ - return m_updateAutomationMgr.startResourceAutomation(this, id, type); -} - -SimulatorResult SimulatorResource::startUpdateAutomation(const std::string &attrName, - AutomationType type, int &id) -{ - return m_updateAutomationMgr.startAttributeAutomation(this, attrName, id, type); -} - -void SimulatorResource::stopUpdateAutomation(const int id) -{ - m_updateAutomationMgr.stop(id); -} - -OC::OCRepresentation SimulatorResource::getOCRepresentation() -{ - return m_resModel.getOCRepresentation(); -} - -bool SimulatorResource::modifyResourceModel(OC::OCRepresentation &ocRep, - SimulatorResourceModel::UpdateType type) -{ - return m_resModel.update(ocRep, type); -} - -OCEntityHandlerResult SimulatorResource::entityHandler(std::shared_ptr - request) -{ - OCEntityHandlerResult errCode = OC_EH_ERROR; - if (!request) - { - return OC_EH_ERROR; - } - - if (OC::RequestHandlerFlag::RequestFlag & request->getRequestHandlerFlag()) - { - auto response = std::make_shared(); - response->setRequestHandle(request->getRequestHandle()); - response->setResourceHandle(request->getResourceHandle()); - - if ("GET" == request->getRequestType()) - { - response->setErrorCode(200); - response->setResponseResult(OC_EH_OK); - response->setResourceRepresentation(getOCRepresentation()); - - if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) - { - errCode = OC_EH_OK; - } - } - else if ("PUT" == request->getRequestType()) - { - OC::OCRepresentation rep = request->getResourceRepresentation(); - if (true == modifyResourceModel(rep, SimulatorResourceModel::UpdateType::PUT)) - { - response->setErrorCode(200); - response->setResponseResult(OC_EH_OK); - response->setResourceRepresentation(getOCRepresentation()); - } - else - { - response->setErrorCode(400); - response->setResponseResult(OC_EH_ERROR); - } - - if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) - { - errCode = OC_EH_OK; - } - } - else if ("POST" == request->getRequestType()) - { - OC::OCRepresentation rep = request->getResourceRepresentation(); - if (true == modifyResourceModel(rep, SimulatorResourceModel::UpdateType::POST)) - { - response->setErrorCode(200); - response->setResponseResult(OC_EH_OK); - response->setResourceRepresentation(getOCRepresentation()); - } - else - { - response->setErrorCode(400); - response->setResponseResult(OC_EH_ERROR); - } - - if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) - { - errCode = OC_EH_OK; - } - } - else if ("DELETE" == request->getRequestType()) - { - OC::OCRepresentation rep = request->getResourceRepresentation(); - if (true == modifyResourceModel(rep, SimulatorResourceModel::UpdateType::DELETE)) - { - response->setErrorCode(200); - response->setResponseResult(OC_EH_OK); - response->setResourceRepresentation(getOCRepresentation()); - } - else - { - response->setErrorCode(400); - response->setResponseResult(OC_EH_ERROR); - } - - if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) - { - errCode = OC_EH_OK; - } - } - else - { - response->setResponseResult(OC_EH_ERROR); - OC::OCPlatform::sendResponse(response); - errCode = OC_EH_ERROR; - } - } - - if (OC::RequestHandlerFlag::ObserverFlag & request->getRequestHandlerFlag()) - { - OC::ObservationInfo observationInfo = request->getObservationInfo(); - if (OC::ObserveAction::ObserveRegister == observationInfo.action) - { - m_interestedObservers.push_back(observationInfo.obsId); - } - else if (OC::ObserveAction::ObserveUnregister == observationInfo.action) - { - m_interestedObservers.erase(std::remove(m_interestedObservers.begin(), - m_interestedObservers.end(), - observationInfo.obsId), - m_interestedObservers.end()); - } - errCode = OC_EH_OK; - } - - return errCode; -} - -void SimulatorResource::notifyListOfObservers () -{ - if(getHandle()) - { - if (m_interestedObservers.size()) - { - std::shared_ptr resourceResponse = - {std::make_shared()}; - - resourceResponse->setErrorCode(200); - resourceResponse->setResponseResult(OC_EH_OK); - resourceResponse->setResourceRepresentation(getOCRepresentation(), OC::DEFAULT_INTERFACE); - - OC::OCPlatform::notifyListOfObservers(getHandle(), m_interestedObservers, resourceResponse); - } - if(m_callback) - { - m_callback(getURI(),getModel()); - } - } -} diff --git a/service/simulator/src/simulator_resource_creator.cpp b/service/simulator/src/simulator_resource_creator.cpp index 6011fea..fb2359d 100644 --- a/service/simulator/src/simulator_resource_creator.cpp +++ b/service/simulator/src/simulator_resource_creator.cpp @@ -19,24 +19,25 @@ ******************************************************************/ #include "simulator_resource_creator.h" +#include "simulator_logger.h" -SimulatorResourcePtr SimulatorResourceCreator::createLightResoure() +SimulatorResourceServerPtr SimulatorResourceCreator::createLightResoure() { - std::shared_ptr lightResource(new SimulatorResource); + std::shared_ptr lightResource(new SimulatorResourceServer); // set power attribute with its properties { lightResource->addAttribute("power", std::string("on")); std::vector values {"on", "off"}; lightResource->setAllowedValues("power", values); - lightResource->setUpdateInterval("power", 1000); + lightResource->setUpdateInterval("power", 2000); } // set intensity attributes with its properties { lightResource->addAttribute("intensity", int(1)); lightResource->setRange("intensity", 1, 10); - lightResource->setUpdateInterval("intensity", 2000); + lightResource->setUpdateInterval("intensity", 3000); } // set other properties @@ -45,6 +46,7 @@ SimulatorResourcePtr SimulatorResourceCreator::createLightResoure() lightResource->setResourceType("oic.light"); lightResource->setInterfaceType(OC::DEFAULT_INTERFACE); + SIM_LOG(ILogger::INFO, "Created sample light resource"); return lightResource; } diff --git a/service/simulator/src/simulator_resource_creator.h b/service/simulator/src/simulator_resource_creator.h index 5707029..44d1faf 100644 --- a/service/simulator/src/simulator_resource_creator.h +++ b/service/simulator/src/simulator_resource_creator.h @@ -21,7 +21,7 @@ #ifndef SIMULATOR_RESOURCE_CREATOR_H_ #define SIMULATOR_RESOURCE_CREATOR_H_ -#include "simulator_resource.h" +#include "simulator_resource_server.h" class SimulatorResourceCreator { @@ -30,7 +30,7 @@ class SimulatorResourceCreator * This is temporary method to get the light resource as parser * needs to implemented/integrated */ - SimulatorResourcePtr createLightResoure(); + SimulatorResourceServerPtr createLightResoure(); }; #endif \ No newline at end of file diff --git a/service/simulator/src/simulator_resource_model.cpp b/service/simulator/src/simulator_resource_model.cpp index a059226..ce20a9d 100644 --- a/service/simulator/src/simulator_resource_model.cpp +++ b/service/simulator/src/simulator_resource_model.cpp @@ -100,28 +100,6 @@ class range_validation : public boost::static_visitor SimulatorResourceModel::Attribute &m_attrItem; }; -class Converter -{ - public: - void convert(const OC::OCRepresentation::AttributeItem &attrItem) - { - if (attrItem.type() == OC::AttributeType::Integer) - m_attribute.setValue(attrItem.getValue()); - if (attrItem.type() == OC::AttributeType::Double) - m_attribute.setValue(attrItem.getValue()); - if (attrItem.type() == OC::AttributeType::String) - m_attribute.setValue(attrItem.getValue()); - } - - SimulatorResourceModel::Attribute &&get() - { - return std::move(m_attribute); - } - - private: - SimulatorResourceModel::Attribute m_attribute; -}; - SimulatorResourceModel::Attribute::ValueVariant &SimulatorResourceModel::Attribute::AllowedValues::at(int index) { @@ -213,7 +191,7 @@ std::vector SimulatorResourceModel::Attribute::allowedValuesToVecto } void SimulatorResourceModel::Attribute::addValuetoRepresentation(OC::OCRepresentation &rep, - const std::string &key) + const std::string &key) const { add_to_representation visitor(rep, key); boost::apply_visitor(visitor, m_value); @@ -281,7 +259,7 @@ void SimulatorResourceModel::removeAttribute(const std::string &attrName) return; } -OC::OCRepresentation SimulatorResourceModel::getOCRepresentation() +OC::OCRepresentation SimulatorResourceModel::getOCRepresentation() const { OC::OCRepresentation rep; for (auto & attribute : m_attributes) @@ -292,70 +270,57 @@ OC::OCRepresentation SimulatorResourceModel::getOCRepresentation() return rep; } -bool SimulatorResourceModel::update(OC::OCRepresentation &ocRep, UpdateType type) +bool SimulatorResourceModel::update(OC::OCRepresentation &ocRep) { if (0 == ocRep.size()) return true; // Convert OCRepresentation to SimulatorResourceModel - SimulatorResourceModel resModel; - for (auto & attributeItem : ocRep) - { - Converter converter; - converter.convert(attributeItem); - SimulatorResourceModel::Attribute attribute = converter.get(); - attribute.setName(attributeItem.attrname()); - resModel.m_attributes[attributeItem.attrname()] = attribute; - } + SimulatorResourceModel resModel = create(ocRep); - return update(resModel, type); + return update(resModel); } -bool SimulatorResourceModel::update(SimulatorResourceModel &repModel, UpdateType type) +bool SimulatorResourceModel::update(SimulatorResourceModel &repModel) { std::map attributes = repModel.getAttributes(); for (auto & attributeItem : attributes) { // Check the attribute presence SimulatorResourceModel::Attribute attribute; - if (type == PUT) - { - if (false == getAttribute((attributeItem.second).getName(), attribute)) - { - return false; - } - - // Check the validity of the value to be set - if (false == attribute.compare(attributeItem.second)) - { - return false; - } - m_attributes[(attributeItem.second).getName()].setValue((attributeItem.second).getValue()); - } - else if (type == POST) + if (false == getAttribute((attributeItem.second).getName(), attribute)) { - if (false == getAttribute((attributeItem.second).getName(), attribute)) - { - addAttribute(((attributeItem.second).getName()) , ((attributeItem.second).getValue())); - continue; - } - else - { - // Check the validity of the value to be set - if (false == attribute.compare(attributeItem.second)) - { - return false; - } - m_attributes[(attributeItem.second).getName()].setValue((attributeItem.second).getValue()); - } + return false; } - else if (type == DELETE ) + + // Check the validity of the value to be set + if (false == attribute.compare(attributeItem.second)) { - if (true == getAttribute((attributeItem.second).getName(), attribute)) - { - removeAttribute((attributeItem.second).getName()); - } + return false; } + m_attributes[(attributeItem.second).getName()].setValue((attributeItem.second).getValue()); } + return true; -} \ No newline at end of file +} + +SimulatorResourceModel SimulatorResourceModel::create(const OC::OCRepresentation &ocRep) +{ + SimulatorResourceModel resModel; + for (auto & attributeItem : ocRep) + { + SimulatorResourceModel::Attribute attribute; + if (attributeItem.type() == OC::AttributeType::Integer) + attribute.setValue(attributeItem.getValue()); + if (attributeItem.type() == OC::AttributeType::Double) + attribute.setValue(attributeItem.getValue()); + if (attributeItem.type() == OC::AttributeType::String) + attribute.setValue(attributeItem.getValue()); + + attribute.setName(attributeItem.attrname()); + resModel.m_attributes[attributeItem.attrname()] = attribute; + } + + return resModel; +} + diff --git a/service/simulator/src/simulator_resource_model.h b/service/simulator/src/simulator_resource_model.h index e4fe454..439082e 100644 --- a/service/simulator/src/simulator_resource_model.h +++ b/service/simulator/src/simulator_resource_model.h @@ -33,16 +33,25 @@ #include "OCPlatform.h" #include "OCApi.h" -class SimulatorResource; +class SimulatorResourceServer; /** * @class SimulatorResourceModel * @brief This class provides a set of functions for accessing and manipulating the resource model. */ class SimulatorResourceModel { - friend class SimulatorResource; + friend class SimulatorResourceServer; public: + + SimulatorResourceModel() = default; + SimulatorResourceModel(SimulatorResourceModel &&) = default; + SimulatorResourceModel(const SimulatorResourceModel &) = default; + SimulatorResourceModel &operator=(const SimulatorResourceModel &) = default; + SimulatorResourceModel &operator=(SimulatorResourceModel &&) = default; + + virtual ~SimulatorResourceModel() {} + /** * @class Attribute * @brief This class represents a resource attribute whose values can be generic. @@ -126,7 +135,8 @@ class SimulatorResourceModel std::string allowedValuesToString() const; std::vector allowedValuesToVectorString() const; - void addValuetoRepresentation(OC::OCRepresentation &rep, const std::string &key); + void addValuetoRepresentation(OC::OCRepresentation &rep, + const std::string &key) const; bool compare(Attribute &attribute); @@ -173,8 +183,6 @@ class SimulatorResourceModel int m_updateInterval; }; - typedef enum { POST, PUT, DELETE } UpdateType; - /** * This method is used to get the number of attributes in the resource. * @@ -200,7 +208,8 @@ class SimulatorResourceModel */ std::map getAttributes() const; - private: + static SimulatorResourceModel create(const OC::OCRepresentation &ocRep); + template void addAttribute(const std::string &attrName, const T &attrValue) { @@ -211,6 +220,7 @@ class SimulatorResourceModel } } + private: void setRange(const std::string &attrName, const int min, const int max); template @@ -233,11 +243,11 @@ class SimulatorResourceModel void removeAttribute(const std::string &attrName); - OC::OCRepresentation getOCRepresentation(); + OC::OCRepresentation getOCRepresentation() const; - bool update(OC::OCRepresentation &ocRep, UpdateType type); + bool update(OC::OCRepresentation &ocRep); - bool update(SimulatorResourceModel &repModel, UpdateType type); + bool update(SimulatorResourceModel &repModel); std::map m_attributes; }; diff --git a/service/simulator/src/simulator_resource_server.cpp b/service/simulator/src/simulator_resource_server.cpp new file mode 100644 index 0000000..84ebac6 --- /dev/null +++ b/service/simulator/src/simulator_resource_server.cpp @@ -0,0 +1,354 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "simulator_resource_server.h" +#include "simulator_attribute_automation.h" +#include "simulator_logger.h" + +SimulatorResourceServer::SimulatorResourceServer() + : m_resourceHandle(NULL), + m_property((OCResourceProperty) (OC_DISCOVERABLE | OC_OBSERVABLE)) {} + +SimulatorResult SimulatorResourceServer::setURI(const std::string &uri) +{ + if (m_resourceHandle) + return SIMULATOR_OPERATION_NOT_ALLOWED; + m_uri = uri; + return SIMULATOR_SUCCESS; +} + +std::string SimulatorResourceServer::getURI() const +{ + return m_uri; +} + +SimulatorResult SimulatorResourceServer::setResourceType(const std::string &resourceType) +{ + if (m_resourceHandle) + return SIMULATOR_OPERATION_NOT_ALLOWED; + m_resourceType = resourceType; + return SIMULATOR_SUCCESS; +} + +std::string SimulatorResourceServer::getResourceType() const +{ + return m_resourceType; +} + +SimulatorResult SimulatorResourceServer::setInterfaceType(const std::string &interfaceType) +{ + if (m_resourceHandle) + return SIMULATOR_OPERATION_NOT_ALLOWED; + m_interfaceType = interfaceType; + return SIMULATOR_SUCCESS; +} + +std::string SimulatorResourceServer::getInterfaceType() const +{ + return m_interfaceType; +} + +void SimulatorResourceServer::setName(const std::string &name) +{ + m_name = name; +} + +std::string SimulatorResourceServer::getName() const +{ + return m_name; +} + +SimulatorResult SimulatorResourceServer::setObservable(bool state) +{ + if (m_resourceHandle) + return SIMULATOR_OPERATION_NOT_ALLOWED; + + if (true == state) + m_property = static_cast(m_property | OC_OBSERVABLE); + else + m_property = static_cast(m_property ^ OC_OBSERVABLE); + + return SIMULATOR_SUCCESS; +} + +bool SimulatorResourceServer::isObservable() const +{ + return (m_property & OC_OBSERVABLE); +} + +SimulatorResult SimulatorResourceServer::start() +{ + if (m_resourceHandle) + return SIMULATOR_RESOURCE_ALREADY_REGISTERED; + + if (m_uri.empty() || m_resourceType.empty() || m_interfaceType.empty() + || !m_callback) + { + return SIMULATOR_BAD_INPUT; + } + + OCStackResult result = OC::OCPlatform::registerResource(m_resourceHandle, + m_uri, + m_resourceType, + m_interfaceType, + std::bind(&SimulatorResourceServer::entityHandler, + this, std::placeholders::_1), m_property); + + if (OC_STACK_OK != result) + return SIMULATOR_ERROR; + return SIMULATOR_SUCCESS; +} + +SimulatorResult SimulatorResourceServer::stop() +{ + if (nullptr == m_resourceHandle) + { + SIM_LOG(ILogger::ERROR, "Resourece is not registered!"); + return SIMULATOR_RESOURCE_NOT_REGISTERED; + } + + OCStackResult result = OC::OCPlatform::unregisterResource(m_resourceHandle); + if (OC_STACK_OK != result) + return SIMULATOR_ERROR; + + m_resourceHandle = nullptr; + return SIMULATOR_SUCCESS; +} + +void SimulatorResourceServer::setRange(const std::string &attrName, const int min, const int max) +{ + m_resModel.setRange(attrName, min, max); +} + +void SimulatorResourceServer::setUpdateInterval(const std::string &attrName, int interval) +{ + m_resModel.setUpdateInterval(attrName, interval); +} + +void SimulatorResourceServer::removeAttribute(const std::string &attrName) +{ + m_resModel.removeAttribute(attrName); + notifyListOfObservers(); +} + +void SimulatorResourceServer::updateAttributeFromAllowedValues(const std::string &attrName, + const int allowedValueIndex) +{ + m_resModel.updateAttributeFromAllowedValues(attrName, allowedValueIndex); + notifyListOfObservers(); +} + +SimulatorResourceModel SimulatorResourceServer::getModel() const +{ + return m_resModel; +} + +void SimulatorResourceServer::setModelChangeCallback(ResourceModelChangedCB callback) +{ + m_callback = callback; +} + +SimulatorResult SimulatorResourceServer::startUpdateAutomation(AutomationType type, + updateCompleteCallback callback, int &id) +{ + return m_updateAutomationMgr.startResourceAutomation(this, id, callback, type); +} + +SimulatorResult SimulatorResourceServer::startUpdateAutomation(const std::string &attrName, + AutomationType type, updateCompleteCallback callback, int &id) +{ + return m_updateAutomationMgr.startAttributeAutomation(this, attrName, id, callback, type); +} + +std::vector SimulatorResourceServer::getResourceAutomationIds() +{ + return m_updateAutomationMgr.getResourceAutomationIds(); +} + +std::vector SimulatorResourceServer::getAttributeAutomationIds() +{ + return m_updateAutomationMgr.getAttributeAutomationIds(); +} + +void SimulatorResourceServer::stopUpdateAutomation(const int id) +{ + m_updateAutomationMgr.stop(id); +} + +OC::OCRepresentation SimulatorResourceServer::getOCRepresentation() +{ + return m_resModel.getOCRepresentation(); +} + +bool SimulatorResourceServer::modifyResourceModel(OC::OCRepresentation &ocRep) +{ + bool status = m_resModel.update(ocRep); + if (true == status) + { + notifyListOfObservers(); + } + return status; +} + +OCEntityHandlerResult SimulatorResourceServer::entityHandler(std::shared_ptr + request) +{ + OCEntityHandlerResult errCode = OC_EH_ERROR; + if (!request) + { + return OC_EH_ERROR; + } + + if (OC::RequestHandlerFlag::RequestFlag & request->getRequestHandlerFlag()) + { + auto response = std::make_shared(); + response->setRequestHandle(request->getRequestHandle()); + response->setResourceHandle(request->getResourceHandle()); + + if ("GET" == request->getRequestType()) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] GET request received"); + response->setErrorCode(200); + response->setResponseResult(OC_EH_OK); + response->setResourceRepresentation(getOCRepresentation()); + + if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) + { + errCode = OC_EH_OK; + } + } + else if ("PUT" == request->getRequestType()) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] PUT request received"); + OC::OCRepresentation rep = request->getResourceRepresentation(); + if (true == modifyResourceModel(rep)) + { + response->setErrorCode(200); + response->setResponseResult(OC_EH_OK); + response->setResourceRepresentation(getOCRepresentation()); + } + else + { + response->setErrorCode(400); + response->setResponseResult(OC_EH_ERROR); + } + + if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) + { + errCode = OC_EH_OK; + } + } + else if ("POST" == request->getRequestType()) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] POST request received"); + OC::OCRepresentation rep = request->getResourceRepresentation(); + if (true == modifyResourceModel(rep)) + { + response->setErrorCode(200); + response->setResponseResult(OC_EH_OK); + response->setResourceRepresentation(getOCRepresentation()); + } + else + { + response->setErrorCode(400); + response->setResponseResult(OC_EH_ERROR); + } + + if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) + { + errCode = OC_EH_OK; + } + } + else if ("DELETE" == request->getRequestType()) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] DELETE request received!"); + OC::OCRepresentation rep = request->getResourceRepresentation(); + + // DELETE request handling not supported right now + response->setErrorCode(400); + response->setResponseResult(OC_EH_ERROR); + if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) + { + errCode = OC_EH_OK; + } + } + else + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] UNKNOWN type request received"); + response->setResponseResult(OC_EH_ERROR); + OC::OCPlatform::sendResponse(response); + errCode = OC_EH_ERROR; + } + } + + if (OC::RequestHandlerFlag::ObserverFlag & request->getRequestHandlerFlag()) + { + if (false == isObservable()) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE request received"); + SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending error as resource is in unobservable state"); + return OC_EH_ERROR; + } + + OC::ObservationInfo observationInfo = request->getObservationInfo(); + if (OC::ObserveAction::ObserveRegister == observationInfo.action) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE REGISTER request received"); + m_interestedObservers.push_back(observationInfo.obsId); + } + else if (OC::ObserveAction::ObserveUnregister == observationInfo.action) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE UNREGISTER request received"); + m_interestedObservers.erase(std::remove(m_interestedObservers.begin(), + m_interestedObservers.end(), + observationInfo.obsId), + m_interestedObservers.end()); + } + errCode = OC_EH_OK; + } + + return errCode; +} + +void SimulatorResourceServer::notifyListOfObservers () +{ + if (!m_resourceHandle) + { + return; + } + + if (m_interestedObservers.size()) + { + std::shared_ptr resourceResponse = + {std::make_shared()}; + + resourceResponse->setErrorCode(200); + resourceResponse->setResponseResult(OC_EH_OK); + resourceResponse->setResourceRepresentation(getOCRepresentation(), OC::DEFAULT_INTERFACE); + + SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending notification to all observers" << m_uri); + OC::OCPlatform::notifyListOfObservers(m_resourceHandle, m_interestedObservers, resourceResponse); + } + + if (m_callback) + { + m_callback(m_uri, m_resModel); + } +} diff --git a/service/simulator/src/simulator_resource.h b/service/simulator/src/simulator_resource_server.h similarity index 81% rename from service/simulator/src/simulator_resource.h rename to service/simulator/src/simulator_resource_server.h index ab5389f..e0dfc89 100644 --- a/service/simulator/src/simulator_resource.h +++ b/service/simulator/src/simulator_resource_server.h @@ -19,14 +19,14 @@ ******************************************************************/ /** - * @file simulator_resource.h + * @file simulator_resource_server.h * * @brief This file contains a class which represents a simulator resource that provides a set * of functions for operating a resource and performing automation on attribute values. */ -#ifndef SIMULATOR_RESOURCE_H_ -#define SIMULATOR_RESOURCE_H_ +#ifndef SIMULATOR_RESOURCE_SERVER_H_ +#define SIMULATOR_RESOURCE_SERVER_H_ #include "simulator_resource_model.h" #include "simulator_attribute_automation.h" @@ -34,10 +34,10 @@ class ResourceManager; /** - * @class SimulatorResource + * @class SimulatorResourceServer * @brief This class provides a set of functions for operating and automating a resource. */ -class SimulatorResource +class SimulatorResourceServer { friend class ResourceManager; @@ -45,14 +45,16 @@ class SimulatorResource typedef std::function ResourceModelChangedCB; + SimulatorResourceServer(); + /** * This method is used to set the resource URI. * * @param uri - Resource URI * - * @return void + * @return SimulatorResult */ - void setURI(const std::string &uri); + SimulatorResult setURI(const std::string &uri); /** * This method is used to get the resource URI. @@ -66,9 +68,9 @@ class SimulatorResource * * @param resourceType - Resource Type * - * @return void + * @return SimulatorResult */ - void setResourceType(const std::string &resourceType); + SimulatorResult setResourceType(const std::string &resourceType); /** * This method is used to get the resource URI. @@ -82,9 +84,9 @@ class SimulatorResource * * @param interfaceType - Interface Type of the resource * - * @return void + * @return SimulatorResult */ - void setInterfaceType(const std::string &interfaceType); + SimulatorResult setInterfaceType(const std::string &interfaceType); /** * This method is used to get the interface type of the resource. @@ -110,6 +112,22 @@ class SimulatorResource std::string getName() const; /** + * This method is used to set whether resource can be observable or not. + * + * @param state - true for resource observable, otherwise false. + * + * @return SimulatorResult + */ + SimulatorResult setObservable(bool state); + + /** + * This method is used to get the observable state of resource. + * + * @return bool - true if resource is observable, otherwise false. + */ + bool isObservable() const; + + /** * This method is used to start the attribute value automation for all attributes. * Once started, values for the attributes will be selected randomly from their allowed range * and the updated values will be notified to all the observers of the resource. @@ -118,7 +136,8 @@ class SimulatorResource * * @return SimulatorResult */ - SimulatorResult startUpdateAutomation(AutomationType type, int &id); + SimulatorResult startUpdateAutomation(AutomationType type, + updateCompleteCallback callback, int &id); /** * This method is used to start the attribute value automation for a specific attribute. @@ -130,7 +149,22 @@ class SimulatorResource * * @return SimulatorResult */ - SimulatorResult startUpdateAutomation(const std::string &attrName, AutomationType type, int &id); + SimulatorResult startUpdateAutomation(const std::string &attrName, AutomationType type, + updateCompleteCallback callback, int &id); + + /** + * This method is used to get the Ids of all ongoing resource update automation . + * + * @return Ids as vector of int + */ + std::vector getResourceAutomationIds(); + + /** + * This method is used to get the Ids of all ongoing attribute update automation . + * + * @return Ids as vector of int + */ + std::vector getAttributeAutomationIds(); /** * This method is used to stop the automation. @@ -244,23 +278,26 @@ class SimulatorResource void setModelChangeCallback(ResourceModelChangedCB callback); private: - OCResourceHandle getHandle() const; + SimulatorResult start(); + SimulatorResult stop(); OC::OCRepresentation getOCRepresentation(); - bool modifyResourceModel(OC::OCRepresentation &ocRep, SimulatorResourceModel::UpdateType type); + bool modifyResourceModel(OC::OCRepresentation &ocRep); OCEntityHandlerResult entityHandler(std::shared_ptr request); void notifyListOfObservers (); SimulatorResourceModel m_resModel; - OCResourceHandle m_resourceHandle; std::string m_uri; std::string m_resourceType; std::string m_interfaceType; std::string m_name; - OC::ObservationIds m_interestedObservers; ResourceModelChangedCB m_callback; UpdateAutomationManager m_updateAutomationMgr; + + OCResourceHandle m_resourceHandle; + OCResourceProperty m_property; + OC::ObservationIds m_interestedObservers; }; -typedef std::shared_ptr SimulatorResourcePtr; +typedef std::shared_ptr SimulatorResourceServerPtr; #endif -- 2.7.4