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"
32 const int SUCCESS_RESPONSE = 0;
34 std::map< std::string, DiagnosticsRequestEntry > diagnosticsRequestTable;
36 ThingsDiagnostics* ThingsDiagnostics::thingsDiagnosticsInstance = NULL;
38 ThingsDiagnostics* ThingsDiagnostics::getInstance()
40 if (thingsDiagnosticsInstance == NULL)
42 thingsDiagnosticsInstance = new ThingsDiagnostics();
44 return thingsDiagnosticsInstance;
47 void ThingsDiagnostics::deleteInstance()
49 if (thingsDiagnosticsInstance)
51 delete thingsDiagnosticsInstance;
52 thingsDiagnosticsInstance = NULL;
56 std::string ThingsDiagnostics::getAttributeByDiagnosticsName(DiagnosticsName name)
58 for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
60 if ((*it).m_name == name)
61 return (*it).m_attribute;
67 std::string ThingsDiagnostics::getUriByDiagnosticsName(DiagnosticsName name)
69 for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
71 if ((*it).m_name == name)
78 std::string ThingsDiagnostics::getUpdateVal(std::string diag)
80 std::map< std::string, DiagnosticsRequestEntry >::iterator it = diagnosticsRequestTable.find(
83 if (it == diagnosticsRequestTable.end())
86 return it->second.m_updateVal;
89 std::shared_ptr< OCResource > ThingsDiagnostics::getResource(std::string diag)
91 std::map< std::string, DiagnosticsRequestEntry >::iterator it = diagnosticsRequestTable.find(
94 if (it == diagnosticsRequestTable.end())
97 return it->second.m_resource;
100 DiagnosticsCallback ThingsDiagnostics::getCallback(std::string diag)
102 std::map< std::string, DiagnosticsRequestEntry >::iterator it = diagnosticsRequestTable.find(
105 if (it == diagnosticsRequestTable.end())
108 return it->second.m_callback;
111 std::string ThingsDiagnostics::getHostFromURI(std::string oldUri)
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(), "");
124 std::string ThingsDiagnostics::getListOfSupportedDiagnosticsUnits()
128 res = "{\"Diagnostics Units\":[";
130 auto it = DiagnosticsUnitTable.begin();
133 res = res + (*it).getJSON();
136 if (it == DiagnosticsUnitTable.end())
147 void ThingsDiagnostics::onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
148 const OCRepresentation& rep, const int eCode, std::string diag)
150 if (eCode == SUCCESS_RESPONSE)
152 std::cout << "GET request was successful" << std::endl;
154 std::cout << "\tResource URI: " << rep.getUri() << std::endl;
156 std::vector < OCRepresentation > children = rep.getChildren();
157 for (auto oit = children.begin(); oit != children.end(); ++oit)
159 std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
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);
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
176 ActionSet *newActionSet = new ActionSet();
177 newActionSet->actionsetName = diag;
179 for (auto oit = children.begin(); oit != children.end(); ++oit)
181 Action *newAction = new Action();
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;
189 Capability *newCapability = new Capability();
190 newCapability->capability = attr;
191 newCapability->status = getUpdateVal(diag);
193 newAction->listOfCapability.push_back(newCapability);
194 newActionSet->listOfAction.push_back(newAction);
197 // Request to create a new action set by using the above actionSet
198 g_groupmanager->addActionSet(resource, newActionSet,
200 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
202 std::bind(&ThingsDiagnostics::onCreateActionSet, this,
203 std::placeholders::_1, std::placeholders::_2,
204 std::placeholders::_3, diag)));
211 std::cout << "onPut Response error: " << eCode << std::endl;
216 void ThingsDiagnostics::onCreateActionSet(const HeaderOptions& headerOptions,
217 const OCRepresentation& rep, const int eCode, std::string diag)
219 if (eCode == SUCCESS_RESPONSE)
221 std::cout << "PUT request was successful" << std::endl;
223 std::shared_ptr < OCResource > resource = getResource(diag);
226 // Now, it is time to execute the action set.
227 g_groupmanager->executeActionSet(resource, diag,
229 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
231 std::bind(&ThingsDiagnostics::onExecuteForGroupAction, this,
232 std::placeholders::_1, std::placeholders::_2,
233 std::placeholders::_3, diag)));
238 std::cout << "onPut Response error: " << eCode << std::endl;
243 void ThingsDiagnostics::onExecuteForGroupAction(const HeaderOptions& headerOptions,
244 const OCRepresentation& rep, const int eCode, std::string diag)
246 if (eCode == SUCCESS_RESPONSE)
248 std::cout << "PUT request was successful" << std::endl;
250 getCallback(diag)(headerOptions, rep, eCode);
254 std::cout << "onPut Response error: " << eCode << std::endl;
259 void ThingsDiagnostics::onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep,
260 const int eCode, std::string diag)
262 if (eCode == SUCCESS_RESPONSE)
264 std::cout << "PUT request was successful" << std::endl;
266 getCallback(diag)(headerOptions, rep, eCode);
270 std::cout << "onPut Response error: " << eCode << std::endl;
275 bool ThingsDiagnostics::isSimpleResource(std::shared_ptr< OCResource > resource)
277 for (unsigned int i = 0; i < resource->getResourceInterfaces().size(); ++i)
279 //std::cout << resource->getResourceInterfaces().at(0) << std::endl;
280 if (resource->getResourceInterfaces().at(0) == BATCH_INTERFACE)
286 OCStackResult ThingsDiagnostics::reboot(std::shared_ptr< OCResource > resource,
287 DiagnosticsCallback callback)
291 std::cout << "resource is NULL\n";
292 return OC_STACK_ERROR;
295 std::string diag = "reboot";
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(
300 if (iter != diagnosticsRequestTable.end())
301 diagnosticsRequestTable.erase(iter);
303 // Create new request entry stored in the queue
304 DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
305 diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
307 QueryParamsMap query;
308 OCRepresentation rep;
310 if (isSimpleResource(resource))
312 // This resource is a simple resource. Just send a PUT message
313 OCRepresentation rep;
314 rep.setValue<std::string>(diag, "true");
316 return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
318 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
320 std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
321 std::placeholders::_2, std::placeholders::_3, diag)));
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,
331 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
333 std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
334 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
339 OCStackResult ThingsDiagnostics::factoryReset(std::shared_ptr< OCResource > resource,
340 DiagnosticsCallback callback)
344 std::cout << "resource is NULL\n";
345 return OC_STACK_ERROR;
348 std::string diag = "factoryreset";
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(
353 if (iter != diagnosticsRequestTable.end())
354 diagnosticsRequestTable.erase(iter);
356 // Create new request entry stored in the queue
357 DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
358 diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
360 QueryParamsMap query;
361 OCRepresentation rep;
363 if (isSimpleResource(resource))
365 // This resource is a simple resource. Just send a PUT message
366 OCRepresentation rep;
367 rep.setValue<std::string>("factoryReset", "true");
369 return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
371 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
373 std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
374 std::placeholders::_2, std::placeholders::_3, diag)));
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,
384 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
386 std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
387 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,