X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fstack%2Fsrc%2Foicgroup.c;h=5114f4166229c299a242df63e93933d091b52954;hb=3c093548382bb2542c87a67e6e5fa32552c29cb3;hp=946b0940e93c4b5f50020054d72999bada81a33f;hpb=4ef23d30d0dba85164073b2baa17e13089447844;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/src/oicgroup.c b/resource/csdk/stack/src/oicgroup.c old mode 100644 new mode 100755 index 946b094..5114f41 --- a/resource/csdk/stack/src/oicgroup.c +++ b/resource/csdk/stack/src/oicgroup.c @@ -18,23 +18,27 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// Defining _POSIX_C_SOURCE macro with 200112L (or greater) as value -// causes header files to expose definitions -// corresponding to the POSIX.1-2001 base -// specification (excluding the XSI extension). -// For POSIX.1-2001 base specification, -// Refer http://pubs.opengroup.org/onlinepubs/009695399/ #define _POSIX_C_SOURCE 200112L + +#include "iotivity_config.h" + #include -#include "cJSON.h" -#include "ocmalloc.h" #include "oicgroup.h" -#include "ocresource.h" +#if defined (__TIZENRT__) +#include +#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 PCF("OICGROUP") +#define TAG "OIC_RI_GROUP" #define DESC_DELIMITER "\"" #define ACTION_DELIMITER "*" @@ -45,8 +49,233 @@ #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_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 + 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; + + 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; + +#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; @@ -56,7 +285,7 @@ typedef struct aggregatehandleinfo struct aggregatehandleinfo *next; } ClientRequestInfo; -static ClientRequestInfo *clientRequestList = NULL; +ClientRequestInfo *clientRequstList = NULL; void AddClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* add) { @@ -78,7 +307,8 @@ void AddClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* add) } } -ClientRequestInfo* GetClientRequestInfo(ClientRequestInfo *head, OCDoHandle handle) +ClientRequestInfo* GetClientRequestInfo(ClientRequestInfo *head, + OCDoHandle handle) { ClientRequestInfo *tmp = NULL; @@ -105,6 +335,9 @@ void RemoveClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* del) { ClientRequestInfo *tmp = NULL; + if (del == NULL) + return; + if (*head == del) { *head = (*head)->next; @@ -160,31 +393,46 @@ void AddAction(OCAction** head, OCAction* 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) { - OCFree(del->capability); + OCFREE(del->capability) del->capability = NULL; - OCFree(del->status); + OCFREE(del->status) del->status = NULL; + OCFREE(del) } void DeleteAction(OCAction** action) @@ -198,32 +446,36 @@ 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) { @@ -244,6 +496,7 @@ OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actions (*resource)->actionsetHead = pointer->next; else (*resource)->actionsetHead = NULL; + DeleteActionSet(&pointer); } else if (pointer->next != NULL) @@ -252,7 +505,8 @@ OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actions { 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; @@ -271,25 +525,8 @@ OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actions 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; @@ -308,61 +545,103 @@ OCStackResult GetActionSet(const char *actionName, OCActionSet *head, OCActionSe } - -#define OIC_ACTION_PREFIX "{\"oc\":[{\"rep\":{" -#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;\ - } - -OCStackResult ExtractKeyValueFromRequest(char *request, char **key, char **value) +OCStackResult ExtractKeyValueFromRequest(OCEntityHandlerRequest *ehRequest, + char **key, char **value) { OCStackResult result = OC_STACK_OK; - size_t length = 0; - if(strlen(request) <= strlen(OIC_ACTION_PREFIX)) + char *actionSetStr = NULL; + + if( NULL == ehRequest->payload ) { - return OC_STACK_INVALID_PARAM; + result = OC_STACK_ERROR; + goto exit; } - char* pRequest = (char *)request + strlen(OIC_ACTION_PREFIX); - char* iterToken = NULL; - char* iterTokenPtr = NULL; + OCRepPayload* input; - iterToken = (char *) strtok_r(pRequest, ":", &iterTokenPtr); - length = strlen(iterToken) + 1; + input = (OCRepPayload*)(ehRequest->payload); - *key = (char *)OCMalloc(length); - VARIFY_POINTER_NULL(*key, result, exit); + if(OCRepPayloadGetPropString(input, ACTIONSET, &actionSetStr)) + { + *key = OICStrdup(ACTIONSET); + VARIFY_POINTER_NULL(*key, result, exit); - strncpy(*key, iterToken + 1, length); - ((*key)[ (( length - 1 ) - 2) ]) = '\0'; + *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); - iterToken = (char *) strtok_r(NULL, "}", &iterTokenPtr); - length = strlen(iterToken) + 1; + *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); - *value = (char *)OCMalloc(length); - VARIFY_POINTER_NULL(*key, result, exit); + *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); + + *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); + + *value = OICStrdup(actionSetStr); + VARIFY_POINTER_NULL(*value, result, exit); + } + else + { + result = OC_STACK_ERROR; + } - strncpy(*value, iterToken + 1, length); - ((*value)[ (( length - 1 ) - 2) ]) = '\0'; exit: - if(result != OC_STACK_OK) + if (result != OC_STACK_OK) { - OCFree(*key); - OCFree(*value); - *key = NULL; - *value = NULL; + OCFREE(*key) + OCFREE(*value) } + OCFREE(actionSetStr); + + return result; +} + +OCStackResult ExtractActionSetNameAndDelaytime(char *pChar, char **setName, + long int *pa) +{ + char *token = NULL, *tokenPtr = NULL; + OCStackResult result = OC_STACK_OK; + + token = (char*) strtok_r(pChar, ACTION_DELIMITER, &tokenPtr); + VARIFY_POINTER_NULL(token, result, exit) + + *setName = (char *) OICMalloc(strlen(token) + 1); + VARIFY_POINTER_NULL(*setName, result, exit) + VARIFY_PARAM_NULL(token, result, exit) + strncpy(*setName, token, strlen(token) + 1); + + token = strtok_r(NULL, ACTION_DELIMITER, &tokenPtr); + VARIFY_POINTER_NULL(pa, result, exit) + VARIFY_PARAM_NULL(token, result, exit) + *pa = atoi(token); + + return OC_STACK_OK; + +exit: + OCFREE(*setName); return result; } @@ -371,81 +650,108 @@ OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc) OCStackResult result = OC_STACK_OK; char *iterToken = NULL, *iterTokenPtr = NULL; - char *descIterToken = NULL; - char *descIterTokenPtr = NULL; - char *attrIterToken = NULL; - char *attrIterTokenPtr = NULL; - char *desc = NULL; - char *attr = NULL; - char *key = NULL; - char *value = 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; - OC_LOG(INFO, TAG, PCF("Build ActionSet Instance.")); + OIC_LOG(INFO, TAG, "Build ActionSet Instance."); - *set = (OCActionSet*) OCMalloc(sizeof(OCActionSet)); + *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 *)OCMalloc(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); - OC_LOG_V(INFO, TAG, "ActionSet Name : %s", (*set)->actionsetName); + // 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 + + OIC_LOG_V(INFO, TAG, "ActionSet Name : %s", (*set)->actionsetName); iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr); - while(iterToken) + while (iterToken) { - desc = (char *)OCMalloc(strlen(iterToken) + 1); + 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) + descIterToken = (char *) strtok_r(desc, ATTR_DELIMITER, + &descIterTokenPtr); + while (descIterToken) { - attr = (char *)OCMalloc(strlen(descIterToken) + 1); + 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); - key = (char *)OCMalloc(strlen(attrIterToken) + 1); - VARIFY_POINTER_NULL(key, result, exit) + 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); - value = (char *)OCMalloc(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(strncmp(key, "uri", sizeof("uri") - 1) == 0) + if (strcmp(key, "uri") == 0) { - OC_LOG(INFO, TAG, PCF("Build OCAction Instance.")); + OIC_LOG(INFO, TAG, "Build OCAction Instance."); - action = (OCAction*)OCMalloc(sizeof(OCAction)); + action = (OCAction*) OICMalloc(sizeof(OCAction)); VARIFY_POINTER_NULL(action, result, exit) memset(action, 0, sizeof(OCAction)); - action->resourceUri = (char *)OCMalloc(strlen(value) + 1); + 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( (key != NULL) && (value != NULL)) + if ((key != NULL) && (value != NULL)) { - OC_LOG(INFO, TAG, PCF("Build OCCapability Instance.")); - capa = (OCCapability*)OCMalloc(sizeof(OCCapability)); + OIC_LOG(INFO, TAG, "Build OCCapability Instance."); + + capa = (OCCapability*) OICMalloc(sizeof(OCCapability)); VARIFY_POINTER_NULL(capa, result, exit) memset(capa, 0, sizeof(OCCapability)); - capa->capability = (char *)OCMalloc(strlen(key) + 1); - capa->status = (char *)OCMalloc(strlen(value) + 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); + + 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); VARIFY_POINTER_NULL(action, result, exit) @@ -454,129 +760,196 @@ OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc) } } - OCFree(key); - OCFree(value); - OCFree(attr); + OCFREE(key) + OCFREE(value) + OCFREE(attr) - descIterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &descIterTokenPtr); + descIterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, + &descIterTokenPtr); } AddAction(&(*set)->head, action); iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr); - OCFree(desc); + OCFREE(desc); } return OC_STACK_OK; exit: - OCFree(attr); - OCFree(desc); - OCFree(capa); - OCFree(action); - OCFree(*set); - *set = NULL; + OCFREE(attr) + OCFREE(desc) + OCFREE(capa) + OCFREE(action) + OCFREE((*set)->actionsetName) + OCFREE(*set) + OCFREE(key) + OCFREE(value) + OCFREE(attr) + return result; } OCStackResult BuildStringFromActionSet(OCActionSet* actionset, char** desc) { + // 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 }; - uint16_t remaining = sizeof(temp) - 1; + size_t remaining = sizeof(temp) - 1; + OCStackResult res = OC_STACK_ERROR; + char* actionTypeStr = NULL; OCAction *action = actionset->head; - if (remaining >= strlen(actionset->actionsetName) + (sizeof(ACTION_DELIMITER)-1) ) + if (remaining >= strlen(actionset->actionsetName) + 1) { - strncat(temp, actionset->actionsetName, remaining); + strncat(temp, actionset->actionsetName, strlen(actionset->actionsetName)); remaining -= strlen(actionset->actionsetName); - strcat(temp, ACTION_DELIMITER); - remaining -= (sizeof(ACTION_DELIMITER)-1); + 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) { - OC_LOG_V(INFO, TAG, "\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); remaining -= strlen(action->resourceUri); - strcat(temp, ATTR_DELIMITER); + strcat(temp, "|"); remaining--; OCCapability *capas = action->head; while (capas != NULL) { - OC_LOG_V(INFO, TAG, "\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, ATTR_ASSIGN); + strcat(temp, "="); remaining--; strcat(temp, capas->status); - remaining -= strlen(capas->capability); + remaining -= strlen(capas->status); capas = capas->next; if (capas != NULL) { - strcat(temp, ATTR_DELIMITER); + if (remaining < 1) + { + res = OC_STACK_ERROR; + goto exit; + } + strcat(temp, "|"); + remaining --; } } action = action->next; if (action != NULL) { + if (remaining < strlen(ACTION_DELIMITER)) + { + res = OC_STACK_ERROR; + goto exit; + } strcat(temp, ACTION_DELIMITER); remaining--; } } - *desc = (char *) OCMalloc(1024 - remaining); - if(!*desc) - { - return OC_STACK_NO_MEMORY; - } - - strcpy(*desc, temp); + *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) { - OC_LOG(INFO, TAG, PCF("\n\n\tcallback is called\n\n")); + (void)context; + (void)clientResponse; + OIC_LOG(INFO, TAG, "Entering ActionSetCB"); - ClientRequestInfo *info = GetClientRequestInfo(clientRequestList, handle); + ClientRequestInfo *info = GetClientRequestInfo(clientRequstList, handle); if (info) { - uint32_t idx = 0; + OCEntityHandlerResponse response = { 0 }; - char *responseJson = (char *) OCMalloc( - (unsigned int) (strlen( clientResponse->resJSONPayload) + 1)); + response.ehResult = OC_EH_OK; - // We need the body of response. - // Copy the body from the response - strncpy((char *) responseJson, (clientResponse->resJSONPayload - + OC_JSON_PREFIX_LEN), strlen(clientResponse->resJSONPayload) + 1); - idx = strlen((char *) responseJson) - OC_JSON_SUFFIX_LEN; - // And insert NULL at the end of body. - (responseJson[idx]) = 0; + if(NULL == clientResponse->payload) + { + OIC_LOG(ERROR, TAG, "Error sending response"); + return OC_STACK_DELETE_TRANSACTION; + } - OCEntityHandlerResponse response = { }; - response.ehResult = OC_EH_OK; - response.payload = responseJson; - response.payloadSize = (unsigned int) strlen((char *) responseJson) + 1; + // 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; - response.requestHandle = (OCRequestHandle) info->ehRequest; - response.resourceHandle = (OCResourceHandle) info->collResource; - OCDoResponse(&response); + // Send the response + if (OCDoResponse(&response) != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "Error sending response"); + return OC_STACK_DELETE_TRANSACTION; + } - RemoveClientRequestInfo(&clientRequestList, info); - OCFree(responseJson); + RemoveClientRequestInfo(&clientRequstList, info); + OCFREE(info) } return OC_STACK_KEEP_TRANSACTION; @@ -584,26 +957,29 @@ OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle, void ActionSetCD(void *context) { + (void)context; } -OCStackResult BuildActionJSON(OCAction* action, char* bufferPtr, uint16_t *remaining) +OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr, + uint16_t *remaining) { OCStackResult ret = OC_STACK_ERROR; - cJSON *json = NULL; - cJSON *body = NULL; + cJSON *json; + cJSON *body; - char *jsonStr = NULL; - uint16_t jsonLen = 0; + char *jsonStr; + uint16_t jsonLen; - OC_LOG(INFO, TAG, PCF("Entering BuildActionJSON")); + OIC_LOG(INFO, TAG, "Entering BuildActionJSON"); json = cJSON_CreateObject(); - cJSON_AddItemToObject(json, OC_RSRVD_REPRESENTATION, body = 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; } @@ -612,21 +988,41 @@ OCStackResult BuildActionJSON(OCAction* action, char* bufferPtr, uint16_t *remai jsonLen = strlen(jsonStr); if (jsonLen < *remaining) { - strcat((char*) bufferPtr, jsonStr); + strncat((char*) bufferPtr, jsonStr, jsonLen); *remaining -= jsonLen; bufferPtr += jsonLen; ret = OC_STACK_OK; } cJSON_Delete(json); - OCFree(jsonStr); + free(jsonStr); return ret; } -uint32_t GetNumOfTargetResource(OCAction *actionset) +OCPayload* BuildActionCBOR(OCAction* action) { - uint32_t numOfResource = 0; + 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) +{ + int numOfResource = 0; OCAction *pointerAction = actionset; @@ -639,65 +1035,195 @@ uint32_t GetNumOfTargetResource(OCAction *actionset) return numOfResource; } -OCStackResult SendAction(OCDoHandle *handle, const char *targetUri, const char *action) +OCStackResult SendAction(OCDoHandle *handle, OCServerRequest* requestHandle, const char *targetUri, + OCPayload *payload) { - OCCallbackData cbdata = { }; - cbdata.cb = &ActionSetCB; - cbdata.cd = &ActionSetCD; - cbdata.context = (void *) 0x99; - return OCDoResource(handle, OC_REST_PUT, targetUri, - //temp->rsrcType->resourcetypename, - NULL, (char *) action, OC_WIFI, OC_NA_QOS, &cbdata, NULL, 0); + 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 BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/, - OCResource *resource, OCEntityHandlerRequest *ehRequest) +OCStackResult DoAction(OCResource* resource, OCActionSet* actionset, + OCServerRequest* requestHandle) { - OCStackResult stackRet = OC_STACK_ERROR; + OCStackResult result = OC_STACK_ERROR; - OC_LOG(INFO, TAG, PCF("Group Action is requested.")); - char *doWhat = NULL; - char *details = NULL; + if( NULL == actionset->head) + { + return result; + } - size_t bufferLength = 0; - char buffer[MAX_RESPONSE_LENGTH] = { 0 }; - char *bufferPtr = NULL; + OCAction *pointerAction = actionset->head; - bufferPtr = buffer; + while (pointerAction != NULL) + { + OCPayload* payload; + payload = BuildActionCBOR(pointerAction); - OCResource * collResource = (OCResource *) ehRequest->resource; + if(payload == NULL) + { + return result; + } - char *jsonResponse; + ClientRequestInfo *info = (ClientRequestInfo *) OICMalloc( + sizeof(ClientRequestInfo)); - stackRet = ExtractKeyValueFromRequest((char *)ehRequest->reqJSONPayload, &doWhat, &details); + if( info == NULL ) + { + OCFREE(payload); + return OC_STACK_NO_MEMORY; + } + + memset(info, 0, sizeof(ClientRequestInfo)); + + info->collResource = resource; + info->ehRequest = requestHandle; - if (stackRet != OC_STACK_OK) + result = SendAction(&info->required, info->ehRequest, pointerAction->resourceUri, + payload); + + if (result != OC_STACK_OK) + { + OICFree(info); + return result; + } + + AddClientRequestInfo(&clientRequstList, info); + + pointerAction = pointerAction->next; + } + + return result; +} + +void DoScheduledGroupAction() +{ + OIC_LOG(INFO, TAG, "DoScheduledGroupAction Entering..."); + ScheduledResourceInfo* info = GetScheduledResource(g_scheduleResourceList); + + if (info == NULL) { - return stackRet; + 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; } - cJSON *json; - cJSON *format; + MUTEX_LOCK(&g_scheduledResourceLock); + DoAction(info->resource, info->actionset, info->ehRequest); - if (method == OC_REST_PUT) + MUTEX_UNLOCK(&g_scheduledResourceLock); + + + if (info->actionset->type == RECURSIVE) + { + ScheduledResourceInfo *schedule; + schedule = (ScheduledResourceInfo *) OICMalloc( + sizeof(ScheduledResourceInfo)); + + if (schedule) + { + 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) { - json = cJSON_CreateObject(); - cJSON_AddStringToObject(json, OC_RSRVD_HREF, resource->uri); - cJSON_AddItemToObject(json, OC_RSRVD_REPRESENTATION, format = cJSON_CreateObject()); + OIC_LOG_V(ERROR, TAG, "ExtractKeyValueFromRequest failed: %d", stackRet); + return stackRet; + } + + stackRet = OC_STACK_ERROR; - OC_LOG(INFO, TAG, PCF("Group Action[PUT].")); + if (method == OC_REST_PUT) + { + OIC_LOG(INFO, TAG, "Group Action[PUT]."); - if(strcmp(doWhat, ACTIONSET) == 0) + if (strcmp(doWhat, ACTIONSET) == 0) { - OCActionSet *actionSet; - BuildActionSetFromString(&actionSet, details); + OCActionSet *actionSet = NULL; + stackRet = BuildActionSetFromString(&actionSet, details); - if(actionSet != NULL) + if(stackRet == OC_STACK_OK) { - AddActionSet(&resource->actionsetHead, actionSet); - stackRet = 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 { @@ -705,7 +1231,7 @@ OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHa } } - else if (strncmp(doWhat, DELETE_ACTIONSET, sizeof(DELETE_ACTIONSET)) == 0) + else if (strcmp(doWhat, DELETE_ACTIONSET) == 0) { if (FindAndDeleteActionSet(&resource, details) == OC_STACK_OK) { @@ -717,96 +1243,178 @@ OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHa } } - jsonResponse = cJSON_Print(json); - cJSON_Delete(json); - - strcat((char *) bufferPtr, jsonResponse); + OCRepPayload* payload = OCRepPayloadCreate(); - bufferLength = strlen((const char *) buffer); - if (bufferLength > 0) + if(!payload) + { + OIC_LOG(ERROR, TAG, "Failed to allocate Payload"); + stackRet = OC_STACK_ERROR; + } + else { OCEntityHandlerResponse response = { 0 }; - response.ehResult = OC_EH_OK; - response.payload = buffer; - response.payloadSize = bufferLength + 1; + + 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.requestHandle = (OCRequestHandle) ehRequest->requestHandle; - response.resourceHandle = (OCResourceHandle) collResource; - stackRet = OCDoResponse(&response); - } + response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR; - stackRet = OC_STACK_OK; + // Send the response + if (OCDoResponse(&response) != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "Error sending response"); + stackRet = OC_STACK_ERROR; + } + } + OCRepPayloadDestroy(payload); } - - if (method == OC_REST_POST) + else if (method == OC_REST_POST) { - OC_LOG(INFO, TAG, PCF("Group Action[POST].")); - OCActionSet *actionset = NULL; - json = cJSON_CreateObject(); - cJSON_AddStringToObject(json, OC_RSRVD_HREF, resource->uri); + OCRepPayload* payload = OCRepPayloadCreate(); + OCRepPayloadSetUri(payload, resource->uri); - if (strcmp(doWhat, DO_ACTION) == 0) + if ((strcmp(doWhat, DO_ACTION) == 0) + || (strcmp(doWhat, "DoScheduledAction") == 0)) { - if (GetActionSet(details, resource->actionsetHead, &actionset) != OC_STACK_OK) - { - OC_LOG(ERROR, TAG, PCF("ERROR: GetActionSet failed")); - stackRet = OC_STACK_ERROR; - } + char *pActionsetName = NULL; + long int delay = -1; - if (actionset == NULL) + if (strcmp(doWhat, "DoScheduledAction") == 0) { - OC_LOG(ERROR, TAG, PCF("ERROR: Actionset is NULL")); - stackRet = OC_STACK_ERROR; + stackRet = ExtractActionSetNameAndDelaytime(details, + &pActionsetName, &delay); + + OCFREE(details) + details = pActionsetName; } else { + stackRet = OC_STACK_OK; + } - OCAction *pointerAction = actionset->head; - - uint32_t num = GetNumOfTargetResource(pointerAction); - - ((OCServerRequest *) ehRequest->requestHandle)->ehResponseHandler = - HandleAggregateResponse; - ((OCServerRequest *) ehRequest->requestHandle)->numResponses = num + 1; + if (stackRet == OC_STACK_OK) + { + if (GetActionSet(details, resource->actionsetHead, + &actionset) != OC_STACK_OK) + { + OIC_LOG(INFO, TAG, "ERROR"); + stackRet = OC_STACK_ERROR; + } - while (pointerAction != NULL) + if (actionset == NULL) + { + OIC_LOG(INFO, TAG, "Cannot Find ActionSet"); + stackRet = OC_STACK_ERROR; + } + else { - char actionDesc[MAX_RESPONSE_LENGTH] = { 0 }; - char* actionDescPtr = actionDesc; - uint16_t remaining = MAX_RESPONSE_LENGTH; + OIC_LOG(INFO, TAG, "Group Action[POST]."); + OCServerRequest *request = + GetServerRequestUsingHandle(ehRequest->requestHandle); + if (NULL == request) + { + stackRet = OC_STACK_ERROR; + goto exit; + } - strncpy((char *) actionDescPtr, (const char *) OC_JSON_PREFIX, - strlen((const char *) OC_JSON_PREFIX) + 1); - BuildActionJSON(pointerAction, actionDescPtr, &remaining); - strncat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX, - strlen((const char *) OC_JSON_SUFFIX)); + if (actionset->type == NONE) + { + OIC_LOG_V(INFO, TAG, "Execute ActionSet : %s", + actionset->actionsetName); + unsigned int num = GetNumOfTargetResource( + actionset->head); + + request->ehResponseHandler = HandleAggregateResponse; + request->numResponses = num + 1; - ClientRequestInfo *info = (ClientRequestInfo *) OCMalloc( - sizeof(ClientRequestInfo)); - memset(info, 0, sizeof(ClientRequestInfo)); + DoAction(resource, actionset, request); - info->collResource = resource; - info->ehRequest = (OCServerRequest *) ehRequest->requestHandle; + stackRet = OC_STACK_OK; + } + else + { + OIC_LOG_V(INFO, TAG, "Execute Scheduled ActionSet : %s", + actionset->actionsetName); - SendAction(&info->required, pointerAction->resourceUri, actionDescPtr); + delay = + (delay == -1 ? actionset->timesteps : delay); - AddClientRequestInfo(&clientRequestList, info); + ScheduledResourceInfo *schedule; + schedule = (ScheduledResourceInfo *) OICMalloc( + sizeof(ScheduledResourceInfo)); - pointerAction = pointerAction->next; + 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 (strcmp(doWhat, "CancelAction") == 0) + { + ScheduledResourceInfo *info = + GetScheduledResourceByActionSetName(g_scheduleResourceList, details); + if(info != NULL) + { + 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; + } } + else if (strcmp(doWhat, GET_ACTIONSET) == 0) { char *plainText = NULL; OCActionSet *actionset = NULL; - cJSON_AddItemToObject(json, OC_RSRVD_REPRESENTATION, format = cJSON_CreateObject()); GetActionSet(details, resource->actionsetHead, &actionset); if (actionset != NULL) { @@ -814,35 +1422,67 @@ OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHa if (plainText != NULL) { - cJSON_AddStringToObject(format, ACTIONSET, plainText); + OCRepPayloadSetPropString(payload, ACTIONSET, plainText); } - + OICFree(plainText); stackRet = OC_STACK_OK; } } - jsonResponse = cJSON_Print(json); - cJSON_Delete(json); - - strcat((char *) bufferPtr, jsonResponse); - - bufferLength = strlen((const char *) buffer); - if (bufferLength > 0) + if(!payload) { - OCEntityHandlerResponse response = {}; - response.ehResult = OC_EH_OK; - response.payload = buffer; - response.payloadSize = bufferLength + 1; + 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.requestHandle = (OCRequestHandle) ehRequest->requestHandle; - response.resourceHandle = (OCResourceHandle) collResource; - stackRet = OCDoResponse(&response); + response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR; + + // Send the response + if (OCDoResponse(&response) != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "Error sending response"); + stackRet = OC_STACK_ERROR; + } } + OCRepPayloadDestroy(payload); } - OCFree(doWhat); - OCFree(details); +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); + + MUTEX_TERMINATE(&g_scheduledResourceLock); +}