Removed execute permissions from non-executable files.
[platform/upstream/iotivity.git] / service / things-manager / sdk / src / ThingsDiagnostics.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 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 /// @file    ThingsDiagnostics.cpp
22 ///  @brief
23
24 #include <OCApi.h>
25 #include <OCPlatform.h>
26 #include <cstdlib>
27
28 #include "ThingsDiagnostics.h"
29
30 using namespace OC;
31
32 const int SUCCESS_RESPONSE = 0;
33
34 std::map< std::string, DiagnosticsRequestEntry > diagnosticsRequestTable;
35
36 ThingsDiagnostics* ThingsDiagnostics::thingsDiagnosticsInstance = NULL;
37
38 ThingsDiagnostics* ThingsDiagnostics::getInstance()
39 {
40     if (thingsDiagnosticsInstance == NULL)
41     {
42         thingsDiagnosticsInstance = new ThingsDiagnostics();
43     }
44     return thingsDiagnosticsInstance;
45 }
46
47 void ThingsDiagnostics::deleteInstance()
48 {
49     if (thingsDiagnosticsInstance)
50     {
51         delete thingsDiagnosticsInstance;
52         thingsDiagnosticsInstance = NULL;
53     }
54 }
55
56 std::string ThingsDiagnostics::getAttributeByDiagnosticsName(DiagnosticsName name)
57 {
58     for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
59     {
60         if ((*it).m_name == name)
61             return (*it).m_attribute;
62     }
63
64     return "";
65 }
66
67 std::string ThingsDiagnostics::getUriByDiagnosticsName(DiagnosticsName name)
68 {
69     for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
70     {
71         if ((*it).m_name == name)
72             return (*it).m_uri;
73     }
74
75     return "";
76 }
77
78 std::string ThingsDiagnostics::getUpdateVal(std::string diag)
79 {
80     std::map< std::string, DiagnosticsRequestEntry >::iterator it = diagnosticsRequestTable.find(
81             diag);
82
83     if (it == diagnosticsRequestTable.end())
84         return NULL;
85     else
86         return it->second.m_updateVal;
87
88 }
89 std::shared_ptr< OCResource > ThingsDiagnostics::getResource(std::string diag)
90 {
91     std::map< std::string, DiagnosticsRequestEntry >::iterator it = diagnosticsRequestTable.find(
92             diag);
93
94     if (it == diagnosticsRequestTable.end())
95         return NULL;
96     else
97         return it->second.m_resource;
98 }
99
100 DiagnosticsCallback ThingsDiagnostics::getCallback(std::string diag)
101 {
102     std::map< std::string, DiagnosticsRequestEntry >::iterator it = diagnosticsRequestTable.find(
103             diag);
104
105     if (it == diagnosticsRequestTable.end())
106         return NULL;
107     else
108         return it->second.m_callback;
109 }
110
111 std::string ThingsDiagnostics::getHostFromURI(std::string oldUri)
112 {
113     size_t f;
114     std::string newUri;
115
116     if ((f = oldUri.find("/factoryset/oic/")) != string::npos)
117         newUri = oldUri.replace(f, oldUri.size(), "");
118     else if ((f = oldUri.find("/oic/")) != string::npos)
119         newUri = oldUri.replace(f, oldUri.size(), "");
120
121     return newUri;
122 }
123
124 std::string ThingsDiagnostics::getListOfSupportedDiagnosticsUnits()
125 {
126     std::string res;
127
128     res = "{\"Diagnostics Units\":[";
129
130     auto it = DiagnosticsUnitTable.begin();
131     while (1)
132     {
133         res = res + (*it).getJSON();
134         it++;
135
136         if (it == DiagnosticsUnitTable.end())
137             break;
138         else
139             res += ",";
140     }
141
142     res += "]}";
143
144     return res;
145 }
146
147 void ThingsDiagnostics::onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
148         const OCRepresentation& rep, const int eCode, std::string diag)
149 {
150     if (eCode == SUCCESS_RESPONSE)
151     {
152         std::cout << "GET request was successful" << std::endl;
153
154         std::cout << "\tResource URI: " << rep.getUri() << std::endl;
155
156         std::vector < OCRepresentation > children = rep.getChildren();
157         for (auto oit = children.begin(); oit != children.end(); ++oit)
158         {
159             std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
160         }
161
162         // Get information by using diagnostics name(diag)
163         std::shared_ptr < OCResource > resource = getResource(diag);
164         std::string actionstring = diag;
165         std::string uri = getUriByDiagnosticsName(diag);
166         std::string attr = getAttributeByDiagnosticsName(diag);
167
168         if (uri == "")
169             return;
170
171         if (resource)
172         {
173             // In this nest, we create a new action set of which name is the dignostics name.
174             // Required information consists of a host address, URI, attribute key, and attribute
175             // value.
176             ActionSet *newActionSet = new ActionSet();
177             newActionSet->actionsetName = diag;
178
179             for (auto oit = children.begin(); oit != children.end(); ++oit)
180             {
181                 Action *newAction = new Action();
182
183                 // oit->getUri() includes a host address as well as URI.
184                 // We should split these to each other and only use the host address to create
185                 // a child resource's URI. Note that the collection resource and its child resource
186                 // are located in same host.
187                 newAction->target = getHostFromURI(oit->getUri()) + uri;
188
189                 Capability *newCapability = new Capability();
190                 newCapability->capability = attr;
191                 newCapability->status = getUpdateVal(diag);
192
193                 newAction->listOfCapability.push_back(newCapability);
194                 newActionSet->listOfAction.push_back(newAction);
195             }
196
197             // Request to create a new action set by using the above actionSet
198             g_groupmanager->addActionSet(resource, newActionSet,
199                     std::function<
200                             void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
201                                     const int eCode) >(
202                             std::bind(&ThingsDiagnostics::onCreateActionSet, this,
203                                     std::placeholders::_1, std::placeholders::_2,
204                                     std::placeholders::_3, diag)));
205
206         }
207
208     }
209     else
210     {
211         std::cout << "onPut Response error: " << eCode << std::endl;
212         std::exit(-1);
213     }
214 }
215
216 void ThingsDiagnostics::onCreateActionSet(const HeaderOptions& headerOptions,
217         const OCRepresentation& rep, const int eCode, std::string diag)
218 {
219     if (eCode == SUCCESS_RESPONSE)
220     {
221         std::cout << "PUT request was successful" << std::endl;
222
223         std::shared_ptr < OCResource > resource = getResource(diag);
224         if (resource)
225         {
226             // Now, it is time to execute the action set.
227             g_groupmanager->executeActionSet(resource, diag,
228                     std::function<
229                             void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
230                                     const int eCode) >(
231                             std::bind(&ThingsDiagnostics::onExecuteForGroupAction, this,
232                                     std::placeholders::_1, std::placeholders::_2,
233                                     std::placeholders::_3, diag)));
234         }
235     }
236     else
237     {
238         std::cout << "onPut Response error: " << eCode << std::endl;
239         std::exit(-1);
240     }
241 }
242
243 void ThingsDiagnostics::onExecuteForGroupAction(const HeaderOptions& headerOptions,
244         const OCRepresentation& rep, const int eCode, std::string diag)
245 {
246     if (eCode == SUCCESS_RESPONSE)
247     {
248         std::cout << "PUT request was successful" << std::endl;
249
250         getCallback(diag)(headerOptions, rep, eCode);
251     }
252     else
253     {
254         std::cout << "onPut Response error: " << eCode << std::endl;
255         std::exit(-1);
256     }
257 }
258
259 void ThingsDiagnostics::onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep,
260         const int eCode, std::string diag)
261 {
262     if (eCode == SUCCESS_RESPONSE)
263     {
264         std::cout << "PUT request was successful" << std::endl;
265
266         getCallback(diag)(headerOptions, rep, eCode);
267     }
268     else
269     {
270         std::cout << "onPut Response error: " << eCode << std::endl;
271         std::exit(-1);
272     }
273 }
274
275 bool ThingsDiagnostics::isSimpleResource(std::shared_ptr< OCResource > resource)
276 {
277     for (unsigned int i = 0; i < resource->getResourceInterfaces().size(); ++i)
278     {
279         //std::cout << resource->getResourceInterfaces().at(0) << std::endl;
280         if (resource->getResourceInterfaces().at(0) == BATCH_INTERFACE)
281             return false;
282     }
283     return true;
284 }
285
286 OCStackResult ThingsDiagnostics::reboot(std::shared_ptr< OCResource > resource,
287         DiagnosticsCallback callback)
288 {
289     if (!resource)
290     {
291         std::cout << "resource is NULL\n";
292         return OC_STACK_ERROR;
293     }
294
295     std::string diag = "reboot";
296
297     // Check the request queue if a previous request is still left. If so, remove it.
298     std::map< std::string, DiagnosticsRequestEntry >::iterator iter = diagnosticsRequestTable.find(
299             diag);
300     if (iter != diagnosticsRequestTable.end())
301         diagnosticsRequestTable.erase(iter);
302
303     // Create new request entry stored in the queue
304     DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
305     diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
306
307     QueryParamsMap query;
308     OCRepresentation rep;
309
310     if (isSimpleResource(resource))
311     {
312         // This resource is a simple resource. Just send a PUT message
313         OCRepresentation rep;
314         rep.setValue<std::string>(diag, "true");
315
316         return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
317                 std::function<
318                         void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
319                                 const int eCode) >(
320                         std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
321                                 std::placeholders::_2, std::placeholders::_3, diag)));
322     }
323     else
324     {
325         // This resource is a collection resource. It just acquires child resource's URI and send
326         // GET massages to the child resources in turn.
327         // First, request the child resources's URI.
328         // TODO: Add a deletion of actionset
329         return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
330                 std::function<
331                         void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
332                                 const int eCode) >(
333                         std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
334                                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
335                                 diag)));
336     }
337 }
338
339 OCStackResult ThingsDiagnostics::factoryReset(std::shared_ptr< OCResource > resource,
340         DiagnosticsCallback callback)
341 {
342     if (!resource)
343     {
344         std::cout << "resource is NULL\n";
345         return OC_STACK_ERROR;
346     }
347
348     std::string diag = "factoryreset";
349
350     // Check the request queue if a previous request is still left. If so, remove it.
351     std::map< std::string, DiagnosticsRequestEntry >::iterator iter = diagnosticsRequestTable.find(
352             diag);
353     if (iter != diagnosticsRequestTable.end())
354         diagnosticsRequestTable.erase(iter);
355
356     // Create new request entry stored in the queue
357     DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
358     diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
359
360     QueryParamsMap query;
361     OCRepresentation rep;
362
363     if (isSimpleResource(resource))
364     {
365         // This resource is a simple resource. Just send a PUT message
366         OCRepresentation rep;
367         rep.setValue<std::string>("factoryReset", "true");
368
369         return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
370                 std::function<
371                         void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
372                                 const int eCode) >(
373                         std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
374                                 std::placeholders::_2, std::placeholders::_3, diag)));
375     }
376     else
377     {
378         // This resource is a collection resource. It just acquires child resource's URI and send
379         // GET massages to the child resources in turn.
380         // First, request the child resources's URI.
381         // TODO: Add a deletion of actionset
382         return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
383                 std::function<
384                         void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
385                                 const int eCode) >(
386                         std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
387                                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
388                                 diag)));
389     }
390 }
391