//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#define _POSIX_C_SOURCE 200112L
+
+#include "iotivity_config.h"
+
#include <string.h>
-#include "cJSON.h"
-#include "ocmalloc.h"
#include "oicgroup.h"
-#include "ocresource.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
+#include "cJSON.h"
+#endif
+#include "cbor.h"
+#include "ocpayload.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
#include "occollection.h"
+#include "logger.h"
+#include "timer.h"
+
+#define TAG "OIC_RI_GROUP"
+
+#define DESC_DELIMITER "\""
+#define ACTION_DELIMITER "*"
+#define ATTR_DELIMITER "|"
+#define ATTR_ASSIGN "="
+
+// Definitions for operations related to actions
+#define DO_ACTION "DoAction"
+#define GET_ACTIONSET "GetActionSet"
+#define ACTIONSET "ActionSet"
+#define CANCEL_ACTIONSET "CancelAction"
+#define DELETE_ACTIONSET "DelActionSet"
+
+#define DEFAULT_CONTEXT_VALUE 0x99
+
+#define VARIFY_POINTER_NULL(pointer, result, toExit) \
+ if(pointer == NULL) \
+ {\
+ result = OC_STACK_NO_MEMORY;\
+ goto toExit;\
+ }
+#define VARIFY_PARAM_NULL(pointer, result, toExit) \
+ if(pointer == NULL)\
+ {\
+ result = OC_STACK_INVALID_PARAM;\
+ goto exit;\
+ }
+
+#define OCFREE(pointer) \
+ { \
+ OICFree(pointer); \
+ pointer = NULL; \
+ }
+
+// Mutex implementation macros
+#if defined(HAVE_PTHREAD_H)
+
+ #include <pthread.h>
+ pthread_mutex_t g_scheduledResourceLock;
+ #define MUTEX_LOCK(ARG_NAME) { pthread_mutex_lock(ARG_NAME); }
+ #define MUTEX_UNLOCK(ARG_NAME) { pthread_mutex_unlock(ARG_NAME); }
+ #define MUTEX_INITIALIZE(ARG_NAME) { }
+ #define MUTEX_TERMINATE(ARG_NAME) { }
+
+#elif defined(HAVE_WINDOWS_H)
+
+ #include <windows.h>
+ CRITICAL_SECTION g_scheduledResourceLock;
+ bool g_initializedScheduledResourceLock = false;
+ #define MUTEX_LOCK(ARG_NAME) { EnterCriticalSection(ARG_NAME); }
+ #define MUTEX_UNLOCK(ARG_NAME) { LeaveCriticalSection(ARG_NAME); }
+ #define MUTEX_INITIALIZE(ARG_NAME) { assert(!g_initializedScheduledResourceLock); \
+ InitializeCriticalSection(ARG_NAME); \
+ g_initializedScheduledResourceLock = true; \
+ }
+ #define MUTEX_TERMINATE(ARG_NAME) { if (g_initializedScheduledResourceLock) \
+ { \
+ DeleteCriticalSection(ARG_NAME); \
+ g_initializedScheduledResourceLock = false; \
+ } \
+ }
+
+#elif defined(WITH_ARDUINO)
+
+ #define MUTEX_LOCK(ARG_NAME) { }
+ #define MUTEX_UNLOCK(ARG_NAME) { }
+ #define MUTEX_INITIALIZE(ARG_NAME) { }
+ #define MUTEX_TERMINATE(ARG_NAME) { }
+
+#else
+
+ ERROR Need mutex implementation on this platform
+
+#endif
+
+enum ACTION_TYPE
+{
+ NONE = 0, SCHEDULED, RECURSIVE
+};
+
+typedef struct scheduledresourceinfo
+{
+ OCResource *resource;
+ OCActionSet *actionset;
+
+ int timer_id;
+
+ OCServerRequest *ehRequest;
+
+ time_t time;
+ struct scheduledresourceinfo* next;
+} ScheduledResourceInfo;
+
+ScheduledResourceInfo *g_scheduleResourceList = NULL;
+
+void AddScheduledResource(ScheduledResourceInfo **head,
+ ScheduledResourceInfo* add)
+{
+ OIC_LOG(INFO, TAG, "AddScheduledResource Entering...");
+
+ MUTEX_LOCK(&g_scheduledResourceLock);
+ ScheduledResourceInfo *tmp = NULL;
-#define TAG PCF("OICGROUP")
+ if (*head != NULL)
+ {
+ tmp = *head;
+
+ while (tmp->next)
+ {
+ tmp = tmp->next;
+ }
+ tmp->next = add;
+ }
+ else
+ {
+ *head = add;
+ }
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+}
+
+ScheduledResourceInfo* GetScheduledResource(ScheduledResourceInfo *head)
+{
+ OIC_LOG(INFO, TAG, "GetScheduledResource Entering...");
+
+ MUTEX_LOCK(&g_scheduledResourceLock);
+
+ time_t t_now;
+
+ ScheduledResourceInfo *tmp = NULL;
+ tmp = head;
-#define DESC_DELIMITER "\""
-#define ACTION_DELIMITER "*"
-#define ATTR_DELIMITER "|"
+#if !defined(WITH_ARDUINO)
+ time(&t_now);
+#else
+ t_now = now();
+#endif
+
+ if (tmp)
+ {
+ while (tmp)
+ {
+ time_t diffTm = 0;
+ diffTm = timespec_diff(tmp->time, t_now);
+
+ if (diffTm <= (time_t) 0)
+ {
+ OIC_LOG(INFO, TAG, "return Call INFO.");
+ goto exit;
+ }
+
+ tmp = tmp->next;
+ }
+ }
+
+ exit:
+
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+
+ if (tmp == NULL)
+ {
+ OIC_LOG(INFO, TAG, "Cannot Find Call Info.");
+ }
+ return tmp;
+}
+
+ScheduledResourceInfo* GetScheduledResourceByActionSetName(ScheduledResourceInfo *head, char *setName)
+{
+ OIC_LOG(INFO, TAG, "GetScheduledResourceByActionSetName Entering...");
+
+ MUTEX_LOCK(&g_scheduledResourceLock);
+
+ ScheduledResourceInfo *tmp = NULL;
+ tmp = head;
+
+ if (tmp)
+ {
+ while (tmp)
+ {
+ if (strcmp(tmp->actionset->actionsetName, setName) == 0)
+ {
+ OIC_LOG(INFO, TAG, "return Call INFO.");
+ goto exit;
+ }
+ tmp = tmp->next;
+ }
+ }
+
+exit:
+
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+
+ if (tmp == NULL)
+ {
+ OIC_LOG(INFO, TAG, "Cannot Find Call Info.");
+ }
+ return tmp;
+}
+
+void RemoveScheduledResource(ScheduledResourceInfo **head,
+ ScheduledResourceInfo* del)
+{
+
+ MUTEX_LOCK(&g_scheduledResourceLock);
+
+ OIC_LOG(INFO, TAG, "RemoveScheduledResource Entering...");
+ ScheduledResourceInfo *tmp = NULL;
+
+ if (del == NULL)
+ {
+
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+
+ return;
+ }
+
+ if (*head == del)
+ {
+ *head = (*head)->next;
+ }
+ else
+ {
+ tmp = *head;
+ while (tmp->next && (tmp->next != del))
+ {
+ tmp = tmp->next;
+ }
+ if (tmp->next)
+ {
+ tmp->next = del->next;
+ }
+ }
+
+ OCFREE(del)
+
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+}
+
+typedef struct aggregatehandleinfo
+{
+ OCServerRequest *ehRequest;
+ OCDoHandle required;
+ OCResource *collResource;
+
+ struct aggregatehandleinfo *next;
+} ClientRequestInfo;
+
+ClientRequestInfo *clientRequstList = NULL;
+
+void AddClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* add)
+{
+ ClientRequestInfo *tmp = NULL;
+
+ if (*head != NULL)
+ {
+ tmp = *head;
+
+ while (tmp->next)
+ {
+ tmp = tmp->next;
+ }
+ tmp->next = add;
+ }
+ else
+ {
+ *head = add;
+ }
+}
+
+ClientRequestInfo* GetClientRequestInfo(ClientRequestInfo *head,
+ OCDoHandle handle)
+{
+ ClientRequestInfo *tmp = NULL;
+
+ tmp = head;
+
+ if (tmp)
+ {
+ while (tmp)
+ {
+ if (tmp->required == handle)
+ {
+ break;
+ }
+
+ tmp = tmp->next;
+ }
+
+ return tmp;
+ }
+ return NULL;
+}
+
+void RemoveClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* del)
+{
+ ClientRequestInfo *tmp = NULL;
+
+ if (del == NULL)
+ return;
+
+ if (*head == del)
+ {
+ *head = (*head)->next;
+ }
+ else
+ {
+ tmp = *head;
+ while (tmp->next && (tmp->next != del))
+ {
+ tmp = tmp->next;
+ }
+ if (tmp->next)
+ {
+ tmp->next = del->next;
+ }
+ }
+}
void AddCapability(OCCapability** head, OCCapability* node)
{
}
}
-void AddActionSet(OCActionSet **head, OCActionSet* node)
+OCStackResult AddActionSet(OCActionSet **head, OCActionSet* node)
{
OCActionSet *pointer = *head;
+ OCActionSet *prev = NULL;
+ if(node == NULL)
+ {
+ return OC_STACK_ERROR;
+ }
if (NULL == pointer)
{
*head = node;
}
else
{
-
- while (pointer->next != NULL)
+ prev = pointer;
+ while (pointer != NULL)
{
+ // check the uniqeness of actionsetname.
+ if (strcmp(pointer->actionsetName, node->actionsetName) == 0)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ prev = pointer;
pointer = pointer->next;
}
- pointer->next = node;
+ prev->next = node;
}
+
+ return OC_STACK_OK;
}
void DeleteCapability(OCCapability *del)
{
- free(del->capability);
+ OCFREE(del->capability)
del->capability = NULL;
- free(del->status);
+ OCFREE(del->status)
del->status = NULL;
+ OCFREE(del)
}
void DeleteAction(OCAction** action)
pointer = pointer->next;
DeleteCapability(pDel);
- pDel->next = NULL;
}
- OCFree((*action)->resourceUri);
- (*action)->resourceUri = NULL;
+ OCFREE((*action)->resourceUri)
(*action)->next = NULL;
+ OCFREE(*action)
}
void DeleteActionSet(OCActionSet** actionset)
{
- OCAction* pointer = (*actionset)->head;
+ OCAction* pointer = NULL;
OCAction* pDel = NULL;
+ if(*actionset == NULL)
+ return;
+
+ pointer = (*actionset)->head;
+
while (pointer)
{
pDel = pointer;
pointer = pointer->next;
DeleteAction(&pDel);
- pDel->next = NULL;
}
-
- OCFree((*actionset)->actionsetName);
- (*actionset)->head = NULL;
+ // (*actionset)->head = NULL;
+ OCFREE((*actionset)->actionsetName)
+ OCFREE(*actionset)
}
-OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actionsetName)
+OCStackResult FindAndDeleteActionSet(OCResource **resource,
+ const char * actionsetName)
{
-
if (*resource != NULL)
{
-
OCActionSet *pointer = NULL;
OCActionSet *pDel = NULL;
(*resource)->actionsetHead = NULL;
DeleteActionSet(&pointer);
-
}
else if (pointer->next != NULL)
{
{
if (pointer->next != NULL)
{
- if (strcmp(pointer->next->actionsetName, actionsetName) == 0)
+ if (strcmp(pointer->next->actionsetName, actionsetName)
+ == 0)
{
pDel = pointer->next;
pointer->next = pointer->next->next;
DeleteActionSet(&pDel);
}
}
+ pointer = pointer->next;
}
}
}
}
-
return OC_STACK_ERROR;
}
-OCStackResult DeleteActionSets(OCResource** resource)
-{
- OCActionSet *pointer = (*resource)->actionsetHead;
- OCActionSet *pDel = pointer;
-
- while (pointer)
- {
- pDel = pointer;
- pointer = pointer->next;
-
- DeleteActionSet(&pDel);
- pDel->next = NULL;
- }
-
- (*resource)->actionsetHead = NULL;
- return OC_STACK_OK;
-}
-
-OCStackResult GetActionSet(const char *actionName, OCActionSet *head, OCActionSet** actionset)
+OCStackResult GetActionSet(const char *actionName, OCActionSet *head,
+ OCActionSet** actionset)
{
OCActionSet *pointer = head;
while (pointer)
{
- //printf("%s :: %s\n", pointer->actionsetName, actionsetName);
if (strcmp(pointer->actionsetName, actionName) == 0)
{
*actionset = pointer;
}
-OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method,
- char **actionsetName)
+OCStackResult ExtractKeyValueFromRequest(OCEntityHandlerRequest *ehRequest,
+ char **key, char **value)
{
- char *acitonRequest;
- char *iterTokenPtr = NULL;
- char *iterToken = NULL;
- char *description = NULL;
- char *iterDescPtr = NULL;
+ OCStackResult result = OC_STACK_OK;
- char *attributes = NULL;
- char *iterAttrbutesPtr = NULL;
+ char *actionSetStr = NULL;
- char *attr = NULL;
- char *iterAttrPtr = NULL;
+ if( NULL == ehRequest->payload )
+ {
+ result = OC_STACK_ERROR;
+ goto exit;
+ }
- OCActionSet* actionset = NULL;
- OCAction* action = NULL;
+ OCRepPayload* input;
- acitonRequest = (char *) OCMalloc(strlen((char *) request) + 1);
- strncpy(acitonRequest, (char *) request, strlen((char *) request) + 1);
+ input = (OCRepPayload*)(ehRequest->payload);
- //printf("\t%s\n", acitonRequest);
- if (acitonRequest != NULL)
+ if(OCRepPayloadGetPropString(input, ACTIONSET, &actionSetStr))
{
- iterToken = (char *) strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr);
+ *key = OICStrdup(ACTIONSET);
+ VARIFY_POINTER_NULL(*key, result, exit);
- while (iterToken != NULL)
- {
- if (strcmp(iterToken, "ActionSet") == 0)
- { // if iterToken is ActionSet, will be created and added a new action set.
-
- *method = (char *) OCMalloc(strlen(iterToken) + 1);
- strncpy(*method, iterToken, strlen(iterToken) + 1);
+ *value = OICStrdup(actionSetStr);
+ VARIFY_POINTER_NULL(*value, result, exit);
+ }
+ else if(OCRepPayloadGetPropString(input, DO_ACTION, &actionSetStr))
+ {
+ *key = OICStrdup(DO_ACTION);
+ VARIFY_POINTER_NULL(*key, result, exit);
- //GetActionName(iterToken, &actionsetName);
- // printf("%s\n", iterToken, &iterTokenPtr);
- iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is mean ':'.
- // printf("%s\n", iterToken);
- iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is body of action description.
- // printf("%s\n", iterToken);
+ *value = OICStrdup(actionSetStr);
+ VARIFY_POINTER_NULL(*value, result, exit);
+ }
+ else if(OCRepPayloadGetPropString(input, GET_ACTIONSET, &actionSetStr))
+ {
+ *key = OICStrdup(GET_ACTIONSET);
+ VARIFY_POINTER_NULL(*key, result, exit);
- printf("DESC :: %s\n", iterToken);
- description = (char *) OCMalloc(strlen(iterToken) + 1);
- strncpy(description, iterToken, strlen(iterToken) + 1);
- printf("DESC Copied :: %s\n", description);
+ *value = OICStrdup(actionSetStr);
+ VARIFY_POINTER_NULL(*value, result, exit);
+ }
+ else if(OCRepPayloadGetPropString(input, DELETE_ACTIONSET, &actionSetStr))
+ {
+ *key = OICStrdup(DELETE_ACTIONSET);
+ VARIFY_POINTER_NULL(*key, result, exit);
- // Find the action name from description.
- iterDescPtr = NULL;
- iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
- //while(iterToken != NULL)
- if (iterToken != NULL)
- {
- if (*actionsetName != NULL)
- {
- printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
- return OC_STACK_ERROR; // ERROR OCCURED.
- }
- else
- {
- // Actionset name.
- printf("ACTION SET NAME :: %s\n", iterToken);
- *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
+ *value = OICStrdup(actionSetStr);
+ VARIFY_POINTER_NULL(*value, result, exit);
+ }
+ else if(OCRepPayloadGetPropString(input, CANCEL_ACTIONSET, &actionSetStr))
+ {
+ *key = OICStrdup(CANCEL_ACTIONSET);
+ VARIFY_POINTER_NULL(*key, result, exit);
- strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
- printf("ACTION SET NAME :: %s\n", *actionsetName);
- // break;
- }
+ *value = OICStrdup(actionSetStr);
+ VARIFY_POINTER_NULL(*value, result, exit);
+ }
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
- iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
- }
- else
- {
- return OC_STACK_ERROR;
+exit:
+ if (result != OC_STACK_OK)
+ {
+ OCFREE(*key)
+ OCFREE(*value)
+ }
- } // end Action Set Name.
+ OCFREE(actionSetStr);
- // New ActionSet Add to OCResource's ActionSet list.
- // 1. Allocate a new pointer for actionset.
- actionset = (OCActionSet*) OCMalloc(sizeof(OCActionSet));
- // 2. Initiate actionset.
- memset(actionset, 0, sizeof(OCActionSet));
- actionset->actionsetName = (char *) OCMalloc(strlen(*actionsetName) + 1);
- strncpy(actionset->actionsetName, *actionsetName, strlen(*actionsetName) + 1);
- printf("ACTION SET NAME :: %s\n", actionset->actionsetName);
+ return result;
+}
- while (iterToken != NULL)
- {
- action = (OCAction *) OCMalloc(sizeof(OCAction));
- memset(action, 0, sizeof(OCAction));
+OCStackResult ExtractActionSetNameAndDelaytime(char *pChar, char **setName,
+ long int *pa)
+{
+ char *token = NULL, *tokenPtr = NULL;
+ OCStackResult result = OC_STACK_OK;
- printf("ATTR Copied :: %s\n", iterToken);
- attributes = (char *) OCMalloc(strlen(iterToken) + 1);
- strncpy(attributes, iterToken, strlen(iterToken) + 1);
- printf("ATTR Copied :: %s\n", attributes);
+ token = (char*) strtok_r(pChar, ACTION_DELIMITER, &tokenPtr);
+ VARIFY_POINTER_NULL(token, result, exit)
- iterToken = (char *) strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr);
- while (iterToken != NULL)
- {
- attr = (char *) OCMalloc(strlen(iterToken) + 1);
- strncpy(attr, iterToken, strlen(iterToken) + 1);
+ *setName = (char *) OICMalloc(strlen(token) + 1);
+ VARIFY_POINTER_NULL(*setName, result, exit)
+ VARIFY_PARAM_NULL(token, result, exit)
+ strncpy(*setName, token, strlen(token) + 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->resourceUri = (char *) OCMalloc(strlen(iterToken) + 1);
- strncpy(action->resourceUri, iterToken, strlen(iterToken) + 1);
- }
- else
- {
- OCCapability* capa = (OCCapability*) OCMalloc(sizeof(OCCapability));
- memset(capa, 0, sizeof(OCCapability));
- printf("%s :: ", iterToken);
- capa->capability = (char *) OCMalloc(strlen(iterToken) + 1);
- strncpy(capa->capability, iterToken, strlen(iterToken) + 1);
- iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
- printf("%s\n", iterToken);
- capa->status = (char *) OCMalloc(strlen(iterToken) + 1);
- strncpy(capa->status, iterToken, strlen(iterToken) + 1);
-
- AddCapability(&action->head, capa);
- }
+ token = strtok_r(NULL, ACTION_DELIMITER, &tokenPtr);
+ VARIFY_POINTER_NULL(pa, result, exit)
+ VARIFY_PARAM_NULL(token, result, exit)
+ *pa = atoi(token);
- iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
- }
+ return OC_STACK_OK;
- iterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr);
- } // End of Action
+exit:
+ OCFREE(*setName);
+ return result;
+}
- AddAction(&actionset->head, action);
+OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc)
+{
+ OCStackResult result = OC_STACK_OK;
+
+ char *iterToken = NULL, *iterTokenPtr = NULL;
+ char *descIterToken = NULL, *descIterTokenPtr = NULL;
+ char *attrIterToken = NULL, *attrIterTokenPtr = NULL;
+ char *desc = NULL, *attr = NULL;
+ char *key = NULL, *value = NULL;
+
+ OCAction *action = NULL;
+ OCCapability *capa = NULL;
+
+ OIC_LOG(INFO, TAG, "Build ActionSet Instance.");
+
+ *set = (OCActionSet*) OICMalloc(sizeof(OCActionSet));
+ VARIFY_POINTER_NULL(*set, result, exit)
+
+ iterToken = (char *) strtok_r(actiondesc, ACTION_DELIMITER, &iterTokenPtr);
+ VARIFY_POINTER_NULL(iterToken, result, exit);
+
+ // ActionSet Name
+ memset(*set, 0, sizeof(OCActionSet));
+ (*set)->actionsetName = (char *) OICMalloc(strlen(iterToken) + 1);
+ VARIFY_POINTER_NULL((*set)->actionsetName, result, exit)
+ VARIFY_PARAM_NULL(iterToken, result, exit)
+ strncpy((*set)->actionsetName, iterToken, strlen(iterToken) + 1);
+
+ // Time info. for Scheduled/Recursive Group action.
+ // d is meant Day of the week.
+ // T is meant ActionType.
+ // yyyy-mm-dd hh:mm:ss d
+ iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
+ VARIFY_PARAM_NULL(iterToken, result, exit)
+#if !defined(WITH_ARDUINO)
+ if( 2 != sscanf(iterToken, "%ld %u", &(*set)->timesteps, &(*set)->type) )
+ {
+ // If the return value should be 2, the number of items in the argument. Otherwise, it fails.
+ goto exit;
+ }
+#endif
- iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
- }
+ OIC_LOG_V(INFO, TAG, "ActionSet Name : %s", (*set)->actionsetName);
- // 3. Add the pointer OCResource's ActionSet list.
- AddActionSet(&(*resource)->actionsetHead, actionset);
- return OC_STACK_OK;
+ iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
+ while (iterToken)
+ {
+ desc = (char *) OICMalloc(strlen(iterToken) + 1);
+ VARIFY_POINTER_NULL(desc, result, exit)
+ VARIFY_PARAM_NULL(desc, result, exit)
+ strncpy(desc, iterToken, strlen(iterToken) + 1);
+ descIterToken = (char *) strtok_r(desc, ATTR_DELIMITER,
+ &descIterTokenPtr);
+ while (descIterToken)
+ {
+ attr = (char *) OICMalloc(strlen(descIterToken) + 1);
+ VARIFY_POINTER_NULL(attr, result, exit)
+ VARIFY_PARAM_NULL(descIterToken, result, exit)
+ strncpy(attr, descIterToken, strlen(descIterToken) + 1);
+
+ attrIterToken = (char *) strtok_r(attr, ATTR_ASSIGN,
+ &attrIterTokenPtr);
+ VARIFY_POINTER_NULL(attrIterToken, result, exit);
+
+ key = (char *) OICMalloc(strlen(attrIterToken) + 1);
+ VARIFY_POINTER_NULL(key, result, exit)
+ VARIFY_PARAM_NULL(attrIterToken, result, exit)
+ strncpy(key, attrIterToken, strlen(attrIterToken) + 1);
+
+ attrIterToken = (char *) strtok_r(NULL, ATTR_ASSIGN,
+ &attrIterTokenPtr);
+ VARIFY_POINTER_NULL(attrIterToken, result, exit);
+ value = (char *) OICMalloc(strlen(attrIterToken) + 1);
+ VARIFY_POINTER_NULL(value, result, exit)
+ VARIFY_PARAM_NULL(attrIterToken, result, exit)
+ strncpy(value, attrIterToken, strlen(attrIterToken) + 1);
+
+ if (strcmp(key, "uri") == 0)
+ {
+ OIC_LOG(INFO, TAG, "Build OCAction Instance.");
+
+ action = (OCAction*) OICMalloc(sizeof(OCAction));
+ VARIFY_POINTER_NULL(action, result, exit)
+ memset(action, 0, sizeof(OCAction));
+ action->resourceUri = (char *) OICMalloc(strlen(value) + 1);
+ VARIFY_POINTER_NULL(action->resourceUri, result, exit)
+ VARIFY_PARAM_NULL(value, result, exit)
+ strncpy(action->resourceUri, value, strlen(value) + 1);
}
- else if (strcmp(iterToken, "DoAction") == 0 || strcmp(iterToken, "DelActionSet") == 0
- || strcmp(iterToken, "GetActionSet") == 0)
+ else
{
- *method = (char *) OCMalloc(strlen(iterToken) + 1);
- strncpy(*method, iterToken, strlen(iterToken) + 1);
+ if ((key != NULL) && (value != NULL))
+ {
+ OIC_LOG(INFO, TAG, "Build OCCapability Instance.");
- iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is mean ':'.
- // printf("%s\n", iterToken);
- iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is body of action description.
- // printf("%s\n", iterToken);
+ capa = (OCCapability*) OICMalloc(sizeof(OCCapability));
+ VARIFY_POINTER_NULL(capa, result, exit)
+ memset(capa, 0, sizeof(OCCapability));
- description = (char *) OCMalloc(strlen(iterToken) + 1);
- strncpy(description, iterToken, strlen(iterToken) + 1);
+ capa->capability = (char *) OICMalloc(strlen(key) + 1);
+ VARIFY_POINTER_NULL(capa->capability, result, exit)
+ VARIFY_PARAM_NULL(key, result, exit)
+ strncpy(capa->capability, key, strlen(key) + 1);
- // Find the action name from description.
- iterDescPtr = NULL;
- iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
- if (iterToken != NULL)
- {
- if (*actionsetName != NULL)
- {
- printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
- return OC_STACK_ERROR; // ERROR OCCURED.
- }
- else
- {
- // Actionset name.
- printf("ACTION SET NAME :: %s\n", iterToken);
- *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
+ capa->status = (char *) OICMalloc(strlen(value) + 1);
+ VARIFY_POINTER_NULL(capa->status, result, exit)
+ VARIFY_PARAM_NULL(value, result, exit)
+ strncpy(capa->status, value, strlen(value) + 1);
- strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
- printf("ACTION SET NAME :: %s\n", *actionsetName);
- }
+ VARIFY_POINTER_NULL(action, result, exit)
- iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
- return OC_STACK_OK;
+ AddCapability(&action->head, capa);
}
- else
- {
- return OC_STACK_ERROR;
-
- } // end Action Set Name.
- break;
}
- iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
+ OCFREE(key)
+ OCFREE(value)
+ OCFREE(attr)
+
+ descIterToken = (char *) strtok_r(NULL, ATTR_DELIMITER,
+ &descIterTokenPtr);
}
+
+ AddAction(&(*set)->head, action);
+ iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
+ OCFREE(desc);
}
- return OC_STACK_ERROR;
+ return OC_STACK_OK;
+exit:
+ OCFREE(attr)
+ OCFREE(desc)
+ OCFREE(capa)
+ OCFREE(action)
+ OCFREE((*set)->actionsetName)
+ OCFREE(*set)
+ OCFREE(key)
+ OCFREE(value)
+ OCFREE(attr)
+
+ return result;
}
-OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc)
+OCStackResult BuildStringFromActionSet(OCActionSet* actionset, char** desc)
{
- char temp[1024] =
- { 0 };
- int remaining = 1023;
+ // Can't use the macros here as they are hardcoded to 'exit' and will
+ // result in dereferencing a null pointer.
+ if (!actionset || !desc)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ char temp[1024] = { 0 };
+ size_t remaining = sizeof(temp) - 1;
+ OCStackResult res = OC_STACK_ERROR;
+ char* actionTypeStr = NULL;
- // OCActionSet *as = resource->actionsetHead;
- // while(as != NULL)
- // {
- printf("\n\n\nAction Set Name :: %s\n", actionset->actionsetName);
OCAction *action = actionset->head;
if (remaining >= strlen(actionset->actionsetName) + 1)
{
- strcat(temp, actionset->actionsetName);
+ strncat(temp, actionset->actionsetName, strlen(actionset->actionsetName));
remaining -= strlen(actionset->actionsetName);
- strcat(temp, "*");
+ strncat(temp, ACTION_DELIMITER, strlen(ACTION_DELIMITER));
remaining--;
}
else
{
- return OC_STACK_ERROR;
+ res = OC_STACK_ERROR;
+ goto exit;
+ }
+
+ actionTypeStr = (char *)OICMalloc(1024);
+ if(actionTypeStr != NULL)
+ {
+ sprintf(actionTypeStr, "%ld %u", actionset->timesteps, actionset->type);
+ if(remaining >= strlen(actionTypeStr) + strlen(ACTION_DELIMITER) + 1)
+ {
+ strncat(temp, actionTypeStr, strlen(actionTypeStr));
+ remaining -= strlen(actionTypeStr);
+ strncat(temp, ACTION_DELIMITER, strlen(ACTION_DELIMITER));
+ remaining -= strlen(ACTION_DELIMITER);
+ OICFree(actionTypeStr);
+ }
+ else
+ {
+ OICFree(actionTypeStr);
+ res = OC_STACK_ERROR;
+ goto exit;
+ }
+ }
+ else
+ {
+ res = OC_STACK_ERROR;
+ goto exit;
}
while (action != NULL)
{
- printf("\tURI :: %s\n", action->resourceUri);
+ if (remaining < (strlen("uri=") + strlen(action->resourceUri) + 1))
+ {
+ res = OC_STACK_ERROR;
+ goto exit;
+ }
+
strcat(temp, "uri=");
remaining -= strlen("uri=");
strcat(temp, action->resourceUri);
OCCapability *capas = action->head;
while (capas != NULL)
{
- printf("\t\t%s = %s\n", capas->capability, capas->status);
+ if (remaining < (strlen(capas->capability)
+ + 1 + strlen(capas->status)))
+ {
+ res = OC_STACK_ERROR;
+ goto exit;
+ }
+
strcat(temp, capas->capability);
remaining -= strlen(capas->capability);
strcat(temp, "=");
remaining--;
strcat(temp, capas->status);
- remaining -= strlen(capas->capability);
+ remaining -= strlen(capas->status);
capas = capas->next;
if (capas != NULL)
{
+ if (remaining < 1)
+ {
+ res = OC_STACK_ERROR;
+ goto exit;
+ }
strcat(temp, "|");
+ remaining --;
}
}
action = action->next;
if (action != NULL)
{
- strcat(temp, "*");
+ if (remaining < strlen(ACTION_DELIMITER))
+ {
+ res = OC_STACK_ERROR;
+ goto exit;
+ }
+ strcat(temp, ACTION_DELIMITER);
remaining--;
}
}
- // as = as->next;
- // }
- *desc = (char *) OCMalloc(1024 - remaining);
- strcpy(*desc, temp);
- // printf("\t\tPlain Text = %s(%i)\n", *desc, 1024 - remaining);
+ *desc = OICStrdup(temp);
+ VARIFY_POINTER_NULL(*desc, res, exit);
return OC_STACK_OK;
+
+exit:
+ OCFREE(*desc);
+ return res;
}
OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
OCClientResponse* clientResponse)
{
+ (void)context;
+ (void)clientResponse;
+ OIC_LOG(INFO, TAG, "Entering ActionSetCB");
+
+ ClientRequestInfo *info = GetClientRequestInfo(clientRequstList, handle);
+
+ if (info)
+ {
+ OCEntityHandlerResponse response = { 0 };
- // printf("\n\n\tcallback is called\n\n");
- // printf("\t\tresponse JSON : %s\n", clientResponse->resJSONPayload);
+ response.ehResult = OC_EH_OK;
+
+ if(NULL == clientResponse->payload)
+ {
+ OIC_LOG(ERROR, TAG, "Error sending response");
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ // Format the response. Note this requires some info about the request
+ response.requestHandle = info->ehRequest->requestId;
+ response.resourceHandle = info->collResource;
+ response.payload = clientResponse->payload;
+ response.numSendVendorSpecificHeaderOptions = 0;
+ memset(response.sendVendorSpecificHeaderOptions, 0,
+ sizeof response.sendVendorSpecificHeaderOptions);
+ memset(response.resourceUri, 0, sizeof response.resourceUri);
+ // Indicate that response is NOT in a persistent buffer
+ response.persistentBufferFlag = 0;
+
+ // Send the response
+ if (OCDoResponse(&response) != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "Error sending response");
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ RemoveClientRequestInfo(&clientRequstList, info);
+ OCFREE(info)
+ }
return OC_STACK_KEEP_TRANSACTION;
}
void ActionSetCD(void *context)
{
- // printf("\n\t\tCD is called\n");
-
- // free( context );
+ (void)context;
}
-OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr, uint16_t *remaining)
+OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr,
+ uint16_t *remaining)
{
OCStackResult ret = OC_STACK_ERROR;
cJSON *json;
char *jsonStr;
uint16_t jsonLen;
- OC_LOG(INFO, TAG, PCF("Entering BuildActionJSON"));
+ OIC_LOG(INFO, TAG, "Entering BuildActionJSON");
json = cJSON_CreateObject();
cJSON_AddItemToObject(json, "rep", body = cJSON_CreateObject());
OCCapability* pointerCapa = action->head;
while (pointerCapa)
{
- cJSON_AddStringToObject(body, pointerCapa->capability, pointerCapa->status);
+ cJSON_AddStringToObject(body, pointerCapa->capability,
+ pointerCapa->status);
pointerCapa = pointerCapa->next;
}
jsonLen = strlen(jsonStr);
if (jsonLen < *remaining)
{
- strcat((char*) bufferPtr, jsonStr);
+ strncat((char*) bufferPtr, jsonStr, jsonLen);
*remaining -= jsonLen;
bufferPtr += jsonLen;
ret = OC_STACK_OK;
return ret;
}
-OCStackResult SendAction(const char *targetUri, const unsigned char *action)
+OCPayload* BuildActionCBOR(OCAction* action)
+{
+ OCRepPayload* payload = OCRepPayloadCreate();
+
+ if (!payload)
+ {
+ OIC_LOG(INFO, TAG, "Failed to create put payload object");
+ return NULL;
+ }
+
+ OCCapability* pointerCapa = action->head;
+ while (pointerCapa)
+ {
+ OCRepPayloadSetPropString(payload, pointerCapa->capability, pointerCapa->status);
+ pointerCapa = pointerCapa->next;
+ }
+
+ return (OCPayload*) payload;
+}
+
+unsigned int GetNumOfTargetResource(OCAction *actionset)
{
- OCCallbackData cbdata =
- { 0 };
- cbdata.cb = &ActionSetCB;
- cbdata.cd = &ActionSetCD;
- cbdata.context = (void *) 0x99;
+ int numOfResource = 0;
- OCDoHandle handle;
- return OCDoResource(&handle, OC_REST_PUT, targetUri,
- //temp->rsrcType->resourcetypename,
- NULL, (char *) action, OC_NA_QOS, &cbdata, NULL, 0);
+ OCAction *pointerAction = actionset;
+
+ while (pointerAction != NULL)
+ {
+ numOfResource++;
+ pointerAction = pointerAction->next;
+ }
+
+ return numOfResource;
}
-OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/,
- OCResource *resource, OCEntityHandlerRequest *ehRequest)
+OCStackResult SendAction(OCDoHandle *handle, OCServerRequest* requestHandle, const char *targetUri,
+ OCPayload *payload)
{
- OCStackResult stackRet = OC_STACK_ERROR;
- // OCEntityHandlerResult ehRet = OC_EH_ERROR;
- OC_LOG(INFO, TAG, PCF("Group Action is requested."));
- // if (stackRet == OC_STACK_OK)
+ OCCallbackData cbData;
+ cbData.cb = &ActionSetCB;
+ cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+
+ return OCDoResource(handle, OC_REST_PUT, targetUri, &requestHandle->devAddr,
+ payload, CT_ADAPTER_IP, OC_NA_QOS, &cbData, NULL, 0);
+}
+
+OCStackResult DoAction(OCResource* resource, OCActionSet* actionset,
+ OCServerRequest* requestHandle)
+{
+ OCStackResult result = OC_STACK_ERROR;
+
+ if( NULL == actionset->head)
{
+ return result;
+ }
+
+ OCAction *pointerAction = actionset->head;
- char *doWhat = NULL;
- char *actionName = NULL;
+ while (pointerAction != NULL)
+ {
+ OCPayload* payload;
+ payload = BuildActionCBOR(pointerAction);
- // uint16_t remaining = MAX_RESPONSE_LENGTH;
- size_t bufferLength = 0;
- unsigned char buffer[MAX_RESPONSE_LENGTH] =
- { 0 };
- unsigned char *bufferPtr = NULL;
+ if(payload == NULL)
+ {
+ return result;
+ }
- bufferPtr = buffer;
+ ClientRequestInfo *info = (ClientRequestInfo *) OICMalloc(
+ sizeof(ClientRequestInfo));
- OCResource * collResource = (OCResource *) ehRequest->resource;
- // OCResourceHandle origResourceHandle = ehRequest->resource;
+ if( info == NULL )
+ {
+ OCFREE(payload);
+ return OC_STACK_NO_MEMORY;
+ }
- char *jsonResponse;
+ memset(info, 0, sizeof(ClientRequestInfo));
- cJSON *json = cJSON_CreateObject();
- cJSON *format;
+ info->collResource = resource;
+ info->ehRequest = requestHandle;
- cJSON_AddStringToObject(json, "href", resource->uri);
- cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
+ result = SendAction(&info->required, info->ehRequest, pointerAction->resourceUri,
+ payload);
- if (method == OC_REST_GET)
+ if (result != OC_STACK_OK)
{
- OC_LOG(INFO, TAG, PCF("Group Action[GET]."));
+ OICFree(info);
+ return result;
}
- else if (method == OC_REST_PUT)
+
+ AddClientRequestInfo(&clientRequstList, info);
+
+ pointerAction = pointerAction->next;
+ }
+
+ return result;
+}
+
+void DoScheduledGroupAction()
+{
+ OIC_LOG(INFO, TAG, "DoScheduledGroupAction Entering...");
+ ScheduledResourceInfo* info = GetScheduledResource(g_scheduleResourceList);
+
+ if (info == NULL)
+ {
+ OIC_LOG(INFO, TAG, "Target resource is NULL");
+ goto exit;
+ }
+ else if (info->resource == NULL)
+ {
+ OIC_LOG(INFO, TAG, "Target resource is NULL");
+ goto exit;
+ }
+ else if (info->actionset == NULL)
+ {
+ OIC_LOG(INFO, TAG, "Target ActionSet is NULL");
+ goto exit;
+ }
+ else if (info->ehRequest == NULL)
+ {
+ OIC_LOG(INFO, TAG, "Target ActionSet is NULL");
+ goto exit;
+ }
+
+ MUTEX_LOCK(&g_scheduledResourceLock);
+
+ DoAction(info->resource, info->actionset, info->ehRequest);
+
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+
+
+ if (info->actionset->type == RECURSIVE)
+ {
+ ScheduledResourceInfo *schedule;
+ schedule = (ScheduledResourceInfo *) OICMalloc(
+ sizeof(ScheduledResourceInfo));
+
+ if (schedule)
{
- OC_LOG(INFO, TAG, PCF("Group Action[PUT]."));
+ OIC_LOG(INFO, TAG, "Building New Call Info.");
+ memset(schedule, 0, sizeof(ScheduledResourceInfo));
+
+ if (info->actionset->timesteps > 0)
+ {
+ MUTEX_LOCK(&g_scheduledResourceLock);
+ schedule->resource = info->resource;
+ schedule->actionset = info->actionset;
+ schedule->ehRequest = info->ehRequest;
+
+ schedule->time = registerTimer(info->actionset->timesteps,
+ &schedule->timer_id,
+ &DoScheduledGroupAction);
+
+ OIC_LOG(INFO, TAG, "Reregistration.");
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+ AddScheduledResource(&g_scheduleResourceList, schedule);
+ }
+ else
+ {
+ OICFree(schedule);
+ }
+ }
+ }
+
+ RemoveScheduledResource(&g_scheduleResourceList, info);
+
+ exit:
+
+ return;
+}
+
+OCStackResult BuildCollectionGroupActionCBORResponse(
+ OCMethod method/*OCEntityHandlerFlag flag*/, OCResource *resource,
+ OCEntityHandlerRequest *ehRequest)
+{
+ OCStackResult stackRet = OC_STACK_ERROR;
+
+ OIC_LOG(INFO, TAG, "Group Action is requested.");
+
+ char *doWhat = NULL;
+ char *details = NULL;
+
+ stackRet = ExtractKeyValueFromRequest(ehRequest, &doWhat, &details);
+
+ if(stackRet != OC_STACK_OK)
+ {
+ OIC_LOG_V(ERROR, TAG, "ExtractKeyValueFromRequest failed: %d", stackRet);
+ return stackRet;
+ }
+
+ stackRet = OC_STACK_ERROR;
- unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
+ if (method == OC_REST_PUT)
+ {
+ OIC_LOG(INFO, TAG, "Group Action[PUT].");
- GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
+ if (strcmp(doWhat, ACTIONSET) == 0)
+ {
+ OCActionSet *actionSet = NULL;
+ stackRet = BuildActionSetFromString(&actionSet, details);
- if (strcmp(doWhat, "DelActionSet") == 0)
+ if(stackRet == OC_STACK_OK)
{
- if (FindAndDeleteActionSet(&resource, actionName) == OC_STACK_OK)
+ if (actionSet != NULL)
{
+ stackRet = AddActionSet(&resource->actionsetHead,
+ actionSet);
+ if (stackRet == OC_STACK_ERROR)
+ {
+ if(actionSet != NULL)
+ {
+ DeleteActionSet( &actionSet );
+ }
+ OIC_LOG(INFO, TAG, "Duplicated ActionSet ");
+ }
}
else
{
+ stackRet = OC_STACK_ERROR;
+ goto exit;
}
}
else
{
+ stackRet = OC_STACK_ERROR;
}
- stackRet = OC_STACK_OK;
+ }
+ else if (strcmp(doWhat, DELETE_ACTIONSET) == 0)
+ {
+ if (FindAndDeleteActionSet(&resource, details) == OC_STACK_OK)
+ {
+ stackRet = OC_STACK_OK;
+ }
+ else
+ {
+ stackRet = OC_STACK_ERROR;
+ }
+ }
+
+ OCRepPayload* payload = OCRepPayloadCreate();
+ if(!payload)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
+ stackRet = OC_STACK_ERROR;
}
- else if (method == OC_REST_POST)
+ else
{
- OC_LOG(INFO, TAG, PCF("Group Action[POST]."));
+ OCEntityHandlerResponse response = { 0 };
- OCActionSet *actionset = NULL;
- unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
+ if(stackRet == OC_STACK_OK)
+ response.ehResult = OC_EH_OK;
+ else
+ response.ehResult = OC_EH_ERROR;
+
+ // Format the response. Note this requires some info about the request
+ response.requestHandle = ehRequest->requestHandle;
+ response.resourceHandle = ehRequest->resource;
+ response.payload = (OCPayload*) payload;
+ response.numSendVendorSpecificHeaderOptions = 0;
+ memset(response.sendVendorSpecificHeaderOptions, 0,
+ sizeof response.sendVendorSpecificHeaderOptions);
+ memset(response.resourceUri, 0, sizeof response. resourceUri);
+ // Indicate that response is NOT in a persistent buffer
+ response.persistentBufferFlag = 0;
+ response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR;
- GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
+ // Send the response
+ if (OCDoResponse(&response) != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "Error sending response");
+ stackRet = OC_STACK_ERROR;
+ }
+ }
+ OCRepPayloadDestroy(payload);
+ }
+ else if (method == OC_REST_POST)
+ {
+ OCActionSet *actionset = NULL;
- if (strcmp(doWhat, "DoAction") == 0)
+ OCRepPayload* payload = OCRepPayloadCreate();
+ OCRepPayloadSetUri(payload, resource->uri);
+
+ if ((strcmp(doWhat, DO_ACTION) == 0)
+ || (strcmp(doWhat, "DoScheduledAction") == 0))
+ {
+ char *pActionsetName = NULL;
+ long int delay = -1;
+
+ if (strcmp(doWhat, "DoScheduledAction") == 0)
+ {
+ stackRet = ExtractActionSetNameAndDelaytime(details,
+ &pActionsetName, &delay);
+
+ OCFREE(details)
+ details = pActionsetName;
+ }
+ else
{
- if (GetActionSet(actionName, resource->actionsetHead, &actionset) != OC_STACK_OK)
+ stackRet = OC_STACK_OK;
+ }
+
+ if (stackRet == OC_STACK_OK)
+ {
+ if (GetActionSet(details, resource->actionsetHead,
+ &actionset) != OC_STACK_OK)
{
- OC_LOG(INFO, TAG, PCF("ERROR"));
+ OIC_LOG(INFO, TAG, "ERROR");
stackRet = OC_STACK_ERROR;
}
if (actionset == NULL)
{
- OC_LOG(INFO, TAG, PCF("ERROR"));
+ OIC_LOG(INFO, TAG, "Cannot Find ActionSet");
stackRet = OC_STACK_ERROR;
- } else {
-
- // printf("Execute ActionSet :: %s\n", actionset->actionsetName);
-
- OCAction *pointerAction = actionset->head;
- while (pointerAction != NULL)
+ }
+ else
+ {
+ OIC_LOG(INFO, TAG, "Group Action[POST].");
+ OCServerRequest *request =
+ GetServerRequestUsingHandle(ehRequest->requestHandle);
+ if (NULL == request)
{
- // printf("Action Target :: %s\n", pointerAction->resourceUri);
+ stackRet = OC_STACK_ERROR;
+ goto exit;
+ }
- unsigned char actionDesc[MAX_RESPONSE_LENGTH] =
- { 0 };
- unsigned char* actionDescPtr = actionDesc;
- uint16_t remaining = MAX_RESPONSE_LENGTH;
+ if (actionset->type == NONE)
+ {
+ OIC_LOG_V(INFO, TAG, "Execute ActionSet : %s",
+ actionset->actionsetName);
+ unsigned int num = GetNumOfTargetResource(
+ actionset->head);
- strcpy((char *) actionDescPtr, (const char *) OC_JSON_PREFIX);
- BuildActionJSON(pointerAction, actionDescPtr, &remaining);
- strcat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX);
+ request->ehResponseHandler = HandleAggregateResponse;
+ request->numResponses = num + 1;
- SendAction(pointerAction->resourceUri, actionDescPtr);
+ DoAction(resource, actionset, request);
- pointerAction = pointerAction->next;
+ stackRet = OC_STACK_OK;
}
- stackRet = OC_STACK_OK;
- }
- }
- else if (strcmp(doWhat, "GetActionSet") == 0)
- {
- char *plainText = NULL;
- OCActionSet *actionset = NULL;
-
- // char *jsonResponse;
-
- GetActionSet(actionName, resource->actionsetHead, &actionset);
- if(actionset != NULL)
- {
- GetStringFromActionSet(actionset, &plainText);
-
- if (plainText != NULL)
+ else
{
- cJSON_AddStringToObject(format, "ActionSet", plainText);
+ OIC_LOG_V(INFO, TAG, "Execute Scheduled ActionSet : %s",
+ actionset->actionsetName);
- // jsonResponse = cJSON_Print(json);
- // cJSON_Delete(json);
+ delay =
+ (delay == -1 ? actionset->timesteps : delay);
- // strcat((char *)bufferPtr, jsonResponse);
- }
+ ScheduledResourceInfo *schedule;
+ schedule = (ScheduledResourceInfo *) OICMalloc(
+ sizeof(ScheduledResourceInfo));
- stackRet = OC_STACK_OK;
+ if (schedule)
+ {
+ OIC_LOG(INFO, TAG, "Building New Call Info.");
+ memset(schedule, 0,
+ sizeof(ScheduledResourceInfo));
+ MUTEX_LOCK(&g_scheduledResourceLock);
+ schedule->resource = resource;
+ schedule->actionset = actionset;
+ schedule->ehRequest = request;
+
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+ if (delay > 0)
+ {
+ OIC_LOG_V(INFO, TAG, "delay_time is %ld seconds.",
+ actionset->timesteps);
+ MUTEX_LOCK(&g_scheduledResourceLock);
+ schedule->time = registerTimer(delay,
+ &schedule->timer_id,
+ &DoScheduledGroupAction);
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+ AddScheduledResource(&g_scheduleResourceList,
+ schedule);
+ stackRet = OC_STACK_OK;
+ }
+ else
+ {
+ stackRet = OC_STACK_ERROR;
+ }
+ }
+ }
}
}
- else if (actionName == NULL)
+ }
+ else if (strcmp(doWhat, "CancelAction") == 0)
+ {
+ ScheduledResourceInfo *info =
+ GetScheduledResourceByActionSetName(g_scheduleResourceList, details);
+
+ if(info != NULL)
{
- // printf("Cannot find actionname\n");
- return OC_STACK_ERROR;
+ MUTEX_LOCK(&g_scheduledResourceLock);
+ unregisterTimer(info->timer_id);
+ MUTEX_UNLOCK(&g_scheduledResourceLock);
+
+ RemoveScheduledResource(&g_scheduleResourceList, info);
+ stackRet = OC_STACK_OK;
+ }
+ else
+ {
+ stackRet = OC_STACK_ERROR;
}
}
- jsonResponse = cJSON_Print(json);
- cJSON_Delete(json);
+ else if (strcmp(doWhat, GET_ACTIONSET) == 0)
+ {
+ char *plainText = NULL;
+ OCActionSet *actionset = NULL;
- strcat((char *) bufferPtr, jsonResponse);
+ GetActionSet(details, resource->actionsetHead, &actionset);
+ if (actionset != NULL)
+ {
+ BuildStringFromActionSet(actionset, &plainText);
+
+ if (plainText != NULL)
+ {
+ OCRepPayloadSetPropString(payload, ACTIONSET, plainText);
+ }
+ OICFree(plainText);
+ stackRet = OC_STACK_OK;
+ }
+ }
- // printf("\n\tRESONSE ::\n%s\n", buffer);
- bufferLength = strlen((const char *) buffer);
- if (bufferLength > 0)
+ if(!payload)
{
- OCEntityHandlerResponse response =
- { 0 };
- response.ehResult = OC_EH_OK;
- response.payload = buffer;
- response.payloadSize = bufferLength + 1;
- response.persistentBufferFlag = 0;
- response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
- response.resourceHandle = (OCResourceHandle) collResource;
- stackRet = OCDoResponse(&response);
+ OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
+ stackRet = OC_STACK_ERROR;
}
+ else
+ {
+ OCEntityHandlerResponse response = { 0 };
+ if(stackRet == OC_STACK_OK)
+ response.ehResult = OC_EH_OK;
+ else
+ response.ehResult = OC_EH_ERROR;
+
+ // Format the response. Note this requires some info about the request
+ response.requestHandle = ehRequest->requestHandle;
+ response.resourceHandle = ehRequest->resource;
+ response.payload = (OCPayload*) payload;
+ response.numSendVendorSpecificHeaderOptions = 0;
+ memset(response.sendVendorSpecificHeaderOptions, 0,
+ sizeof response.sendVendorSpecificHeaderOptions);
+ memset(response.resourceUri, 0, sizeof response.resourceUri);
+ // Indicate that response is NOT in a persistent buffer
+ response.persistentBufferFlag = 0;
+ response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR;
- // ehRequest->resource = origResourceHandle;
+ // Send the response
+ if (OCDoResponse(&response) != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "Error sending response");
+ stackRet = OC_STACK_ERROR;
+ }
+ }
+ OCRepPayloadDestroy(payload);
}
+exit:
+
+ OCFREE(doWhat)
+ OCFREE(details)
+
return stackRet;
+}
+
+OCStackResult InitializeScheduleResourceList()
+{
+ MUTEX_INITIALIZE(&g_scheduledResourceLock);
+
+ g_scheduleResourceList = NULL;
+ return OC_STACK_OK;
+}
+
+void TerminateScheduleResourceList()
+{
+ assert(g_scheduleResourceList == NULL);
- //return OC_STACK_OK;
+ MUTEX_TERMINATE(&g_scheduledResourceLock);
}