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 GroupManager.cpp
24 #include "GroupManager.h"
31 #define PLAIN_DELIMITER "\""
32 #define ACTION_DELIMITER "*"
33 #define DESC_DELIMITER "|"
34 #define ATTR_DELIMITER "="
40 std::map< std::vector< std::string >, CandidateCallback > candidateRequest;
41 std::map< std::vector< std::string >, CandidateCallback > candidateRequestForTimer;
42 std::map< std::string, std::map< std::string, std::shared_ptr< OCResource > > > rtForResourceList;
43 std::vector< std::string > allFoundResourceTypes;
45 template< typename T >
46 bool IsSubset(std::vector< T > full, std::vector< T > sub)
48 std::sort(full.begin(), full.end());
49 std::sort(sub.begin(), sub.end());
50 return std::includes(full.begin(), full.end(), sub.begin(), sub.end());
52 std::vector< std::string > &str_split(const std::string &s, char delim,
53 std::vector< std::string > &elems)
55 std::stringstream ss(s);
57 while (std::getline(ss, item, delim))
59 elems.push_back(item);
64 std::vector< std::string > str_split(const std::string &s, char delim)
66 std::vector< std::string > elems;
67 str_split(s, delim, elems);
71 void GroupManager::onFoundResource(std::shared_ptr< OCResource > resource, int waitsec)
74 std::string resourceURI;
75 std::string hostAddress;
78 // Do some operations with resource object.
82 std::cout << "DISCOVERED Resource:" << std::endl;
83 // Get the resource URI
84 resourceURI = resource->uri();
85 std::cout << "\tURI of the resource: " << resourceURI << std::endl;
87 // Get the resource host address
88 hostAddress = resource->host();
89 std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
91 // Get the resource types
92 std::cout << "\tList of resource types: " << std::endl;
94 hostAddress.append(resourceURI);
96 for (auto &resourceTypes : resource->getResourceTypes())
98 std::cout << "\t\t" << resourceTypes << std::endl;
100 if (std::find(allFoundResourceTypes.begin(), allFoundResourceTypes.end(),
101 resourceTypes) == allFoundResourceTypes.end())
103 allFoundResourceTypes.push_back(resourceTypes);
106 rtForResourceList[resourceTypes][hostAddress] = resource;
109 // Get the resource interfaces
110 std::cout << "\tList of resource interfaces: " << std::endl;
111 for (auto &resourceInterfaces : resource->getResourceInterfaces())
113 std::cout << "\t\t" << resourceInterfaces << std::endl;
118 findPreparedRequest(candidateRequest);
123 // Resource is invalid
124 std::cout << "Resource is invalid" << std::endl;
128 catch (std::exception& e)
134 GroupManager::GroupManager(void)
142 GroupManager::~GroupManager(void)
144 candidateRequest.clear();
145 candidateRequestForTimer.clear();
146 rtForResourceList.clear();
147 allFoundResourceTypes.clear();
150 void GroupManager::findPreparedRequest(
151 std::map< std::vector< std::string >, CandidateCallback > &request)
153 std::vector< std::shared_ptr< OCResource > > resources;
155 for (auto it = request.begin(); it != request.end();)
158 if (IsSubset(allFoundResourceTypes, it->first))
160 //std::cout << "IS SUBSET !!! \n";
162 for (unsigned int i = 0; i < it->first.size(); ++i)
165 for (auto secondIt = rtForResourceList[it->first.at(i)].begin();
166 secondIt != rtForResourceList[it->first.at(i)].end(); ++secondIt)
168 resources.push_back(secondIt->second);
172 it->second(resources);
174 //TODO : decide policy - callback only once
186 void GroupManager::lazyCallback(int second)
189 findPreparedRequest(candidateRequestForTimer);
193 OCStackResult GroupManager::findCandidateResources(std::vector< std::string > resourceTypes,
194 CandidateCallback callback, int waitsec)
196 if (resourceTypes.size() < 1)
198 return OC_STACK_ERROR;
202 return OC_STACK_ERROR;
205 std::sort(resourceTypes.begin(), resourceTypes.end());
206 resourceTypes.erase(std::unique(resourceTypes.begin(), resourceTypes.end()),
207 resourceTypes.end());
211 candidateRequestForTimer.insert(std::make_pair(resourceTypes, callback));
215 candidateRequest.insert(std::make_pair(resourceTypes, callback));
218 for (unsigned int i = 0; i < resourceTypes.size(); ++i)
220 std::string query = "coap://224.0.1.187:5298/oc/core?rt=";
221 // std::cout << "resourceTypes : " << resourceTypes.at(i) << std::endl;
222 query.append(resourceTypes.at(i));
225 OCPlatform::findResource("", query.c_str(),
226 OC_ETHERNET | OC_WIFI,
227 std::function < void(std::shared_ptr < OCResource > resource)
228 > (std::bind(&GroupManager::onFoundResource, this, std::placeholders::_1,
231 OCPlatform::findResource("", query.c_str(),
232 std::function < void(std::shared_ptr < OCResource > resource)
233 > (std::bind(&GroupManager::onFoundResource, this, std::placeholders::_1,
241 std::function< void(int second) >(
242 std::bind(&GroupManager::lazyCallback, this, std::placeholders::_1)),
251 OCStackResult GroupManager::bindResourceToGroup(OCResourceHandle& childHandle, std::shared_ptr< OCResource > resource, OCResourceHandle& collectionHandle)
254 OCStackResult result = OCPlatform::registerResource(childHandle, resource);
256 cout << "\tresource registed!" << endl;
258 if(result == OC_STACK_OK)
260 OCPlatform::bindResource(collectionHandle, childHandle);
264 cout << "\tresource Error!" << endl;
276 std::map< std::string, CollectionPresenceCallback > presenceCallbacks;
278 // Callback to presence
279 void GroupManager::collectionPresenceHandler(OCStackResult result, const unsigned int nonce,
280 const std::string& hostAddress, std::string host, std::string uri)
282 std::cout << "uri : " << uri << std::endl;
283 std::cout << "host : " << host << std::endl;
284 std::cout << "result : " << result << std::endl;
288 std::cout << "Nonce# " << nonce << std::endl;
290 case OC_STACK_PRESENCE_STOPPED:
291 std::cout << "Presence Stopped\n";
293 case OC_STACK_PRESENCE_DO_NOT_HANDLE:
294 std::cout << "Presence do not handle\n";
296 case OC_STACK_PRESENCE_TIMEOUT:
297 std::cout << "Presence TIMEOUT\n";
300 std::cout << "Error\n";
304 if (presenceCallbacks.find(uri) != presenceCallbacks.end())
306 (presenceCallbacks.find(uri)->second)(uri, result);
310 void GroupManager::checkCollectionRepresentation(const OCRepresentation& rep,
311 CollectionPresenceCallback callback)
313 std::cout << "\tResource URI: " << rep.getUri() << std::endl;
316 if(rep.hasAttribute("name"))
318 std::cout << "\tRoom name: " << rep.getValue<std::string>("name") << std::endl;
321 std::vector< OCRepresentation > children = rep.getChildren();
323 if(children.size() == 0 )
325 callback("", OC_STACK_ERROR);
329 for (auto oit = children.begin(); oit != children.end(); ++oit)
331 std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
332 std::vector< std::string > hostAddressVector = str_split(oit->getUri(), '/');
333 std::string hostAddress = "";
334 for (unsigned int i = 0; i < hostAddressVector.size(); ++i)
338 hostAddress.append(hostAddressVector.at(i));
341 hostAddress.append("/");
346 std::vector< std::string > resourceTypes = oit->getResourceTypes();
347 for (unsigned int i = 0; i < resourceTypes.size(); ++i)
349 std::cout << "\t\t\tresourcetype :" << resourceTypes.at(i) << std::endl;
352 std::string resourceType = "core.";
353 resourceType.append(str_split(oit->getUri(), '/').at(4));
354 std::cout << "\t\tconvertRT : " << resourceType << std::endl;
355 std::cout << "\t\thost : " << hostAddress << std::endl;
356 OCPlatform::OCPresenceHandle presenceHandle;
359 OCStackResult result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
361 OC_ETHERNET | OC_WIFI,
363 void(OCStackResult result, const unsigned int nonce,
364 const std::string& hostAddress) >(
365 std::bind(&GroupManager::collectionPresenceHandler, this,
366 std::placeholders::_1, std::placeholders::_2,
367 std::placeholders::_3, hostAddress, oit->getUri())));
369 OCStackResult result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
372 void(OCStackResult result, const unsigned int nonce,
373 const std::string& hostAddress) >(
374 std::bind(&GroupManager::collectionPresenceHandler, this,
375 std::placeholders::_1, std::placeholders::_2,
376 std::placeholders::_3, hostAddress, oit->getUri())));
379 if (result == OC_STACK_OK)
381 std::cout << "\t\tOK!" << std::endl;
382 presenceCallbacks.insert(std::make_pair(oit->getUri(), callback));
386 callback("", OC_STACK_ERROR);
392 void GroupManager::onGetForPresence(const HeaderOptions& headerOptions,
393 const OCRepresentation& rep, const int eCode, CollectionPresenceCallback callback)
395 if (eCode == OC_STACK_OK)
397 std::cout << "GET request was successful" << std::endl;
398 std::cout << "Resource URI: " << rep.getUri() << std::endl;
400 checkCollectionRepresentation(rep, callback);
405 std::cout << "onGET Response error: " << eCode << std::endl;
406 callback("", OC_STACK_ERROR);
411 OCStackResult GroupManager::subscribeCollectionPresence(
412 std::shared_ptr< OCResource > collectionResource, CollectionPresenceCallback callback)
414 if(callback == NULL || collectionResource == NULL)
416 return OC_STACK_ERROR;
419 OCStackResult result = OC_STACK_OK;
420 //callback("core.room",OC_STACK_OK);
422 QueryParamsMap queryParam;
424 //parameter 1 = resourceType
425 collectionResource->get("", DEFAULT_INTERFACE, queryParam,
427 void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
429 std::bind(&GroupManager::onGetForPresence, this, std::placeholders::_1,
430 std::placeholders::_2, std::placeholders::_3, callback)));
439 std::string GroupManager::getStringFromActionSet(const ActionSet *newActionSet)
441 std::string message = "";
443 if(newActionSet == NULL)
446 message = newActionSet->actionsetName;
448 for (auto iterAction = newActionSet->listOfAction.begin();
449 iterAction != newActionSet->listOfAction.end(); iterAction++)
451 message.append("uri=");
452 message.append((*iterAction)->target);
455 for (auto iterCapa = (*iterAction)->listOfCapability.begin();
456 iterCapa != (*iterAction)->listOfCapability.end(); iterCapa++)
458 message.append((*iterCapa)->capability);
460 message.append((*iterCapa)->status);
462 if (iterCapa + 1 != (*iterAction)->listOfCapability.end())
466 if (iterAction + 1 != newActionSet->listOfAction.end())
475 ActionSet* GroupManager::getActionSetfromString(std::string desc)
479 char *plainText = NULL;
480 char *plainPtr = NULL;
482 ActionSet *actionset = new ActionSet();
483 plainText = new char[(desc.length() + 1)];
484 strcpy(plainText, desc.c_str());
486 token = strtok_r(plainText, ACTION_DELIMITER, &plainPtr);
490 actionset->actionsetName = std::string(token);
491 token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr);
502 char *descPtr = NULL;
503 char *desc = new char[(strlen(token) + 1)];
507 Action *action = NULL;
509 token = strtok_r(desc, DESC_DELIMITER, &descPtr);
511 // cout << "desc :: " << token << endl;
512 while (token != NULL)
514 char *attrPtr = NULL;
515 char *attr = new char[(strlen(token) + 1)];
519 // cout << "attr :: " << attr << endl;
521 token = strtok_r(attr, ATTR_DELIMITER, &attrPtr);
522 while (token != NULL)
524 if (strcmp(token, "uri") == 0)
526 token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
527 action = new Action();
531 action->target = std::string(token);
544 Capability *capa = new Capability();
545 capa->capability = std::string(token);
546 token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
547 capa->status = std::string(token);
551 action->listOfCapability.push_back(capa);
564 token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
568 token = strtok_r(NULL, DESC_DELIMITER, &descPtr);
571 actionset->listOfAction.push_back(action);
583 token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr);
590 OCStackResult GroupManager::addActionSet(std::shared_ptr< OCResource > resource,
591 const ActionSet* newActionSet, PutCallback cb)
593 // BUILD message of ActionSet which it is included delimiter.
594 if ((resource != NULL) && (newActionSet != NULL))
596 std::string message = getStringFromActionSet(newActionSet);
597 OCRepresentation rep;
599 rep.setValue("ActionSet", message);
601 return resource->put(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
602 QueryParamsMap(), cb);
606 return OC_STACK_ERROR;
610 OCStackResult GroupManager::executeActionSet(std::shared_ptr< OCResource > resource,
611 std::string actionsetName, PostCallback cb)
613 if (resource != NULL)
615 OCRepresentation rep;
617 rep.setValue("DoAction", actionsetName);
618 return resource->post(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
619 QueryParamsMap(), cb);
623 return OC_STACK_ERROR;
627 OCStackResult GroupManager::getActionSet(std::shared_ptr< OCResource > resource,
628 std::string actionsetName, PostCallback cb)
630 if (resource != NULL)
632 OCRepresentation rep;
634 rep.setValue("GetActionSet", actionsetName);
636 return resource->post(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
637 QueryParamsMap(), cb);
641 return OC_STACK_ERROR;
645 OCStackResult GroupManager::deleteActionSet(std::shared_ptr< OCResource > resource,
646 std::string actionsetName, PutCallback cb)
648 if (resource != NULL)
650 OCRepresentation rep;
652 rep.setValue("DelActionSet", actionsetName);
654 return resource->put(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
655 QueryParamsMap(), cb);
659 return OC_STACK_ERROR;