Implementation of APIs for managing resource list and callback
[platform/upstream/iotivity.git] / service / simulator / src / simulator_attribute_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 "simulator_attribute_automation.h"
22 #include "simulator_resource_server.h"
23 #include <thread>
24
25 #define SLEEP_FOR(X) if (X > 0) std::this_thread::sleep_for(std::chrono::milliseconds(X));
26
27 AttributeUpdateAutomation::AttributeUpdateAutomation(
28     SimulatorResourceServer *resource, const std::string &attrName, updateCompleteCallback callback,
29     int automationId, std::function<void (const int)> finishedCallback, AutomationType type,
30     int interval)
31     : m_resource(resource),
32       m_attrName(attrName),
33       m_type(type),
34       m_id(automationId),
35       m_status(false),
36       m_stopRequested(false),
37       m_updateInterval(interval),
38       m_callback(callback),
39       m_finishedCallback(finishedCallback) {}
40
41 SimulatorResult AttributeUpdateAutomation::start()
42 {
43     if (true == m_status)
44         return SIMULATOR_AUTOMATION_ALREADY_STARTED;
45
46     // Check the validity of attribute
47     SimulatorResourceModel resModel = m_resource->getModel();
48     if (false == resModel.getAttribute(m_attrName, m_attribute))
49         return SIMULATOR_ERROR;
50
51     if (m_updateInterval < 0)
52     {
53         m_updateInterval = m_attribute.getUpdateFrequencyTime();
54         if (0 > m_updateInterval)
55             m_updateInterval = 0;
56     }
57
58     m_thread = new std::thread(&AttributeUpdateAutomation::updateAttribute, this);
59     m_status = true;
60
61     return SIMULATOR_SUCCESS;
62 }
63
64 void AttributeUpdateAutomation::stop()
65 {
66     m_stopRequested = true;
67     m_thread->join();
68     m_status = false;
69 }
70
71 void AttributeUpdateAutomation::updateAttribute()
72 {
73     do
74     {
75         setAttributeValue();
76         if (m_stopRequested)
77             break;
78     }
79     while (AutomationType::RECURRENT == m_type);
80
81     m_status = false;
82
83     // Notify application through callback
84     if (m_callback)
85         m_callback(m_resource->getURI(), m_id);
86     if (m_finishedCallback && !m_stopRequested)
87         m_finishedCallback(m_id);
88 }
89
90 void AttributeUpdateAutomation::setAttributeValue()
91 {
92     if (0 == m_attribute.getValueType()) // For integer type values
93     {
94         int min;
95         int max;
96         m_attribute.getRange(min, max);
97         for (int value = min; value <= max; value++)
98         {
99             if (m_stopRequested)
100                 break;
101             m_resource->updateAttribute(m_attribute.getName(), value);
102             SLEEP_FOR(m_updateInterval);
103         }
104     }
105     else
106     {
107         for (int index = 0; index < m_attribute.getAllowedValuesSize(); index++)
108         {
109             if (m_stopRequested)
110                 break;
111             m_resource->updateAttributeFromAllowedValues(m_attribute.getName(), index);
112             SLEEP_FOR(m_updateInterval);
113         }
114     }
115 }
116
117
118 ResourceUpdateAutomation::ResourceUpdateAutomation(
119     SimulatorResourceServer *resource, updateCompleteCallback callback,
120     int automationId, std::function<void (const int)> finishedCallback, AutomationType type,
121     int interval)
122     : m_resource(resource),
123       m_type(type),
124       m_id(automationId),
125       m_status(false),
126       m_updateInterval(interval),
127       m_callback(callback),
128       m_finishedCallback(finishedCallback) {}
129
130 SimulatorResult ResourceUpdateAutomation::start()
131 {
132     if (true == m_status)
133         return SIMULATOR_AUTOMATION_ALREADY_STARTED;
134
135     m_resModel = m_resource->getModel();
136     std::map<std::string, SimulatorResourceModel::Attribute> attributes = m_resModel.getAttributes();
137     if (0 == attributes.size())
138     {
139         m_status = false;
140         return SIMULATOR_ERROR;
141     }
142
143     int id = 0;
144     for (auto & attribute : attributes)
145     {
146         AttributeUpdateAutomationPtr attributeAutomation = std::make_shared<AttributeUpdateAutomation>
147                 (m_resource, attribute.first, nullptr, id,
148                  std::bind(&ResourceUpdateAutomation::finished, this, std::placeholders::_1),
149                  m_type, m_updateInterval);
150         m_attrUpdationList[id++] = attributeAutomation;
151         if (SIMULATOR_SUCCESS != attributeAutomation->start())
152         {
153             m_status = false;
154             stop();
155             return SIMULATOR_ERROR;
156         }
157     }
158
159     m_status = true;
160     return SIMULATOR_SUCCESS;
161 }
162
163 void ResourceUpdateAutomation::finished(int id)
164 {
165     if (m_attrUpdationList.end() != m_attrUpdationList.find(id))
166     {
167         m_attrUpdationList.erase(m_attrUpdationList.find(id));
168     }
169
170     if (!m_attrUpdationList.size())
171     {
172         // Notify application through callback
173         if (m_callback)
174             m_callback(m_resource->getURI(), m_id);
175         if (m_finishedCallback)
176             m_finishedCallback(m_id);
177     }
178 }
179 void ResourceUpdateAutomation::stop()
180 {
181     // Stop all the attributes updation
182     for (auto & attrAutomation : m_attrUpdationList)
183     {
184         (attrAutomation.second)->stop();
185     }
186
187     m_attrUpdationList.clear();
188     m_status = false;
189 }
190
191 UpdateAutomationManager::UpdateAutomationManager()
192     : m_automationId(0) {}
193
194 SimulatorResult UpdateAutomationManager::startResourceAutomation(SimulatorResourceServer *resource,
195         int &id, updateCompleteCallback callback, AutomationType type, int interval)
196 {
197     std::lock_guard<std::mutex> lock(m_mutex);
198
199     ResourceUpdateAutomationPtr resourceAutomation(new ResourceUpdateAutomation(
200                 resource, callback, m_automationId,
201                 std::bind(&UpdateAutomationManager::automationFinished, this, std::placeholders::_1),
202                 type, interval));
203     SimulatorResult result = resourceAutomation->start();
204     if (SIMULATOR_SUCCESS != result)
205     {
206         id = -1;
207         return result;
208     }
209
210     m_resourceUpdationList[m_automationId] = resourceAutomation;
211     id = m_automationId++;
212     return result;
213 }
214
215 SimulatorResult UpdateAutomationManager::startAttributeAutomation(SimulatorResourceServer *resource,
216         const std::string &attrName, int &id, updateCompleteCallback callback, AutomationType type,
217         int interval)
218 {
219     std::lock_guard<std::mutex> lock(m_mutex);
220
221     AttributeUpdateAutomationPtr attributeAutomation(new AttributeUpdateAutomation(
222                 resource, attrName, callback, m_automationId,
223                 std::bind(&UpdateAutomationManager::automationFinished, this, std::placeholders::_1),
224                 type, interval));
225     SimulatorResult result = attributeAutomation->start();
226     if (SIMULATOR_SUCCESS != result)
227     {
228         id = -1;
229         return result;
230     }
231
232     m_attrUpdationList[m_automationId] = attributeAutomation;
233     id = m_automationId++;
234     return result;
235 }
236
237 std::vector<int> UpdateAutomationManager::getResourceAutomationIds()
238 {
239     std::vector<int> ids;
240     std::lock_guard<std::mutex> lock(m_mutex);
241     for (auto & automation : m_resourceUpdationList)
242         ids.push_back(automation.first);
243
244     return ids;
245 }
246
247 std::vector<int> UpdateAutomationManager::getAttributeAutomationIds()
248 {
249     std::vector<int> ids;
250     std::lock_guard<std::mutex> lock(m_mutex);
251     for (auto & automation : m_attrUpdationList)
252         ids.push_back(automation.first);
253
254     return ids;
255 }
256
257 void UpdateAutomationManager::stop(int automationId)
258 {
259     std::lock_guard<std::mutex> lock(m_mutex);
260     if (m_resourceUpdationList.end() != m_resourceUpdationList.find(automationId))
261     {
262         m_resourceUpdationList[automationId]->stop();
263         m_resourceUpdationList.erase(m_resourceUpdationList.find(automationId));
264     }
265     else if (m_attrUpdationList.end() != m_attrUpdationList.find(automationId))
266     {
267         m_attrUpdationList[automationId]->stop();
268         m_attrUpdationList.erase(m_attrUpdationList.find(automationId));
269     }
270 }
271
272 void UpdateAutomationManager::stopAll()
273 {
274     std::lock_guard<std::mutex> lock(m_mutex);
275     std::for_each(m_resourceUpdationList.begin(),
276                   m_resourceUpdationList.end(), [] (std::pair<int, ResourceUpdateAutomationPtr> element)
277     {
278         element.second->stop();
279     });
280     m_resourceUpdationList.clear();
281
282     std::for_each(m_attrUpdationList.begin(),
283                   m_attrUpdationList.end(), [] (std::pair<int, AttributeUpdateAutomationPtr> element)
284     {
285         element.second->stop();
286     });
287     m_attrUpdationList.clear();
288 }
289
290 void UpdateAutomationManager::automationFinished(int id)
291 {
292     std::lock_guard<std::mutex> lock(m_mutex);
293     if (m_resourceUpdationList.end() != m_resourceUpdationList.find(id))
294     {
295         m_resourceUpdationList.erase(m_resourceUpdationList.find(id));
296     }
297     else if (m_attrUpdationList.end() != m_attrUpdationList.find(id))
298     {
299         m_attrUpdationList.erase(m_attrUpdationList.find(id));
300     }
301 }