//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-/// @file GroupManager.cpp
-/// @brief
+/**
+ * @file
+ *
+ */
-#include "GroupManager.h"
#include <algorithm>
#include <thread>
#include <unistd.h>
-
#include <string.h>
-#define PLAIN_DELIMITER "\""
+#include "GroupManager.h"
+
#define ACTION_DELIMITER "*"
#define DESC_DELIMITER "|"
#define ATTR_DELIMITER "="
using namespace OC;
+using namespace OIC;
-namespace OIC
-{
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;
+std::mutex callbackLock;
+
template< typename T >
bool IsSubset(std::vector< T > full, std::vector< T > sub)
void GroupManager::findPreparedRequest(
std::map< std::vector< std::string >, CandidateCallback > &request)
{
+ std::lock_guard<std::mutex> lock(callbackLock);
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)
{
+ //insert resource related to request
resources.push_back(secondIt->second);
}
}
}
-OCStackResult GroupManager::findCandidateResources(std::vector< std::string > resourceTypes,
+OCStackResult GroupManager::findCandidateResources(
+ std::vector< std::string > resourceTypes,
CandidateCallback callback, int waitsec)
{
if (resourceTypes.size() < 1)
{
return OC_STACK_ERROR;
}
+ if(callback == NULL)
+ {
+ return OC_STACK_ERROR;
+ }
std::sort(resourceTypes.begin(), resourceTypes.end());
resourceTypes.erase(std::unique(resourceTypes.begin(), resourceTypes.end()),
resourceTypes.end());
- if (waitsec != -1)
+ if (waitsec >= 0)
{
candidateRequestForTimer.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=";
+ // std::cout << "resourceTypes : " << resourceTypes.at(i) << std::endl;
+
+ std::string query = OC_RSRVD_WELL_KNOWN_URI;
+ query.append("?rt=");
query.append(resourceTypes.at(i));
- OCPlatform::findResource("", query.c_str(),
+
+ OCPlatform::findResource("",
+ query,
+ CT_DEFAULT,
std::function < void(std::shared_ptr < OCResource > resource)
- > (std::bind(&GroupManager::onFoundResource, this,
- std::placeholders::_1, waitsec)));
+ > (std::bind(&GroupManager::onFoundResource, this, std::placeholders::_1,
+ waitsec)));
}
- if (waitsec != -1)
+ if (waitsec >= 0)
{
std::thread exec(
std::function< void(int second) >(
return OC_STACK_OK;
}
+
+OCStackResult GroupManager::bindResourceToGroup(OCResourceHandle& childHandle, std::shared_ptr< OCResource > resource, OCResourceHandle& collectionHandle)
+{
+
+ OCStackResult result = OCPlatform::registerResource(childHandle, resource);
+
+ cout << "\tresource registed!" << endl;
+
+ if(result == OC_STACK_OK)
+ {
+ OCPlatform::bindResource(collectionHandle, childHandle);
+ }
+ else
+ {
+ cout << "\tresource Error!" << endl;
+ }
+
+ return result;
+ }
+
+
+
/*
Presence Check
*/
// Callback to presence
void GroupManager::collectionPresenceHandler(OCStackResult result, const unsigned int nonce,
- const std::string& hostAddress, std::string host, std::string uri)
+ const std::string& /*hostAddress*/, std::string host, std::string uri)
{
std::cout << "uri : " << uri << std::endl;
std::cout << "host : " << host << std::endl;
{
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();
+ if(children.size() == 0 )
+ {
+ callback("", OC_STACK_ERROR);
+ return;
+ }
for (auto oit = children.begin(); oit != children.end(); ++oit)
{
- std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+ if(oit->getUri().find("coap://") == std::string::npos)
+ {
+ std::cout << "The resource with a URI " << oit->getUri() << " is not a remote resource."
+ << " Thus, we ignore to send a request for presence check to the resource.\n";
+
+ continue;
+ }
+
std::vector< std::string > hostAddressVector = str_split(oit->getUri(), '/');
std::string hostAddress = "";
for (unsigned int i = 0; i < hostAddressVector.size(); ++i)
}
std::vector< std::string > resourceTypes = oit->getResourceTypes();
- for (unsigned int i = 0; i < resourceTypes.size(); ++i)
+ // 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\tresource type front : " << resourceTypes.front() << endl;
+ // std::cout << "\t\thost : " << hostAddress << std::endl;
+ OCPlatform::OCPresenceHandle presenceHandle;
+ OCStackResult result = OC_STACK_ERROR;
+
+ try
+ {
+ result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
+ // resourceType,
+ resourceTypes.front(),
+ CT_DEFAULT,
+ 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())));
+ }catch(OCException& e)
{
- std::cout << "\t\t\tresourcetype :" << resourceTypes.at(i) << std::endl;
+ std::cout<< "Exception in subscribePresence: "<< e.what() << 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,
+void GroupManager::onGetForPresence(const HeaderOptions& /*headerOptions*/,
const OCRepresentation& rep, const int eCode, CollectionPresenceCallback callback)
{
if (eCode == OC_STACK_OK)
{
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)
{
+ if(callback == NULL || collectionResource == NULL)
+ {
+ return OC_STACK_ERROR;
+ }
+
OCStackResult result = OC_STACK_OK;
//callback("core.room",OC_STACK_OK);
{
std::string message = "";
+ if(newActionSet == NULL)
+ return message;
+
message = newActionSet->actionsetName;
message.append("*");
+ message.append(newActionSet->toString());
+ message.append("*");
for (auto iterAction = newActionSet->listOfAction.begin();
iterAction != newActionSet->listOfAction.end(); iterAction++)
{
return message;
}
-ActionSet* GroupManager::getActionSetfromString(std::string desc)
-{
+#define DELETE(p) { \
+ delete p; \
+ p = NULL; \
+}
+
+#define DELETEARRAY(p) { \
+ delete[] p; \
+ p = NULL; \
+}
+ActionSet* GroupManager::getActionSetfromString(std::string description)
+{
char *token = NULL;
char *plainText = NULL;
char *plainPtr = NULL;
+ char *attr = NULL, *desc = NULL;
+ Action *action = NULL;
+ Capability *capa = NULL;
ActionSet *actionset = new ActionSet();
- plainText = new char[(desc.length() + 1)];
- strcpy(plainText, desc.c_str());
+ if(actionset == NULL)
+ {
+ goto exit;
+ }
+
+ if(description.empty())
+ {
+ goto exit;
+ }
+ else if(description.at(0) == '*')
+ {
+ goto exit;
+ }
+
+ plainText = new char[(description.length() + 1)];
+ strncpy(plainText, description.c_str(), description.length()+1);
+
+ // All tokens are seperated by "*" character.
+ // First token means an actionset name
token = strtok_r(plainText, ACTION_DELIMITER, &plainPtr);
if (token != NULL)
{
actionset->actionsetName = std::string(token);
+
+ if((actionset->actionsetName).empty())
+ goto exit;
+
+ // Find the second token
+ token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr);
+ }
+ else
+ {
+ goto exit;
+ }
+
+ if (token != NULL)
+ {
+ // The second token consists of two digits: time delay and actionset Type.
+ // Time delay is used as a parameter to scheduled/recursive group action feature
+ // And actionset type indicates if the actionset is scheduled or recursive group action.
+ char *subText = NULL;
+ char *subToken = NULL;
+ char *subTextPtr = NULL;
+
+ subText = new char[strlen(token)+1];
+ strncpy(subText, token, strlen(token)+1);
+
+ subToken = strtok_r(subText, " ", &subTextPtr);
+ if(subToken == NULL)
+ {
+ DELETEARRAY(subText);
+ goto exit;
+ }
+ actionset->mDelay = atol(subToken);
+
+ subToken = strtok_r(NULL, " ", &subTextPtr);
+ if(subToken == NULL)
+ {
+ DELETEARRAY(subText);
+ goto exit;
+ }
+ actionset->type = (OIC::ACTIONSET_TYPE)atoi(subToken);
+
+ DELETEARRAY(subText);
+
+ // Find the third token
token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr);
}
else
{
- delete actionset;
- delete[] plainText;
- return NULL;
+ goto exit;
}
while (token)
{
+ // The third token consists of two sub-segement: host address plus URI and attribute key/value pair.
+ // These two segments can be divided by "|" character.
+ // The third token can be repeatively appeared.
+
char *descPtr = NULL;
- char *desc = new char[(strlen(token) + 1)];
+ desc = new char[(strlen(token) + 1)];
if (desc != NULL)
{
- Action *action = NULL;
- strcpy(desc, token);
+ // copy a host address plus URI string from the third token
+ strncpy(desc, token, (strlen(token) + 1));
+
+ // Find "|" character to find key/value pair
token = strtok_r(desc, DESC_DELIMITER, &descPtr);
- // cout << "desc :: " << token << endl;
while (token != NULL)
{
char *attrPtr = NULL;
- char *attr = new char[(strlen(token) + 1)];
-
+ attr = new char[(strlen(token) + 1)];
+ // copy the host address plus URI string
strcpy(attr, token);
- // cout << "attr :: " << attr << endl;
-
+ // Find "=" charactor to divide attribute key and value string.
token = strtok_r(attr, ATTR_DELIMITER, &attrPtr);
while (token != NULL)
{
- if (strcmp(token, "uri") == 0)
+ if ( (action == NULL) && strcmp(token, "uri") == 0)
{
token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
- action = new Action();
+ if(token == NULL)
+ {
+ goto exit;
+ }
+ action = new Action();
if (action != NULL)
{
action->target = std::string(token);
}
else
{
- delete actionset;
- delete[] attr;
- delete desc;
- delete[] plainText;
- return NULL;
+ goto exit;
}
}
else
{
- Capability *capa = new Capability();
+ capa = new Capability();
capa->capability = std::string(token);
token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
+
+ if( token == NULL )
+ goto exit;
+
capa->status = std::string(token);
if (action != NULL)
- {
action->listOfCapability.push_back(capa);
- }
else
- {
- delete capa;
- delete actionset;
- delete[] attr;
- delete[] plainText;
- delete desc;
- return NULL;
- }
+ goto exit;
}
token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
}
-
- delete[] attr;
+ DELETEARRAY(attr);
token = strtok_r(NULL, DESC_DELIMITER, &descPtr);
}
- actionset->listOfAction.push_back(action);
+ if( action != NULL )
+ {
+ actionset->listOfAction.push_back(action);
+ action = NULL;
+ }
+ else
+ goto exit;
//delete action;
}
else
{
- delete actionset;
- delete[] plainText;
- return NULL;
+ goto exit;
}
- delete[] desc;
+ DELETEARRAY(desc);
token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr);
}
- delete plainText;
+ DELETEARRAY(plainText);
return actionset;
+
+exit:
+ DELETE(action);
+ DELETE(capa)
+ DELETE(actionset)
+ DELETEARRAY(attr);
+ DELETEARRAY(plainText);
+ DELETEARRAY(desc);
+ return NULL;
}
OCStackResult GroupManager::addActionSet(std::shared_ptr< OCResource > resource,
// BUILD message of ActionSet which it is included delimiter.
if ((resource != NULL) && (newActionSet != NULL))
{
+ if(newActionSet->mDelay < 0)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
std::string message = getStringFromActionSet(newActionSet);
- OCRepresentation rep;
+ 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, long int delay, PostCallback cb)
+{
+ if(delay <= 0 )
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ if (resource != NULL)
+ {
+ std::string value = actionsetName;
+ value.append("*");
+ value.append(std::to_string(delay));
+
+ OCRepresentation rep;
+ rep.setValue("DoScheduledAction", value);
+ return resource->post(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
+ QueryParamsMap(), cb);
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
+}
+
+OCStackResult GroupManager::cancelActionSet(std::shared_ptr< OCResource > resource,
+ std::string actionsetName, PostCallback cb)
+{
+ if (resource != NULL)
+ {
+ OCRepresentation rep;
+
+ rep.setValue("CancelAction", actionsetName);
+ return resource->post(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
+ QueryParamsMap(), cb);
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
+}
+
OCStackResult GroupManager::getActionSet(std::shared_ptr< OCResource > resource,
std::string actionsetName, PostCallback cb)
{
return OC_STACK_ERROR;
}
}
-}