1 //******************************************************************
3 // Copyright 2014 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #define _POSIX_C_SOURCE 200112L
28 #include "ocpayload.h"
29 #include "oic_malloc.h"
30 #include "oic_string.h"
31 #include "occollection.h"
39 #define TAG "OICGROUP"
41 #define DESC_DELIMITER "\""
42 #define ACTION_DELIMITER "*"
43 #define ATTR_DELIMITER "|"
44 #define ATTR_ASSIGN "="
46 // Definitions for operations related to actions
47 #define DO_ACTION "DoAction"
48 #define GET_ACTIONSET "GetActionSet"
49 #define ACTIONSET "ActionSet"
50 #define CANCEL_ACTIONSET "CancelAction"
51 #define DELETE_ACTIONSET "DelActionSet"
53 #define DEFAULT_CONTEXT_VALUE 0x99
55 #define VARIFY_POINTER_NULL(pointer, result, toExit) \
58 result = OC_STACK_NO_MEMORY;\
61 #define VARIFY_PARAM_NULL(pointer, result, toExit) \
64 result = OC_STACK_INVALID_PARAM;\
68 #define OCFREE(pointer) \
80 NONE = 0, SCHEDULED, RECURSIVE
83 typedef struct scheduledresourceinfo
86 OCActionSet *actionset;
90 OCServerRequest *ehRequest;
93 struct scheduledresourceinfo* next;
94 } ScheduledResourceInfo;
96 ScheduledResourceInfo *scheduleResourceList = NULL;
98 void AddScheduledResource(ScheduledResourceInfo **head,
99 ScheduledResourceInfo* add)
101 OC_LOG(INFO, TAG, "AddScheduledResource Entering...");
104 pthread_mutex_lock(&lock);
106 ScheduledResourceInfo *tmp = NULL;
123 pthread_mutex_unlock(&lock);
127 ScheduledResourceInfo* GetScheduledResource(ScheduledResourceInfo *head)
129 OC_LOG(INFO, TAG, "GetScheduledResource Entering...");
132 pthread_mutex_lock(&lock);
137 ScheduledResourceInfo *tmp = NULL;
152 diffTm = timespec_diff(tmp->time, t_now);
154 diffTm = timespec_diff(tmp->time, t_now);
157 if (diffTm <= (time_t) 0)
159 OC_LOG(INFO, TAG, "return Call INFO.");
169 pthread_mutex_unlock(&lock);
173 OC_LOG(INFO, TAG, "Cannot Find Call Info.");
178 ScheduledResourceInfo* GetScheduledResourceByActionSetName(ScheduledResourceInfo *head, char *setName)
180 OC_LOG(INFO, TAG, "GetScheduledResourceByActionSetName Entering...");
183 pthread_mutex_lock(&lock);
185 ScheduledResourceInfo *tmp = NULL;
192 if (strcmp(tmp->actionset->actionsetName, setName) == 0)
194 OC_LOG(INFO, TAG, "return Call INFO.");
203 pthread_mutex_unlock(&lock);
207 OC_LOG(INFO, TAG, "Cannot Find Call Info.");
212 void RemoveScheduledResource(ScheduledResourceInfo **head,
213 ScheduledResourceInfo* del)
216 pthread_mutex_lock(&lock);
218 OC_LOG(INFO, TAG, "RemoveScheduledResource Entering...");
219 ScheduledResourceInfo *tmp = NULL;
228 *head = (*head)->next;
233 while (tmp->next && (tmp->next != del))
239 tmp->next = del->next;
245 pthread_mutex_unlock(&lock);
249 typedef struct aggregatehandleinfo
251 OCServerRequest *ehRequest;
253 OCResource *collResource;
255 struct aggregatehandleinfo *next;
258 ClientRequestInfo *clientRequstList = NULL;
260 void AddClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* add)
262 ClientRequestInfo *tmp = NULL;
280 ClientRequestInfo* GetClientRequestInfo(ClientRequestInfo *head,
283 ClientRequestInfo *tmp = NULL;
291 if (tmp->required == handle)
304 void RemoveClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* del)
306 ClientRequestInfo *tmp = NULL;
313 *head = (*head)->next;
318 while (tmp->next && (tmp->next != del))
324 tmp->next = del->next;
329 void AddCapability(OCCapability** head, OCCapability* node)
331 OCCapability *pointer = *head;
338 while (pointer->next != NULL)
340 pointer = pointer->next;
343 pointer->next = node;
347 void AddAction(OCAction** head, OCAction* node)
349 OCAction *pointer = *head;
357 while (pointer->next != NULL)
359 pointer = pointer->next;
362 pointer->next = node;
366 OCStackResult AddActionSet(OCActionSet **head, OCActionSet* node)
368 OCActionSet *pointer = *head;
369 OCActionSet *prev = NULL;
372 return OC_STACK_ERROR;
381 while (pointer != NULL)
383 // check the uniqeness of actionsetname.
384 if (strcmp(pointer->actionsetName, node->actionsetName) == 0)
386 return OC_STACK_ERROR;
390 pointer = pointer->next;
399 void DeleteCapability(OCCapability *del)
401 OCFREE(del->capability)
402 del->capability = NULL;
408 void DeleteAction(OCAction** action)
410 OCCapability* pointer = (*action)->head;
411 OCCapability* pDel = NULL;
416 pointer = pointer->next;
418 DeleteCapability(pDel);
420 OCFREE((*action)->resourceUri)
421 (*action)->next = NULL;
425 void DeleteActionSet(OCActionSet** actionset)
427 if(*actionset == NULL)
430 OCAction* pointer = (*actionset)->head;
431 OCAction* pDel = NULL;
436 pointer = pointer->next;
440 // (*actionset)->head = NULL;
441 OCFREE((*actionset)->actionsetName)
445 OCStackResult FindAndDeleteActionSet(OCResource **resource,
446 const char * actionsetName)
448 if (*resource != NULL)
450 OCActionSet *pointer = NULL;
451 OCActionSet *pDel = NULL;
453 pointer = (*resource)->actionsetHead;
457 return OC_STACK_ERROR;
461 if (strcmp(pointer->actionsetName, actionsetName) == 0)
463 if (pointer->next != NULL)
464 (*resource)->actionsetHead = pointer->next;
466 (*resource)->actionsetHead = NULL;
468 DeleteActionSet(&pointer);
470 else if (pointer->next != NULL)
474 if (pointer->next != NULL)
476 if (strcmp(pointer->next->actionsetName, actionsetName)
479 pDel = pointer->next;
480 pointer->next = pointer->next->next;
482 DeleteActionSet(&pDel);
485 pointer = pointer->next;
493 return OC_STACK_ERROR;
496 OCStackResult DeleteActionSets(OCResource** resource)
498 OCActionSet *pointer = (*resource)->actionsetHead;
499 OCActionSet *pDel = pointer;
504 pointer = pointer->next;
506 DeleteActionSet(&pDel);
510 (*resource)->actionsetHead = NULL;
514 OCStackResult GetActionSet(const char *actionName, OCActionSet *head,
515 OCActionSet** actionset)
517 OCActionSet *pointer = head;
521 if (strcmp(pointer->actionsetName, actionName) == 0)
523 *actionset = pointer;
527 pointer = pointer->next;
530 return OC_STACK_ERROR;
534 OCStackResult ExtractKeyValueFromRequest(OCEntityHandlerRequest *ehRequest,
535 char **key, char **value)
537 OCStackResult result = OC_STACK_OK;
541 if( NULL == ehRequest->payload )
543 result = OC_STACK_ERROR;
549 input = (OCRepPayload*)(ehRequest->payload);
551 if(OCRepPayloadGetPropString(input, ACTIONSET, &actionSetStr))
553 *key = OICStrdup(ACTIONSET);
554 VARIFY_POINTER_NULL(*key, result, exit);
556 *value = OICStrdup(actionSetStr);
557 VARIFY_POINTER_NULL(*value, result, exit);
559 else if(OCRepPayloadGetPropString(input, DO_ACTION, &actionSetStr))
561 *key = OICStrdup(DO_ACTION);
562 VARIFY_POINTER_NULL(*key, result, exit);
564 *value = OICStrdup(actionSetStr);
565 VARIFY_POINTER_NULL(*value, result, exit);
567 else if(OCRepPayloadGetPropString(input, GET_ACTIONSET, &actionSetStr))
569 *key = OICStrdup(GET_ACTIONSET);
570 VARIFY_POINTER_NULL(*key, result, exit);
572 *value = OICStrdup(actionSetStr);
573 VARIFY_POINTER_NULL(*value, result, exit);
575 else if(OCRepPayloadGetPropString(input, DELETE_ACTIONSET, &actionSetStr))
577 *key = OICStrdup(DELETE_ACTIONSET);
578 VARIFY_POINTER_NULL(*key, result, exit);
580 *value = OICStrdup(actionSetStr);
581 VARIFY_POINTER_NULL(*value, result, exit);
583 else if(OCRepPayloadGetPropString(input, CANCEL_ACTIONSET, &actionSetStr))
585 *key = OICStrdup(CANCEL_ACTIONSET);
586 VARIFY_POINTER_NULL(*key, result, exit);
588 *value = OICStrdup(actionSetStr);
589 VARIFY_POINTER_NULL(*value, result, exit);
593 result = OC_STACK_ERROR;
597 if (result != OC_STACK_OK)
606 OCStackResult ExtractActionSetNameAndDelaytime(char *pChar, char **setName,
609 char *token, *tokenPtr;
610 OCStackResult result = OC_STACK_OK;
612 token = (char*) strtok_r(pChar, ACTION_DELIMITER, &tokenPtr);
613 *setName = (char *) OICMalloc(strlen(token) + 1);
614 VARIFY_POINTER_NULL(*setName, result, exit)
615 VARIFY_PARAM_NULL(token, result, exit)
616 strncpy(*setName, token, strlen(token) + 1);
618 token = strtok_r(NULL, ACTION_DELIMITER, &tokenPtr);
619 VARIFY_POINTER_NULL(pa, result, exit)
620 VARIFY_PARAM_NULL(token, result, exit)
630 OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc)
632 OCStackResult result = OC_STACK_OK;
634 char *iterToken = NULL, *iterTokenPtr = NULL;
635 char *descIterToken = NULL, *descIterTokenPtr = NULL;
636 char *attrIterToken = NULL, *attrIterTokenPtr = NULL;
637 char *desc = NULL, *attr = NULL;
638 char *key = NULL, *value = NULL;
640 OCAction *action = NULL;
641 OCCapability *capa = NULL;
643 OC_LOG(INFO, TAG, "Build ActionSet Instance.");
645 *set = (OCActionSet*) OICMalloc(sizeof(OCActionSet));
646 VARIFY_POINTER_NULL(*set, result, exit)
648 iterToken = (char *) strtok_r(actiondesc, ACTION_DELIMITER, &iterTokenPtr);
651 memset(*set, 0, sizeof(OCActionSet));
652 (*set)->actionsetName = (char *) OICMalloc(strlen(iterToken) + 1);
653 VARIFY_POINTER_NULL((*set)->actionsetName, result, exit)
654 VARIFY_PARAM_NULL(iterToken, result, exit)
655 strncpy((*set)->actionsetName, iterToken, strlen(iterToken) + 1);
657 // Time info. for Scheduled/Recursive Group action.
658 // d is meant Day of the week.
659 // T is meant ActionType.
660 // yyyy-mm-dd hh:mm:ss d
661 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
662 VARIFY_PARAM_NULL(iterToken, result, exit)
664 sscanf(iterToken, "%ld %u", &(*set)->timesteps, &(*set)->type);
667 OC_LOG_V(INFO, TAG, "ActionSet Name : %s", (*set)->actionsetName);
669 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
672 desc = (char *) OICMalloc(strlen(iterToken) + 1);
673 VARIFY_POINTER_NULL(desc, result, exit)
674 VARIFY_PARAM_NULL(desc, result, exit)
675 strncpy(desc, iterToken, strlen(iterToken) + 1);
676 descIterToken = (char *) strtok_r(desc, ATTR_DELIMITER,
678 while (descIterToken)
680 attr = (char *) OICMalloc(strlen(descIterToken) + 1);
681 VARIFY_POINTER_NULL(attr, result, exit)
682 VARIFY_PARAM_NULL(descIterToken, result, exit)
683 strncpy(attr, descIterToken, strlen(descIterToken) + 1);
685 attrIterToken = (char *) strtok_r(attr, ATTR_ASSIGN,
687 key = (char *) OICMalloc(strlen(attrIterToken) + 1);
688 VARIFY_POINTER_NULL(key, result, exit)
689 VARIFY_PARAM_NULL(attrIterToken, result, exit)
690 strncpy(key, attrIterToken, strlen(attrIterToken) + 1);
692 attrIterToken = (char *) strtok_r(NULL, ATTR_ASSIGN,
694 value = (char *) OICMalloc(strlen(attrIterToken) + 1);
695 VARIFY_POINTER_NULL(value, result, exit)
696 VARIFY_PARAM_NULL(attrIterToken, result, exit)
697 strncpy(value, attrIterToken, strlen(attrIterToken) + 1);
699 if (strcmp(key, "uri") == 0)
701 OC_LOG(INFO, TAG, "Build OCAction Instance.");
705 OICFree(action->resourceUri);
708 action = (OCAction*) OICMalloc(sizeof(OCAction));
709 VARIFY_POINTER_NULL(action, result, exit)
710 memset(action, 0, sizeof(OCAction));
711 action->resourceUri = (char *) OICMalloc(strlen(value) + 1);
712 VARIFY_POINTER_NULL(action->resourceUri, result, exit)
713 VARIFY_PARAM_NULL(value, result, exit)
714 strncpy(action->resourceUri, value, strlen(value) + 1);
718 if ((key != NULL) && (value != NULL))
720 OC_LOG(INFO, TAG, "Build OCCapability Instance.");
722 capa = (OCCapability*) OICMalloc(sizeof(OCCapability));
723 VARIFY_POINTER_NULL(capa, result, exit)
724 memset(capa, 0, sizeof(OCCapability));
726 capa->capability = (char *) OICMalloc(strlen(key) + 1);
727 VARIFY_POINTER_NULL(capa->capability, result, exit)
728 VARIFY_PARAM_NULL(key, result, exit)
729 strncpy(capa->capability, key, strlen(key) + 1);
731 capa->status = (char *) OICMalloc(strlen(value) + 1);
732 VARIFY_POINTER_NULL(capa->status, result, exit)
733 VARIFY_PARAM_NULL(value, result, exit)
734 strncpy(capa->status, value, strlen(value) + 1);
736 VARIFY_POINTER_NULL(action, result, exit)
738 AddCapability(&action->head, capa);
746 descIterToken = (char *) strtok_r(NULL, ATTR_DELIMITER,
750 AddAction(&(*set)->head, action);
751 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
769 OCStackResult BuildStringFromActionSet(OCActionSet* actionset, char** desc)
771 // Can't use the macros here as they are hardcoded to 'exit' and will
772 // result in dereferencing a null pointer.
773 if (!actionset || !desc)
775 return OC_STACK_INVALID_PARAM;
777 char temp[1024] = { 0 };
778 size_t remaining = sizeof(temp) - 1;
779 OCStackResult res = OC_STACK_ERROR;
781 OCAction *action = actionset->head;
783 if (remaining >= strlen(actionset->actionsetName) + 1)
785 strcat(temp, actionset->actionsetName);
786 remaining -= strlen(actionset->actionsetName);
787 strcat(temp, ACTION_DELIMITER);
792 res = OC_STACK_ERROR;
796 while (action != NULL)
798 if (remaining < (strlen("uri=") + strlen(action->resourceUri) + 1))
800 res = OC_STACK_ERROR;
803 strcat(temp, "uri=");
804 remaining -= strlen("uri=");
805 strcat(temp, action->resourceUri);
806 remaining -= strlen(action->resourceUri);
810 OCCapability *capas = action->head;
811 while (capas != NULL)
813 if (remaining < (strlen(capas->capability)
814 + 1 + strlen(capas->status)))
816 res = OC_STACK_ERROR;
820 strcat(temp, capas->capability);
821 remaining -= strlen(capas->capability);
824 strcat(temp, capas->status);
825 remaining -= strlen(capas->status);
832 res = OC_STACK_ERROR;
839 action = action->next;
842 if (remaining < strlen(ACTION_DELIMITER))
844 res = OC_STACK_ERROR;
847 strcat(temp, ACTION_DELIMITER);
852 *desc = OICStrdup(temp);
853 VARIFY_POINTER_NULL(*desc, res, exit);
862 OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
863 OCClientResponse* clientResponse)
866 (void)clientResponse;
867 OC_LOG(INFO, TAG, "Entering ActionSetCB");
869 ClientRequestInfo *info = GetClientRequestInfo(clientRequstList, handle);
873 OCEntityHandlerResponse response = { 0 };
875 response.ehResult = OC_EH_OK;
877 if(NULL == clientResponse->payload)
879 OC_LOG(ERROR, TAG, "Error sending response");
880 return OC_STACK_DELETE_TRANSACTION;
883 // Format the response. Note this requires some info about the request
884 response.requestHandle = info->ehRequest;
885 response.resourceHandle = info->collResource;
886 response.payload = clientResponse->payload;
887 response.numSendVendorSpecificHeaderOptions = 0;
888 memset(response.sendVendorSpecificHeaderOptions, 0,
889 sizeof response.sendVendorSpecificHeaderOptions);
890 memset(response.resourceUri, 0, sizeof response.resourceUri);
891 // Indicate that response is NOT in a persistent buffer
892 response.persistentBufferFlag = 0;
895 if (OCDoResponse(&response) != OC_STACK_OK)
897 OC_LOG(ERROR, TAG, "Error sending response");
898 return OC_STACK_DELETE_TRANSACTION;
901 RemoveClientRequestInfo(&clientRequstList, info);
905 return OC_STACK_KEEP_TRANSACTION;
908 void ActionSetCD(void *context)
913 OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr,
916 OCStackResult ret = OC_STACK_ERROR;
923 OC_LOG(INFO, TAG, "Entering BuildActionJSON");
924 json = cJSON_CreateObject();
926 cJSON_AddItemToObject(json, "rep", body = cJSON_CreateObject());
928 OCCapability* pointerCapa = action->head;
931 cJSON_AddStringToObject(body, pointerCapa->capability,
932 pointerCapa->status);
933 pointerCapa = pointerCapa->next;
936 jsonStr = cJSON_PrintUnformatted(json);
938 jsonLen = strlen(jsonStr);
939 if (jsonLen < *remaining)
941 strcat((char*) bufferPtr, jsonStr);
942 *remaining -= jsonLen;
943 bufferPtr += jsonLen;
953 OCPayload* BuildActionCBOR(OCAction* action)
955 OCRepPayload* payload = OCRepPayloadCreate();
959 OC_LOG(INFO, TAG, "Failed to create put payload object");
963 OCCapability* pointerCapa = action->head;
966 OCRepPayloadSetPropString(payload, pointerCapa->capability, pointerCapa->status);
967 pointerCapa = pointerCapa->next;
970 return (OCPayload*) payload;
973 unsigned int GetNumOfTargetResource(OCAction *actionset)
975 int numOfResource = 0;
977 OCAction *pointerAction = actionset;
979 while (pointerAction != NULL)
982 pointerAction = pointerAction->next;
985 return numOfResource;
988 OCStackResult SendAction(OCDoHandle *handle, OCServerRequest* requestHandle, const char *targetUri,
992 OCCallbackData cbData;
993 cbData.cb = &ActionSetCB;
994 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
997 return OCDoResource(handle, OC_REST_PUT, targetUri, &requestHandle->devAddr,
998 payload, CT_ADAPTER_IP, OC_NA_QOS, &cbData, NULL, 0);
1001 OCStackResult DoAction(OCResource* resource, OCActionSet* actionset,
1002 OCServerRequest* requestHandle)
1004 OCStackResult result = OC_STACK_ERROR;
1006 if( NULL == actionset->head)
1011 OCAction *pointerAction = actionset->head;
1013 while (pointerAction != NULL)
1016 payload = BuildActionCBOR(pointerAction);
1023 ClientRequestInfo *info = (ClientRequestInfo *) OICMalloc(
1024 sizeof(ClientRequestInfo));
1027 return OC_STACK_NO_MEMORY;
1029 memset(info, 0, sizeof(ClientRequestInfo));
1031 info->collResource = resource;
1032 info->ehRequest = requestHandle;
1034 result = SendAction(&info->required, info->ehRequest, pointerAction->resourceUri,
1037 if (result != OC_STACK_OK)
1043 AddClientRequestInfo(&clientRequstList, info);
1045 pointerAction = pointerAction->next;
1051 void DoScheduledGroupAction()
1053 OC_LOG(INFO, TAG, "DoScheduledGroupAction Entering...");
1054 ScheduledResourceInfo* info = GetScheduledResource(scheduleResourceList);
1058 OC_LOG(INFO, TAG, "Target resource is NULL");
1061 else if (info->resource == NULL)
1063 OC_LOG(INFO, TAG, "Target resource is NULL");
1066 else if (info->actionset == NULL)
1068 OC_LOG(INFO, TAG, "Target ActionSet is NULL");
1071 else if (info->ehRequest == NULL)
1073 OC_LOG(INFO, TAG, "Target ActionSet is NULL");
1076 #ifndef WITH_ARDUINO
1077 pthread_mutex_lock(&lock);
1079 DoAction(info->resource, info->actionset, info->ehRequest);
1080 #ifndef WITH_ARDUINO
1081 pthread_mutex_unlock(&lock);
1084 if (info->actionset->type == RECURSIVE)
1086 ScheduledResourceInfo *schedule;
1087 schedule = (ScheduledResourceInfo *) OICMalloc(
1088 sizeof(ScheduledResourceInfo));
1092 OC_LOG(INFO, TAG, "Building New Call Info.");
1093 memset(schedule, 0, sizeof(ScheduledResourceInfo));
1095 if (info->actionset->timesteps > 0)
1097 #ifndef WITH_ARDUINO
1098 pthread_mutex_lock(&lock);
1100 schedule->resource = info->resource;
1101 schedule->actionset = info->actionset;
1102 schedule->ehRequest = info->ehRequest;
1104 schedule->time = registerTimer(info->actionset->timesteps,
1105 &schedule->timer_id,
1106 &DoScheduledGroupAction);
1108 OC_LOG(INFO, TAG, "Reregisteration.");
1109 #ifndef WITH_ARDUINO
1110 pthread_mutex_unlock(&lock);
1112 AddScheduledResource(&scheduleResourceList, schedule);
1121 RemoveScheduledResource(&scheduleResourceList, info);
1128 OCStackResult BuildCollectionGroupActionCBORResponse(
1129 OCMethod method/*OCEntityHandlerFlag flag*/, OCResource *resource,
1130 OCEntityHandlerRequest *ehRequest)
1132 OCStackResult stackRet = OC_STACK_ERROR;
1134 OC_LOG(INFO, TAG, "Group Action is requested.");
1136 char *doWhat = NULL;
1137 char *details = NULL;
1139 stackRet = ExtractKeyValueFromRequest(ehRequest, &doWhat, &details);
1141 if(stackRet != OC_STACK_OK)
1143 OC_LOG_V(ERROR, TAG, "ExtractKeyValueFromRequest failed: %d", stackRet);
1147 stackRet = OC_STACK_ERROR;
1149 if (method == OC_REST_PUT)
1151 OC_LOG(INFO, TAG, "Group Action[PUT].");
1153 if (strcmp(doWhat, ACTIONSET) == 0)
1155 OCActionSet *actionSet = NULL;
1156 stackRet = BuildActionSetFromString(&actionSet, details);
1158 if(stackRet == OC_STACK_OK)
1160 if (actionSet != NULL)
1162 stackRet = AddActionSet(&resource->actionsetHead,
1164 if (stackRet == OC_STACK_ERROR)
1166 if(actionSet != NULL)
1168 DeleteActionSet( &actionSet );
1170 OC_LOG(INFO, TAG, "Duplicated ActionSet ");
1175 stackRet = OC_STACK_ERROR;
1181 stackRet = OC_STACK_ERROR;
1185 else if (strcmp(doWhat, DELETE_ACTIONSET) == 0)
1187 if (FindAndDeleteActionSet(&resource, details) == OC_STACK_OK)
1189 stackRet = OC_STACK_OK;
1193 stackRet = OC_STACK_ERROR;
1197 OCRepPayload* payload = OCRepPayloadCreate();
1201 OC_LOG(ERROR, TAG, "Failed to allocate Payload");
1202 stackRet = OC_STACK_ERROR;
1206 OCEntityHandlerResponse response = { 0 };
1208 if(stackRet == OC_STACK_OK)
1209 response.ehResult = OC_EH_OK;
1211 response.ehResult = OC_EH_ERROR;
1213 // Format the response. Note this requires some info about the request
1214 response.requestHandle = ehRequest->requestHandle;
1215 response.resourceHandle = ehRequest->resource;
1216 response.payload = (OCPayload*) payload;
1217 response.numSendVendorSpecificHeaderOptions = 0;
1218 memset(response.sendVendorSpecificHeaderOptions, 0,
1219 sizeof response.sendVendorSpecificHeaderOptions);
1220 memset(response.resourceUri, 0, sizeof response. resourceUri);
1221 // Indicate that response is NOT in a persistent buffer
1222 response.persistentBufferFlag = 0;
1223 response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR;
1225 // Send the response
1226 if (OCDoResponse(&response) != OC_STACK_OK)
1228 OC_LOG(ERROR, TAG, "Error sending response");
1229 stackRet = OC_STACK_ERROR;
1233 else if (method == OC_REST_POST)
1235 OCActionSet *actionset = NULL;
1237 OCRepPayload* payload = OCRepPayloadCreate();
1238 OCRepPayloadSetUri(payload, resource->uri);
1240 if ((strcmp(doWhat, DO_ACTION) == 0)
1241 || (strcmp(doWhat, "DoScheduledAction") == 0))
1243 char *pActionsetName = NULL;
1244 long int delay = -1;
1246 if (strcmp(doWhat, "DoScheduledAction") == 0)
1248 stackRet = ExtractActionSetNameAndDelaytime(details,
1249 &pActionsetName, &delay);
1252 details = pActionsetName;
1256 stackRet = OC_STACK_OK;
1259 if (stackRet == OC_STACK_OK)
1261 if (GetActionSet(details, resource->actionsetHead,
1262 &actionset) != OC_STACK_OK)
1264 OC_LOG(INFO, TAG, "ERROR");
1265 stackRet = OC_STACK_ERROR;
1268 if (actionset == NULL)
1270 OC_LOG(INFO, TAG, "Cannot Find ActionSet");
1271 stackRet = OC_STACK_ERROR;
1275 OC_LOG(INFO, TAG, "Group Action[POST].");
1276 if (actionset->type == NONE)
1278 OC_LOG_V(INFO, TAG, "Execute ActionSet : %s",
1279 actionset->actionsetName);
1280 unsigned int num = GetNumOfTargetResource(
1283 ((OCServerRequest *) ehRequest->requestHandle)->ehResponseHandler =
1284 HandleAggregateResponse;
1285 ((OCServerRequest *) ehRequest->requestHandle)->numResponses =
1288 DoAction(resource, actionset,
1289 (OCServerRequest*) ehRequest->requestHandle);
1290 stackRet = OC_STACK_OK;
1294 OC_LOG_V(INFO, TAG, "Execute Scheduled ActionSet : %s",
1295 actionset->actionsetName);
1298 (delay == -1 ? actionset->timesteps : delay);
1300 ScheduledResourceInfo *schedule;
1301 schedule = (ScheduledResourceInfo *) OICMalloc(
1302 sizeof(ScheduledResourceInfo));
1306 OC_LOG(INFO, TAG, "Building New Call Info.");
1308 sizeof(ScheduledResourceInfo));
1310 schedule->resource = resource;
1311 schedule->actionset = actionset;
1312 schedule->ehRequest =
1313 (OCServerRequest*) ehRequest->requestHandle;
1317 OC_LOG_V(INFO, TAG, "delay_time is %lf seconds.",
1318 actionset->timesteps);
1320 schedule->time = registerTimer(delay,
1321 &schedule->timer_id,
1322 &DoScheduledGroupAction);
1324 AddScheduledResource(&scheduleResourceList,
1326 stackRet = OC_STACK_OK;
1330 stackRet = OC_STACK_ERROR;
1337 else if (strcmp(doWhat, "CancelAction") == 0)
1339 ScheduledResourceInfo *info =
1340 GetScheduledResourceByActionSetName(scheduleResourceList, details);
1344 unregisterTimer(info->timer_id);
1346 RemoveScheduledResource(&scheduleResourceList, info);
1347 stackRet = OC_STACK_OK;
1351 stackRet = OC_STACK_ERROR;
1355 else if (strcmp(doWhat, GET_ACTIONSET) == 0)
1357 char *plainText = NULL;
1358 OCActionSet *actionset = NULL;
1360 GetActionSet(details, resource->actionsetHead, &actionset);
1361 if (actionset != NULL)
1363 BuildStringFromActionSet(actionset, &plainText);
1365 if (plainText != NULL)
1367 OCRepPayloadSetPropString(payload, ACTIONSET, plainText);
1370 stackRet = OC_STACK_OK;
1376 OC_LOG(ERROR, TAG, "Failed to allocate Payload");
1377 stackRet = OC_STACK_ERROR;
1381 OCEntityHandlerResponse response = { 0 };
1382 if(stackRet == OC_STACK_OK)
1383 response.ehResult = OC_EH_OK;
1385 response.ehResult = OC_EH_ERROR;
1387 // Format the response. Note this requires some info about the request
1388 response.requestHandle = ehRequest->requestHandle;
1389 response.resourceHandle = ehRequest->resource;
1390 response.payload = (OCPayload*) payload;
1391 response.numSendVendorSpecificHeaderOptions = 0;
1392 memset(response.sendVendorSpecificHeaderOptions, 0,
1393 sizeof response.sendVendorSpecificHeaderOptions);
1394 memset(response.resourceUri, 0, sizeof response.resourceUri);
1395 // Indicate that response is NOT in a persistent buffer
1396 response.persistentBufferFlag = 0;
1397 response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR;
1399 // Send the response
1400 if (OCDoResponse(&response) != OC_STACK_OK)
1402 OC_LOG(ERROR, TAG, "Error sending response");
1403 stackRet = OC_STACK_ERROR;