c66711a92fb16855770b18c37e378c071ed02834
[platform/upstream/iotivity.git] / service / simulator / src / service-provider / resource_update_automation.cpp
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include "resource_update_automation.h"
22 #include "simulator_resource_server_impl.h"
23 #include "simulator_exceptions.h"
24 #include "simulator_logger.h"
25 #include "logger.h"
26
27 #define ATAG "ATTRIBUTE_AUTOMATION"
28 #define RTAG "RESOURCE_AUTOMATION"
29
30 #define SLEEP_FOR(X) if (X > 0) std::this_thread::sleep_for(std::chrono::milliseconds(X));
31
32 AttributeUpdateAutomation::AttributeUpdateAutomation(int id, SimulatorResourceServer *resource,
33         const std::string &attrName, AutomationType type, int interval,
34         updateCompleteCallback callback, std::function<void (const int)> finishedCallback)
35     :   m_resource(resource),
36         m_attrName(attrName),
37         m_type(type),
38         m_id(id),
39         m_stopRequested(false),
40         m_updateInterval(interval),
41         m_callback(callback),
42         m_finishedCallback(finishedCallback),
43         m_thread(nullptr) {}
44
45 void AttributeUpdateAutomation::start()
46 {
47     // Check the validity of attribute
48     SimulatorResourceModel resModel = m_resource->getModel();
49     if (false == resModel.getAttribute(m_attrName, m_attribute))
50     {
51         OC_LOG_V(ERROR, ATAG, "Attribute:%s not present in resource!", m_attrName.c_str());
52         throw SimulatorException(SIMULATOR_ERROR, "Attribute is not present in resource!");
53     }
54
55     if (m_updateInterval < 0)
56     {
57         m_updateInterval = m_attribute.getUpdateFrequencyTime();
58         if (0 > m_updateInterval)
59             m_updateInterval = 0;
60     }
61
62     m_thread = new std::thread(&AttributeUpdateAutomation::updateAttribute, this);
63 }
64
65 void AttributeUpdateAutomation::stop()
66 {
67     m_stopRequested = true;
68     if (m_thread)
69         m_thread->join();
70 }
71
72 void AttributeUpdateAutomation::updateAttribute()
73 {
74     do
75     {
76         try
77         {
78             setAttributeValue();
79         }
80         catch (SimulatorException &e)
81         {
82             break;
83         }
84         if (m_stopRequested)
85             break;
86     }
87     while (AutomationType::RECURRENT == m_type);
88
89     if (!m_stopRequested)
90     {
91         OC_LOG_V(DEBUG, ATAG, "Attribute:%s automation is completed!", m_attrName.c_str());
92         SIM_LOG(ILogger::INFO, "Automation of " << m_attrName << " attribute is completed.");
93     }
94
95     // Notify application through callback
96     if (m_callback)
97         m_callback(m_resource->getURI(), m_id);
98
99     if (m_finishedCallback && !m_stopRequested)
100         m_finishedCallback(m_id);
101 }
102
103 void AttributeUpdateAutomation::setAttributeValue()
104 {
105     SimulatorResourceServerImpl *resourceImpl =
106         dynamic_cast<SimulatorResourceServerImpl *>(m_resource);
107     if (!resourceImpl)
108         return;
109
110     if (SimulatorResourceModel::Attribute::ValueType::INTEGER ==
111             m_attribute.getValueType()) // For integer type values
112     {
113         int min;
114         int max;
115
116         m_attribute.getRange(min, max);
117         for (int value = min; value <= max; value++)
118         {
119             if (m_stopRequested)
120                 break;
121             resourceImpl->updateAttributeValue(m_attribute.getName(), value);
122             resourceImpl->notifyApp();
123             SLEEP_FOR(m_updateInterval);
124         }
125     }
126     else
127     {
128         for (int index = 0; index < m_attribute.getAllowedValuesSize(); index++)
129         {
130             if (m_stopRequested)
131                 break;
132             resourceImpl->updateFromAllowedValues(m_attribute.getName(), index);
133             resourceImpl->notifyApp();
134             SLEEP_FOR(m_updateInterval);
135         }
136     }
137 }
138
139 ResourceUpdateAutomation::ResourceUpdateAutomation(int id, SimulatorResourceServer *resource,
140         AutomationType type, int interval, updateCompleteCallback callback,
141         std::function<void (const int)> finishedCallback)
142     :   m_resource(resource),
143         m_type(type),
144         m_id(id),
145         m_updateInterval(interval),
146         m_callback(callback),
147         m_finishedCallback(finishedCallback) {}
148
149 void ResourceUpdateAutomation::start()
150 {
151     m_resModel = m_resource->getModel();
152     std::map<std::string, SimulatorResourceModel::Attribute> attributes = m_resModel.getAttributes();
153     if (0 == attributes.size())
154     {
155         OC_LOG(ERROR, RTAG, "Resource has zero attributes!");
156         throw SimulatorException(SIMULATOR_ERROR, "Resource has zero attributes!");
157     }
158
159     int id = 0;
160     for (auto & attribute : attributes)
161     {
162         AttributeUpdateAutomationSP attributeAutomation(new AttributeUpdateAutomation(
163                     id, m_resource, attribute.first, m_type, m_updateInterval, nullptr,
164                     std::bind(&ResourceUpdateAutomation::finished, this, std::placeholders::_1)));
165
166         m_attrUpdationList[id++] = attributeAutomation;
167         try
168         {
169             attributeAutomation->start();
170         }
171         catch (SimulatorException &e)
172         {
173             stop();
174             throw;
175         }
176     }
177 }
178
179 void ResourceUpdateAutomation::finished(int id)
180 {
181     if (m_attrUpdationList.end() != m_attrUpdationList.find(id))
182     {
183         m_attrUpdationList.erase(m_attrUpdationList.find(id));
184     }
185
186     if (!m_attrUpdationList.size())
187     {
188         // Notify application through callback
189         if (m_callback)
190             m_callback(m_resource->getURI(), m_id);
191
192         if (m_finishedCallback)
193             m_finishedCallback(m_id);
194     }
195 }
196
197 void ResourceUpdateAutomation::stop()
198 {
199     // Stop all the attributes updation
200     for (auto & attrAutomation : m_attrUpdationList)
201     {
202         (attrAutomation.second)->stop();
203     }
204
205     m_attrUpdationList.clear();
206 }