Base code for simulator module.
[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.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     SimulatorResource *resource, const std::string &attrName, AutomationType type, int interval)
29     : m_resource(resource),
30       m_attrName(attrName),
31       m_type(type),
32       m_status(false),
33       m_stopRequested(false),
34       m_updateInterval(interval) {}
35
36 SimulatorResult AttributeUpdateAutomation::start()
37 {
38     if (true == m_status)
39         return SIMULATOR_AUTOMATION_ALREADY_STARTED;
40
41     // Check the validity of attribute
42     SimulatorResourceModel resModel = m_resource->getModel();
43     if (false == resModel.getAttribute(m_attrName, m_attribute))
44         return SIMULATOR_ERROR;
45
46     if (m_updateInterval < 0)
47     {
48         m_updateInterval = m_attribute.getUpdateFrequencyTime();
49         if (0 > m_updateInterval)
50             m_updateInterval = 0;
51     }
52
53     m_thread = new std::thread(&AttributeUpdateAutomation::updateAttribute, this);
54     m_status = true;
55
56     return SIMULATOR_SUCCESS;
57 }
58
59 void AttributeUpdateAutomation::stop()
60 {
61     m_stopRequested = true;
62     m_thread->join();
63     m_status = false;
64 }
65
66 void AttributeUpdateAutomation::updateAttribute()
67 {
68     do
69     {
70         setAttributeValue();
71         if (m_stopRequested)
72             break;
73     }
74     while (AutomationType::RECURRENT == m_type);
75
76     m_status = false;
77 }
78
79 void AttributeUpdateAutomation::setAttributeValue()
80 {
81     if (0 == m_attribute.getValueType()) // For integer type values
82     {
83         int min;
84         int max;
85         m_attribute.getRange(min, max);
86         for (int value = min; value <= max; value++)
87         {
88             m_resource->updateAttribute(m_attribute.getName(), value);
89             SLEEP_FOR(m_updateInterval);
90         }
91     }
92     else
93     {
94         for (int index = 0; index < m_attribute.getAllowedValuesSize(); index++)
95         {
96             m_resource->updateAttributeFromAllowedValues(m_attribute.getName(), index);
97             SLEEP_FOR(m_updateInterval);
98         }
99     }
100 }
101
102
103 ResourceUpdateAutomation::ResourceUpdateAutomation(
104     SimulatorResource *resource, AutomationType type, int interval)
105     : m_resource(resource),
106       m_type(type),
107       m_status(false),
108       m_updateInterval(interval) {}
109
110 SimulatorResult ResourceUpdateAutomation::start()
111 {
112     if (true == m_status)
113         return SIMULATOR_AUTOMATION_ALREADY_STARTED;
114
115     m_resModel = m_resource->getModel();
116     std::map<std::string, SimulatorResourceModel::Attribute> attributes = m_resModel.getAttributes();
117     if (0 == attributes.size())
118     {
119         m_status = false;
120         return SIMULATOR_ERROR;
121     }
122
123     for (auto & attribute : attributes)
124     {
125         AttributeUpdateAutomationPtr attributeAutomation = std::make_shared<AttributeUpdateAutomation>
126                 (m_resource, attribute.first, m_type, m_updateInterval);
127         m_attrUpdationList.push_back(attributeAutomation);
128         if (SIMULATOR_SUCCESS != attributeAutomation->start())
129         {
130             m_status = false;
131             stop();
132             return SIMULATOR_ERROR;
133         }
134     }
135
136     m_status = true;
137     return SIMULATOR_SUCCESS;
138 }
139
140 void ResourceUpdateAutomation::stop()
141 {
142     // Stop all the attributes updation
143     for (auto & attrAutomation : m_attrUpdationList)
144     {
145         attrAutomation->stop();
146     }
147
148     m_attrUpdationList.clear();
149     m_status = false;
150 }
151
152 UpdateAutomationManager::UpdateAutomationManager()
153     : m_automationId(0) {}
154
155 SimulatorResult UpdateAutomationManager::startResourceAutomation(SimulatorResource *resource,
156         int &id, AutomationType type, int interval)
157 {
158     ResourceUpdateAutomationPtr resoureceAutomation(new ResourceUpdateAutomation(resource, type,
159             interval));
160     SimulatorResult result = resoureceAutomation->start();
161     if (SIMULATOR_SUCCESS != result)
162     {
163         id = -1;
164         return result;
165     }
166
167     std::lock_guard<std::mutex> lock(m_mutex);
168     m_resourceUpdationList[m_automationId++] = resoureceAutomation;
169     id = m_automationId - 1;
170     return result;
171 }
172
173 SimulatorResult UpdateAutomationManager::startAttributeAutomation(SimulatorResource *resource,
174         const std::string &attrName, int &id, AutomationType type, int interval)
175 {
176     AttributeUpdateAutomationPtr attributeAutomation(new AttributeUpdateAutomation(resource, attrName,
177             type, interval));
178     SimulatorResult result = attributeAutomation->start();
179     if (SIMULATOR_SUCCESS != result)
180     {
181         id = -1;
182         return result;
183     }
184
185     std::lock_guard<std::mutex> lock(m_mutex);
186     m_attrUpdationList[m_automationId++] = attributeAutomation;
187     id = m_automationId - 1;
188     return result;
189 }
190
191 void UpdateAutomationManager::stop(int automationId)
192 {
193     std::lock_guard<std::mutex> lock(m_mutex);
194     if (m_resourceUpdationList.end() != m_resourceUpdationList.find(automationId))
195     {
196         m_resourceUpdationList[automationId]->stop();
197         m_resourceUpdationList.erase(m_resourceUpdationList.find(automationId));
198     }
199     else if (m_attrUpdationList.end() != m_attrUpdationList.find(automationId))
200     {
201         m_attrUpdationList[automationId]->stop();
202         m_attrUpdationList.erase(m_attrUpdationList.find(automationId));
203     }
204 }
205
206 void UpdateAutomationManager::stopAll()
207 {
208     std::lock_guard<std::mutex> lock(m_mutex);
209     std::for_each(m_resourceUpdationList.begin(),
210                   m_resourceUpdationList.end(), [] (std::pair<int, ResourceUpdateAutomationPtr> element)
211     {
212         element.second->stop();
213     });
214     m_resourceUpdationList.clear();
215
216     std::for_each(m_attrUpdationList.begin(),
217                   m_attrUpdationList.end(), [] (std::pair<int, AttributeUpdateAutomationPtr> element)
218     {
219         element.second->stop();
220     });
221     m_attrUpdationList.clear();
222 }