X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fstack%2Fsrc%2Foicgroup.c;h=47d34be774fdcd6c6fc033821e1f95753a5d4360;hb=935fdb9b67b6c10d007e652e9e2e028fd6ccfe09;hp=b9f70aca3473486d97003cab8a4b1b3c609b14e0;hpb=00b3660e45c56cb3db35dc2596a054f801b5591a;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/src/oicgroup.c b/resource/csdk/stack/src/oicgroup.c index b9f70ac..47d34be 100644 --- a/resource/csdk/stack/src/oicgroup.c +++ b/resource/csdk/stack/src/oicgroup.c @@ -19,19 +19,227 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #define _POSIX_C_SOURCE 200112L + #include +#include "oicgroup.h" #include "cJSON.h" #include "ocmalloc.h" -#include "oicgroup.h" -#include "ocresource.h" #include "occollection.h" +#include "logger.h" +#include "timer.h" + +#ifndef WITH_ARDUINO +#include +#endif #define TAG PCF("OICGROUP") -#define DESC_DELIMITER "\"" -#define ACTION_DELIMITER "*" -#define ATTR_DELIMITER "|" +#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 DELETE_ACTIONSET "DelActionSet" + +#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;\ + } + +#define OCFREE(pointer) \ + { \ + OCFree(pointer); \ + pointer = NULL; \ + } + +#ifndef WITH_ARDUINO +pthread_mutex_t lock; +#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 *scheduleResourceList = NULL; + +void AddScheduledResource(ScheduledResourceInfo **head, + ScheduledResourceInfo* add) +{ + OC_LOG(INFO, TAG, PCF("AddScheduledResource Entering...")); + +#ifndef WITH_ARDUINO + pthread_mutex_lock(&lock); +#endif + ScheduledResourceInfo *tmp = NULL; + + if (*head != NULL) + { + tmp = *head; + + while (tmp->next) + { + tmp = tmp->next; + } + tmp->next = add; + } + else + { + *head = add; + } +#ifndef WITH_ARDUINO + pthread_mutex_unlock(&lock); +#endif +} + +ScheduledResourceInfo* GetScheduledResource(ScheduledResourceInfo *head) +{ + OC_LOG(INFO, TAG, PCF("GetScheduledResource Entering...")); + +#ifndef WITH_ARDUINO + pthread_mutex_lock(&lock); +#endif + + time_t t_now; + + ScheduledResourceInfo *tmp = NULL; + tmp = head; + +#ifndef WITH_ARDUINO + time(&t_now); +#else + t_now = now(); +#endif + + if (tmp) + { + while (tmp) + { + time_t diffTm = 0; +#ifndef WITH_ARDUINO + diffTm = timespec_diff(tmp->time, t_now); +#else + diffTm = timespec_diff(tmp->time, t_now); +#endif + + if (diffTm <= (time_t) 0) + { + OC_LOG(INFO, TAG, PCF("return Call INFO.")); + goto exit; + } + + tmp = tmp->next; + } + } + + exit: +#ifndef WITH_ARDUINO + pthread_mutex_unlock(&lock); +#endif + if (tmp == NULL) + { + OC_LOG(INFO, TAG, PCF("Cannot Find Call Info.")); + } + return tmp; +} + +ScheduledResourceInfo* GetScheduledResourceByActionSetName(ScheduledResourceInfo *head, char *setName) +{ + OC_LOG(INFO, TAG, PCF("GetScheduledResourceByActionSetName Entering...")); + +#ifndef WITH_ARDUINO + pthread_mutex_lock(&lock); +#endif + ScheduledResourceInfo *tmp = NULL; + tmp = head; + + if (tmp) + { + while (tmp) + { + if (strcmp(tmp->actionset->actionsetName, setName) == 0) + { + OC_LOG(INFO, TAG, PCF("return Call INFO.")); + goto exit; + } + tmp = tmp->next; + } + } + +exit: +#ifndef WITH_ARDUINO + pthread_mutex_unlock(&lock); +#endif + if (tmp == NULL) + { + OC_LOG(INFO, TAG, PCF("Cannot Find Call Info.")); + } + return tmp; +} + +void RemoveScheduledResource(ScheduledResourceInfo **head, + ScheduledResourceInfo* del) +{ +#ifndef WITH_ARDUINO + pthread_mutex_lock(&lock); +#endif + OC_LOG(INFO, TAG, PCF("RemoveScheduledResource Entering...")); + ScheduledResourceInfo *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; + } + } + + OCFREE(del) +#ifndef WITH_ARDUINO + pthread_mutex_unlock(&lock); +#endif +} typedef struct aggregatehandleinfo { @@ -40,16 +248,13 @@ typedef struct aggregatehandleinfo OCResource *collResource; struct aggregatehandleinfo *next; -} ClientRequstInfo; - -// unsigned int nHandleIdx = 0; -// ClientRequstInfo g_AggregateResponseHandle[10]; +} ClientRequestInfo; -ClientRequstInfo *clientRequstList = NULL; +ClientRequestInfo *clientRequstList = NULL; -void AddClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* add) +void AddClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* add) { - ClientRequstInfo *tmp = NULL; + ClientRequestInfo *tmp = NULL; if (*head != NULL) { @@ -67,9 +272,10 @@ void AddClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* add) } } -ClientRequstInfo* GetClientRequestInfo(ClientRequstInfo *head, OCDoHandle handle) +ClientRequestInfo* GetClientRequestInfo(ClientRequestInfo *head, + OCDoHandle handle) { - ClientRequstInfo *tmp = NULL; + ClientRequestInfo *tmp = NULL; tmp = head; @@ -77,7 +283,6 @@ ClientRequstInfo* GetClientRequestInfo(ClientRequstInfo *head, OCDoHandle handle { while (tmp) { -// printf("%p :: %p\n", tmp->required, handle); if (tmp->required == handle) { break; @@ -91,9 +296,12 @@ ClientRequstInfo* GetClientRequestInfo(ClientRequstInfo *head, OCDoHandle handle return NULL; } -void RemoveClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* del) +void RemoveClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* del) { - ClientRequstInfo *tmp = NULL; + ClientRequestInfo *tmp = NULL; + + if (del == NULL) + return; if (*head == del) { @@ -113,8 +321,6 @@ void RemoveClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* del) } } - - void AddCapability(OCCapability** head, OCCapability* node) { OCCapability *pointer = *head; @@ -152,31 +358,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) { - free(del->capability); + OCFREE(del->capability) del->capability = NULL; - free(del->status); + OCFREE(del->status) del->status = NULL; + OCFREE(del) } void DeleteAction(OCAction** action) @@ -190,15 +411,17 @@ 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) { + if(*actionset == NULL) + return; + OCAction* pointer = (*actionset)->head; OCAction* pDel = NULL; @@ -208,19 +431,17 @@ void DeleteActionSet(OCActionSet** actionset) 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; @@ -240,7 +461,6 @@ OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actions (*resource)->actionsetHead = NULL; DeleteActionSet(&pointer); - } else if (pointer->next != NULL) { @@ -248,7 +468,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; @@ -256,6 +477,7 @@ OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actions DeleteActionSet(&pDel); } } + pointer = pointer->next; } } @@ -263,7 +485,6 @@ OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actions } } - return OC_STACK_ERROR; } @@ -285,7 +506,8 @@ OCStackResult DeleteActionSets(OCResource** resource) 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; @@ -304,227 +526,226 @@ OCStackResult GetActionSet(const char *actionName, OCActionSet *head, OCActionSe } -OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method, - char **actionsetName) +OCStackResult ExtractKeyValueFromRequest(char *request, char **key, + char **value) { - char *acitonRequest; - char *iterTokenPtr = NULL; - char *iterToken = NULL; - char *description = NULL; - char *iterDescPtr = NULL; + OCStackResult result = OC_STACK_OK; + size_t length = 0; + + char* pRequest = (char *) request + strlen(OIC_ACTION_PREFIX); + char* iterToken, *iterTokenPtr; + + iterToken = (char *) strtok_r(pRequest, ":", &iterTokenPtr); + VARIFY_POINTER_NULL(iterToken, result, exit); + length = strlen(iterToken) + 1; - char *attributes = NULL; - char *iterAttrbutesPtr = NULL; + *key = (char *) OCMalloc(length); + VARIFY_POINTER_NULL(*key, result, exit) - char *attr = NULL; - char *iterAttrPtr = NULL; + strncpy(*key, iterToken + 1, length); + ((*key)[((length - 1) - 2)]) = '\0'; - OCActionSet* actionset = NULL; - OCAction* action = NULL; + iterToken = (char *) strtok_r(NULL, "}", &iterTokenPtr); + VARIFY_POINTER_NULL(iterToken, result, exit); + length = strlen(iterToken) + 1; - acitonRequest = (char *) OCMalloc(strlen((char *) request) + 1); - strncpy(acitonRequest, (char *) request, strlen((char *) request) + 1); + *value = (char *) OCMalloc(length); + VARIFY_POINTER_NULL(*value, result, exit) - //printf("\t%s\n", acitonRequest); - if (acitonRequest != NULL) + strncpy(*value, iterToken + 1, length); + ((*value)[((length - 1) - 2)]) = '\0'; + +exit: + if (result != OC_STACK_OK) { - iterToken = (char *) strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr); + OCFREE(*key) + OCFREE(*value) + } - 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); - - //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); - - // printf("DESC :: %s\n", iterToken); - description = (char *) OCMalloc(strlen(iterToken) + 1); - strncpy(description, iterToken, strlen(iterToken) + 1); - // printf("DESC Copied :: %s\n", description); - - // 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); + return result; +} - strncpy(*actionsetName, iterToken, strlen(iterToken) + 1); - // printf("ACTION SET NAME :: %s\n", *actionsetName); - // break; - } +OCStackResult ExtractActionSetNameAndDelaytime(char *pChar, char **setName, + long int *pa) +{ + char *token, *tokenPtr; + OCStackResult result = OC_STACK_OK; - iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr); - } - else - { - return OC_STACK_ERROR; + token = (char*) strtok_r(pChar, ACTION_DELIMITER, &tokenPtr); + *setName = (char *) OCMalloc(strlen(token) + 1); + VARIFY_POINTER_NULL(*setName, result, exit) + VARIFY_PARAM_NULL(token, result, exit) + strncpy(*setName, token, strlen(token) + 1); - } // end Action Set Name. + token = strtok_r(NULL, ACTION_DELIMITER, &tokenPtr); + VARIFY_POINTER_NULL(pa, result, exit) + VARIFY_PARAM_NULL(token, result, exit) + *pa = atoi(token); - // 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 OC_STACK_OK; - while (iterToken != NULL) - { - action = (OCAction *) OCMalloc(sizeof(OCAction)); - memset(action, 0, sizeof(OCAction)); +exit: + OCFREE(*setName); + return result; +} - // printf("ATTR Copied :: %s\n", iterToken); - attributes = (char *) OCMalloc(strlen(iterToken) + 1); - strncpy(attributes, iterToken, strlen(iterToken) + 1); - // printf("ATTR Copied :: %s\n", attributes); +OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc) +{ + OCStackResult result = OC_STACK_OK; - iterToken = (char *) strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr); - while (iterToken != NULL) - { - attr = (char *) OCMalloc(strlen(iterToken) + 1); - strncpy(attr, iterToken, strlen(iterToken) + 1); + 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; - 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); - } + OCAction *action = NULL; + OCCapability *capa = NULL; - iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr); - } + OC_LOG(INFO, TAG, PCF("Build ActionSet Instance.")); - iterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr); - } // End of Action + *set = (OCActionSet*) OCMalloc(sizeof(OCActionSet)); + VARIFY_POINTER_NULL(*set, result, exit) - AddAction(&actionset->head, action); + iterToken = (char *) strtok_r(actiondesc, ACTION_DELIMITER, &iterTokenPtr); - iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr); - } + // ActionSet Name + memset(*set, 0, sizeof(OCActionSet)); + (*set)->actionsetName = (char *) OCMalloc(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) +#ifndef WITH_ARDUINO + sscanf(iterToken, "%ld %d", &(*set)->timesteps, &(*set)->type); +#endif - // 3. Add the pointer OCResource's ActionSet list. - AddActionSet(&(*resource)->actionsetHead, actionset); - return OC_STACK_OK; + OC_LOG_V(INFO, TAG, "ActionSet Name : %s", (*set)->actionsetName); + + iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr); + while (iterToken) + { + desc = (char *) OCMalloc(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 *) OCMalloc(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) + 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); + VARIFY_POINTER_NULL(value, result, exit) + VARIFY_PARAM_NULL(attrIterToken, result, exit) + strncpy(value, attrIterToken, strlen(attrIterToken) + 1); + + if (strcmp(key, "uri") == 0) + { + OC_LOG(INFO, TAG, PCF("Build OCAction Instance.")); + + action = (OCAction*) OCMalloc(sizeof(OCAction)); + VARIFY_POINTER_NULL(action, result, exit) + memset(action, 0, sizeof(OCAction)); + action->resourceUri = (char *) OCMalloc(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)) + { + OC_LOG(INFO, TAG, PCF("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*) OCMalloc(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 *) OCMalloc(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 *) OCMalloc(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) + OCFREE(key) + OCFREE(value) + OCFREE(attr) + + return result; } -OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc) +OCStackResult BuildStringFromActionSet(OCActionSet* actionset, char** desc) { - char temp[1024] = - { 0 }; + char temp[1024] = { 0 }; int remaining = 1023; + OCStackResult res = OC_STACK_ERROR; - // 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); remaining -= strlen(actionset->actionsetName); - strcat(temp, "*"); + strcat(temp, ACTION_DELIMITER); remaining--; } else { - return OC_STACK_ERROR; + res = OC_STACK_ERROR; + goto exit; } while (action != NULL) { - printf("\tURI :: %s\n", action->resourceUri); strcat(temp, "uri="); remaining -= strlen("uri="); strcat(temp, action->resourceUri); @@ -535,7 +756,6 @@ OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc) OCCapability *capas = action->head; while (capas != NULL) { - printf("\t\t%s = %s\n", capas->capability, capas->status); strcat(temp, capas->capability); remaining -= strlen(capas->capability); strcat(temp, "="); @@ -553,26 +773,29 @@ OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc) action = action->next; if (action != NULL) { - strcat(temp, "*"); + strcat(temp, ACTION_DELIMITER); remaining--; } } - // as = as->next; - // } *desc = (char *) OCMalloc(1024 - remaining); + VARIFY_POINTER_NULL(*desc, res, exit); strcpy(*desc, temp); - // printf("\t\tPlain Text = %s(%i)\n", *desc, 1024 - remaining); return OC_STACK_OK; + +exit: + OCFREE(*desc); + return res; + } OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle, OCClientResponse* clientResponse) { - printf("\n\n\tcallback is called\n\n"); + OC_LOG(INFO, TAG, PCF("Entering BuildActionJSON")); - ClientRequstInfo *info = GetClientRequestInfo(clientRequstList, handle); + ClientRequestInfo *info = GetClientRequestInfo(clientRequstList, handle); if (info) { @@ -580,19 +803,23 @@ OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle, unsigned char *responseJson; responseJson = (unsigned char *) OCMalloc( - (unsigned int) (strlen((char *) clientResponse->resJSONPayload) + 1)); + (unsigned int) (strlen((char *) clientResponse->resJSONPayload) + + 1)); + + if( responseJson == NULL ) + return OC_STACK_DELETE_TRANSACTION; // We need the body of response. // Copy the body from the response - strcpy((char *) responseJson, ((char *) clientResponse->resJSONPayload - + OC_JSON_PREFIX_LEN)); + strcpy((char *) responseJson, + ((char *) clientResponse->resJSONPayload + OC_JSON_PREFIX_LEN)); idx = strlen((char *) responseJson) - OC_JSON_SUFFIX_LEN; // And insert NULL at the end of body. (responseJson[idx]) = 0; OCEntityHandlerResponse response = { 0 }; response.ehResult = OC_EH_OK; - response.payload = responseJson; + response.payload = (char*)responseJson; response.payloadSize = (unsigned int) strlen((char *) responseJson) + 1; response.persistentBufferFlag = 0; response.requestHandle = (OCRequestHandle) info->ehRequest; @@ -601,22 +828,19 @@ OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle, OCDoResponse(&response); RemoveClientRequestInfo(&clientRequstList, info); - OCFree(responseJson); + OCFREE(info) + OCFREE(responseJson) } - // g_AggregateResponseHandle - return OC_STACK_KEEP_TRANSACTION; } void ActionSetCD(void *context) { - // printf("\n\t\tCD is called\n"); - - // free( 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; @@ -633,7 +857,8 @@ OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr, uint16 OCCapability* pointerCapa = action->head; while (pointerCapa) { - cJSON_AddStringToObject(body, pointerCapa->capability, pointerCapa->status); + cJSON_AddStringToObject(body, pointerCapa->capability, + pointerCapa->status); pointerCapa = pointerCapa->next; } @@ -656,47 +881,169 @@ OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr, uint16 unsigned int GetNumOfTargetResource(OCAction *actionset) { - int numOfREsource = 0; + int numOfResource = 0; OCAction *pointerAction = actionset; while (pointerAction != NULL) { - numOfREsource++; + numOfResource++; pointerAction = pointerAction->next; } - return numOfREsource; + return numOfResource; } -OCStackResult SendAction(OCDoHandle *handle, const char *targetUri, const unsigned char *action) + +#define DEFAULT_CONTEXT_VALUE 0x99 + +OCStackResult SendAction(OCDoHandle *handle, const char *targetUri, + const unsigned char *action) { - OCCallbackData cbdata = - { 0 }; + OCCallbackData cbdata = { 0 }; cbdata.cb = &ActionSetCB; - cbdata.cd = &ActionSetCD; - cbdata.context = (void *) 0x99; + cbdata.cd = NULL; + cbdata.context = (void*)DEFAULT_CONTEXT_VALUE; + +// TODO: Selecting OC_IPV4. +// It is temporary change as OC_ALL is not working currently. Remove this code and use OC_ALL +// once it is functioning. return OCDoResource(handle, OC_REST_PUT, targetUri, - //temp->rsrcType->resourcetypename, - NULL, (char *) action, OC_NA_QOS, &cbdata, NULL, 0); + NULL, (char *) action, OC_IPV4, OC_NA_QOS, &cbdata, NULL, 0); +} + +OCStackResult DoAction(OCResource* resource, OCActionSet* actionset, + OCServerRequest* requestHandle) +{ + OCStackResult result = OC_STACK_ERROR; + OCAction *pointerAction = actionset->head; + + while (pointerAction != NULL) + { + unsigned char actionDesc[MAX_RESPONSE_LENGTH] = { 0 }; + unsigned char* actionDescPtr = actionDesc; + uint16_t remaining = MAX_RESPONSE_LENGTH; + + 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)); + + ClientRequestInfo *info = (ClientRequestInfo *) OCMalloc( + sizeof(ClientRequestInfo)); + + if( info == NULL ) + return OC_STACK_NO_MEMORY; + + memset(info, 0, sizeof(ClientRequestInfo)); + + info->collResource = resource; + info->ehRequest = requestHandle; + + result = SendAction(&info->required, pointerAction->resourceUri, + actionDescPtr); + if (result != OC_STACK_OK) + { + return result; + } + + AddClientRequestInfo(&clientRequstList, info); + + pointerAction = pointerAction->next; + } + + return result; } -OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/, - OCResource *resource, OCEntityHandlerRequest *ehRequest) +void DoScheduledGroupAction() +{ + OC_LOG(INFO, TAG, PCF("DoScheduledGroupAction Entering...")); + ScheduledResourceInfo* info = GetScheduledResource(scheduleResourceList); + + if (info == NULL) + { + OC_LOG(INFO, TAG, PCF("Target resource is NULL")); + goto exit; + } + else if (info->resource == NULL) + { + OC_LOG(INFO, TAG, PCF("Target resource is NULL")); + goto exit; + } + else if (info->actionset == NULL) + { + OC_LOG(INFO, TAG, PCF("Target ActionSet is NULL")); + goto exit; + } + else if (info->ehRequest == NULL) + { + OC_LOG(INFO, TAG, PCF("Target ActionSet is NULL")); + goto exit; + } +#ifndef WITH_ARDUINO + pthread_mutex_lock(&lock); +#endif + DoAction(info->resource, info->actionset, info->ehRequest); +#ifndef WITH_ARDUINO + pthread_mutex_unlock(&lock); +#endif + + if (info->actionset->type == RECURSIVE) + { + ScheduledResourceInfo *schedule; + schedule = (ScheduledResourceInfo *) OCMalloc( + sizeof(ScheduledResourceInfo)); + + if (schedule) + { + OC_LOG(INFO, TAG, PCF("Building New Call Info.")); + memset(schedule, 0, sizeof(ScheduledResourceInfo)); + + if (info->actionset->timesteps > 0) + { +#ifndef WITH_ARDUINO + pthread_mutex_lock(&lock); +#endif + schedule->resource = info->resource; + schedule->actionset = info->actionset; + schedule->ehRequest = info->ehRequest; + + schedule->time = registerTimer(info->actionset->timesteps, + &schedule->timer_id, + &DoScheduledGroupAction); + + OC_LOG(INFO, TAG, PCF("Reregisteration.")); +#ifndef WITH_ARDUINO + pthread_mutex_unlock(&lock); +#endif + AddScheduledResource(&scheduleResourceList, schedule); + } + } + } + + RemoveScheduledResource(&scheduleResourceList, info); + + exit: + + return; +} + +OCStackResult BuildCollectionGroupActionJSONResponse( + OCMethod method/*OCEntityHandlerFlag flag*/, OCResource *resource, + OCEntityHandlerRequest *ehRequest) { OCStackResult stackRet = OC_STACK_ERROR; OC_LOG(INFO, TAG, PCF("Group Action is requested.")); // if (stackRet == OC_STACK_OK) { - char *doWhat = NULL; - char *actionName = NULL; + char *details = NULL; size_t bufferLength = 0; - unsigned char buffer[MAX_RESPONSE_LENGTH] = - { 0 }; + unsigned char buffer[MAX_RESPONSE_LENGTH] = { 0 }; unsigned char *bufferPtr = NULL; bufferPtr = buffer; @@ -705,6 +1052,17 @@ OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHa char *jsonResponse; + stackRet = ExtractKeyValueFromRequest((char *) ehRequest->reqJSONPayload, + &doWhat, &details); + + if(stackRet != OC_STACK_OK) + { + OC_LOG_V(ERROR, TAG, "ExtractKeyValueFromRequest failed: %d", stackRet); + return stackRet; + } + + stackRet = OC_STACK_ERROR; + cJSON *json; cJSON *format; @@ -716,12 +1074,36 @@ OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHa OC_LOG(INFO, TAG, PCF("Group Action[PUT].")); - unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload; - GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName); + if (strcmp(doWhat, ACTIONSET) == 0) + { + OCActionSet *actionSet = NULL; + stackRet = BuildActionSetFromString(&actionSet, details); + + if(stackRet == OC_STACK_OK) + { + if (actionSet != NULL) + { + stackRet = AddActionSet(&resource->actionsetHead, + actionSet); + if (stackRet == OC_STACK_ERROR) + { + if(actionSet != NULL) + { + DeleteActionSet( &actionSet ); + } + OC_LOG(INFO, TAG, PCF("Duplicated ActionSet ")); + } + } + } + else + { + stackRet = OC_STACK_ERROR; + } - if (strcmp(doWhat, "DelActionSet") == 0) + } + else if (strcmp(doWhat, DELETE_ACTIONSET) == 0) { - if (FindAndDeleteActionSet(&resource, actionName) == OC_STACK_OK) + if (FindAndDeleteActionSet(&resource, details) == OC_STACK_OK) { stackRet = OC_STACK_OK; } @@ -739,106 +1121,165 @@ OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHa bufferLength = strlen((const char *) buffer); if (bufferLength > 0) { - OCEntityHandlerResponse response = - { 0 }; - response.ehResult = OC_EH_OK; - response.payload = buffer; + OCEntityHandlerResponse response = { 0 }; + if(stackRet == OC_STACK_OK) + response.ehResult = OC_EH_OK; + else + response.ehResult = OC_EH_ERROR; + response.payload = (char*)buffer; response.payloadSize = bufferLength + 1; response.persistentBufferFlag = 0; - response.requestHandle = (OCRequestHandle) ehRequest->requestHandle; + response.requestHandle = + (OCRequestHandle) ehRequest->requestHandle; response.resourceHandle = (OCResourceHandle) collResource; stackRet = OCDoResponse(&response); } - - stackRet = OC_STACK_OK; } if (method == OC_REST_POST) { - OC_LOG(INFO, TAG, PCF("Group Action[POST].")); - OCActionSet *actionset = NULL; - unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload; - - GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName); json = cJSON_CreateObject(); cJSON_AddStringToObject(json, "href", resource->uri); - if (strcmp(doWhat, "DoAction") == 0) + if ((strcmp(doWhat, DO_ACTION) == 0) + || (strcmp(doWhat, "DoScheduledAction") == 0)) { - if (GetActionSet(actionName, resource->actionsetHead, &actionset) != OC_STACK_OK) - { - OC_LOG(INFO, TAG, PCF("ERROR")); - stackRet = OC_STACK_ERROR; - } + char *pActionsetName = NULL; + long int delay = -1; - if (actionset == NULL) + if (strcmp(doWhat, "DoScheduledAction") == 0) { - OC_LOG(INFO, TAG, PCF("ERROR")); - stackRet = OC_STACK_ERROR; + stackRet = ExtractActionSetNameAndDelaytime(details, + &pActionsetName, &delay); + + OCFREE(details) + details = pActionsetName; } else { + stackRet = OC_STACK_OK; + } - OCAction *pointerAction = actionset->head; - - unsigned int num = GetNumOfTargetResource(pointerAction); - - ((OCServerRequest *) ehRequest->requestHandle)->ehResponseHandler = - HandleAggregateResponse; - ((OCServerRequest *) ehRequest->requestHandle)->numResponses = num + 1; - -// printf("ActionSet Name :: %s\n", actionset->actionsetName); - while (pointerAction != NULL) + if (stackRet == OC_STACK_OK) + { + if (GetActionSet(details, resource->actionsetHead, + &actionset) != OC_STACK_OK) { - unsigned char actionDesc[MAX_RESPONSE_LENGTH] = { 0 }; - unsigned char* actionDescPtr = actionDesc; - uint16_t remaining = MAX_RESPONSE_LENGTH; - - strcpy((char *) actionDescPtr, (const char *) OC_JSON_PREFIX); - BuildActionJSON(pointerAction, actionDescPtr, &remaining); - strcat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX); - - ClientRequstInfo *info = (ClientRequstInfo *) OCMalloc( - sizeof(ClientRequstInfo)); - memset(info, 0, sizeof(ClientRequstInfo)); - - info->collResource = resource; - info->ehRequest = (OCServerRequest *) ehRequest->requestHandle; + OC_LOG(INFO, TAG, PCF("ERROR")); + stackRet = OC_STACK_ERROR; + } - SendAction(&info->required, pointerAction->resourceUri, actionDescPtr); + if (actionset == NULL) + { + OC_LOG(INFO, TAG, PCF("Cannot Find ActionSet")); + stackRet = OC_STACK_ERROR; + } + else + { + OC_LOG(INFO, TAG, PCF("Group Action[POST].")); + if (actionset->type == NONE) + { + OC_LOG_V(INFO, TAG, "Execute ActionSet : %s", + actionset->actionsetName); + unsigned int num = GetNumOfTargetResource( + actionset->head); + + ((OCServerRequest *) ehRequest->requestHandle)->ehResponseHandler = + HandleAggregateResponse; + ((OCServerRequest *) ehRequest->requestHandle)->numResponses = + num + 1; + + DoAction(resource, actionset, + (OCServerRequest*) ehRequest->requestHandle); + stackRet = OC_STACK_OK; + } + else + { + OC_LOG_V(INFO, TAG, "Execute Scheduled ActionSet : %s", + actionset->actionsetName); - AddClientRequestInfo(&clientRequstList, info); + delay = + (delay == -1 ? actionset->timesteps : delay); + ScheduledResourceInfo *schedule; + schedule = (ScheduledResourceInfo *) OCMalloc( + sizeof(ScheduledResourceInfo)); - pointerAction = pointerAction->next; + if (schedule) + { + OC_LOG(INFO, TAG, PCF("Building New Call Info.")); + memset(schedule, 0, + sizeof(ScheduledResourceInfo)); + + schedule->resource = resource; + schedule->actionset = actionset; + schedule->ehRequest = + (OCServerRequest*) ehRequest->requestHandle; + + if (delay > 0) + { + OC_LOG_V(INFO, TAG, "delay_time is %lf seconds.", + actionset->timesteps); + + schedule->time = registerTimer(delay, + &schedule->timer_id, + &DoScheduledGroupAction); + + AddScheduledResource(&scheduleResourceList, + schedule); + stackRet = OC_STACK_OK; + } + else + { + stackRet = OC_STACK_ERROR; + } + } + } } + } + } + else if (strcmp(doWhat, "CancelAction") == 0) + { + ScheduledResourceInfo *info = + GetScheduledResourceByActionSetName(scheduleResourceList, details); + if(info != NULL) + { + unregisterTimer(info->timer_id); + RemoveScheduledResource(&scheduleResourceList, info); stackRet = OC_STACK_OK; } + else + { + stackRet = OC_STACK_ERROR; + } } - else if (strcmp(doWhat, "GetActionSet") == 0) + + else if (strcmp(doWhat, GET_ACTIONSET) == 0) { char *plainText = NULL; OCActionSet *actionset = NULL; - cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject()); - GetActionSet(actionName, resource->actionsetHead, &actionset); + cJSON_AddItemToObject(json, "rep", format = + cJSON_CreateObject()); + GetActionSet(details, resource->actionsetHead, &actionset); if (actionset != NULL) { - GetStringFromActionSet(actionset, &plainText); + BuildStringFromActionSet(actionset, &plainText); if (plainText != NULL) { - cJSON_AddStringToObject(format, "ActionSet", plainText); + cJSON_AddStringToObject(format, ACTIONSET, plainText); } - + OCFree(plainText); stackRet = OC_STACK_OK; } } + jsonResponse = cJSON_Print(json); cJSON_Delete(json); @@ -847,17 +1288,23 @@ OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHa bufferLength = strlen((const char *) buffer); if (bufferLength > 0) { - OCEntityHandlerResponse response = - { 0 }; - response.ehResult = OC_EH_OK; - response.payload = buffer; + OCEntityHandlerResponse response = { 0 }; + if(stackRet == OC_STACK_OK) + response.ehResult = OC_EH_OK; + else + response.ehResult = OC_EH_ERROR; + response.payload = (char *)buffer; response.payloadSize = bufferLength + 1; response.persistentBufferFlag = 0; - response.requestHandle = (OCRequestHandle) ehRequest->requestHandle; + response.requestHandle = + (OCRequestHandle) ehRequest->requestHandle; response.resourceHandle = (OCResourceHandle) collResource; stackRet = OCDoResponse(&response); } } + + OCFREE(doWhat) + OCFREE(details) } return stackRet;