resourceTypeName.c_str(), // const char * resourceTypeName
resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix
resourceHOST.c_str(), // const char * host
- resourceURI.c_str(), // const char * uri
+ (resourceHOST + resourceURI).c_str(), // const char * uri
EntityHandlerWrapper, // OCEntityHandler entityHandler
resourceProperties // uint8_t resourceProperties
);
resourceTypeName.c_str(), // const char * resourceTypeName
resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix
resourceHOST.c_str(), // const char * host
- resourceURI.c_str(), // const char * uri
+ (resourceHOST + resourceURI).c_str(), // const char * uri
nullptr, // OCEntityHandler entityHandler
resourceProperties // uint8_t resourceProperties
);
const std::shared_ptr< OCResource > resource)
{
uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
+ std::vector<std::string> resourceTypes = resource->getResourceTypes();
return checked_guard(m_server, &IServerWrapper::registerResourceWithHost,
- ref(resourceHandle), resource->host(), resource->uri(), "core.remote", "oc.mi.def",
+ ref(resourceHandle), resource->host(), resource->uri(), resourceTypes[0]/*"core.remote"*/, "oc.mi.def",
(EntityHandler) nullptr, resourceProperty);
}
.PHONY : pre resource sdk sampleapp
-
#.PHONY : lib tgm sdk sampleapp
all: .PHONY
sampleapp:
- cd ../../sampleapp/linux/tgmclient && $(MAKE)
- cp -Rdp ../../sampleapp/linux/tgmclient/tgmclient release/
+# cd ../../sampleapp/linux/tgmclient && $(MAKE)
+# cp -Rdp ../../sampleapp/linux/tgmclient/tgmclient release/
clean:
cd ../../sdk/build/linux && $(MAKE) clean
+++ /dev/null
-##
-# sampleapp build script
-##
-
-Import('env')
-
-if env.get('TARGET_OS') == 'linux':
- # Build linux sample app
- SConscript('linux/tgmclient/SConscript')
CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl
-CXX_INC := -I../../ -I../../inc/
+CXX_INC := -I../../ -I../../inc/ -I../../src/
CXX_INC += -I${IOT_BASE}/include/
CXX_INC += -I${IOT_BASE}/oc_logger/include
CXX_INC += -I${IOT_BASE}/csdk/stack/include
CXX_INC += -I${IOT_BASE}/csdk/ocsocket/include
CXX_INC += -I${IOT_BASE}/csdk/ocrandom/include
CXX_INC += -I${IOT_BASE}/csdk/logger/include
+CXX_INC += -I${IOT_BASE}/dependencies/cereal/include
CXX_LIB=-L""
+++ /dev/null
-//******************************************************************
-//
-// Copyright 2014 Samsung Electronics All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-/// @file TGMClient.h
-
-/// @brief This file contains the declaration of classes and its members related to TGMClient.
-
-#ifndef __OC_TGMCLIENT__
-#define __OC_TGMCLIENT__
-
-#include <string>
-#include <vector>
-#include <map>
-#include <cstdlib>
-#include "OCPlatform.h"
-#include "OCApi.h"
-
-using namespace OC;
-
-typedef std::function< void(std::vector< std::shared_ptr< OCResource > >) > CandidateCallback;
-typedef std::function< void(std::vector< std::shared_ptr< OCResource > >) > CollectionPresenceCallback;
-
-class TGMClient
-{
-public:
- /**
- * Constructor for TGMClient. Constructs a new TGMClient
- */
- TGMClient(void);
-
- /**
- * Virtual destructor
- */
- ~TGMClient(void);
-
- /**
- * API for candidate resources discovery.
- * Callback only call when all resource types found.
- *
- * @param resourceTypes - required resource types(called "candidate")
- * @param candidateCallback - callback. OCResource vector.
- *
- * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
- *
- * NOTE: OCStackResult is defined in ocstack.h.
- */
- OCStackResult findCandidateResources(std::vector< std::string > resourceTypes,
- CandidateCallback callback, int waitsec = -1);
-
- /**
- * API for Collection member's state subscribe.
- *
- * NOTE: NOT IMPLEMENT YET
- */
- OCStackResult subscribeCollectionPresence(OCResourceHandle&, CollectionPresenceCallback)
- {
- return OC_STACK_NOTIMPL;
- }
-
-private:
-
- void onFoundResource(std::shared_ptr< OCResource > resource, int waitsec);
- void findPreparedRequest(std::map< std::vector< std::string >, CandidateCallback > &request);
- void lazyCallback(int second);
-
-};
-
-#endif /* __OC_TGMCLIENT__*/
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file ThingsManager.h
+
+/// @brief This file contains the declaration of classes and its members related to TGMClient.
+
+#ifndef __OC_THINGSMANAGER__
+#define __OC_THINGSMANAGER__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "GroupManager.h"
+
+using namespace OC;
+
+
+class ThingsManager
+{
+public:
+ /**
+ * Constructor for TGMClient. Constructs a new TGMClient
+ */
+ ThingsManager(void);
+
+ /**
+ * Virtual destructor
+ */
+ ~ThingsManager(void);
+
+ /**
+ * API for candidate resources discovery.
+ * Callback only call when all resource types found.
+ *
+ * @param resourceTypes - required resource types(called "candidate")
+ * @param candidateCallback - callback. OCResource vector.
+ *
+ * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+ *
+ * NOTE: OCStackResult is defined in ocstack.h.
+ */
+ OCStackResult findCandidateResources(std::vector< std::string > resourceTypes,
+ std::function< void(std::vector< std::shared_ptr< OCResource > >) > callback, int waitsec = -1);
+
+ /**
+ * API for Collection member's state subscribe.
+ *
+ *
+ */
+ OCStackResult subscribeCollectionPresence(std::shared_ptr< OCResource >, std::function< void(std::string, OCStackResult) > );
+
+ // Group Synchronization
+ OCStackResult findGroup (std::vector <std::string> collectionResourceTypes, FindCallback resourceHandler);
+ OCStackResult createGroup (std::string collectionResourceType);
+ OCStackResult joinGroup (std::string collectionResourceType, OCResourceHandle resourceHandle);
+ OCStackResult joinGroup (const std::shared_ptr<OCResource> resource, OCResourceHandle resourceHandle);
+ OCStackResult leaveGroup (std::string collectionResourceType, OCResourceHandle resourceHandle);
+ void deleteGroup (std::string collectionResourceType);
+ std::map<std::string, OCResourceHandle> getGroupList ();
+
+ // Things Configuration
+ OCStackResult updateConfigurations(std::shared_ptr< OCResource > resource, std::map<std::string, std::string> configurations,
+ std::function< void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) > callback);
+ OCStackResult getConfigurations(std::shared_ptr< OCResource > resource, std::vector<std::string> configurations,
+ std::function< void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) > callback);
+ std::string getListOfSupportedConfigurationUnits();
+ OCStackResult doBootstrap(
+ std::function< void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) > callback);
+
+ // Things Diagnostics
+ OCStackResult reboot(std::shared_ptr< OCResource > resource,
+ std::function< void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) > callback);
+ OCStackResult factoryReset(std::shared_ptr< OCResource > resource,
+ std::function< void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) > callback);
+
+
+
+
+ // Group Action.
+ std::string getStringFromActionSet(const ActionSet *newActionSet);
+ ActionSet* getActionSetfromString(std::string desc);
+
+ OCStackResult addActionSet(std::shared_ptr< OCResource > resource, const ActionSet* newActionSet, PutCallback cb);
+ OCStackResult executeActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback cb);
+ OCStackResult getActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, GetCallback cb);
+ OCStackResult deleteActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback);
+
+};
+
+#endif /* __OC_THINGSMANAGER__*/
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file GroupManager.cpp
+/// @brief
+
+
+#include "GroupManager.h"
+#include <algorithm>
+#include <thread>
+#include <unistd.h>
+
+#include <string.h>
+
+#define DESC_DELIMITER "\""
+#define ACTION_DELIMITER "*"
+#define ATTR_DELIMITER "|"
+
+using namespace OC;
+
+std::map< std::vector< std::string >, CandidateCallback > candidateRequest;
+std::map< std::vector< std::string >, CandidateCallback > candidateRequestForTimer;
+std::map< std::string, std::map< std::string, std::shared_ptr< OCResource > > > rtForResourceList;
+std::vector< std::string > allFoundResourceTypes;
+
+template< typename T >
+bool IsSubset(std::vector< T > full, std::vector< T > sub)
+{
+ std::sort(full.begin(), full.end());
+ std::sort(sub.begin(), sub.end());
+ return std::includes(full.begin(), full.end(), sub.begin(), sub.end());
+}
+std::vector< std::string > &str_split(const std::string &s, char delim,
+ std::vector< std::string > &elems)
+{
+ std::stringstream ss(s);
+ std::string item;
+ while (std::getline(ss, item, delim))
+ {
+ elems.push_back(item);
+ }
+ return elems;
+}
+
+std::vector< std::string > str_split(const std::string &s, char delim)
+{
+ std::vector< std::string > elems;
+ str_split(s, delim, elems);
+ return elems;
+}
+
+void GroupManager::onFoundResource(std::shared_ptr< OCResource > resource, int waitsec)
+{
+
+ std::string resourceURI;
+ std::string hostAddress;
+ try
+ {
+ // Do some operations with resource object.
+ if (resource)
+ {
+
+ std::cout << "DISCOVERED Resource:" << std::endl;
+ // Get the resource URI
+ resourceURI = resource->uri();
+ std::cout << "\tURI of the resource: " << resourceURI << std::endl;
+
+ // Get the resource host address
+ hostAddress = resource->host();
+ std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
+
+ // Get the resource types
+ std::cout << "\tList of resource types: " << std::endl;
+
+ hostAddress.append(resourceURI);
+
+ for (auto &resourceTypes : resource->getResourceTypes())
+ {
+ std::cout << "\t\t" << resourceTypes << std::endl;
+
+ if (std::find(allFoundResourceTypes.begin(), allFoundResourceTypes.end(),
+ resourceTypes) == allFoundResourceTypes.end())
+ {
+ allFoundResourceTypes.push_back(resourceTypes);
+ }
+
+ rtForResourceList[resourceTypes][hostAddress] = resource;
+ }
+
+ // Get the resource interfaces
+ std::cout << "\tList of resource interfaces: " << std::endl;
+ for (auto &resourceInterfaces : resource->getResourceInterfaces())
+ {
+ std::cout << "\t\t" << resourceInterfaces << std::endl;
+ }
+
+ if (waitsec == -1)
+ {
+ findPreparedRequest(candidateRequest);
+ }
+ }
+ else
+ {
+ // Resource is invalid
+ std::cout << "Resource is invalid" << std::endl;
+ }
+
+ }
+ catch (std::exception& e)
+ {
+ //log(e.what());
+ }
+}
+
+GroupManager::GroupManager(void)
+{
+ ;
+}
+
+/**
+ * Virtual destructor
+ */
+GroupManager::~GroupManager(void)
+{
+ candidateRequest.clear();
+ candidateRequestForTimer.clear();
+ rtForResourceList.clear();
+ allFoundResourceTypes.clear();
+}
+
+void GroupManager::findPreparedRequest(
+ std::map< std::vector< std::string >, CandidateCallback > &request)
+{
+ std::vector < std::shared_ptr < OCResource >> resources;
+
+ for (auto it = request.begin(); it != request.end();)
+ {
+
+ if (IsSubset(allFoundResourceTypes, it->first))
+ {
+ //std::cout << "IS SUBSET !!! \n";
+
+ for (unsigned int i = 0; i < it->first.size(); ++i)
+ {
+
+ for (auto secondIt = rtForResourceList[it->first.at(i)].begin();
+ secondIt != rtForResourceList[it->first.at(i)].end(); ++secondIt)
+ {
+ resources.push_back(secondIt->second);
+ }
+ }
+
+ it->second(resources);
+
+ //TODO : decide policy - callback only once
+ request.erase(it++);
+ }
+ else
+ {
+ ++it;
+ }
+
+ }
+
+}
+
+void GroupManager::lazyCallback(int second)
+{
+ sleep(second);
+ findPreparedRequest(candidateRequestForTimer);
+
+}
+
+OCStackResult GroupManager::findCandidateResources(std::vector< std::string > resourceTypes,
+ CandidateCallback callback, int waitsec)
+{
+ if (resourceTypes.size() < 1)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ std::sort(resourceTypes.begin(), resourceTypes.end());
+ resourceTypes.erase(std::unique(resourceTypes.begin(), resourceTypes.end()),
+ resourceTypes.end());
+
+ if (waitsec != -1)
+ {
+ candidateRequestForTimer.insert(std::make_pair(resourceTypes, callback));
+ }
+ else
+ {
+ candidateRequest.insert(std::make_pair(resourceTypes, callback));
+ }
+
+ for (unsigned int i = 0; i < resourceTypes.size(); ++i)
+ {
+ std::cout << "resourceTypes : " << resourceTypes.at(i) << std::endl;
+ std::string query = "coap://224.0.1.187/oc/core?rt=";
+ query.append(resourceTypes.at(i));
+ OCPlatform::findResource("", query.c_str(),
+ std::function < void(std::shared_ptr < OCResource > resource)
+ > (std::bind(&GroupManager::onFoundResource, this, std::placeholders::_1,
+ waitsec)));
+ }
+
+ if (waitsec != -1)
+ {
+ std::thread exec(
+ std::function< void(int second) >(
+ std::bind(&GroupManager::lazyCallback, this, std::placeholders::_1)), waitsec);
+ exec.detach();
+ }
+
+ return OC_STACK_OK;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+ Presence Check
+*/
+
+
+
+std::map<std::string, CollectionPresenceCallback> presenceCallbacks;
+
+// Callback to presence
+void GroupManager::collectionPresenceHandler(OCStackResult result, const unsigned int nonce, const std::string& hostAddress, std::string host, std::string uri)
+{
+ std::cout << "uri : " << uri << std::endl;
+ std::cout << "host : " << host << std::endl;
+ std::cout << "result : " << result << std::endl;
+ switch(result)
+ {
+ case OC_STACK_OK:
+ std::cout << "Nonce# " << nonce << std::endl;
+ break;
+ case OC_STACK_PRESENCE_STOPPED:
+ std::cout << "Presence Stopped\n";
+ break;
+ case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+ std::cout << "Presence do not handle\n";
+ break;
+ case OC_STACK_PRESENCE_TIMEOUT:
+ std::cout << "Presence TIMEOUT\n";
+ break;
+ default:
+ std::cout << "Error\n";
+ break;
+ }
+
+ if(presenceCallbacks.find(uri) != presenceCallbacks.end())
+ {
+ (presenceCallbacks.find(uri)->second)(uri,result);
+ }
+}
+
+void GroupManager::checkCollectionRepresentation(const OCRepresentation& rep, CollectionPresenceCallback callback)
+{
+ std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+/* //bug not found
+ if(rep.hasAttribute("name"))
+ {
+ std::cout << "\tRoom name: " << rep.getValue<std::string>("name") << std::endl;
+ }
+*/
+ std::vector<OCRepresentation> children = rep.getChildren();
+
+ for(auto oit = children.begin(); oit != children.end(); ++oit)
+ {
+ std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+ std::vector<std::string> hostAddressVector = str_split(oit->getUri(), '/');
+ std::string hostAddress = "";
+ for(unsigned int i = 0 ; i < hostAddressVector.size() ; ++i)
+ {
+ if(i < 3)
+ {
+ hostAddress.append(hostAddressVector.at(i));
+ if(i!=2)
+ {
+ hostAddress.append("/");
+ }
+ }
+ }
+
+
+ std::vector<std::string> resourceTypes = oit->getResourceTypes();
+ for(unsigned int i = 0 ; i < resourceTypes.size() ; ++i)
+ {
+ std::cout << "\t\t\tresourcetype :" << resourceTypes.at(i) << std::endl;
+ }
+
+ std::string resourceType = "core.";
+ resourceType.append(str_split(oit->getUri(), '/').at(4));
+ std::cout << "\t\tconvertRT : " << resourceType << std::endl;
+ std::cout << "\t\thost : " << hostAddress << std::endl;
+ OCPlatform::OCPresenceHandle presenceHandle;
+ OCStackResult result = OCPlatform::subscribePresence(presenceHandle, hostAddress, resourceType ,
+ std::function< void(OCStackResult result, const unsigned int nonce, const std::string& hostAddress)>
+ (std::bind(&GroupManager::collectionPresenceHandler, this, std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,hostAddress,oit->getUri())));
+
+ if(result == OC_STACK_OK)
+ {
+ std::cout << "\t\tOK!" << std::endl;
+ presenceCallbacks.insert(std::make_pair(oit->getUri(),callback));
+ }
+ else
+ {
+ callback("",OC_STACK_ERROR);
+ }
+
+ }
+}
+
+void GroupManager::onGetForPresence(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode, CollectionPresenceCallback callback)
+{
+ if (eCode == OC_STACK_OK)
+ {
+ std::cout << "GET request was successful" << std::endl;
+ std::cout << "Resource URI: " << rep.getUri() << std::endl;
+
+ checkCollectionRepresentation(rep,callback);
+
+ }
+ else
+ {
+ std::cout << "onGET Response error: " << eCode << std::endl;
+ callback("",OC_STACK_ERROR);
+ std::exit(-1);
+ }
+}
+
+OCStackResult GroupManager::subscribeCollectionPresence(std::shared_ptr< OCResource > collectionResource, CollectionPresenceCallback callback)
+{
+ OCStackResult result = OC_STACK_OK;
+ //callback("core.room",OC_STACK_OK);
+
+ QueryParamsMap queryParam;
+
+ //parameter 1 = resourceType
+ collectionResource->get("",DEFAULT_INTERFACE,queryParam,
+ std::function< void(const HeaderOptions& headerOptions,const OCRepresentation& rep,const int eCode)>
+ (std::bind(&GroupManager::onGetForPresence, this, std::placeholders::_1,std::placeholders::_2,std::placeholders::_3, callback)));
+
+ return result;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+ Group Action
+*/
+
+std::string GroupManager::getStringFromActionSet(const ActionSet *newActionSet)
+{
+ std::string message = "";
+
+ message = newActionSet->actionsetName;
+ message.append("*");
+ for(auto iterAction= newActionSet->listOfAction.begin(); iterAction != newActionSet->listOfAction.end();
+ iterAction++)
+ {
+ message.append("uri=");
+ message.append((*iterAction)->target);
+ message.append("|");
+
+ for( auto iterCapa = (*iterAction)->listOfCapability.begin(); iterCapa != (*iterAction)->listOfCapability.end();
+ iterCapa++)
+ {
+ message.append((*iterCapa)->capability);
+ message.append("=");
+ message.append((*iterCapa)->status);
+
+ if( iterCapa + 1 != (*iterAction)->listOfCapability.end() )
+ message.append( "|");
+ }
+
+ if( iterAction + 1 != newActionSet->listOfAction.end())
+ {
+ message.append("*");
+ }
+ }
+
+ return message;
+}
+
+ActionSet* GroupManager::getActionSetfromString(std::string desc)
+{
+ char *acitonRequest;
+ char *iterTokenPtr = NULL;
+ char *iterToken = NULL;
+ char *description = NULL;
+ char *iterDescPtr = NULL;
+
+ char *attributes = NULL;
+ char *iterAttrbutesPtr = NULL;
+
+ char *attr = NULL;
+ char *iterAttrPtr = NULL;
+
+ std::string actionsetName;
+
+ ActionSet* actionset = NULL;
+ Action* action = NULL;
+
+ actionset = new ActionSet();
+
+ acitonRequest = new char[strlen((char *)desc.c_str() + 1)];
+ strncpy(acitonRequest, (char *)desc.c_str(), strlen((char *)desc.c_str()) + 1);
+
+ //printf("\t%s\n", acitonRequest);
+ if(acitonRequest != NULL)
+ {
+ iterToken = (char *)strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr);
+
+ while(iterToken != NULL)
+ {
+ if( strcmp(iterToken, "ActionSet") == 0)
+ {// if iterToken is ActionSet, will be created and added a new action set.
+ iterToken = (char *)strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is mean ':'.
+ iterToken = (char *)strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is body of action description.
+
+ description = new char[(strlen(iterToken) + 1)];
+ strncpy(description, iterToken, strlen(iterToken) + 1);
+
+ // Find the action name from description.
+ iterDescPtr = NULL;
+ iterToken = (char *)strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
+ //while(iterToken != NULL)
+ if(iterToken != NULL)
+ {
+ // Actionset name.
+ actionsetName = std::string(iterToken);
+ // printf("ACTION SET NAME :: %s\n", *actionsetName);
+ iterToken = (char *)strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
+ } else {
+ return NULL;
+
+ }// end Action Set Name.
+
+ // New ActionSet Add to OCResource's ActionSet list.
+ // 1. Allocate a new pointer for actionset.
+ actionset = new ActionSet;
+ // 2. Initiate actionset.
+ actionset->actionsetName = std::string(actionsetName);
+ // printf("ACTION SET NAME :: %s\n", actionset->actionsetName);
+
+ while(iterToken != NULL)
+ {
+ action = new Action;
+
+ // printf("ATTR Copied :: %s\n", iterToken);
+ attributes = new char[strlen(iterToken) + 1];
+ strncpy(attributes, iterToken, strlen(iterToken) + 1);
+ // printf("ATTR Copied :: %s\n", attributes);
+
+ iterToken = (char *)strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr);
+ while(iterToken != NULL)
+ {
+ attr = new char[(strlen(iterToken) + 1)];
+ strncpy(attr, iterToken, strlen(iterToken) + 1);
+
+ iterToken = (char *)strtok_r(attr, "=",&iterAttrPtr);
+ while(iterToken != NULL)
+ {
+ // Find the URI from description.
+ if(strcmp(iterToken, "uri") == 0)
+ {
+ iterToken = (char *)strtok_r(NULL, "=", &iterAttrPtr);
+ // printf("uri :: %s\n", iterToken);
+
+ action->target =std::string(iterToken);
+ } else {
+ Capability* capa = new Capability();
+ // printf("%s :: ", iterToken);
+ capa->capability = std::string(iterToken);
+ iterToken = (char *)strtok_r(NULL, "=", &iterAttrPtr);
+ // printf("%s\n", iterToken);
+ capa->status = std::string(iterToken);
+
+ action->listOfCapability.push_back(capa);
+ }
+
+ iterToken = (char *)strtok_r(NULL, "=", &iterAttrPtr);
+ }
+
+ iterToken = (char *)strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr);
+ }// End of Action
+
+ actionset->listOfAction.push_back(action);
+
+ iterToken = (char *)strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
+ }
+
+ return actionset;
+ }
+ iterToken = (char *)strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
+ }
+ }
+
+ return NULL;
+}
+
+OCStackResult GroupManager::addActionSet(std::shared_ptr< OCResource > resource, const ActionSet* newActionSet, PutCallback cb)
+{
+ // BUILD message of ActionSet which it is included delimiter.
+ std::string message = getStringFromActionSet(newActionSet);
+ OCRepresentation rep;
+
+ rep.setValue("ActionSet", message);
+
+ return resource->put(resource->getResourceTypes().front(),
+ GROUP_INTERFACE, rep, QueryParamsMap(),
+ cb );
+}
+
+
+OCStackResult GroupManager::executeActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback cb)
+{
+ OCRepresentation rep;
+
+ rep.setValue("DoAction", actionsetName);
+ return resource->post(resource->getResourceTypes().front(),
+ GROUP_INTERFACE, rep, QueryParamsMap(),
+ cb );
+}
+
+OCStackResult GroupManager::getActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, GetCallback cb)
+{
+ OCRepresentation rep;
+
+ rep.setValue("GetActionSet", actionsetName);
+
+ return resource->put(resource->getResourceTypes().front(),
+ GROUP_INTERFACE, rep, QueryParamsMap(),
+ cb );
+}
+
+
+OCStackResult GroupManager::deleteActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback cb)
+{
+ OCRepresentation rep;
+
+ rep.setValue("DelActionSet", actionsetName);
+
+ return resource->put(resource->getResourceTypes().front(),
+ GROUP_INTERFACE, rep, QueryParamsMap(),
+ cb );
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file GroupManager.h
+
+/// @brief This file contains the declaration of classes and its members related to TGMClient.
+
+#ifndef __OC_GROUPMANAGER__
+#define __OC_GROUPMANAGER__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+typedef std::function< void(std::vector< std::shared_ptr< OCResource > >) > CandidateCallback;
+typedef std::function< void(std::string, OCStackResult) > CollectionPresenceCallback;
+
+typedef std::function<void(const HeaderOptions&, const OCRepresentation&, const int)> GetCallback;
+typedef std::function<void(const HeaderOptions&, const OCRepresentation&, const int)> PostCallback;
+typedef std::function<void(const HeaderOptions&, const OCRepresentation&, const int)> PutCallback;
+
+
+class Capability
+{
+public:
+ std::string capability;
+ std::string status;
+};
+
+class Action
+{
+public:
+ Action() : target("")
+ {
+ }
+ ~Action()
+ {
+ listOfCapability.clear();
+ }
+ std::string target;
+
+ std::vector<Capability*> listOfCapability;
+};
+
+class ActionSet
+{
+public:
+ ActionSet() : actionsetName("")
+ {
+ }
+ ~ActionSet()
+ {
+ listOfAction.clear();
+ }
+ std::string actionsetName;
+
+ std::vector<Action*> listOfAction;
+};
+
+
+class GroupManager
+{
+public:
+ /**
+ * Constructor for TGMClient. Constructs a new TGMClient
+ */
+ GroupManager(void);
+
+ /**
+ * Virtual destructor
+ */
+ ~GroupManager(void);
+
+ /**
+ * API for candidate resources discovery.
+ * Callback only call when all resource types found.
+ *
+ * @param resourceTypes - required resource types(called "candidate")
+ * @param candidateCallback - callback. OCResource vector.
+ *
+ * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+ *
+ * NOTE: OCStackResult is defined in ocstack.h.
+ */
+ OCStackResult findCandidateResources(std::vector< std::string > resourceTypes,
+ CandidateCallback callback, int waitsec = -1);
+
+ /**
+ * API for Collection member's state subscribe.
+ *
+ * NOTE: NOT IMPLEMENT YET
+ */
+ OCStackResult subscribeCollectionPresence(std::shared_ptr< OCResource > resource, CollectionPresenceCallback);
+
+private:
+
+ void onFoundResource(std::shared_ptr< OCResource > resource, int waitsec);
+ void findPreparedRequest(std::map< std::vector< std::string >, CandidateCallback > &request);
+ void lazyCallback(int second);
+
+ void onGetForPresence(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode,CollectionPresenceCallback callback);
+ void checkCollectionRepresentation(const OCRepresentation& rep, CollectionPresenceCallback callback);
+ void collectionPresenceHandler(OCStackResult result, const unsigned int nonce, const std::string& hostAddress, std::string host, std::string uri);
+
+
+
+
+
+ /**
+ * API for Collection(Group) action.
+ */
+
+public:
+ std::string getStringFromActionSet(const ActionSet *newActionSet);
+ ActionSet* getActionSetfromString(std::string desc);
+
+ OCStackResult addActionSet(std::shared_ptr< OCResource > resource, const ActionSet* newActionSet, PutCallback cb);
+ OCStackResult executeActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback cb);
+ OCStackResult getActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, GetCallback cb);
+ OCStackResult deleteActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback);
+};
+
+
+
+
+
+#endif /* __OC_GROUPMANAGER__*/
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//a
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file GroupSynchronizatin.cpp
+/// @brief
+
+#include "GroupSynchronization.h"
+
+using namespace OC;
+
+
+GroupSynchronization* GroupSynchronization::groupSyncnstance = NULL;
+
+
+GroupSynchronization* GroupSynchronization::getInstance ()
+{
+ if (groupSyncnstance == NULL)
+ {
+ groupSyncnstance = new GroupSynchronization();
+ }
+ return groupSyncnstance;
+}
+
+
+void GroupSynchronization::deleteInstance()
+{
+ if (groupSyncnstance)
+ {
+ delete groupSyncnstance;
+ groupSyncnstance = NULL;
+ }
+}
+
+
+
+OCStackResult GroupSynchronization::findGroup (std::vector<std::string> collectionResourceTypes, FindCallback resourceHandler)
+{
+ cout << "GroupSynchronization::findGroup" << endl;
+
+ foundGroupResourceList.clear();
+
+ findCallback = resourceHandler;
+
+ for (unsigned int i = 0; i < collectionResourceTypes.size(); ++i)
+ {
+ std::string query = "coap://224.0.1.187/oc/core?rt=";
+ query.append(collectionResourceTypes.at(i));
+ cout << "GroupSynchronization::findGroup - " << query << endl;
+
+ OCPlatform::findResource("", query,std::bind(&GroupSynchronization::onFindGroup, this, std::placeholders::_1));
+ }
+
+ // thread to check if GroupSynchronization::onFoundGroup is called or not.
+ std::thread t(std::bind(&GroupSynchronization::checkFindGroup, this));
+ t.detach();
+
+ return OC_STACK_OK;
+}
+
+
+OCStackResult GroupSynchronization::createGroup (std::string collectionResourceType)
+{
+ foundGroupResourceList.clear();
+
+ OCResourceHandle collectionResHandle = NULL;
+ OCResourceHandle groupSyncResHandle = NULL;
+
+ if (0 != collectionResourceType.length())
+ {
+ cout << "GroupSynchronization::createGroup - The created group is added." << endl;
+
+ OCStackResult result;
+
+/* result = OCPlatform::startPresence (30); // time is temporary
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::createGroup : startPresence was unsuccessful. result - " << result << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::createGroup : startPresence" << endl;
+ }
+*/
+ // creating master collection resource
+ std::string collectionUri = "/" + collectionResourceType;
+ int i;
+ while ((i = collectionUri.find(".")) != std::string::npos)
+ {
+ collectionUri.replace (i, 1, "/");
+ }
+ cout << "GroupSynchronization::createGroup : collection uri - " << collectionUri << ", type - " << collectionResourceType << endl;
+
+ std::string resourceInterface = DEFAULT_INTERFACE;
+
+ result = OCPlatform::registerResource (collectionResHandle, collectionUri, collectionResourceType, resourceInterface, NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+ if (OC_STACK_OK != result)
+ {
+ cout << "Resource creation (" << collectionUri << ") was unsuccessful. result - " << result << endl;
+ goto Error;
+ }
+
+ collectionResourceHandleList[collectionResourceType] = collectionResHandle;
+
+ // creating master group sync resource
+ std::string groupSyncUri = collectionUri + "/groupsync";
+ std::string groupSyncResType = collectionResourceType + ".groupsync";
+
+ cout << "GroupSynchronization::createGroup : groupSync uri - " << groupSyncUri << ", type - " << collectionResourceType<< endl;
+
+ result = OCPlatform::registerResource (groupSyncResHandle, groupSyncUri, groupSyncResType, resourceInterface,
+ std::bind(&GroupSynchronization::groupEntityHandler, this, std::placeholders::_1),
+ OC_DISCOVERABLE | OC_OBSERVABLE);
+ if (OC_STACK_OK != result)
+ {
+ cout << "Resource creation (groupsync) was unsuccessful. result - " << result << endl;
+ goto Error;
+ }
+
+ groupSyncResourceHandleList[collectionResourceType] = groupSyncResHandle;
+
+ return OC_STACK_OK;
+ }
+ else
+ {
+ cout << "GroupSynchronization::createGroup : Error! Input params are wrong." << endl;
+ return OC_STACK_INVALID_PARAM;
+ }
+
+Error :
+
+ std::map<std::string, OCResourceHandle>::iterator It;
+ if (collectionResHandle)
+ {
+ OCPlatform::unregisterResource (collectionResHandle);
+ It = collectionResourceHandleList.find(collectionResourceType);
+ if (It != collectionResourceHandleList.end())
+ {
+ collectionResourceHandleList.erase(It);
+ }
+ }
+
+ if (groupSyncResHandle)
+ {
+ OCPlatform::unregisterResource (groupSyncResHandle);
+ It = groupSyncResourceHandleList.find(collectionResourceType);
+ if (It != groupSyncResourceHandleList.end())
+ {
+ groupSyncResourceHandleList.erase(It);
+ }
+ }
+
+ return OC_STACK_NO_RESOURCE;
+}
+
+
+OCStackResult GroupSynchronization::joinGroup (std::string collectionResourceType, OCResourceHandle resourceHandle)
+{
+ if ((0 != collectionResourceType.length()) && (resourceHandle))
+ {
+ std::map<std::string, OCResourceHandle>::iterator resIt = collectionResourceHandleList.find(collectionResourceType);
+ if (resIt == groupSyncResourceHandleList.end())
+ {
+ cout << "GroupSynchronization::joinGroup : error! There is no collection to join" << endl;
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCResourceHandle collectionResHandle = resIt->second;
+
+ OCStackResult result = OCPlatform::bindResource(collectionResHandle, resourceHandle);
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::joinGroup : Resource bind was unsuccessful. result - " << result << endl;
+ return OC_STACK_ERROR;
+ }
+ cout << "GroupSynchronization::joinGroup : binding collectionResHandle and resourceHandle" << endl;
+
+ std::vector<OCResourceHandle> childHandleList;
+
+ std::map<OCResourceHandle, std::vector<OCResourceHandle>>::iterator childIt = childResourceHandleList.find(collectionResHandle);
+ if (childIt != childResourceHandleList.end())
+ {
+ childHandleList = childIt->second;
+ }
+
+ childHandleList.push_back(resourceHandle);
+ childResourceHandleList[collectionResHandle] = childHandleList;
+
+ deviceResourceHandleList.push_back(resourceHandle);
+
+ debugGroupSync();
+ }
+ else
+ {
+ cout << "GroupSynchronization::joinGroup : error! input params are wrong." << endl;
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ return OC_STACK_OK;
+}
+
+
+
+OCStackResult GroupSynchronization::joinGroup (const std::shared_ptr<OCResource> resource, OCResourceHandle resourceHandle)
+{
+ if ((resource) && (resourceHandle))
+ {
+ cout << "GroupSynchronization::joinGroup" << endl;
+
+ // making representation to join group
+ std::string method = "joinGroup";
+ std::vector<std::string> type = resource->getResourceTypes();
+ std::string resourceType;
+ resourceType.append(OCGetResourceTypeName (resourceHandle, 0));
+
+ OCRepresentation rep;
+ rep.setValue("method", method);
+ rep.setValue("collectionResourceType", type[0]);
+ rep.setValue("resourceType", resourceType);
+
+ cout << "\tmethod - " << method << endl;
+ cout << "\tcollectionResourceType - " << type[0] << endl;
+ cout << "\tresourceType - " << resourceType << endl;
+
+ // creating group sync resource with the received collection resource. entity handler of group sync is used to join group.
+ std::string host = resource->host();
+ std::string uri = resource->uri() + "/groupsync";
+
+ std::vector<std::string> resourceTypes;
+ std::string temp;
+ for (unsigned int i = 0; i < type.size(); ++i)
+ {
+ temp = type[0] + ".groupsync";
+ resourceTypes.push_back(temp);
+ }
+
+ std::vector<std::string> resourceInterface;
+ resourceInterface.push_back (DEFAULT_INTERFACE);
+
+ OCResource::Ptr groupSyncResource = OCPlatform::constructResourceObject(host, uri, 1, resourceTypes, resourceInterface);
+ groupSyncResourceList[type[0]] = groupSyncResource;
+
+ cout << "GroupSynchronization::joinGroup : creating groupSyncResource." << endl;
+
+ // Create QueryParameters Map and add query params (if any)
+ QueryParamsMap queryParamsMap;
+
+ // request to join group to the remote group sync resource
+ OCStackResult result = groupSyncResource->put(rep, queryParamsMap, std::bind(&GroupSynchronization::onJoinGroup, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::joinGroup : groupSyncResource->put was unsuccessful. result - " << result << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::joinGroup : groupSyncResource->put" << endl;
+ }
+
+ // saving the remote collection resource. It is used in onJoinGroup() and onGetJoinedRemoteChild().
+ remoteCollectionResource = resource;
+
+ // saving the resource handle to join. It is used in onGetJoinedRemoteChild()
+ deviceResourceHandle = resourceHandle;
+
+ return OC_STACK_OK;
+ }
+ else
+ {
+ cout << "GroupSynchronization::joinGroup : Error! Input params are wrong." << endl;
+ return OC_STACK_INVALID_PARAM;
+ }
+}
+
+
+OCStackResult GroupSynchronization::leaveGroup (std::string collectionResourceType, OCResourceHandle resourceHandle)
+{
+ if ((0 != collectionResourceType.length()) && (resourceHandle))
+ {
+ cout << "GroupSynchronization::leaveGroup : collectionResourceType - " << collectionResourceType << endl;
+
+ OCResourceHandle collectionResHandle;
+
+ std::map<std::string, OCResourceHandle>::iterator handleIt = groupSyncResourceHandleList.find(collectionResourceType);
+
+ // if groupSyncResourceHandleList has resourceType, this app created collection resource handle.
+ if (handleIt != groupSyncResourceHandleList.end())
+ {
+ handleIt = collectionResourceHandleList.find(collectionResourceType);
+ if (handleIt == collectionResourceHandleList.end())
+ {
+ cout << "GroupSynchronization::leaveGroup : Error! There is no collection resource handle to leave." << endl;
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ collectionResHandle = handleIt->second;
+ cout << "GroupSynchronization::leaveGroup : collection handle uri - " << OCGetResourceUri(collectionResHandle)<< endl;
+
+ OCStackResult result = OCPlatform::unbindResource (collectionResHandle, resourceHandle);
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::leaveGroup : UnbindResource was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::leaveGroup : UnbindResource was unsuccessful. result - " << result << endl;
+ }
+
+ std::vector<OCResourceHandle>::iterator It = std::find(deviceResourceHandleList.begin(), deviceResourceHandleList.end(), resourceHandle);
+ if (It == deviceResourceHandleList.end()) // there is no resource handle to find
+ {
+ result = OCPlatform::unregisterResource (resourceHandle);
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::leaveGroup : UnregisterResource was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::leaveGroup : UnregisterResource was unsuccessful. result - " << result << endl;
+ }
+ }
+ else
+ {
+ cout << "GroupSynchronization::leaveGroup : This resource cannot be unregistered." << endl;
+ deviceResourceHandleList.erase(It);
+ }
+
+ std::map<OCResourceHandle, std::vector<OCResourceHandle>>::iterator handleListIt = childResourceHandleList.find(collectionResHandle);
+ if (handleListIt == childResourceHandleList.end())
+ {
+ cout << "GroupSynchronization::leaveGroup : Error! There is no child resource list to delete." << endl;
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ std::vector<OCResourceHandle> childList = handleListIt->second;
+ std::vector<OCResourceHandle>::iterator childIt = std::find(childList.begin(), childList.end(), resourceHandle);
+ if (childIt != childList.end())
+ {
+ cout << "GroupSynchronization::groupEntityHandler : Found! The resource to leave is found in the child resource handle list." << endl;
+ childList.erase(childIt);
+ }
+
+ childResourceHandleList[collectionResHandle] = childList;
+
+ debugGroupSync();
+ }
+ else // requesting to unbind this resourceHandle to the remote collection resource
+ {
+ std::map<std::string, std::shared_ptr< OCResource>>::iterator resourceIt = groupSyncResourceList.find(collectionResourceType);
+
+ if (resourceIt == groupSyncResourceList.end())
+ {
+ cout << "GroupSynchronization::leaveGroup : Error! There is no collectin resource type to leave." << endl;
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ std::shared_ptr< OCResource> resource = resourceIt->second;
+ cout << "GroupSynchronization::leaveGroup : group sync resource uri - " << resource->uri() << endl;
+
+ handleIt = collectionResourceHandleList.find(collectionResourceType);
+ if (handleIt == collectionResourceHandleList.end())
+ {
+ cout << "GroupSynchronization::leaveGroup : Error! There is no collection resource handle to leave." << endl;
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ collectionResHandle = handleIt->second;
+
+ // making representation to leave group
+ std::string method = "leaveGroup";
+ std::string type = OCGetResourceTypeName(collectionResHandle,0);
+ std::string resourceType;
+ resourceType.append(OCGetResourceTypeName (resourceHandle, 0));
+
+ OCRepresentation rep;
+ rep.setValue("method", method);
+ rep.setValue("collectionResourceType", type);
+ rep.setValue("resourceType", resourceType);
+
+ cout << "\tmethod - " << method << endl;
+ cout << "\tcollectionResourceType - " << type << endl;
+ cout << "\tresourceType - " << resourceType << endl;
+
+ QueryParamsMap queryParamsMap;
+
+ // request to leave group to the remote group sync resource
+ OCStackResult result = resource->put(rep, queryParamsMap, std::bind(&GroupSynchronization::onLeaveGroup, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::leaveGroup : groupSyncResource->put was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::leaveGroup : groupSyncResource->put was unsuccessful. result - " << result << endl;
+ }
+
+ // deleting all remote resources. These are copied in onGetJoinedRemoteChild()
+ deleteGroup (collectionResourceType);
+ }
+ }
+ else
+ {
+ cout << "GroupSynchronization::leaveGroup : Error! Input params are wrong." << endl;
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ return OC_STACK_OK;
+}
+
+
+void GroupSynchronization::deleteGroup (std::string collectionResourceType)
+{
+ cout << "GroupSynchronization::deleteGroup" << endl;
+
+ OCStackResult result;
+/* result = OCPlatform::stopPresence();
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::leaveGroup : StopPresence was unsuccessful. result - " << result << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::leaveGroup : StopPresence" << endl;
+ }
+*/
+ std::map<std::string, OCResourceHandle>::iterator handleIt = collectionResourceHandleList.find(collectionResourceType);
+ if (handleIt == collectionResourceHandleList.end())
+ {
+ cout << "GroupSynchronization::deleteGroup : Error! There is no collection resource handle to delete." << endl;
+ return;
+ }
+ OCResourceHandle collectionResHandle = handleIt->second;
+
+ collectionResourceHandleList.erase(handleIt);
+
+ std::map<OCResourceHandle, std::vector<OCResourceHandle>>::iterator handleListIt = childResourceHandleList.find(collectionResHandle);
+ if (handleListIt == childResourceHandleList.end())
+ {
+ cout << "GroupSynchronization::deleteGroup : Error! There is no child resource list to delete." << endl;
+ return;
+ }
+ std::vector<OCResourceHandle> childList = handleListIt->second;
+
+ childResourceHandleList.erase(handleListIt);
+
+ result = OCPlatform::unbindResources (collectionResHandle, childList);
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::deleteGroup : UnbindResources was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::deleteGroup : UnbindResources was unsuccessful. result - " << result << endl;
+ }
+
+ result = OCPlatform::unregisterResource (collectionResHandle);
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::deleteGroup : UnregisterResource(collection resource handle) was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::deleteGroup : UnregisterResource(collection resource handle) was unsuccessful. result - " << result << endl;
+ }
+
+ OCResourceHandle resourceHandle;
+ std::vector<OCResourceHandle>::iterator It;
+
+ for (unsigned int i = 0; i < childList.size(); i++)
+ {
+ resourceHandle = childList.at(i);
+
+ It = std::find(deviceResourceHandleList.begin(), deviceResourceHandleList.end(), resourceHandle);
+ if (It != deviceResourceHandleList.end()) // find !!
+ {
+ cout << "GroupSynchronization::deleteGroup : This resource cannot be unregistered. uri - " << OCGetResourceUri(resourceHandle)<< endl;
+ deviceResourceHandleList.erase(It);
+ }
+ else
+ {
+ result = OCPlatform::unregisterResource (resourceHandle);
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::deleteGroup : UnregisterResource(" << i+1 <<") was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::deleteGroup : UnregisterResource(" << i+1 <<") was unsuccessful. result - " << result << endl;
+ }
+ }
+ }
+
+ handleIt = groupSyncResourceHandleList.find(collectionResourceType);
+
+ // if groupSyncResourceHandleList has resourceType, group sync of this app created collection resource.
+ if (handleIt != groupSyncResourceHandleList.end())
+ {
+ resourceHandle = handleIt->second; // group sync resource handle
+ result = OCPlatform::unregisterResource (resourceHandle);
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::deleteGroup : UnregisterResource(group sync resource handle) was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::deleteGroup : UnregisterResource(group sync resource handle) was unsuccessful. result - " << result << endl;
+ }
+
+ groupSyncResourceHandleList.erase(handleIt);
+ }
+
+ std::map<std::string, std::shared_ptr< OCResource>>::iterator resourceIt = groupSyncResourceList.find(collectionResourceType);
+ if (resourceIt != groupSyncResourceList.end())
+ {
+ cout << "GroupSynchronization::deleteGroup : Since OCResource is share_ptr, only groupSyncResourceList is updated and OCResource is not deleted." << endl;
+ groupSyncResourceList.erase(resourceIt);
+ }
+
+ debugGroupSync();
+}
+
+
+std::map<std::string, OCResourceHandle> GroupSynchronization::getGroupList ()
+{
+ return collectionResourceHandleList;
+}
+
+
+OCEntityHandlerResult GroupSynchronization::groupEntityHandler(const std::shared_ptr<OCResourceRequest> request)
+{
+ cout << "GroupSynchronization::groupEntityHandler\n";
+
+ if (request)
+ {
+ // Get the request type and request flag
+ std::string requestType = request->getRequestType();
+ int requestFlag = request->getRequestHandlerFlag();
+
+ if (requestFlag == RequestHandlerFlag::InitFlag)
+ {
+ cout << "\trequestFlag : Init\n";
+
+ // entity handler to perform resource initialization operations
+ }
+ else if (requestFlag == RequestHandlerFlag::RequestFlag)
+ {
+ cout << "\trequestFlag : Request\n";
+
+ // If the request type is GET
+ if (requestType == "GET")
+ {
+ cout << "\t\trequestType : GET\n";
+ }
+ else if (requestType == "PUT")
+ {
+ cout << "\t\trequestType : PUT\n";
+
+ //get method name, group resource type and resource type to join group
+ OCRepresentation rp = request->getResourceRepresentation();
+ std::string methodType = rp.getValue<std::string>("method");
+ std::string collectionResourceType = rp.getValue<std::string>("collectionResourceType");
+ std::string resourceType = rp.getValue<std::string>("resourceType");
+
+ cout << "\t\t\tmethod : " << methodType << endl;
+ cout << "\t\t\tcollection resourceType : " << collectionResourceType << endl;
+ cout << "\t\t\tresourceType : " << resourceType << endl;
+
+ std::map<std::string, OCResourceHandle>::iterator handleIt = collectionResourceHandleList.find(collectionResourceType);
+ if (handleIt == collectionResourceHandleList.end())
+ {
+ cout << "GroupSynchronization::groupEntityHandler : Error! There is no collection resource handle to delete." << endl;
+ return OC_EH_ERROR;
+ }
+ collectionResourceHandle = handleIt->second; // in case of join group it is used in onFindResource()
+
+ if (methodType == "joinGroup")
+ {
+ std::string resourceName = "coap://224.0.1.187/oc/core?rt=";
+ resourceName += resourceType;
+ cout << "\t\t\tresourceName : " << resourceName << endl;
+
+ resourceRequest = request;
+
+ OCPlatform::findResource ("", resourceName, std::bind(&GroupSynchronization::onFindResource, this, std::placeholders::_1));
+ }
+ else if (methodType == "leaveGroup")
+ {
+ std::map<OCResourceHandle, std::vector<OCResourceHandle>>::iterator it = childResourceHandleList.find(collectionResourceHandle);
+ if (it == childResourceHandleList.end())
+ {
+ cout << "GroupSynchronization::groupEntityHandler : Error! There is no child resource list." << endl;
+ return OC_EH_ERROR;
+ }
+
+ std::vector<OCResourceHandle> childList = it->second;
+ std::vector<OCResourceHandle>::iterator childIt;
+ OCResourceHandle resourceHandle;
+ for(childIt = childList.begin(); childIt != childList.end(); )
+ {
+ resourceHandle = (*childIt);
+ char* type = (char*)OCGetResourceTypeName (resourceHandle, 0);
+
+ if (0 == resourceType.compare(type))
+ {
+ cout << "GroupSynchronization::groupEntityHandler : Found! The resource to leave is found. - " << type << endl;
+
+ childIt = childList.erase(childIt++);
+
+ OCStackResult result = OCPlatform::unbindResource (collectionResourceHandle, resourceHandle);
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::groupEntityHandler : UnbindResource was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::groupEntityHandler : UnbindResource was unsuccessful. result - " << result << endl;
+ }
+
+ result = OCPlatform::unregisterResource (resourceHandle);
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::groupEntityHandler : UnregisterResource was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::groupEntityHandler : UnregisterResource was unsuccessful. result - " << result << endl;
+ }
+
+// break;
+ }
+ else
+ {
+ ++childIt;
+ }
+ }
+
+ childResourceHandleList[collectionResourceHandle] = childList;
+
+ debugGroupSync();
+
+ auto pResponse = std::make_shared<OC::OCResourceResponse>();
+ pResponse->setRequestHandle(request->getRequestHandle());
+ pResponse->setResourceHandle(request->getResourceHandle());
+ pResponse->setErrorCode(200);
+ pResponse->setResponseResult(OC_EH_OK);
+
+ OCRepresentation rep = request->getResourceRepresentation();
+ pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+ if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+ {
+ cout << "GroupSynchronization::groupEntityHandler : sendResponse is successful." << endl;
+ }
+ }
+
+ if (methodType != "") //TODO: Check groupmethodtype NULL
+ {
+ }
+ }
+ else if (requestType == "POST")
+ {
+ // POST request operations
+ }
+ else if (requestType == "DELETE")
+ {
+ // DELETE request operations
+ }
+ }
+ else if (requestFlag == RequestHandlerFlag::ObserverFlag)
+ {
+ cout << "\trequestFlag : Observer\n";
+ }
+ }
+ else
+ {
+ std::cout << "Request invalid" << std::endl;
+ }
+
+ return OC_EH_OK;
+}
+
+
+void GroupSynchronization::onFindGroup(std::shared_ptr< OCResource > resource)
+{
+ cout << "GroupSynchronization::onFindGroup" << endl;
+
+ try
+ {
+ if (resource)
+ {
+//////////////////////////////////////////////////////////////////////////////////////////////////
+////////////debugging
+ std::string resourceURI;
+ std::string hostAddress;
+
+ // Get the resource URI
+ resourceURI = resource->uri();
+ cout << "\tURI of the resource: " << resourceURI << endl;
+
+ // Get the resource host address
+ hostAddress = resource->host();
+ cout << "\tHost address of the resource: " << hostAddress << endl;
+
+ hostAddress.append(resourceURI);
+
+ // Get the resource types
+ cout << "\tList of resource types: " << endl;
+
+ for (auto &resourceTypes : resource->getResourceTypes())
+ {
+ cout << "\t\t" << resourceTypes << endl;
+ }
+
+ // Get the resource interfaces
+ cout << "\tList of resource interfaces: " << endl;
+ for (auto &resourceInterfaces : resource->getResourceInterfaces())
+ {
+ cout << "\t\t" << resourceInterfaces << endl;
+ }
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+ if (false == IsSameGroup(resource))
+ {
+ saveGroup (resource);
+ findCallback (resource);
+ }
+ }
+ else
+ {
+ // Resource is invalid
+ cout << "Resource is invalid" << endl;
+ findCallback (NULL);
+ }
+
+ }
+ catch (std::exception& e)
+ {
+ //log(e.what());
+ }
+}
+
+
+void GroupSynchronization::checkFindGroup (void)
+{
+ cout << "GroupSynchronization::checkFindGroup" << endl;
+
+ for (int i = 0; i < 15; i++)
+ {
+ std::chrono::milliseconds workTime(300);
+ std::this_thread::sleep_for(workTime);
+
+ std::lock_guard<std::mutex> guard(foundGroupMutex);
+
+ if (false == foundGroupResourceList.empty())
+ {
+ cout << "GroupSynchronization::checkFoundGroup : Some group is received." << endl;
+ return;
+ }
+ }
+
+ cout << "GroupSynchronization::checkFoundGroup : It is failed to find resource within 3s." << endl;
+
+ onFindGroup (NULL);
+ return;
+}
+
+
+bool GroupSynchronization::IsSameGroup (std::shared_ptr< OCResource > resource)
+{
+ std::lock_guard<std::mutex> guard(foundGroupMutex);
+
+ if (true == foundGroupResourceList.empty())
+ {
+ cout << "GroupSynchronization::IsSameGroup : There is no found group." << endl;
+ return false;
+ }
+
+ std::string foundHostAddress, savedHostAddress;
+ foundHostAddress = resource->host();
+// foundHostAddress.append (resource->uri());
+
+ for (unsigned int i = 0; i < foundGroupResourceList.size(); ++i)
+ {
+ savedHostAddress = (foundGroupResourceList.at(i))->host();
+// savedHostAddress.append ((foundGroupResourceList.at(i))->uri());
+ cout << "GroupSynchronization::IsSameGroup : foundHostAddress - " << foundHostAddress << ", savedHostAddress - " << savedHostAddress << endl;
+
+ if (0 == foundHostAddress.compare(savedHostAddress.c_str()))
+ {
+ cout << "GroupSynchronization::IsSameGroup : Found! The same group is found." << endl;
+ return true;
+ }
+ }
+
+ cout << "GroupSynchronization::IsSameGroup : There is no same group." << endl;
+ return false;
+}
+
+
+void GroupSynchronization::saveGroup (std::shared_ptr< OCResource > resource)
+{
+ cout << "GroupSynchronization::saveGroup" << endl;
+
+ std::lock_guard<std::mutex> guard(foundGroupMutex);
+
+ foundGroupResourceList.push_back(resource);
+}
+
+
+void GroupSynchronization::onJoinGroup(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+ if(eCode == OC_STACK_OK)
+ {
+ cout << "GroupSynchronization::onJoinGroup : " << endl;
+
+ if (remoteCollectionResource)
+ {
+ std::string resourceInterface = DEFAULT_INTERFACE;
+ QueryParamsMap queryParamsMap;
+
+ OCStackResult result = remoteCollectionResource->get("", resourceInterface, queryParamsMap,
+ std::bind(&GroupSynchronization::onGetJoinedRemoteChild, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::onJoinGroup : remoteCollectionResource->get was successful." << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::onJoinGroup : remoteCollectionResource->get was unsuccessful. result - " << result << endl;
+ }
+
+// OCPlatform::OCPresenceHandle presenceHandle;
+// std::vector<std::string> types = remoteCollectionResource->getResourceTypes();
+// result = OCPlatform::subscribePresence (presenceHandle, remoteCollectionResource->host(), types[0],
+// std::function< void(OCStackResult result, const unsigned int nonce)>
+// (std::bind(&GroupSynchronization::onSubscribePresence, this, std::placeholders::_1, std::placeholders::_2/*, types[0], remoteCollectionResource->host()*/)));
+ }
+ }
+ else
+ {
+ cout << "GroupSynchronization::onJoinGroup : error - " << eCode << endl;
+ }
+}
+
+
+void GroupSynchronization::onFindResource (std::shared_ptr<OCResource> resource)
+{
+ cout << "GroupSynchronization::onFindResource" << endl;
+
+ if (resource)
+ {
+//////////////////////////////////////////////////////////////////////////////////////////////////
+////////// debugging
+ std::string resourceURI;
+ std::string hostAddress;
+
+ // Get the resource URI
+ resourceURI = resource->uri();
+ cout << "\tURI of the resource: " << resourceURI << endl;
+
+ // Get the resource host address
+ hostAddress = resource->host();
+ cout << "\tHost address of the resource: " << hostAddress << endl;
+
+ hostAddress.append(resourceURI);
+
+ // Get the resource types
+ cout << "\tList of resource types: " << endl;
+
+ for (auto &resourceTypes : resource->getResourceTypes())
+ {
+ cout << "\t\t" << resourceTypes << endl;
+ }
+
+ // Get the resource interfaces
+ cout << "\tList of resource interfaces: " << endl;
+ for (auto &resourceInterfaces : resource->getResourceInterfaces())
+ {
+ cout << "\t\t" << resourceInterfaces << endl;
+ }
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+ OCResourceHandle resourceHandle;
+ OCStackResult result = OCPlatform::registerResource (resourceHandle, resource);
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::onFindResource - Resource to join creation was unsuccessful. result - " << result << endl;
+ return;
+ }
+ cout << "GroupSynchronization::onFindResource : creating resourceHandle. resource type - " << OCGetResourceTypeName (resourceHandle,0)<< endl;
+
+ result = OCPlatform::bindResource(collectionResourceHandle, resourceHandle);
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::onFindResource : Resource bind was unsuccessful. result - " << result << endl;
+ return;
+ }
+ cout << "GroupSynchronization::onFindResource : binding joinGroupHandle and resourceHandle" << endl;
+
+ std::map<OCResourceHandle, std::vector<OCResourceHandle>>::iterator it = childResourceHandleList.find(collectionResourceHandle);
+ std::vector<OCResourceHandle> childHandleList;
+ if (it != childResourceHandleList.end())
+ {
+ childHandleList = it->second;
+ }
+
+ childHandleList.push_back(resourceHandle);
+ childResourceHandleList[collectionResourceHandle] = childHandleList;
+
+ auto pResponse = std::make_shared<OC::OCResourceResponse>();
+ pResponse->setRequestHandle(resourceRequest->getRequestHandle());
+ pResponse->setResourceHandle(resourceRequest->getResourceHandle());
+ pResponse->setErrorCode(200);
+ pResponse->setResponseResult(OC_EH_OK);
+
+ OCRepresentation rep = resourceRequest->getResourceRepresentation();
+ pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+ if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+ {
+ cout << "GroupSynchronization::onFindResource : sendResponse is successful." << endl;
+ }
+ }
+ else
+ {
+ cout << "GroupSynchronization::onFindResource : Resource is invalid. So a new Group Resource has to be created." << endl;
+ }
+
+ debugGroupSync();
+}
+
+
+void GroupSynchronization::onGetJoinedRemoteChild(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+ if(eCode == OC_STACK_OK)
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild" << endl;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+////////// debugging
+ std::string resourceURI;
+
+ // Get the resource URI
+ resourceURI = rep.getUri();
+ cout << "\tURI of the resource: " << resourceURI << endl;
+
+ // Get the resource types
+ cout << "\tList of resource types: " << endl;
+
+ for (auto &resourceTypes : rep.getResourceTypes())
+ {
+ cout << "\t\t" << resourceTypes << endl;
+ }
+
+ // Get the resource interfaces
+ cout << "\tList of resource interfaces: " << endl;
+ for (auto &resourceInterfaces : rep.getResourceInterfaces())
+ {
+ cout << "\t\t" << resourceInterfaces << endl;
+ }
+
+ std::vector<OCRepresentation> childList = rep.getChildren();
+ OCRepresentation child;
+ for (unsigned int i = 0; i < childList.size(); ++i)
+ {
+ cout << "\n\tchild resource - " << i+1 << endl;
+
+ child = childList.at(i);
+ resourceURI = child.getUri();
+ cout << "\t\tURI of the resource: " << resourceURI << endl;
+
+ cout << "\t\tList of resource types: " << endl;
+ for (auto &types : child.getResourceTypes())
+ {
+ cout << "\t\t\t" << types << endl;
+ }
+
+ cout << "\tList of resource interfaces: " << endl;
+ for (auto &interfaces : child.getResourceInterfaces())
+ {
+ cout << "\t\t\t" << interfaces << endl;
+ }
+ }
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // creating remote collection resource handle
+ OCResourceHandle remoteCollectionResourceHandle;
+ resourceURI = remoteCollectionResource->uri();
+ std::vector<std::string> types = remoteCollectionResource->getResourceTypes();
+ std::vector<std::string> interfaces = remoteCollectionResource->getResourceInterfaces();
+
+ OCStackResult result = OCPlatform::registerResource (remoteCollectionResourceHandle, resourceURI, types[0], interfaces[0], NULL, OC_OBSERVABLE);
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild - remoteCollectionResourceHandle creation was unsuccessful. result - " << result << endl;
+ return;
+ }
+ cout << "GroupSynchronization::onGetJoinedRemoteChild : creating remoteCollectionResourceHandle" << endl;
+
+ // binding remote collection resource handle and resource handle to join
+ collectionResourceHandleList[types[0]] = remoteCollectionResourceHandle;
+
+ result = OCPlatform::bindResource(remoteCollectionResourceHandle, deviceResourceHandle);
+ if (OC_STACK_OK == result)
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild : binding remoteCollectionResourceHandle and deviceResourceHandle" << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild - binding remoteCollectionResourceHandle and deviceResourceHandle was unsuccessful. result - " << result << endl;
+ }
+
+ std::vector<OCResourceHandle> childHandleList;
+ childHandleList.push_back(deviceResourceHandle);
+ deviceResourceHandleList.push_back(deviceResourceHandle);
+
+ // binding copied remote collection resource handle and copied remote resource
+ OCResourceHandle resourceHandle;
+ for (unsigned int i = 0; i < childList.size(); ++i)
+ {
+ cout << "\tremote resource - " << i+1 << endl;
+
+ child = childList.at(i);
+ resourceURI = child.getUri();
+ types = child.getResourceTypes();
+ interfaces = child.getResourceInterfaces();
+
+ if (0 == types[0].compare(OCGetResourceTypeName (deviceResourceHandle,0)))
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild : " << types[0] << " is bind already." << endl;
+ continue;
+ }
+
+ result = OCPlatform::registerResource (resourceHandle, resourceURI, types[0], interfaces[0], NULL, OC_OBSERVABLE);
+ if (OC_STACK_OK == result)
+ {
+ result = OCPlatform::bindResource(remoteCollectionResourceHandle, resourceHandle);
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild - binding remoteCollectionResourceHandle and resourceHandle was unsuccessful. result - " << result << endl;
+ OCPlatform::unregisterResource (resourceHandle);
+ }
+
+ childHandleList.push_back(resourceHandle);
+ cout << "GroupSynchronization::onGetJoinedRemoteChild : binding remoteCollectionResourceHandle and resourceHandle" << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild - remoteCollectionResourceHandle creation was unsuccessful. result - " << result << endl;
+ }
+ }
+
+ childResourceHandleList[remoteCollectionResourceHandle] = childHandleList; // this handle list is used to leave group
+
+/* OCPlatform::OCPresenceHandle presenceHandle;
+ types = remoteCollectionResource->getResourceTypes();
+ result = OCPlatform::subscribePresence (presenceHandle, remoteCollectionResource->host(), types[0],onSubscribePresence);
+ if (OC_STACK_OK != result)
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild : subscribePresence was unsuccessful. result - " << result << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild : subscribePresence. types - " << types[0] << endl;
+ }
+*/ }
+ else
+ {
+ cout << "GroupSynchronization::onGetJoinedRemoteChild : error - " << eCode << endl;
+ }
+
+ debugGroupSync();
+}
+
+
+void GroupSynchronization::onLeaveGroup(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+ if(eCode == OC_STACK_OK)
+ {
+ cout << "GroupSynchronization::onLeaveGroup" << endl;
+ }
+ else
+ {
+ cout << "GroupSynchronization::onLeaveGroup : error - " << eCode << endl;
+ }
+ debugGroupSync();
+}
+
+/*
+void onSubscribePresence (OCStackResult result, const unsigned int nonce, std::string resourceType, std::string host)
+{
+ cout << "GroupSynchronization::onSubscribePresence" << endl;
+
+// std::cout << "resourceType : " << resourceType << std::endl;
+// std::cout << "host : " << host << std::endl;
+ std::cout << "result : " << result << std::endl;
+
+ switch(result)
+ {
+ case OC_STACK_OK:
+ std::cout << "Nonce# " << nonce << std::endl;
+ break;
+ case OC_STACK_PRESENCE_STOPPED:
+ std::cout << "Presence Stopped\n";
+ break;
+ case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+ std::cout << "Presence do not handle\n";
+ break;
+ case OC_STACK_PRESENCE_TIMEOUT:
+ std::cout << "Presence TIMEOUT\n";
+ break;
+ default:
+ std::cout << "Error\n";
+ break;
+ }
+}
+*/
+
+void GroupSynchronization::debugGroupSync (void)
+{
+ cout << "GroupSynchronization::debugGroupSync" << endl;
+
+ unsigned int i;
+ std::map<std::string, OCResourceHandle>::iterator handleIt;
+ std::map<OCResourceHandle, std::vector<OCResourceHandle>>::iterator childIt;
+ std::string type;
+ OCResourceHandle resourceHandle;
+ std::vector<OCResourceHandle> handleList;
+ std::shared_ptr< OCResource> resource;
+
+ cout << "Resource Handle Created by App" << endl;
+ for (i = 0; i < deviceResourceHandleList.size(); i++)
+ {
+ resourceHandle = deviceResourceHandleList.at(i);
+
+ cout << i+1 << ". details" << endl;
+ cout << " uri - " << OCGetResourceUri (resourceHandle)<< endl;
+ cout << " resource type - " << OCGetResourceTypeName (resourceHandle, 0) << endl;
+ cout << " resource interface - " << OCGetResourceInterfaceName (resourceHandle, 0) << endl;
+ cout << " resource property - " << OCGetResourceProperties (resourceHandle) << endl << endl;
+ }
+
+
+ cout << "The number of collection Resource Handle is " << collectionResourceHandleList.size() << endl;
+ cout << "The number of child resource handle list is " << childResourceHandleList.size() << endl;
+
+ cout << "Collection Resource Handle List" << endl;
+ i = 1;
+ for (handleIt = collectionResourceHandleList.begin(); handleIt != collectionResourceHandleList.end(); ++handleIt)
+ {
+ type = handleIt->first;
+ cout << "\t" << i << ". collection resource type - " << type << endl;
+ cout << "\t details" << endl;
+
+ resourceHandle = handleIt->second;
+ cout << "\t uri - " << OCGetResourceUri (resourceHandle)<< endl;
+ cout << "\t resource type - " << OCGetResourceTypeName (resourceHandle, 0) << endl;
+ cout << "\t resource interface - " << OCGetResourceInterfaceName (resourceHandle, 0) << endl;
+ cout << "\t resource property - " << OCGetResourceProperties (resourceHandle) << endl << endl;
+
+ childIt = childResourceHandleList.find(resourceHandle);
+ if (childIt != childResourceHandleList.end())
+ {
+ handleList = childIt->second;
+ for (unsigned int j = 0; j < handleList.size(); j++)
+ {
+
+ cout << "\t\t" << j + 1 << ". child resource details" << endl;
+
+ resourceHandle = handleList.at(j);
+ cout << "\t\t uri - " << OCGetResourceUri (resourceHandle)<< endl;
+ cout << "\t\t resource type - " << OCGetResourceTypeName (resourceHandle, 0) << endl;
+ cout << "\t\t resource interface - " << OCGetResourceInterfaceName (resourceHandle, 0) << endl;
+ cout << "\t\t resource property - " << OCGetResourceProperties (resourceHandle) << endl << endl;
+ }
+ }
+
+ i++;
+ }
+
+ cout << "Group Sync Resource Handle List. The number is " << groupSyncResourceHandleList.size() << endl;
+ i = 1;
+ for (handleIt = groupSyncResourceHandleList.begin(); handleIt != groupSyncResourceHandleList.end(); ++handleIt)
+ {
+ type = handleIt->first;
+ cout << "\t" << i << ". group sync resource type - " << type << endl;
+ cout << "\t details" << endl;
+
+ resourceHandle = handleIt->second;
+ cout << "\t uri - " << OCGetResourceUri (resourceHandle)<< endl;
+ cout << "\t resource type - " << OCGetResourceTypeName (resourceHandle, 0) << endl;
+ cout << "\t resource interface - " << OCGetResourceInterfaceName (resourceHandle, 0) << endl;
+ cout << "\t resource property - " << OCGetResourceProperties (resourceHandle) << endl << endl;;
+ i++;
+ }
+
+ cout << "Copied Remote Group Sync Resource List. The number is " << groupSyncResourceList.size() << endl;
+ std::map<std::string, std::shared_ptr< OCResource>>::iterator resourceIt;
+ std::vector<std::string> list;
+ i = 1;
+ for (resourceIt = groupSyncResourceList.begin(); resourceIt != groupSyncResourceList.end(); ++resourceIt)
+ {
+ type = resourceIt->first;
+ cout << "\t" << i << ". group sync resource type - " << type << endl;
+ cout << "\t details" << endl;
+
+ resource = resourceIt->second;
+ cout << "\t host - " << resource->host() << endl;
+ cout << "\t uri - " << resource->uri() << endl;
+ list = resource->getResourceTypes();
+ cout << "\t resource type - " << list[0] << endl;
+ list = resource->getResourceInterfaces();
+ cout << "\t resource interface - " << list[0] << endl << endl;
+ i++;
+ }
+}
\ No newline at end of file
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file GroupSynchronizatin.h
+
+/// @brief This file contains the declaration of classes and its members related to GroupSynchronization.
+
+#ifndef __OC_GROUPSYNCHRONIZATION__
+#define __OC_GROUPSYNCHRONIZATION__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+class GroupSynchronization
+{
+private :
+
+ std::map<std::string, OCResourceHandle> collectionResourceHandleList; // collection resource handle list
+
+ std::map<std::string, OCResourceHandle> groupSyncResourceHandleList; // group sync resource handle list
+ std::map<std::string, std::shared_ptr< OCResource>> groupSyncResourceList; // remote group sync resource list
+
+ std::vector<OCResourceHandle> deviceResourceHandleList; // these cannot be removed.
+ OCResourceHandle deviceResourceHandle;
+
+ OCResourceHandle collectionResourceHandle; // collection handle
+ std::shared_ptr< OCResource> remoteCollectionResource;
+
+ std::map<OCResourceHandle, std::vector<OCResourceHandle>> childResourceHandleList;
+
+ FindCallback findCallback;
+ std::vector<std::shared_ptr< OCResource >> foundGroupResourceList;
+
+ std::mutex foundGroupMutex;
+ std::mutex groupSyncMutex;
+
+ std::shared_ptr<OCResourceRequest> resourceRequest; // this is used for slow response
+
+ static GroupSynchronization* groupSyncnstance;
+
+
+ GroupSynchronization ()
+ {
+ collectionResourceHandleList.clear();
+ groupSyncResourceHandleList.clear();
+ groupSyncResourceList.clear();
+ foundGroupResourceList.clear();
+ deviceResourceHandleList.clear();
+
+ deviceResourceHandle = NULL;
+ remoteCollectionResource = NULL;
+ findCallback = NULL;
+ };
+
+ ~GroupSynchronization ()
+ {
+ std::map<std::string, OCResourceHandle>::iterator handleIt;
+ for (handleIt = collectionResourceHandleList.begin(); handleIt != collectionResourceHandleList.end(); ++handleIt)
+ {
+ deleteGroup (handleIt->first);
+ }
+ };
+
+
+public :
+
+ static GroupSynchronization* getInstance ();
+ void deleteInstance();
+
+ OCStackResult findGroup (std::vector <std::string> collectionResourceTypes, FindCallback resourceHandler);
+ OCStackResult createGroup (std::string collectionResourceType);
+ OCStackResult joinGroup (std::string collectionResourceTyps, OCResourceHandle resourceHandle);
+ OCStackResult joinGroup (const std::shared_ptr<OCResource> resource, OCResourceHandle resourceHandle);
+ OCStackResult leaveGroup (std::string collectionResourceType, OCResourceHandle resourceHandle);
+ void deleteGroup (std::string collectionResourceType);
+
+ std::map<std::string, OCResourceHandle> getGroupList ();
+
+private :
+
+ OCEntityHandlerResult groupEntityHandler(const std::shared_ptr<OCResourceRequest> request);
+
+ void onFindGroup(std::shared_ptr< OCResource > resource);
+ void onJoinGroup(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
+ void onFindResource (std::shared_ptr<OCResource> resource);
+ void onGetJoinedRemoteChild(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
+ void onLeaveGroup(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
+// void onSubscribePresence (OCStackResult result, const unsigned int nonce/*, std::string resourceType, std::string host*/);
+
+ void checkFindGroup (void);
+ bool IsSameGroup (std::shared_ptr< OCResource > resource);
+ void saveGroup (std::shared_ptr< OCResource > resource);
+
+ void debugGroupSync (void);
+
+};
+
+#endif // __OC_GROUPSYNCHRONIZATION__
\ No newline at end of file
+++ /dev/null
-//******************************************************************
-//
-// Copyright 2014 Samsung Electronics All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-/// @file TGMClient.cpp
-/// @brief
-
-#include "TGMClient.h"
-#include <algorithm>
-#include <thread>
-
-using namespace OC;
-
-std::map< std::vector< std::string >, CandidateCallback > candidateRequest;
-std::map< std::vector< std::string >, CandidateCallback > candidateRequestForTimer;
-std::map< std::string, std::map< std::string, std::shared_ptr< OCResource > > > rtForResourceList;
-std::vector< std::string > allFoundResourceTypes;
-
-template< typename T >
-bool IsSubset(std::vector< T > full, std::vector< T > sub)
-{
- std::sort(full.begin(), full.end());
- std::sort(sub.begin(), sub.end());
- return std::includes(full.begin(), full.end(), sub.begin(), sub.end());
-}
-
-void TGMClient::onFoundResource(std::shared_ptr< OCResource > resource, int waitsec)
-{
-
- std::string resourceURI;
- std::string hostAddress;
- try
- {
- // Do some operations with resource object.
- if (resource)
- {
-
- std::cout << "DISCOVERED Resource:" << std::endl;
- // Get the resource URI
- resourceURI = resource->uri();
- std::cout << "\tURI of the resource: " << resourceURI << std::endl;
-
- // Get the resource host address
- hostAddress = resource->host();
- std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
-
- // Get the resource types
- std::cout << "\tList of resource types: " << std::endl;
-
- hostAddress.append(resourceURI);
-
- for (auto &resourceTypes : resource->getResourceTypes())
- {
- std::cout << "\t\t" << resourceTypes << std::endl;
-
- if (std::find(allFoundResourceTypes.begin(), allFoundResourceTypes.end(),
- resourceTypes) == allFoundResourceTypes.end())
- {
- allFoundResourceTypes.push_back(resourceTypes);
- }
-
- rtForResourceList[resourceTypes][hostAddress] = resource;
- }
-
- // Get the resource interfaces
- std::cout << "\tList of resource interfaces: " << std::endl;
- for (auto &resourceInterfaces : resource->getResourceInterfaces())
- {
- std::cout << "\t\t" << resourceInterfaces << std::endl;
- }
-
- if (waitsec == -1)
- {
- findPreparedRequest(candidateRequest);
- }
- }
- else
- {
- // Resource is invalid
- std::cout << "Resource is invalid" << std::endl;
- }
-
- }
- catch (std::exception& e)
- {
- //log(e.what());
- }
-}
-
-TGMClient::TGMClient(void)
-{
- ;
-}
-
-/**
- * Virtual destructor
- */
-TGMClient::~TGMClient(void)
-{
- candidateRequest.clear();
- candidateRequestForTimer.clear();
- rtForResourceList.clear();
- allFoundResourceTypes.clear();
-}
-
-void TGMClient::findPreparedRequest(
- std::map< std::vector< std::string >, CandidateCallback > &request)
-{
- std::vector < std::shared_ptr < OCResource >> resources;
-
- for (auto it = request.begin(); it != request.end();)
- {
-
- if (IsSubset(allFoundResourceTypes, it->first))
- {
- //std::cout << "IS SUBSET !!! \n";
-
- for (unsigned int i = 0; i < it->first.size(); ++i)
- {
-
- for (auto secondIt = rtForResourceList[it->first.at(i)].begin();
- secondIt != rtForResourceList[it->first.at(i)].end(); ++secondIt)
- {
- resources.push_back(secondIt->second);
- }
- }
-
- it->second(resources);
-
- //TODO : decide policy - callback only once
- request.erase(it++);
- }
- else
- {
- ++it;
- }
-
- }
-
-}
-
-void TGMClient::lazyCallback(int second)
-{
- sleep(second);
- findPreparedRequest(candidateRequestForTimer);
-
-}
-OCStackResult TGMClient::findCandidateResources(std::vector< std::string > resourceTypes,
- CandidateCallback callback, int waitsec)
-{
- if (resourceTypes.size() < 1)
- {
- return OC_STACK_ERROR;
- }
-
- std::sort(resourceTypes.begin(), resourceTypes.end());
- resourceTypes.erase(std::unique(resourceTypes.begin(), resourceTypes.end()),
- resourceTypes.end());
-
- if (waitsec != -1)
- {
- candidateRequestForTimer.insert(std::make_pair(resourceTypes, callback));
- }
- else
- {
- candidateRequest.insert(std::make_pair(resourceTypes, callback));
- }
-
- for (unsigned int i = 0; i < resourceTypes.size(); ++i)
- {
- std::cout << "resourceTypes : " << resourceTypes.at(i) << std::endl;
- std::string query = "coap://224.0.1.187/oc/core?rt=";
- query.append(resourceTypes.at(i));
- OCPlatform::findResource("", query.c_str(),
- std::function < void(std::shared_ptr < OCResource > resource)
- > (std::bind(&TGMClient::onFoundResource, this, std::placeholders::_1,
- waitsec)));
- }
-
- if (waitsec != -1)
- {
- std::thread exec(
- std::function< void(int second) >(
- std::bind(&TGMClient::lazyCallback, this, std::placeholders::_1)), waitsec);
- exec.detach();
- }
-
- return OC_STACK_OK;
-}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file ThingsConfiguration.cpp
+/// @brief
+
+#include <OCApi.h>
+#include <OCPlatform.h>
+#include <cstdlib>
+#include <algorithm>
+#include "ThingsConfiguration.h"
+
+using namespace OC;
+
+const int SUCCESS_RESPONSE = 0;
+int cnt = 0;
+
+std::map< std::string, ConfigurationRequestEntry > configurationRequestTable;
+
+ThingsConfiguration* ThingsConfiguration::thingsConfigurationInstance = NULL;
+
+ConfigurationCallback g_bootstrapCallback;
+
+ThingsConfiguration* ThingsConfiguration::getInstance()
+{
+ if (thingsConfigurationInstance == NULL)
+ {
+ thingsConfigurationInstance = new ThingsConfiguration();
+ }
+ return thingsConfigurationInstance;
+}
+
+void ThingsConfiguration::deleteInstance()
+{
+ if (thingsConfigurationInstance)
+ {
+ delete thingsConfigurationInstance;
+ thingsConfigurationInstance = NULL;
+ }
+}
+
+std::string ThingsConfiguration::getAttributeByConfigurationName(ConfigurationName name)
+{
+ for (auto it = ConfigurationUnitTable.begin(); ConfigurationUnitTable.end() != it; it++)
+ {
+ if ((*it).m_name == name)
+ return (*it).m_attribute;
+ }
+
+ return "";
+}
+
+std::string ThingsConfiguration::getUriByConfigurationName(ConfigurationName name)
+{
+ for (auto it = ConfigurationUnitTable.begin(); ConfigurationUnitTable.end() != it; it++)
+ {
+ if ((*it).m_name == name)
+ return (*it).m_uri;
+ }
+
+ return "";
+}
+
+std::string ThingsConfiguration::getUpdateVal(std::string conf)
+{
+ std::map< std::string, ConfigurationRequestEntry >::iterator it =
+ configurationRequestTable.find(conf);
+
+ if (it == configurationRequestTable.end())
+ return NULL;
+ else
+ return it->second.m_updateVal;
+
+}
+std::shared_ptr< OCResource > ThingsConfiguration::getResource(std::string conf)
+{
+ std::map< std::string, ConfigurationRequestEntry >::iterator it =
+ configurationRequestTable.find(conf);
+
+ if (it == configurationRequestTable.end())
+ return NULL;
+ else
+ return it->second.m_resource;
+}
+
+ConfigurationCallback ThingsConfiguration::getCallback(std::string conf)
+{
+ std::map< std::string, ConfigurationRequestEntry >::iterator it =
+ configurationRequestTable.find(conf);
+
+ if (it == configurationRequestTable.end())
+ return NULL;
+ else
+ return it->second.m_callback;
+}
+
+std::string ThingsConfiguration::getListOfSupportedConfigurationUnits()
+{
+ std::string res;
+
+ res = "{\"Configuration Units\":[";
+
+ auto it = ConfigurationUnitTable.begin();
+ while (1)
+ {
+ res = res + (*it).getJSON();
+ it++;
+
+ if (it == ConfigurationUnitTable.end())
+ break;
+ else
+ res += ",";
+ }
+
+ res += "]}";
+
+ return res;
+}
+
+std::string ThingsConfiguration::getHostFromURI(std::string oldUri)
+{
+ size_t f;
+ std::string newUri;
+
+ if ((f = oldUri.find("/factoryset/oic/")) != string::npos)
+ newUri = oldUri.replace(f, oldUri.size(), "");
+ else if ((f = oldUri.find("/oic/")) != string::npos)
+ newUri = oldUri.replace(f, oldUri.size(), "");
+
+ return newUri;
+}
+
+void ThingsConfiguration::onDeleteActionSet(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep, const int eCode, std::string conf)
+{
+ std::shared_ptr < OCResource > resource = getResource(conf);
+
+ std::cout << __func__ << std::endl;
+
+ if (resource)
+ {
+ QueryParamsMap query;
+
+ // After deletion of the left action set, find target child resource's URIs by sending GET
+ // message. Note that, this resource is surely a collection resource which has child
+ // resources.
+ resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsConfiguration::onGetChildInfoForUpdate, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+ conf)));
+
+ }
+
+}
+
+void ThingsConfiguration::onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep, const int eCode, std::string conf)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "GET request was successful" << std::endl;
+
+ std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+ std::vector < OCRepresentation > children = rep.getChildren();
+ for (auto oit = children.begin(); oit != children.end(); ++oit)
+ {
+ std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+ }
+
+ // Get information by using configuration name(conf)
+ std::shared_ptr < OCResource > resource = getResource(conf);
+ std::string actionstring = conf;
+ std::string uri = getUriByConfigurationName(conf);
+ std::string attr = getAttributeByConfigurationName(conf);
+
+ if (uri == "")
+ return;
+
+ if (resource)
+ {
+ // In this nest, we create a new action set of which name is the configuration name.
+ // Required information consists of a host address, URI, attribute key, and attribute
+ // value.
+ ActionSet *newActionSet = new ActionSet();
+ newActionSet->actionsetName = conf;
+
+ for (auto oit = children.begin(); oit != children.end(); ++oit)
+ {
+ Action *newAction = new Action();
+
+ // oit->getUri() includes a host address as well as URI.
+ // We should split these to each other and only use the host address to create
+ // a child resource's URI. Note that the collection resource and its child resource
+ // are located in same host.
+ newAction->target = getHostFromURI(oit->getUri()) + uri;
+
+ Capability *newCapability = new Capability();
+ newCapability->capability = attr;
+ newCapability->status = getUpdateVal(conf);
+
+ newAction->listOfCapability.push_back(newCapability);
+ newActionSet->listOfAction.push_back(newAction);
+ }
+
+ // Request to create a new action set by using the above actionSet
+ g_groupmanager->addActionSet(resource, newActionSet,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsConfiguration::onCreateActionSet, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, conf)));
+ }
+
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+void ThingsConfiguration::onGetChildInfoForGet(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep, const int eCode, std::string conf)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "GET request was successful" << std::endl;
+ std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+ std::shared_ptr< OCResource > resource, tempResource;
+ std::vector < std::shared_ptr < OCResource >> p_resources;
+ std::vector < std::string > m_if;
+ std::string uri = getUriByConfigurationName(conf);
+
+ if (uri == "")
+ return;
+
+ if (uri == "/oic/con" || uri == "/factoryset" || uri == "/factoryset/oic/con")
+ m_if.push_back(BATCH_INTERFACE);
+ else
+ m_if.push_back(DEFAULT_INTERFACE);
+
+ std::vector < OCRepresentation > children = rep.getChildren();
+ for (auto oit = children.begin(); oit != children.end(); ++oit)
+ {
+ std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+
+ // Using a host address and child URIs, we can dynamically create resource objects.
+ // Note that, the child resources have not found before, we have no resource objects.
+ // For this reason, we create the resource objects.
+
+ std::string host = getHostFromURI(oit->getUri());
+ tempResource = OCPlatform::constructResourceObject(host, uri, true,
+ oit->getResourceTypes(), m_if);
+
+ p_resources.push_back(tempResource);
+ }
+
+ // Send GET messages to the child resources in turn.
+ for (unsigned int i = 0; i < p_resources.size(); ++i)
+ {
+ resource = p_resources.at(i);
+ if (resource)
+ {
+ try
+ {
+ if (isSimpleResource(resource))
+ {
+ QueryParamsMap test;
+ resource->get(test, getCallback(conf));
+ }
+ else
+ {
+ QueryParamsMap test;
+ resource->get(resource->getResourceTypes().at(0), BATCH_INTERFACE, test,
+ getCallback(conf));
+ }
+ }
+ catch (OCException& e)
+ {
+ std::cout << e.reason() << std::endl;
+ }
+
+ }
+ }
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+void ThingsConfiguration::onCreateActionSet(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep, const int eCode, std::string conf)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "PUT request was successful" << std::endl;
+
+ std::shared_ptr < OCResource > resource = getResource(conf);
+ if (resource)
+ {
+ // Now, it is time to execute the action set.
+ g_groupmanager->executeActionSet(resource, conf,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsConfiguration::onExecuteForGroupAction, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, conf)));
+ }
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+void ThingsConfiguration::onExecuteForGroupAction(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep, const int eCode, std::string conf)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "PUT request was successful" << std::endl;
+
+ getCallback(conf)(headerOptions, rep, eCode);
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+bool ThingsConfiguration::isSimpleResource(std::shared_ptr< OCResource > resource)
+{
+ for (unsigned int i = 0; i < resource->getResourceInterfaces().size(); ++i)
+ {
+ if (resource->getResourceInterfaces().at(i) == BATCH_INTERFACE)
+ return false;
+ }
+ return true;
+}
+
+void ThingsConfiguration::onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "Get request was successful" << std::endl;
+
+ getCallback(conf)(headerOptions, rep, eCode);
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+void ThingsConfiguration::onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "PUT request was successful" << std::endl;
+
+ // Callback
+ getCallback(conf)(headerOptions, rep, eCode);
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+OCStackResult ThingsConfiguration::updateConfigurations(std::shared_ptr< OCResource > resource,
+ std::map< ConfigurationName, ConfigurationValue > configurations,
+ ConfigurationCallback callback)
+{
+ // For M2, # of configurations is 1
+ // First, mapping a semantic name(ConfigurationUnit) into resource's name(uri ...)
+ if (configurations.size() == 0)
+ {
+ std::cout << "# of request configuration is 0" << std::endl;
+ return OC_STACK_ERROR;
+ }
+
+ if (!resource)
+ {
+ std::cout << "resource is NULL\n";
+ return OC_STACK_ERROR;
+ }
+
+ std::map< ConfigurationName, ConfigurationValue >::iterator it = configurations.begin();
+ std::string conf = it->first; // configuration name
+ std::transform(conf.begin(), conf.end(), conf.begin(), ::tolower); // to lower case
+
+ // Check the request queue if a previous request is still left. If so, remove it.
+ std::map< std::string, ConfigurationRequestEntry >::iterator iter =
+ configurationRequestTable.find(conf);
+ if (iter != configurationRequestTable.end())
+ configurationRequestTable.erase(iter);
+
+ // Create new request entry stored in the queue
+ ConfigurationRequestEntry newCallback(conf, callback, resource, it->second);
+ configurationRequestTable.insert(std::make_pair(conf, newCallback));
+
+ OCRepresentation rep;
+ QueryParamsMap query;
+ if (isSimpleResource(resource))
+ {
+ // This resource does not need to use a group manager. Just send a PUT message
+ rep.setValue(getAttributeByConfigurationName(conf), getUpdateVal(conf));
+ return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsConfiguration::onGet, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3, conf)));
+ }
+ else
+ {
+ // This resource is a collection resource which uses group manager functionalities.
+ // First, delete an existing action set of which name is same as a current action set name.
+ // As of now, the name is determined by "Configuration Name" which a user just specifies.
+ return g_groupmanager->deleteActionSet(resource, conf,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsConfiguration::onDeleteActionSet, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+ conf)));
+ }
+}
+
+OCStackResult ThingsConfiguration::getConfigurations(std::shared_ptr< OCResource > resource,
+ std::vector< ConfigurationName > configurations, ConfigurationCallback callback)
+{
+ // For M2, # of configurations is 1
+ // First, mapping a semantic name(ConfigurationUnit) into resource's name(uri ...)
+ if (configurations.size() == 0)
+ {
+ std::cout << "# of request configuration is 0" << std::endl;
+ return OC_STACK_ERROR;
+ }
+ if (!resource)
+ {
+ std::cout << "resource is NULL\n";
+ return OC_STACK_ERROR;
+ }
+
+ std::vector< ConfigurationName >::iterator it = configurations.begin();
+ std::string conf = (*it); // configuration name
+ std::transform(conf.begin(), conf.end(), conf.begin(), ::tolower); // to lower case
+
+ // Check the request queue if a previous request is still left. If so, remove it.
+ std::map< std::string, ConfigurationRequestEntry >::iterator iter =
+ configurationRequestTable.find(conf);
+ if (iter != configurationRequestTable.end())
+ configurationRequestTable.erase(iter);
+
+ // Create new request entry stored in the queue
+ ConfigurationRequestEntry newCallback(conf, callback, resource, conf);
+ configurationRequestTable.insert(std::make_pair(conf, newCallback));
+
+ QueryParamsMap query;
+ OCRepresentation rep;
+
+ if (isSimpleResource(resource))
+ {
+ // This resource is a simple resource. Just send a PUT message
+ return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsConfiguration::onGet, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3, conf)));
+ }
+ else
+ {
+ // This resource is a collection resource. On the contrary of a update, it does not use
+ // group manager functionality. It just acquires child resource's URI and send GET massages
+ // to the child resources in turn.
+ // First, request the child resources's URI.
+ return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsConfiguration::onGetChildInfoForGet, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+ conf)));
+ }
+
+}
+
+// callback handler on GET request
+void ThingsConfiguration::onGetBootstrapInformation(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+ if(eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "GET request was successful" << std::endl;
+
+ std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+ g_bootstrapCallback(headerOptions, rep, eCode);
+ }
+
+ else
+ {
+ std::cout << "onGET Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+void ThingsConfiguration::onFoundBootstrapServer(std::vector< std::shared_ptr< OCResource > > resources)
+{
+ std::string resourceURI;
+ std::string hostAddress;
+
+ try
+ {
+ // Do some operations with resource object.
+ for (unsigned int i = 0; i < resources.size(); ++i)
+ {
+ std::shared_ptr < OCResource > resource = resources.at(i);
+
+ if (resource)
+ {
+ std::cout << "DISCOVERED Resource:" << std::endl;
+ // Get the resource URI
+ resourceURI = resource->uri();
+ std::cout << "\tURI of the resource: " << resourceURI << std::endl;
+
+ // Get the resource host address
+ hostAddress = resource->host();
+ std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
+
+ // Get the resource types
+ std::cout << "\tList of resource types: " << std::endl;
+ for (auto &resourceTypes : resource->getResourceTypes())
+ {
+ std::cout << "\t\t" << resourceTypes << std::endl;
+ }
+
+ // Get the resource interfaces
+ cout << "\tList of resource interfaces: " << endl;
+ for (auto &resourceInterfaces : resource->getResourceInterfaces())
+ {
+ cout << "\t\t" << resourceInterfaces << endl;
+ }
+
+ // Request configuration resources
+ std::cout << "Getting bootstrap server representation on: "<< DEFAULT_INTERFACE << std::endl;
+
+ resource->get("bootstrap", DEFAULT_INTERFACE, QueryParamsMap(), &onGetBootstrapInformation);
+
+ }
+ else
+ {
+ // Resource is invalid
+ std::cout << "Resource is invalid" << std::endl;
+ }
+ }
+
+ }
+ catch (std::exception& e)
+ {
+ //log(e.what());
+ }
+}
+
+OCStackResult ThingsConfiguration::doBootstrap(ConfigurationCallback callback)
+{
+ g_bootstrapCallback = callback;
+
+ // Find bootstrap server.
+ std::vector<std::string> type;
+ type.push_back("bootstrap");
+
+ std::cout << "Finding Bootstrap Server resource... " << std::endl;
+ return g_groupmanager->findCandidateResources(type, &onFoundBootstrapServer);
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file ThingsConfiguration.h
+
+/// @brief This file contains the declaration of classes and its members related to
+/// ThingsConfiguration.
+
+#ifndef __OC_THINGSCONFIGURATION__
+#define __OC_THINGSCONFIGURATION__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "GroupManager.h"
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+/// Declearation of Configuation Callback funtion type
+typedef std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) > ConfigurationCallback;
+
+typedef std::string ConfigurationName;
+typedef std::string ConfigurationValue;
+
+/**
+ * @brief
+ * The following class is used as a item stacking in request queue. The class stores a request and
+ * referential information (e.g., a configuration name, a target resource object, a callback functi-
+ * on passed from the applications, and a update value). When the function for updating/getting
+ * configuration value is called from applications, this class instance is created and stored in the
+ * request queue. The queue is maintained in a std::map structure so if desiring to find a specific
+ * request, you can find it by querying a configuration name.
+ */
+class ConfigurationRequestEntry
+{
+public:
+ ConfigurationRequestEntry(std::string ID, ConfigurationCallback callback,
+ std::shared_ptr< OCResource > resource, std::string updateVal) :
+ m_ID(ID), m_callback(callback), m_resource(resource), m_updateVal(updateVal)
+ {
+ }
+ ;
+
+ // Configuration Name (used in key value in std::map structure)
+ // e.g., time, network, security, and so on
+ std::string m_ID;
+
+ // Reference callback pointer
+ ConfigurationCallback m_callback;
+
+ // Reference resource object
+ std::shared_ptr< OCResource > m_resource;
+
+ // Update value only used for configuration update
+ std::string m_updateVal;
+};
+
+/**
+ * @brief
+ * The following class is used to store providing configuration name and its relevant information
+ * The relevant information includes a brief description, uri, and attribute key.
+ * Note that a developer only specifies a configuration name, not URI nor attribute key, to
+ * update/get a value to a remote. Thus, using configuration name, we convert it to more specific
+ * information (i.e. uri and attribute key) to send a request. This class is reponsible to storing
+ * these information.
+ */
+class ConfigurationUnitInfo
+{
+public:
+
+ std::string m_name;
+ std::string m_description;
+ std::string m_uri;
+ std::string m_attribute;
+
+ ConfigurationUnitInfo(std::string name, std::string description, std::string uri,
+ std::string attribute) :
+ m_name(name), m_description(description), m_uri(uri), m_attribute(attribute)
+ {
+ }
+ ;
+
+ // If a developer wants to know a list of configuration names, gives it in JSON format.
+ std::string getJSON()
+ {
+ std::string res;
+
+ res = "{\"name\":\"" + m_name + "\",\"description\":\"" + m_description + "\"}";
+
+ return res;
+ }
+};
+
+#define NUMCONFUNIT 6
+typedef std::string ConfigurationName;
+typedef std::string ConfigurationValue;
+
+class ThingsConfiguration
+{
+public:
+ /**
+ * Constructor for ThingsConfiguration. Constructs a new ThingsConfiguration
+ */
+ ThingsConfiguration(void)
+ {
+ ConfigurationUnitInfo unit[] =
+ {
+ { "installedlocation", "the semantic location at a specific area (e.g., living room)",
+ "/oic/con", "installedLocation" },
+ { "time", "Resource for system time information including time zones etc.", "/oic/time",
+ "currentTime" },
+ { "network", "Resource for network information", "/oic/net", "address" },
+ { "security", "Resource for security information (credentials, access control list etc.)",
+ "/oic/sec", "mode" },
+ { "setattr1", "attribute 1 of Set Resource", "/oic/customset", "attr1" },
+ { "getfactoryset", "get all default configuration value", "/factoryset/oic/con", "" } };
+
+ for (int i = 0; i < NUMCONFUNIT; i++)
+ ConfigurationUnitTable.push_back(unit[i]);
+ }
+ ;
+
+ /**
+ * Virtual destructor
+ */
+ ~ThingsConfiguration(void)
+ {
+ }
+ ;
+
+ static ThingsConfiguration *thingsConfigurationInstance;
+ static ThingsConfiguration* getInstance();
+ void deleteInstance();
+
+ void setGroupManager(GroupManager *groupmanager)
+ {
+ g_groupmanager = groupmanager;
+ }
+ ;
+
+ /**
+ * @brief
+ * API for updating configuration value of multiple things of a target group or a single thing.
+ * Callback is called when a response arrives.
+ * Before using the below function, a developer should acquire a resource pointer of
+ * (collection) resource that he want to send a request by calling findResource() function
+ * provided in OCPlatform. And he should also notice a "Configuration Name" term which
+ * represents a nickname of a target attribute of a resource that he wants to update.
+ * The base motivation to introduce the term is to avoid a usage of URI to access a resource
+ * from a developer. Thus, a developer should know which configuration names are supported
+ * by Things Configuration class and what the configuration name means.
+ * To get a list of supported configuration names, use getListOfSupportedConfigurationUnits()
+ * function, which provides the list in JSON format.
+ * NOTICE: A series of callback functions is called from updateConfigurations() function:
+ * (1) For a collection resource
+ * updateConfiguration()->onDeleteActionSet()->onGetChildInfoForUpdate()->onCreateActionSet()
+ * ->...(CoAP msg. is transmitted)->OnExecuteForGroupAction()->callback function in APP.
+ * (2) For a simple resource
+ * updateConfiguration()->...(CoAP msg. is transmitted)->OnPut()->callback function in APP.
+ *
+ * @param resource - resource pointer representing the target group or the single thing.
+ * @param configurations - ConfigurationUnit: a nickname of attribute of target resource
+ * (e.g., installedlocation, currency, (IP)address)
+ * Value : a value to be updated
+ * @param callback - callback.
+ *
+ * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+ *
+ * NOTE: OCStackResult is defined in ocstack.h.
+ */
+ OCStackResult updateConfigurations(std::shared_ptr< OCResource > resource,
+ std::map< ConfigurationName, ConfigurationValue > configurations,
+ ConfigurationCallback callback);
+
+ /**
+ * API for getting configuration value of multiple things of a target group or a single thing.
+ * Callback is called when a response arrives.
+ * NOTICE: A series of callback functions is called from getConfigurations() function:
+ * (1) For a collection resource
+ * getConfigurations()->onGetChildInfoForGet()->...(CoAP msg. is transmitted)
+ * ->callback function in APP.
+ * (2) For a simple resource
+ * getConfigurations()->...(CoAP msg. is transmitted)->onGet()->callback function in APP.
+ *
+ * @param resource - resource pointer representing the target group or the single thing.
+ * @param configurations - ConfigurationUnit: a nickname of attribute of target resource.
+ * @param callback - callback.
+ *
+ * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+ *
+ * NOTE: OCStackResult is defined in ocstack.h.
+ */
+ OCStackResult getConfigurations(std::shared_ptr< OCResource > resource,
+ std::vector< ConfigurationName > configurations, ConfigurationCallback callback);
+
+ /**
+ * API to show a list of supported configuration units (configurable parameters)
+ * Callback call when a response arrives.
+ *
+ * @return the list in JSON format
+ */
+ std::string getListOfSupportedConfigurationUnits();
+
+ /**
+ * API for bootstrapping functionality. Find a bootstrap server and get configuration
+ * information from the bootstrap server. With the information, make a configuration resource.
+ *
+ * @param callback - callback.
+ *
+ * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+ *
+ * NOTE: OCStackResult is defined in ocstack.h.
+ */
+ OCStackResult doBootstrap(ConfigurationCallback callback);
+
+private:
+
+ GroupManager *g_groupmanager;
+
+ std::vector< ConfigurationUnitInfo > ConfigurationUnitTable;
+
+ void onExecuteForGroupAction(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf);
+ void onGetChildInfoForUpdate(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf);
+ void onGetChildInfoForGet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf);
+ void onCreateActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf);
+ void onGetActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf);
+ void onDeleteActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf);
+ void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode,
+ std::string conf);
+ void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode,
+ std::string conf);
+ static void onFoundBootstrapServer(std::vector< std::shared_ptr< OCResource > > resources);
+ static void onGetBootstrapInformation(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
+
+ std::shared_ptr< OCResource > getResource(std::string conf);
+ ConfigurationCallback getCallback(std::string conf);
+ std::string getUpdateVal(std::string conf);
+ std::string getAttributeByConfigurationName(ConfigurationName name);
+ std::string getUriByConfigurationName(ConfigurationName name);
+
+ std::string getHostFromURI(std::string oldUri);
+
+ bool isSimpleResource(std::shared_ptr< OCResource > resource);
+
+};
+
+#endif /* __OC_THINGSCONFIGURATION__*/
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file ThingsDiagnostics.cpp
+/// @brief
+
+#include <OCApi.h>
+#include <OCPlatform.h>
+#include <cstdlib>
+
+#include "ThingsDiagnostics.h"
+
+using namespace OC;
+
+const int SUCCESS_RESPONSE = 0;
+
+std::map< std::string, DiagnosticsRequestEntry > diagnosticsRequestTable;
+
+ThingsDiagnostics* ThingsDiagnostics::thingsDiagnosticsInstance = NULL;
+
+ThingsDiagnostics* ThingsDiagnostics::getInstance()
+{
+ if (thingsDiagnosticsInstance == NULL)
+ {
+ thingsDiagnosticsInstance = new ThingsDiagnostics();
+ }
+ return thingsDiagnosticsInstance;
+}
+
+void ThingsDiagnostics::deleteInstance()
+{
+ if (thingsDiagnosticsInstance)
+ {
+ delete thingsDiagnosticsInstance;
+ thingsDiagnosticsInstance = NULL;
+ }
+}
+
+std::string ThingsDiagnostics::getAttributeByDiagnosticsName(DiagnosticsName name)
+{
+ for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
+ {
+ if ((*it).m_name == name)
+ return (*it).m_attribute;
+ }
+
+ return "";
+}
+
+std::string ThingsDiagnostics::getUriByDiagnosticsName(DiagnosticsName name)
+{
+ for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
+ {
+ if ((*it).m_name == name)
+ return (*it).m_uri;
+ }
+
+ return "";
+}
+
+std::string ThingsDiagnostics::getUpdateVal(std::string diag)
+{
+ std::map< std::string, DiagnosticsRequestEntry >::iterator it = diagnosticsRequestTable.find(
+ diag);
+
+ if (it == diagnosticsRequestTable.end())
+ return NULL;
+ else
+ return it->second.m_updateVal;
+
+}
+std::shared_ptr< OCResource > ThingsDiagnostics::getResource(std::string diag)
+{
+ std::map< std::string, DiagnosticsRequestEntry >::iterator it = diagnosticsRequestTable.find(
+ diag);
+
+ if (it == diagnosticsRequestTable.end())
+ return NULL;
+ else
+ return it->second.m_resource;
+}
+
+DiagnosticsCallback ThingsDiagnostics::getCallback(std::string diag)
+{
+ std::map< std::string, DiagnosticsRequestEntry >::iterator it = diagnosticsRequestTable.find(
+ diag);
+
+ if (it == diagnosticsRequestTable.end())
+ return NULL;
+ else
+ return it->second.m_callback;
+}
+
+std::string ThingsDiagnostics::getHostFromURI(std::string oldUri)
+{
+ size_t f;
+ std::string newUri;
+
+ if ((f = oldUri.find("/factoryset/oic/")) != string::npos)
+ newUri = oldUri.replace(f, oldUri.size(), "");
+ else if ((f = oldUri.find("/oic/")) != string::npos)
+ newUri = oldUri.replace(f, oldUri.size(), "");
+
+ return newUri;
+}
+
+std::string ThingsDiagnostics::getListOfSupportedDiagnosticsUnits()
+{
+ std::string res;
+
+ res = "{\"Diagnostics Units\":[";
+
+ auto it = DiagnosticsUnitTable.begin();
+ while (1)
+ {
+ res = res + (*it).getJSON();
+ it++;
+
+ if (it == DiagnosticsUnitTable.end())
+ break;
+ else
+ res += ",";
+ }
+
+ res += "]}";
+
+ return res;
+}
+
+void ThingsDiagnostics::onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep, const int eCode, std::string diag)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "GET request was successful" << std::endl;
+
+ std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+ std::vector < OCRepresentation > children = rep.getChildren();
+ for (auto oit = children.begin(); oit != children.end(); ++oit)
+ {
+ std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+ }
+
+ // Get information by using diagnostics name(diag)
+ std::shared_ptr < OCResource > resource = getResource(diag);
+ std::string actionstring = diag;
+ std::string uri = getUriByDiagnosticsName(diag);
+ std::string attr = getAttributeByDiagnosticsName(diag);
+
+ if (uri == "")
+ return;
+
+ if (resource)
+ {
+ // In this nest, we create a new action set of which name is the dignostics name.
+ // Required information consists of a host address, URI, attribute key, and attribute
+ // value.
+ ActionSet *newActionSet = new ActionSet();
+ newActionSet->actionsetName = diag;
+
+ for (auto oit = children.begin(); oit != children.end(); ++oit)
+ {
+ Action *newAction = new Action();
+
+ // oit->getUri() includes a host address as well as URI.
+ // We should split these to each other and only use the host address to create
+ // a child resource's URI. Note that the collection resource and its child resource
+ // are located in same host.
+ newAction->target = getHostFromURI(oit->getUri()) + uri;
+
+ Capability *newCapability = new Capability();
+ newCapability->capability = attr;
+ newCapability->status = getUpdateVal(diag);
+
+ newAction->listOfCapability.push_back(newCapability);
+ newActionSet->listOfAction.push_back(newAction);
+ }
+
+ // Request to create a new action set by using the above actionSet
+ g_groupmanager->addActionSet(resource, newActionSet,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsDiagnostics::onCreateActionSet, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, diag)));
+
+ }
+
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+void ThingsDiagnostics::onCreateActionSet(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep, const int eCode, std::string diag)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "PUT request was successful" << std::endl;
+
+ std::shared_ptr < OCResource > resource = getResource(diag);
+ if (resource)
+ {
+ // Now, it is time to execute the action set.
+ g_groupmanager->executeActionSet(resource, diag,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsDiagnostics::onExecuteForGroupAction, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, diag)));
+ }
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+void ThingsDiagnostics::onExecuteForGroupAction(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep, const int eCode, std::string diag)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "PUT request was successful" << std::endl;
+
+ getCallback(diag)(headerOptions, rep, eCode);
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+void ThingsDiagnostics::onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string diag)
+{
+ if (eCode == SUCCESS_RESPONSE)
+ {
+ std::cout << "PUT request was successful" << std::endl;
+
+ getCallback(diag)(headerOptions, rep, eCode);
+ }
+ else
+ {
+ std::cout << "onPut Response error: " << eCode << std::endl;
+ std::exit(-1);
+ }
+}
+
+bool ThingsDiagnostics::isSimpleResource(std::shared_ptr< OCResource > resource)
+{
+ for (unsigned int i = 0; i < resource->getResourceInterfaces().size(); ++i)
+ {
+ //std::cout << resource->getResourceInterfaces().at(0) << std::endl;
+ if (resource->getResourceInterfaces().at(0) == BATCH_INTERFACE)
+ return false;
+ }
+ return true;
+}
+
+OCStackResult ThingsDiagnostics::reboot(std::shared_ptr< OCResource > resource,
+ DiagnosticsCallback callback)
+{
+ if (!resource)
+ {
+ std::cout << "resource is NULL\n";
+ return OC_STACK_ERROR;
+ }
+
+ std::string diag = "reboot";
+
+ // Check the request queue if a previous request is still left. If so, remove it.
+ std::map< std::string, DiagnosticsRequestEntry >::iterator iter = diagnosticsRequestTable.find(
+ diag);
+ if (iter != diagnosticsRequestTable.end())
+ diagnosticsRequestTable.erase(iter);
+
+ // Create new request entry stored in the queue
+ DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
+ diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
+
+ QueryParamsMap query;
+ OCRepresentation rep;
+
+ if (isSimpleResource(resource))
+ {
+ // This resource is a simple resource. Just send a PUT message
+ OCRepresentation rep;
+ rep.setValue<std::string>(diag, "true");
+
+ return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3, diag)));
+ }
+ else
+ {
+ // This resource is a collection resource. It just acquires child resource's URI and send
+ // GET massages to the child resources in turn.
+ // First, request the child resources's URI.
+ // TODO: Add a deletion of actionset
+ return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+ diag)));
+ }
+}
+
+OCStackResult ThingsDiagnostics::factoryReset(std::shared_ptr< OCResource > resource,
+ DiagnosticsCallback callback)
+{
+ if (!resource)
+ {
+ std::cout << "resource is NULL\n";
+ return OC_STACK_ERROR;
+ }
+
+ std::string diag = "factoryreset";
+
+ // Check the request queue if a previous request is still left. If so, remove it.
+ std::map< std::string, DiagnosticsRequestEntry >::iterator iter = diagnosticsRequestTable.find(
+ diag);
+ if (iter != diagnosticsRequestTable.end())
+ diagnosticsRequestTable.erase(iter);
+
+ // Create new request entry stored in the queue
+ DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
+ diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
+
+ QueryParamsMap query;
+ OCRepresentation rep;
+
+ if (isSimpleResource(resource))
+ {
+ // This resource is a simple resource. Just send a PUT message
+ OCRepresentation rep;
+ rep.setValue<std::string>("factoryReset", "true");
+
+ return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3, diag)));
+ }
+ else
+ {
+ // This resource is a collection resource. It just acquires child resource's URI and send
+ // GET massages to the child resources in turn.
+ // First, request the child resources's URI.
+ // TODO: Add a deletion of actionset
+ return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+ diag)));
+ }
+}
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file ThingsDiagnostics.h
+
+/// @brief This file contains the declaration of classes and its members related to
+/// ThingsDiagnostics.
+
+#ifndef __OC_THINGSDIAGNOSTICS__
+#define __OC_THINGSDIAGNOSTICS__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "GroupManager.h"
+
+using namespace OC;
+
+/// Declearation of Diagnostics Callback funtion type
+typedef std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) > DiagnosticsCallback;
+
+/**
+ * @brief
+ * The following class is used as a item stacking in request queue. The class stores a request and
+ * referential information (e.g., a diagnostics name, a target resource object, a callback functi-
+ * on passed from the applications, and a update value). When the function for updating/getting
+ * diagnostics value is called from applications, this class instance is created and stored in the
+ * request queue. The queue is maintained in a std::map structure so if desiring to find a specific
+ * request, you can find it by querying a diagnostics name.
+ */
+class DiagnosticsRequestEntry
+{
+public:
+ DiagnosticsRequestEntry(std::string ID, DiagnosticsCallback callback,
+ std::shared_ptr< OCResource > resource, std::string updateVal) :
+ m_ID(ID), m_callback(callback), m_resource(resource), m_updateVal(updateVal)
+ {
+ }
+ ;
+
+ // Diagnostics Name (used in key value in std::map structure)
+ // e.g., reboot and factoryset
+ std::string m_ID;
+
+ // Reference callback pointer
+ DiagnosticsCallback m_callback;
+
+ // Reference resource object
+ std::shared_ptr< OCResource > m_resource;
+
+ // Update value only used for diagnostics update (always "true")
+ std::string m_updateVal;
+};
+
+/**
+ * @brief
+ * The following class is used to store providing diagnostics name and its relevant information
+ * The relevant information includes a brief description, uri, and attribute key.
+ * Note that a developer only specifies a diagnostics name, not URI nor attribute key, to
+ * update a value to a remote. Thus, using diagnostics name, we convert it to more specific
+ * information (i.e. uri and attribute key) to send a request. This class is reponsible to storing
+ * these information.
+ */
+class DiagnosticsUnitInfo
+{
+public:
+ DiagnosticsUnitInfo(std::string name, std::string description, std::string uri,
+ std::string attribute) :
+ m_name(name), m_description(description), m_uri(uri), m_attribute(attribute)
+ {
+ }
+ ;
+
+ std::string m_name;
+ std::string m_description;
+ std::string m_uri;
+ std::string m_attribute;
+
+ // If a developer wants to know a list of diagnostics names, gives it in JSON format.
+ std::string getJSON()
+ {
+ std::string res;
+
+ res = "{\"name\":\"" + m_name + "\",\"description\":\"" + m_description + "\"}";
+
+ return res;
+ }
+};
+
+#define NUMDIAGUNIT 3
+typedef std::string DiagnosticsName;
+typedef std::string DiagnosticsValue;
+
+class ThingsDiagnostics
+{
+public:
+ /**
+ * Constructor for ThingsDiagnostics. Constructs a new ThingsDiagnostics
+ */
+ ThingsDiagnostics(void)
+ {
+ DiagnosticsUnitInfo unit[] =
+ {
+ { "reboot",
+ "reboot",
+ "/oic/diag", "reboot" },
+ { "startcollection",
+ "Toggles between collecting and not collecting any device statistics depending on the value being 0 or 1",
+ "/oic/diag", "startCollection" },
+ { "factoryreset",
+ "restore all configuration values to default values",
+ "/oic/diag", "factoryReset" } };
+
+ for (int i = 0; i < NUMDIAGUNIT; i++)
+ DiagnosticsUnitTable.push_back(unit[i]);
+ }
+ ;
+
+ /**
+ * Virtual destructor
+ */
+ ~ThingsDiagnostics(void)
+ {
+ }
+ ;
+
+ static ThingsDiagnostics *thingsDiagnosticsInstance;
+ static ThingsDiagnostics* getInstance();
+ void deleteInstance();
+
+ void setGroupManager(GroupManager *groupmanager)
+ {
+ g_groupmanager = groupmanager;
+ }
+ ;
+
+ /**
+ * API to make things reboot
+ * Callback call when a response arrives.
+ *
+ * @param resource - resource pointer representing the target group
+ * @param callback - callback.
+ *
+ * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+ *
+ * NOTE: OCStackResult is defined in ocstack.h.
+ */
+ OCStackResult reboot(std::shared_ptr< OCResource > resource, DiagnosticsCallback callback);
+
+ /**
+ * API for factory reset on device
+ * Callback call when a response arrives.
+ *
+ * @param resource - resource pointer representing the target group
+ * @param callback - callback.
+ *
+ * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+ *
+ * NOTE: OCStackResult is defined in ocstack.h.
+ */
+
+ OCStackResult factoryReset(std::shared_ptr< OCResource > resource,
+ DiagnosticsCallback callback);
+
+ /**
+ * API to show a list of supported diagnostics units
+ * Callback call when a response arrives.
+ *
+ * @return the list in JSON format
+ */
+ std::string getListOfSupportedDiagnosticsUnits();
+
+private:
+
+ GroupManager *g_groupmanager;
+
+ std::vector< DiagnosticsUnitInfo > DiagnosticsUnitTable;
+
+ void onExecuteForGroupAction(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf);
+ void onGetChildInfoForUpdate(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf);
+ void onCreateActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode, std::string conf);
+ void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode,
+ std::string conf);
+ void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode,
+ std::string conf);
+
+ std::shared_ptr< OCResource > getResource(std::string conf);
+ DiagnosticsCallback getCallback(std::string conf);
+ std::string getUpdateVal(std::string conf);
+ std::string getAttributeByDiagnosticsName(DiagnosticsName name);
+ std::string getUriByDiagnosticsName(DiagnosticsName name);
+
+ std::string getHostFromURI(std::string oldUri);
+
+ bool isSimpleResource(std::shared_ptr< OCResource > resource);
+
+};
+
+#endif /* __OC_THINGSCONFIGURATION__*/
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file ThingsManager.cpp
+/// @brief
+
+#include "ThingsManager.h"
+#include "GroupManager.h"
+#include "GroupSynchronization.h"
+#include "ThingsConfiguration.h"
+#include "ThingsDiagnostics.h"
+#include <algorithm>
+#include <thread>
+
+
+using namespace OC;
+
+GroupManager *g_groupManager;
+GroupSynchronization *g_groupSync = NULL;
+ThingsConfiguration *g_thingsConf = NULL;
+ThingsDiagnostics *g_thingsDiag = NULL;
+
+ThingsManager::ThingsManager(void)
+{
+ g_groupManager = new GroupManager();
+ g_groupSync = GroupSynchronization::getInstance();
+ g_thingsConf = ThingsConfiguration::getInstance();
+ g_thingsDiag = ThingsDiagnostics::getInstance();
+ g_thingsConf->setGroupManager(g_groupManager);
+ g_thingsDiag->setGroupManager(g_groupManager);
+}
+
+/**
+ * Virtual destructor
+ */
+ThingsManager::~ThingsManager(void)
+{
+ delete g_groupManager;
+ g_groupSync->deleteInstance();
+ g_thingsConf->deleteInstance();
+ g_thingsDiag->deleteInstance();
+}
+
+
+
+OCStackResult ThingsManager::findCandidateResources(std::vector< std::string > resourceTypes,
+ std::function< void(std::vector< std::shared_ptr< OCResource > >) > callback, int waitsec)
+{
+ OCStackResult result = g_groupManager->findCandidateResources(resourceTypes,callback,waitsec);
+
+ return result;
+}
+
+OCStackResult ThingsManager::subscribeCollectionPresence(std::shared_ptr< OCResource > resource, std::function< void(std::string, OCStackResult) > callback)
+{
+ OCStackResult result = g_groupManager->subscribeCollectionPresence(resource,callback);
+
+ return result;
+}
+
+OCStackResult ThingsManager::findGroup (std::vector<std::string> collectionResourceTypes, FindCallback resourceHandler)
+{
+ OCStackResult result = g_groupSync->findGroup(collectionResourceTypes, resourceHandler);
+
+ return result;
+}
+
+OCStackResult ThingsManager::createGroup (std::string collectionResourceType)
+{
+ OCStackResult result = g_groupSync->createGroup(collectionResourceType);
+
+ return result;
+}
+
+OCStackResult ThingsManager::joinGroup (std::string collectionResourceType, OCResourceHandle resourceHandle)
+{
+ OCStackResult result = g_groupSync->joinGroup(collectionResourceType, resourceHandle);
+
+ return result;
+}
+
+OCStackResult ThingsManager::joinGroup (const std::shared_ptr<OCResource> resource, OCResourceHandle resourceHandle)
+{
+ OCStackResult result = g_groupSync->joinGroup(resource, resourceHandle);
+
+ return result;
+}
+
+OCStackResult ThingsManager::leaveGroup (std::string collectionResourceType, OCResourceHandle resourceHandle)
+{
+ OCStackResult result = g_groupSync->leaveGroup(collectionResourceType, resourceHandle);
+
+ return result;
+}
+
+void ThingsManager::deleteGroup (std::string collectionResourceType)
+{
+ g_groupSync->deleteGroup(collectionResourceType);
+}
+
+std::map<std::string, OCResourceHandle> ThingsManager::getGroupList ()
+{
+ return g_groupSync->getGroupList();
+}
+
+OCStackResult ThingsManager::updateConfigurations(std::shared_ptr< OCResource > resource, std::map<ConfigurationName, ConfigurationValue> configurations, ConfigurationCallback callback)
+{
+ return g_thingsConf->updateConfigurations(resource, configurations, callback);
+}
+OCStackResult ThingsManager::getConfigurations(std::shared_ptr< OCResource > resource, std::vector<ConfigurationName> configurations, ConfigurationCallback callback)
+{
+ return g_thingsConf->getConfigurations( resource, configurations, callback);
+}
+std::string ThingsManager::getListOfSupportedConfigurationUnits()
+{
+ return g_thingsConf->getListOfSupportedConfigurationUnits();
+}
+
+OCStackResult ThingsManager::doBootstrap(ConfigurationCallback callback)
+{
+ return g_thingsConf->doBootstrap(callback);
+}
+
+
+OCStackResult ThingsManager::reboot(std::shared_ptr< OCResource > resource, ConfigurationCallback callback)
+{
+ return g_thingsDiag->reboot( resource, callback);
+}
+OCStackResult ThingsManager::factoryReset(std::shared_ptr< OCResource > resource, ConfigurationCallback callback)
+{
+ return g_thingsDiag->factoryReset( resource, callback);
+}
+
+
+
+std::string ThingsManager::getStringFromActionSet(const ActionSet *newActionSet)
+{
+ return g_groupManager->getStringFromActionSet(newActionSet);
+}
+ActionSet* ThingsManager::getActionSetfromString(std::string desc)
+{
+ return g_groupManager->getActionSetfromString(desc);
+}
+OCStackResult ThingsManager::addActionSet(std::shared_ptr< OCResource > resource, const ActionSet* newActionSet, PutCallback cb)
+{
+ return g_groupManager->addActionSet(resource, newActionSet, cb);
+}
+OCStackResult ThingsManager::executeActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback cb)
+{
+ return g_groupManager->executeActionSet(resource, actionsetName, cb);
+}
+OCStackResult ThingsManager::getActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, GetCallback cb)
+{
+ return g_groupManager->getActionSet(resource, actionsetName, cb);
+}
+OCStackResult ThingsManager::deleteActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, PostCallback cb)
+{
+ return g_groupManager->deleteActionSet(resource, actionsetName, cb);
+}