1 //******************************************************************
3 // Copyright 2014 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 /// @file ThingsDiagnostics.cpp
25 #include <OCPlatform.h>
28 #include "ThingsDiagnostics.h"
34 const int SUCCESS_RESPONSE = 0;
36 std::map< std::string, DiagnosticsRequestEntry > diagnosticsRequestTable;
38 ThingsDiagnostics* ThingsDiagnostics::thingsDiagnosticsInstance = NULL;
40 ThingsDiagnostics* ThingsDiagnostics::getInstance()
42 if (thingsDiagnosticsInstance == NULL)
44 thingsDiagnosticsInstance = new ThingsDiagnostics();
46 return thingsDiagnosticsInstance;
49 void ThingsDiagnostics::deleteInstance()
51 if (thingsDiagnosticsInstance)
53 delete thingsDiagnosticsInstance;
54 thingsDiagnosticsInstance = NULL;
58 std::string ThingsDiagnostics::getAttributeByDiagnosticsName(DiagnosticsName name)
60 for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
62 if ((*it).m_name == name)
63 return (*it).m_attribute;
69 std::string ThingsDiagnostics::getUriByDiagnosticsName(DiagnosticsName name)
71 for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
73 if ((*it).m_name == name)
80 std::string ThingsDiagnostics::getUpdateVal(std::string diag)
82 std::map< std::string, DiagnosticsRequestEntry >::iterator it =
83 diagnosticsRequestTable.find(diag);
85 if (it == diagnosticsRequestTable.end())
88 return it->second.m_updateVal;
91 std::shared_ptr< OCResource > ThingsDiagnostics::getResource(std::string diag)
93 std::map< std::string, DiagnosticsRequestEntry >::iterator it =
94 diagnosticsRequestTable.find(diag);
96 if (it == diagnosticsRequestTable.end())
99 return it->second.m_resource;
102 DiagnosticsCallback ThingsDiagnostics::getCallback(std::string diag)
104 std::map< std::string, DiagnosticsRequestEntry >::iterator it =
105 diagnosticsRequestTable.find(diag);
107 if (it == diagnosticsRequestTable.end())
110 return it->second.m_callback;
113 std::string ThingsDiagnostics::getHostFromURI(std::string oldUri)
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(), "");
126 std::string ThingsDiagnostics::getListOfSupportedDiagnosticsUnits()
130 res = "{\"Diagnostics Units\":[";
132 auto it = DiagnosticsUnitTable.begin();
135 res = res + (*it).getJSON();
138 if (it == DiagnosticsUnitTable.end())
149 void ThingsDiagnostics::onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
150 const OCRepresentation& rep, const int eCode, std::string diag)
152 if (eCode == SUCCESS_RESPONSE)
154 std::cout << "GET request was successful" << std::endl;
156 std::cout << "\tResource URI: " << rep.getUri() << std::endl;
158 std::vector < OCRepresentation > children = rep.getChildren();
159 for (auto oit = children.begin(); oit != children.end(); ++oit)
161 std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
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);
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
178 ActionSet *newActionSet = new ActionSet();
179 newActionSet->actionsetName = diag;
181 for (auto oit = children.begin(); oit != children.end(); ++oit)
183 Action *newAction = new Action();
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;
191 Capability *newCapability = new Capability();
192 newCapability->capability = attr;
193 newCapability->status = getUpdateVal(diag);
195 newAction->listOfCapability.push_back(newCapability);
196 newActionSet->listOfAction.push_back(newAction);
199 // Request to create a new action set by using the above actionSet
200 g_groupmanager->addActionSet(resource, newActionSet,
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)));
215 std::cout << "onPut Response error: " << eCode << std::endl;
220 void ThingsDiagnostics::onCreateActionSet(const HeaderOptions& headerOptions,
221 const OCRepresentation& rep, const int eCode, std::string diag)
223 if (eCode == SUCCESS_RESPONSE)
225 std::cout << "PUT request was successful" << std::endl;
227 std::shared_ptr < OCResource > resource = getResource(diag);
230 // Now, it is time to execute the action set.
231 g_groupmanager->executeActionSet(resource, diag,
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)));
242 std::cout << "onPut Response error: " << eCode << std::endl;
247 void ThingsDiagnostics::onExecuteForGroupAction(const HeaderOptions& headerOptions,
248 const OCRepresentation& rep, const int eCode, std::string diag)
250 if (eCode == SUCCESS_RESPONSE)
252 std::cout << "PUT request was successful" << std::endl;
254 getCallback(diag)(headerOptions, rep, eCode);
258 std::cout << "onPut Response error: " << eCode << std::endl;
263 void ThingsDiagnostics::onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep,
264 const int eCode, std::string diag)
266 if (eCode == SUCCESS_RESPONSE)
268 std::cout << "PUT request was successful" << std::endl;
270 getCallback(diag)(headerOptions, rep, eCode);
274 std::cout << "onPut Response error: " << eCode << std::endl;
279 bool ThingsDiagnostics::isSimpleResource(std::shared_ptr< OCResource > resource)
281 for (unsigned int i = 0; i < resource->getResourceTypes().size(); ++i)
283 if (resource->getResourceTypes().at(0).find(".resourceset", 0) != std::string::npos)
290 OCStackResult ThingsDiagnostics::reboot(std::shared_ptr< OCResource > resource,
291 DiagnosticsCallback callback)
295 std::cout << "resource is NULL\n";
296 return OC_STACK_ERROR;
299 std::string diag = "reboot";
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);
307 // Create new request entry stored in the queue
308 DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
309 diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
311 QueryParamsMap query;
312 OCRepresentation rep;
314 if (isSimpleResource(resource))
316 // This resource is a simple resource. Just send a PUT message
317 OCRepresentation rep;
318 rep.setValue < std::string > (diag, "true");
320 return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
322 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
324 std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
325 std::placeholders::_2, std::placeholders::_3, diag)));
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,
335 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
337 std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
338 std::placeholders::_1, std::placeholders::_2,
339 std::placeholders::_3, diag)));
343 OCStackResult ThingsDiagnostics::factoryReset(std::shared_ptr< OCResource > resource,
344 DiagnosticsCallback callback)
348 std::cout << "resource is NULL\n";
349 return OC_STACK_ERROR;
352 std::string diag = "factoryreset";
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);
360 // Create new request entry stored in the queue
361 DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
362 diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
364 QueryParamsMap query;
365 OCRepresentation rep;
367 if (isSimpleResource(resource))
369 // This resource is a simple resource. Just send a PUT message
370 OCRepresentation rep;
371 rep.setValue < std::string > ("value", "true");
373 return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
375 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
377 std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
378 std::placeholders::_2, std::placeholders::_3, diag)));
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,
388 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
390 std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
391 std::placeholders::_1, std::placeholders::_2,
392 std::placeholders::_3, diag)));