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
25 #include "GroupManager.h"
32 #define DESC_DELIMITER "\""
33 #define ACTION_DELIMITER "*"
34 #define ATTR_DELIMITER "|"
38 std::map< std::vector< std::string >, CandidateCallback > candidateRequest;
39 std::map< std::vector< std::string >, CandidateCallback > candidateRequestForTimer;
40 std::map< std::string, std::map< std::string, std::shared_ptr< OCResource > > > rtForResourceList;
41 std::vector< std::string > allFoundResourceTypes;
43 template< typename T >
44 bool IsSubset(std::vector< T > full, std::vector< T > sub)
46 std::sort(full.begin(), full.end());
47 std::sort(sub.begin(), sub.end());
48 return std::includes(full.begin(), full.end(), sub.begin(), sub.end());
50 std::vector< std::string > &str_split(const std::string &s, char delim,
51 std::vector< std::string > &elems)
53 std::stringstream ss(s);
55 while (std::getline(ss, item, delim))
57 elems.push_back(item);
62 std::vector< std::string > str_split(const std::string &s, char delim)
64 std::vector< std::string > elems;
65 str_split(s, delim, elems);
69 void GroupManager::onFoundResource(std::shared_ptr< OCResource > resource, int waitsec)
72 std::string resourceURI;
73 std::string hostAddress;
76 // Do some operations with resource object.
80 std::cout << "DISCOVERED Resource:" << std::endl;
81 // Get the resource URI
82 resourceURI = resource->uri();
83 std::cout << "\tURI of the resource: " << resourceURI << std::endl;
85 // Get the resource host address
86 hostAddress = resource->host();
87 std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
89 // Get the resource types
90 std::cout << "\tList of resource types: " << std::endl;
92 hostAddress.append(resourceURI);
94 for (auto &resourceTypes : resource->getResourceTypes())
96 std::cout << "\t\t" << resourceTypes << std::endl;
98 if (std::find(allFoundResourceTypes.begin(), allFoundResourceTypes.end(),
99 resourceTypes) == allFoundResourceTypes.end())
101 allFoundResourceTypes.push_back(resourceTypes);
104 rtForResourceList[resourceTypes][hostAddress] = resource;
107 // Get the resource interfaces
108 std::cout << "\tList of resource interfaces: " << std::endl;
109 for (auto &resourceInterfaces : resource->getResourceInterfaces())
111 std::cout << "\t\t" << resourceInterfaces << std::endl;
116 findPreparedRequest(candidateRequest);
121 // Resource is invalid
122 std::cout << "Resource is invalid" << std::endl;
126 catch (std::exception& e)
132 GroupManager::GroupManager(void)
140 GroupManager::~GroupManager(void)
142 candidateRequest.clear();
143 candidateRequestForTimer.clear();
144 rtForResourceList.clear();
145 allFoundResourceTypes.clear();
148 void GroupManager::findPreparedRequest(
149 std::map< std::vector< std::string >, CandidateCallback > &request)
151 std::vector < std::shared_ptr < OCResource >> resources;
153 for (auto it = request.begin(); it != request.end();)
156 if (IsSubset(allFoundResourceTypes, it->first))
158 //std::cout << "IS SUBSET !!! \n";
160 for (unsigned int i = 0; i < it->first.size(); ++i)
163 for (auto secondIt = rtForResourceList[it->first.at(i)].begin();
164 secondIt != rtForResourceList[it->first.at(i)].end(); ++secondIt)
166 resources.push_back(secondIt->second);
170 it->second(resources);
172 //TODO : decide policy - callback only once
184 void GroupManager::lazyCallback(int second)
187 findPreparedRequest(candidateRequestForTimer);
191 OCStackResult GroupManager::findCandidateResources(std::vector< std::string > resourceTypes,
192 CandidateCallback callback, int waitsec)
194 if (resourceTypes.size() < 1)
196 return OC_STACK_ERROR;
199 std::sort(resourceTypes.begin(), resourceTypes.end());
200 resourceTypes.erase(std::unique(resourceTypes.begin(), resourceTypes.end()),
201 resourceTypes.end());
205 candidateRequestForTimer.insert(std::make_pair(resourceTypes, callback));
209 candidateRequest.insert(std::make_pair(resourceTypes, callback));
212 for (unsigned int i = 0; i < resourceTypes.size(); ++i)
214 std::cout << "resourceTypes : " << resourceTypes.at(i) << std::endl;
215 std::string query = "coap://224.0.1.187/oc/core?rt=";
216 query.append(resourceTypes.at(i));
217 OCPlatform::findResource("", query.c_str(),
218 std::function < void(std::shared_ptr < OCResource > resource)
219 > (std::bind(&GroupManager::onFoundResource, this, std::placeholders::_1,
226 std::function< void(int second) >(
227 std::bind(&GroupManager::lazyCallback, this, std::placeholders::_1)), waitsec);
259 std::map<std::string, CollectionPresenceCallback> presenceCallbacks;
261 // Callback to presence
262 void GroupManager::collectionPresenceHandler(OCStackResult result, const unsigned int nonce, const std::string& hostAddress, std::string host, std::string uri)
264 std::cout << "uri : " << uri << std::endl;
265 std::cout << "host : " << host << std::endl;
266 std::cout << "result : " << result << std::endl;
270 std::cout << "Nonce# " << nonce << std::endl;
272 case OC_STACK_PRESENCE_STOPPED:
273 std::cout << "Presence Stopped\n";
275 case OC_STACK_PRESENCE_DO_NOT_HANDLE:
276 std::cout << "Presence do not handle\n";
278 case OC_STACK_PRESENCE_TIMEOUT:
279 std::cout << "Presence TIMEOUT\n";
282 std::cout << "Error\n";
286 if(presenceCallbacks.find(uri) != presenceCallbacks.end())
288 (presenceCallbacks.find(uri)->second)(uri,result);
292 void GroupManager::checkCollectionRepresentation(const OCRepresentation& rep, CollectionPresenceCallback callback)
294 std::cout << "\tResource URI: " << rep.getUri() << std::endl;
297 if(rep.hasAttribute("name"))
299 std::cout << "\tRoom name: " << rep.getValue<std::string>("name") << std::endl;
302 std::vector<OCRepresentation> children = rep.getChildren();
304 for(auto oit = children.begin(); oit != children.end(); ++oit)
306 std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
307 std::vector<std::string> hostAddressVector = str_split(oit->getUri(), '/');
308 std::string hostAddress = "";
309 for(unsigned int i = 0 ; i < hostAddressVector.size() ; ++i)
313 hostAddress.append(hostAddressVector.at(i));
316 hostAddress.append("/");
322 std::vector<std::string> resourceTypes = oit->getResourceTypes();
323 for(unsigned int i = 0 ; i < resourceTypes.size() ; ++i)
325 std::cout << "\t\t\tresourcetype :" << resourceTypes.at(i) << std::endl;
328 std::string resourceType = "core.";
329 resourceType.append(str_split(oit->getUri(), '/').at(4));
330 std::cout << "\t\tconvertRT : " << resourceType << std::endl;
331 std::cout << "\t\thost : " << hostAddress << std::endl;
332 OCPlatform::OCPresenceHandle presenceHandle;
333 OCStackResult result = OCPlatform::subscribePresence(presenceHandle, hostAddress, resourceType ,
334 std::function< void(OCStackResult result, const unsigned int nonce, const std::string& hostAddress)>
335 (std::bind(&GroupManager::collectionPresenceHandler, this, std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,hostAddress,oit->getUri())));
337 if(result == OC_STACK_OK)
339 std::cout << "\t\tOK!" << std::endl;
340 presenceCallbacks.insert(std::make_pair(oit->getUri(),callback));
344 callback("",OC_STACK_ERROR);
350 void GroupManager::onGetForPresence(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode, CollectionPresenceCallback callback)
352 if (eCode == OC_STACK_OK)
354 std::cout << "GET request was successful" << std::endl;
355 std::cout << "Resource URI: " << rep.getUri() << std::endl;
357 checkCollectionRepresentation(rep,callback);
362 std::cout << "onGET Response error: " << eCode << std::endl;
363 callback("",OC_STACK_ERROR);
368 OCStackResult GroupManager::subscribeCollectionPresence(std::shared_ptr< OCResource > collectionResource, CollectionPresenceCallback callback)
370 OCStackResult result = OC_STACK_OK;
371 //callback("core.room",OC_STACK_OK);
373 QueryParamsMap queryParam;
375 //parameter 1 = resourceType
376 collectionResource->get("",DEFAULT_INTERFACE,queryParam,
377 std::function< void(const HeaderOptions& headerOptions,const OCRepresentation& rep,const int eCode)>
378 (std::bind(&GroupManager::onGetForPresence, this, std::placeholders::_1,std::placeholders::_2,std::placeholders::_3, callback)));
408 std::string GroupManager::getStringFromActionSet(const ActionSet *newActionSet)
410 std::string message = "";
412 message = newActionSet->actionsetName;
414 for(auto iterAction= newActionSet->listOfAction.begin(); iterAction != newActionSet->listOfAction.end();
417 message.append("uri=");
418 message.append((*iterAction)->target);
421 for( auto iterCapa = (*iterAction)->listOfCapability.begin(); iterCapa != (*iterAction)->listOfCapability.end();
424 message.append((*iterCapa)->capability);
426 message.append((*iterCapa)->status);
428 if( iterCapa + 1 != (*iterAction)->listOfCapability.end() )
429 message.append( "|");
432 if( iterAction + 1 != newActionSet->listOfAction.end())
441 ActionSet* GroupManager::getActionSetfromString(std::string desc)
444 char *iterTokenPtr = NULL;
445 char *iterToken = NULL;
446 char *description = NULL;
447 char *iterDescPtr = NULL;
449 char *attributes = NULL;
450 char *iterAttrbutesPtr = NULL;
453 char *iterAttrPtr = NULL;
455 std::string actionsetName;
457 ActionSet* actionset = NULL;
458 Action* action = NULL;
460 actionset = new ActionSet();
462 acitonRequest = new char[strlen((char *)desc.c_str() + 1)];
463 strncpy(acitonRequest, (char *)desc.c_str(), strlen((char *)desc.c_str()) + 1);
465 //printf("\t%s\n", acitonRequest);
466 if(acitonRequest != NULL)
468 iterToken = (char *)strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr);
470 while(iterToken != NULL)
472 if( strcmp(iterToken, "ActionSet") == 0)
473 {// if iterToken is ActionSet, will be created and added a new action set.
474 iterToken = (char *)strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is mean ':'.
475 iterToken = (char *)strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is body of action description.
477 description = new char[(strlen(iterToken) + 1)];
478 strncpy(description, iterToken, strlen(iterToken) + 1);
480 // Find the action name from description.
482 iterToken = (char *)strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
483 //while(iterToken != NULL)
484 if(iterToken != NULL)
487 actionsetName = std::string(iterToken);
488 // printf("ACTION SET NAME :: %s\n", *actionsetName);
489 iterToken = (char *)strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
493 }// end Action Set Name.
495 // New ActionSet Add to OCResource's ActionSet list.
496 // 1. Allocate a new pointer for actionset.
497 actionset = new ActionSet;
498 // 2. Initiate actionset.
499 actionset->actionsetName = std::string(actionsetName);
500 // printf("ACTION SET NAME :: %s\n", actionset->actionsetName);
502 while(iterToken != NULL)
506 // printf("ATTR Copied :: %s\n", iterToken);
507 attributes = new char[strlen(iterToken) + 1];
508 strncpy(attributes, iterToken, strlen(iterToken) + 1);
509 // printf("ATTR Copied :: %s\n", attributes);
511 iterToken = (char *)strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr);
512 while(iterToken != NULL)
514 attr = new char[(strlen(iterToken) + 1)];
515 strncpy(attr, iterToken, strlen(iterToken) + 1);
517 iterToken = (char *)strtok_r(attr, "=",&iterAttrPtr);
518 while(iterToken != NULL)
520 // Find the URI from description.
521 if(strcmp(iterToken, "uri") == 0)
523 iterToken = (char *)strtok_r(NULL, "=", &iterAttrPtr);
524 // printf("uri :: %s\n", iterToken);
526 action->target =std::string(iterToken);
528 Capability* capa = new Capability();
529 // printf("%s :: ", iterToken);
530 capa->capability = std::string(iterToken);
531 iterToken = (char *)strtok_r(NULL, "=", &iterAttrPtr);
532 // printf("%s\n", iterToken);
533 capa->status = std::string(iterToken);
535 action->listOfCapability.push_back(capa);
538 iterToken = (char *)strtok_r(NULL, "=", &iterAttrPtr);
541 iterToken = (char *)strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr);
544 actionset->listOfAction.push_back(action);
546 iterToken = (char *)strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
551 iterToken = (char *)strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
558 OCStackResult GroupManager::addActionSet(std::shared_ptr< OCResource > resource, const ActionSet* newActionSet, PutCallback cb)
560 // BUILD message of ActionSet which it is included delimiter.
561 std::string message = getStringFromActionSet(newActionSet);
562 OCRepresentation rep;
564 rep.setValue("ActionSet", message);
566 return resource->put(resource->getResourceTypes().front(),
567 GROUP_INTERFACE, rep, QueryParamsMap(),
572 OCStackResult GroupManager::executeActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback cb)
574 OCRepresentation rep;
576 rep.setValue("DoAction", actionsetName);
577 return resource->post(resource->getResourceTypes().front(),
578 GROUP_INTERFACE, rep, QueryParamsMap(),
582 OCStackResult GroupManager::getActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, GetCallback cb)
584 OCRepresentation rep;
586 rep.setValue("GetActionSet", actionsetName);
588 return resource->put(resource->getResourceTypes().front(),
589 GROUP_INTERFACE, rep, QueryParamsMap(),
594 OCStackResult GroupManager::deleteActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback cb)
596 OCRepresentation rep;
598 rep.setValue("DelActionSet", actionsetName);
600 return resource->put(resource->getResourceTypes().front(),
601 GROUP_INTERFACE, rep, QueryParamsMap(),