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