From b665c2c2de3a67cee79e6af4a32074cef7aa9458 Mon Sep 17 00:00:00 2001 From: HyunJun Kim Date: Mon, 15 Dec 2014 15:55:14 +0900 Subject: [PATCH] Implementation of Group action feature for Things Manager. Add GROUP_INTERFACE and OC_RSRVD_INTERFACE_GROUP. These interfaces are supported Group Action. When DefaultCollectionEntityHandler is received an message which Using GROUP_INTERFACE, It is called BuildCollectionGroupActionJSONResponse. PUT : Action Create and Delete POST : Action Read and Execute Change-Id: I14519fa85b5319c3e9df72fa27e85a5d8df6ea87 Signed-off-by: HyunJun Kim --- resource/csdk/makefile | 1 + resource/csdk/stack/include/internal/ocresource.h | 37 ++ .../stack/include/internal/ocresourcehandler.h | 3 + resource/csdk/stack/include/internal/oicgroup.h | 57 ++ resource/csdk/stack/src/occollection.c | 49 +- resource/csdk/stack/src/oicgroup.c | 722 +++++++++++++++++++++ resource/include/OCApi.h | 4 + 7 files changed, 870 insertions(+), 3 deletions(-) mode change 100644 => 100755 resource/csdk/makefile mode change 100644 => 100755 resource/csdk/stack/include/internal/ocresource.h mode change 100644 => 100755 resource/csdk/stack/include/internal/ocresourcehandler.h create mode 100755 resource/csdk/stack/include/internal/oicgroup.h mode change 100644 => 100755 resource/csdk/stack/src/occollection.c create mode 100755 resource/csdk/stack/src/oicgroup.c mode change 100644 => 100755 resource/include/OCApi.h diff --git a/resource/csdk/makefile b/resource/csdk/makefile old mode 100644 new mode 100755 index 238a65d..ca77f30 --- a/resource/csdk/makefile +++ b/resource/csdk/makefile @@ -135,6 +135,7 @@ OCTBSTACK_SOURCES += $(OCTBSTACK_SRC)/ocresource.c OCTBSTACK_SOURCES += $(OCTBSTACK_SRC)/ocobserve.c OCTBSTACK_SOURCES += $(OCTBSTACK_SRC)/ocserverrequest.c OCTBSTACK_SOURCES += $(OCTBSTACK_SRC)/occollection.c +OCTBSTACK_SOURCES += $(OCTBSTACK_SRC)/oicgroup.c OCTBSTACK_SOURCES += $(OCTBSTACK_SRC)/ocsecurity.c SOURCES := $(CJSON_SOURCES) diff --git a/resource/csdk/stack/include/internal/ocresource.h b/resource/csdk/stack/include/internal/ocresource.h old mode 100644 new mode 100755 index 542cfb6..01611c1 --- a/resource/csdk/stack/include/internal/ocresource.h +++ b/resource/csdk/stack/include/internal/ocresource.h @@ -49,9 +49,43 @@ typedef enum { STACK_IF_DEFAULT = 0, STACK_IF_LL, STACK_IF_BATCH, + STACK_IF_GROUP, STACK_IF_INVALID } OCStackIfTypes; +// following structure will be create in occollection. +typedef struct occapability { + struct occapability* next; + + char *capability; // It is a name about resource capability. + char *status; // +} OCCapability; + + +// following structure will be create in occollection. +typedef struct ocaction { + struct ocaction *next; + + // Target Uri. + // It will be used to execute the action. + char *resourceUri; + + OCCapability* head; + +} OCAction; + +// following structure will be created in occollection. +typedef struct ocactionset { + + struct ocactionset *next; + + char *actionsetName; + + OCAction* head; +} OCActionSet; + + + typedef struct resourcetype_t { struct resourcetype_t *next; // linked list; for multiple types on resource @@ -116,6 +150,9 @@ typedef struct rsrc_t { /* method_t methods; */ // Sequence number for observable resources. Per the CoAP standard it is a 24 bit value. uint32_t sequenceNum; + + // Pointer of ActionSet which to support group action. + OCActionSet *actionsetHead; } OCResource; diff --git a/resource/csdk/stack/include/internal/ocresourcehandler.h b/resource/csdk/stack/include/internal/ocresourcehandler.h old mode 100644 new mode 100755 index e5a24bc..505a598 --- a/resource/csdk/stack/include/internal/ocresourcehandler.h +++ b/resource/csdk/stack/include/internal/ocresourcehandler.h @@ -34,6 +34,9 @@ #define OC_RSRVD_INTERFACE_DEFAULT "oc.mi.def" #define OC_RSRVD_INTERFACE_LL "oc.mi.ll" #define OC_RSRVD_INTERFACE_BATCH "oc.mi.b" +#define OC_RSRVD_INTERFACE_GROUP "oc.mi.c" + + #define OC_RSRVD_OBSERVABLE "obs" #define OC_RSRVD_SECURE "sec" #define OC_RSRVD_HOSTING_PORT "port" diff --git a/resource/csdk/stack/include/internal/oicgroup.h b/resource/csdk/stack/include/internal/oicgroup.h new file mode 100755 index 0000000..2493fba --- /dev/null +++ b/resource/csdk/stack/include/internal/oicgroup.h @@ -0,0 +1,57 @@ +//****************************************************************** +// +// Copyright 2014 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OIC_GROUP_H +#define OIC_GROUP_H + +#include "ocstack.h" +#include "ocstackinternal.h" + +void AddCapability(OCCapability** head, OCCapability* node); + +void AddAction(OCAction** head, OCAction* node); + +void AddActionSet(OCActionSet **head, OCActionSet* node); + +void DeleteCapability(OCCapability *del); + +void DeleteAction(OCAction** action); + +void DeleteActionSet(OCActionSet** actionset); + +OCStackResult DeleteActionSets(OCResource** resource); + +OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actionsetName); + +OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method, + char **actionsetName); + +OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc); + +OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle, + OCClientResponse* clientResponse); + +void ActionSetCD(void *context); + +OCStackResult +BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/, + OCResource *resource, OCEntityHandlerRequest *ehRequest); + +#endif // OIC_GROUP_H diff --git a/resource/csdk/stack/src/occollection.c b/resource/csdk/stack/src/occollection.c old mode 100644 new mode 100755 index 2efba22..23980ba --- a/resource/csdk/stack/src/occollection.c +++ b/resource/csdk/stack/src/occollection.c @@ -27,6 +27,14 @@ #include "debug.h" #include "cJSON.h" /// Module Name +#include + +#define WITH_GROUPACTION 1 + +#ifdef WITH_GROUPACTION +#include "oicgroup.h" +#endif + #define TAG PCF("occollection") #define NUM_PARAM_IN_QUERY 2 @@ -141,6 +149,10 @@ ValidateQuery (const unsigned char *query, OCResourceHandle resource, { *ifParam = STACK_IF_BATCH; } + else if(strcmp (ifPtr, OC_RSRVD_INTERFACE_GROUP) == 0) + { + *ifParam = STACK_IF_GROUP; + } else { return OC_STACK_ERROR; @@ -379,8 +391,10 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag, if (result != OC_STACK_OK) return result; - if ((ehRequest->method != OC_REST_GET) && - (ehRequest->method != OC_REST_PUT)) + + if(!((ehRequest->method == OC_REST_GET) || + (ehRequest->method == OC_REST_PUT) || + (ehRequest->method == OC_REST_POST))) return OC_STACK_ERROR; if (ehRequest->method == OC_REST_GET) @@ -404,7 +418,11 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag, ((OCServerRequest *)ehRequest->requestHandle)->numResponses = GetNumOfResourcesInCollection((OCResource *)ehRequest->resource) + 1; return HandleBatchInterface(ehRequest); - +#ifdef WITH_GROUPACTION + case STACK_IF_GROUP: + return BuildCollectionGroupActionJSONResponse(OC_REST_GET/*flag*/, (OCResource *)ehRequest->resource, + ehRequest); +#endif // WITH_GROUPACTION default: return OC_STACK_ERROR; } @@ -425,10 +443,35 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag, GetNumOfResourcesInCollection((OCResource *)ehRequest->resource) + 1; return HandleBatchInterface(ehRequest); + +#ifdef WITH_GROUPACTION + case STACK_IF_GROUP: + { + OC_LOG_V(INFO, TAG, "IF_COLLECTION PUT with request ::\n%s\n ", ehRequest->reqJSONPayload); + printf("PUT ::\n%s\n", ehRequest->reqJSONPayload); + return BuildCollectionGroupActionJSONResponse(OC_REST_PUT/*flag*/, (OCResource *)ehRequest->resource, ehRequest); + } +#endif // WITH_GROUPACTION + default: + return OC_STACK_ERROR; + } + } +#ifdef WITH_GROUPACTION + else if(ehRequest->method == OC_REST_POST) { + + switch(ifQueryParam) + { + case STACK_IF_GROUP: + { + OC_LOG_V(INFO, TAG, "IF_COLLECTION POST with request :: \n%s\n ", ehRequest->reqJSONPayload); + printf("POST ::\n%s\n", ehRequest->reqJSONPayload); + return BuildCollectionGroupActionJSONResponse(OC_REST_POST/*flag*/, (OCResource *)ehRequest->resource, ehRequest); + } default: return OC_STACK_ERROR; } } +#endif // WITH_GROUPACTION return result; } diff --git a/resource/csdk/stack/src/oicgroup.c b/resource/csdk/stack/src/oicgroup.c new file mode 100755 index 0000000..35819d8 --- /dev/null +++ b/resource/csdk/stack/src/oicgroup.c @@ -0,0 +1,722 @@ +//****************************************************************** +// +// Copyright 2014 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#define _POSIX_C_SOURCE 200112L +#include + +#include "cJSON.h" +#include "ocmalloc.h" +#include "oicgroup.h" +#include "ocresource.h" +#include "occollection.h" + +#define TAG PCF("OICGROUP") + +#define DESC_DELIMITER "\"" +#define ACTION_DELIMITER "*" +#define ATTR_DELIMITER "|" + +void AddCapability(OCCapability** head, OCCapability* node) +{ + OCCapability *pointer = *head; + if (NULL == pointer) + { + *head = node; + } + else + { + while (pointer->next != NULL) + { + pointer = pointer->next; + } + + pointer->next = node; + } +} + +void AddAction(OCAction** head, OCAction* node) +{ + OCAction *pointer = *head; + if (NULL == pointer) + { + *head = node; + } + else + { + + while (pointer->next != NULL) + { + pointer = pointer->next; + } + + pointer->next = node; + } +} + +void AddActionSet(OCActionSet **head, OCActionSet* node) +{ + OCActionSet *pointer = *head; + if (NULL == pointer) + { + *head = node; + } + else + { + + while (pointer->next != NULL) + { + pointer = pointer->next; + } + + pointer->next = node; + } +} + +void DeleteCapability(OCCapability *del) +{ + free(del->capability); + del->capability = NULL; + free(del->status); + del->status = NULL; +} + +void DeleteAction(OCAction** action) +{ + OCCapability* pointer = (*action)->head; + OCCapability* pDel = NULL; + + while (pointer) + { + pDel = pointer; + pointer = pointer->next; + + DeleteCapability(pDel); + pDel->next = NULL; + } + OCFree((*action)->resourceUri); + (*action)->resourceUri = NULL; + (*action)->next = NULL; +} + +void DeleteActionSet(OCActionSet** actionset) +{ + OCAction* pointer = (*actionset)->head; + OCAction* pDel = NULL; + + while (pointer) + { + pDel = pointer; + pointer = pointer->next; + + DeleteAction(&pDel); + pDel->next = NULL; + } + + OCFree((*actionset)->actionsetName); + (*actionset)->head = NULL; +} + +OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actionsetName) +{ + + if (*resource != NULL) + { + + OCActionSet *pointer = NULL; + OCActionSet *pDel = NULL; + + pointer = (*resource)->actionsetHead; + + if (pointer == NULL) + { + return OC_STACK_ERROR; + } + else + { + if (strcmp(pointer->actionsetName, actionsetName) == 0) + { + if (pointer->next != NULL) + (*resource)->actionsetHead = pointer->next; + else + (*resource)->actionsetHead = NULL; + + DeleteActionSet(&pointer); + + } + else if (pointer->next != NULL) + { + while (pointer) + { + if (pointer->next != NULL) + { + if (strcmp(pointer->next->actionsetName, actionsetName) == 0) + { + pDel = pointer->next; + pointer->next = pointer->next->next; + + DeleteActionSet(&pDel); + } + } + } + } + + return OC_STACK_OK; + } + + } + + 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) +{ + OCActionSet *pointer = head; + + while (pointer) + { + //printf("%s :: %s\n", pointer->actionsetName, actionsetName); + if (strcmp(pointer->actionsetName, actionName) == 0) + { + *actionset = pointer; + return OC_STACK_OK; + } + + pointer = pointer->next; + } + + return OC_STACK_ERROR; + +} + +OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method, + char **actionsetName) +{ + char *acitonRequest; + char *iterTokenPtr = NULL; + char *iterToken = NULL; + char *description = NULL; + char *iterDescPtr = NULL; + + char *attributes = NULL; + char *iterAttrbutesPtr = NULL; + + char *attr = NULL; + char *iterAttrPtr = NULL; + + OCActionSet* actionset = NULL; + OCAction* action = NULL; + + acitonRequest = (char *) OCMalloc(strlen((char *) request) + 1); + strncpy(acitonRequest, (char *) request, strlen((char *) request) + 1); + + //printf("\t%s\n", acitonRequest); + if (acitonRequest != NULL) + { + iterToken = (char *) strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr); + + while (iterToken != NULL) + { + if (strcmp(iterToken, "ActionSet") == 0) + { // if iterToken is ActionSet, will be created and added a new action set. + + *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); + + strncpy(*actionsetName, iterToken, strlen(iterToken) + 1); + printf("ACTION SET NAME :: %s\n", *actionsetName); + // break; + } + + iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr); + } + else + { + return OC_STACK_ERROR; + + } // end Action Set Name. + + // 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); + + while (iterToken != NULL) + { + action = (OCAction *) OCMalloc(sizeof(OCAction)); + memset(action, 0, sizeof(OCAction)); + + printf("ATTR Copied :: %s\n", iterToken); + attributes = (char *) OCMalloc(strlen(iterToken) + 1); + strncpy(attributes, iterToken, strlen(iterToken) + 1); + printf("ATTR Copied :: %s\n", attributes); + + iterToken = (char *) strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr); + while (iterToken != NULL) + { + attr = (char *) OCMalloc(strlen(iterToken) + 1); + strncpy(attr, iterToken, strlen(iterToken) + 1); + + iterToken = (char *) strtok_r(attr, "=", &iterAttrPtr); + while (iterToken != NULL) + { + // Find the URI from description. + if (strcmp(iterToken, "uri") == 0) + { + iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr); + printf("uri :: %s\n", iterToken); + action->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); + } + + iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr); + } + + iterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr); + } // End of Action + + AddAction(&actionset->head, action); + + iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr); + } + + // 3. Add the pointer OCResource's ActionSet list. + AddActionSet(&(*resource)->actionsetHead, actionset); + return OC_STACK_OK; + } + else if (strcmp(iterToken, "DoAction") == 0 || strcmp(iterToken, "DelActionSet") == 0 + || strcmp(iterToken, "GetActionSet") == 0) + { + *method = (char *) OCMalloc(strlen(iterToken) + 1); + strncpy(*method, iterToken, strlen(iterToken) + 1); + + 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); + + description = (char *) OCMalloc(strlen(iterToken) + 1); + strncpy(description, iterToken, strlen(iterToken) + 1); + + // Find the action name from description. + iterDescPtr = NULL; + iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr); + 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); + + strncpy(*actionsetName, iterToken, strlen(iterToken) + 1); + printf("ACTION SET NAME :: %s\n", *actionsetName); + } + + iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr); + return OC_STACK_OK; + } + else + { + return OC_STACK_ERROR; + + } // end Action Set Name. + break; + } + + iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); + } + } + + return OC_STACK_ERROR; +} + +OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc) +{ + char temp[1024] = + { 0 }; + int remaining = 1023; + + // 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, "*"); + remaining--; + } + else + { + return OC_STACK_ERROR; + } + + while (action != NULL) + { + printf("\tURI :: %s\n", action->resourceUri); + strcat(temp, "uri="); + remaining -= strlen("uri="); + strcat(temp, action->resourceUri); + remaining -= strlen(action->resourceUri); + strcat(temp, "|"); + remaining--; + + 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, "="); + remaining--; + strcat(temp, capas->status); + remaining -= strlen(capas->capability); + + capas = capas->next; + if (capas != NULL) + { + strcat(temp, "|"); + } + } + + action = action->next; + if (action != NULL) + { + strcat(temp, "*"); + remaining--; + } + } + // as = as->next; + // } + + *desc = (char *) OCMalloc(1024 - remaining); + strcpy(*desc, temp); + // printf("\t\tPlain Text = %s(%i)\n", *desc, 1024 - remaining); + + return OC_STACK_OK; +} + +OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle, + OCClientResponse* clientResponse) +{ + + // printf("\n\n\tcallback is called\n\n"); + // printf("\t\tresponse JSON : %s\n", clientResponse->resJSONPayload); + + 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 ret = OC_STACK_ERROR; + cJSON *json; + cJSON *body; + + char *jsonStr; + uint16_t jsonLen; + + OC_LOG(INFO, TAG, PCF("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); + pointerCapa = pointerCapa->next; + } + + jsonStr = cJSON_PrintUnformatted(json); + + jsonLen = strlen(jsonStr); + if (jsonLen < *remaining) + { + strcat((char*) bufferPtr, jsonStr); + *remaining -= jsonLen; + bufferPtr += jsonLen; + ret = OC_STACK_OK; + } + + cJSON_Delete(json); + free(jsonStr); + + return ret; +} + +OCStackResult SendAction(const char *targetUri, const unsigned char *action) +{ + OCCallbackData cbdata = + { 0 }; + cbdata.cb = &ActionSetCB; + cbdata.cd = &ActionSetCD; + cbdata.context = (void *) 0x99; + + OCDoHandle handle; + return OCDoResource(&handle, OC_REST_PUT, targetUri, + //temp->rsrcType->resourcetypename, + NULL, (char *) action, OC_NA_QOS, &cbdata, NULL, 0); +} + +OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/, + OCResource *resource, OCEntityHandlerRequest *ehRequest) +{ + OCStackResult stackRet = OC_STACK_ERROR; + // OCEntityHandlerResult ehRet = OC_EH_ERROR; + + OC_LOG(INFO, TAG, PCF("Group Action is requested.")); + // if (stackRet == OC_STACK_OK) + { + + char *doWhat = NULL; + char *actionName = NULL; + + // uint16_t remaining = MAX_RESPONSE_LENGTH; + size_t bufferLength = 0; + unsigned char buffer[MAX_RESPONSE_LENGTH] = + { 0 }; + unsigned char *bufferPtr = NULL; + + bufferPtr = buffer; + + OCResource * collResource = (OCResource *) ehRequest->resource; + // OCResourceHandle origResourceHandle = ehRequest->resource; + + char *jsonResponse; + + cJSON *json = cJSON_CreateObject(); + cJSON *format; + + cJSON_AddStringToObject(json, "href", resource->uri); + cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject()); + + if (method == OC_REST_GET) + { + OC_LOG(INFO, TAG, PCF("Group Action[GET].")); + } + else if (method == OC_REST_PUT) + { + OC_LOG(INFO, TAG, PCF("Group Action[PUT].")); + + unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload; + + GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName); + + if (strcmp(doWhat, "DelActionSet") == 0) + { + if (FindAndDeleteActionSet(&resource, actionName) == OC_STACK_OK) + { + } + else + { + } + } + else + { + } + + stackRet = OC_STACK_OK; + + } + else 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); + + if (strcmp(doWhat, "DoAction") == 0) + { + if (GetActionSet(actionName, resource->actionsetHead, &actionset) != OC_STACK_OK) + { + OC_LOG(INFO, TAG, PCF("ERROR")); + stackRet = OC_STACK_ERROR; + } + + if (actionset == NULL) + { + OC_LOG(INFO, TAG, PCF("ERROR")); + stackRet = OC_STACK_ERROR; + } else { + + // printf("Execute ActionSet :: %s\n", actionset->actionsetName); + + OCAction *pointerAction = actionset->head; + while (pointerAction != NULL) + { + // printf("Action Target :: %s\n", pointerAction->resourceUri); + + 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); + + SendAction(pointerAction->resourceUri, actionDescPtr); + + pointerAction = pointerAction->next; + } + 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) + { + cJSON_AddStringToObject(format, "ActionSet", plainText); + + // jsonResponse = cJSON_Print(json); + // cJSON_Delete(json); + + // strcat((char *)bufferPtr, jsonResponse); + } + + stackRet = OC_STACK_OK; + } + } + else if (actionName == NULL) + { + // printf("Cannot find actionname\n"); + return OC_STACK_ERROR; + } + } + + jsonResponse = cJSON_Print(json); + cJSON_Delete(json); + + strcat((char *) bufferPtr, jsonResponse); + + // printf("\n\tRESONSE ::\n%s\n", buffer); + bufferLength = strlen((const char *) buffer); + if (bufferLength > 0) + { + 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); + } + + // ehRequest->resource = origResourceHandle; + } + + return stackRet; + + //return OC_STACK_OK; +} diff --git a/resource/include/OCApi.h b/resource/include/OCApi.h old mode 100644 new mode 100755 index 97076c5..f46dac0 --- a/resource/include/OCApi.h +++ b/resource/include/OCApi.h @@ -194,6 +194,10 @@ namespace OC // Used in GET, PUT, POST, DELETE methods on links to other resources of a collection. const std::string BATCH_INTERFACE = "oc.mi.b"; + // Used in GET, PUT, POST methods on links to other remote resources of a group. + const std::string GROUP_INTERFACE = "oc.mi.c"; + + typedef std::function)> FindCallback; typedef std::function