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 "OIC_RI_GROUP"
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 OIC_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 OIC_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 OIC_LOG(INFO, TAG, "return Call INFO.");
169 pthread_mutex_unlock(&lock);
173 OIC_LOG(INFO, TAG, "Cannot Find Call Info.");
178 ScheduledResourceInfo* GetScheduledResourceByActionSetName(ScheduledResourceInfo *head, char *setName)
180 OIC_LOG(INFO, TAG, "GetScheduledResourceByActionSetName Entering...");
183 pthread_mutex_lock(&lock);
185 ScheduledResourceInfo *tmp = NULL;
192 if (strcmp(tmp->actionset->actionsetName, setName) == 0)
194 OIC_LOG(INFO, TAG, "return Call INFO.");
203 pthread_mutex_unlock(&lock);
207 OIC_LOG(INFO, TAG, "Cannot Find Call Info.");
212 void RemoveScheduledResource(ScheduledResourceInfo **head,
213 ScheduledResourceInfo* del)
216 pthread_mutex_lock(&lock);
218 OIC_LOG(INFO, TAG, "RemoveScheduledResource Entering...");
219 ScheduledResourceInfo *tmp = NULL;
224 pthread_mutex_unlock(&lock);
231 *head = (*head)->next;
236 while (tmp->next && (tmp->next != del))
242 tmp->next = del->next;
248 pthread_mutex_unlock(&lock);
252 typedef struct aggregatehandleinfo
254 OCServerRequest *ehRequest;
256 OCResource *collResource;
258 struct aggregatehandleinfo *next;
261 ClientRequestInfo *clientRequstList = NULL;
263 void AddClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* add)
265 ClientRequestInfo *tmp = NULL;
283 ClientRequestInfo* GetClientRequestInfo(ClientRequestInfo *head,
286 ClientRequestInfo *tmp = NULL;
294 if (tmp->required == handle)
307 void RemoveClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* del)
309 ClientRequestInfo *tmp = NULL;
316 *head = (*head)->next;
321 while (tmp->next && (tmp->next != del))
327 tmp->next = del->next;
332 void AddCapability(OCCapability** head, OCCapability* node)
334 OCCapability *pointer = *head;
341 while (pointer->next != NULL)
343 pointer = pointer->next;
346 pointer->next = node;
350 void AddAction(OCAction** head, OCAction* node)
352 OCAction *pointer = *head;
360 while (pointer->next != NULL)
362 pointer = pointer->next;
365 pointer->next = node;
369 OCStackResult AddActionSet(OCActionSet **head, OCActionSet* node)
371 OCActionSet *pointer = *head;
372 OCActionSet *prev = NULL;
375 return OC_STACK_ERROR;
384 while (pointer != NULL)
386 // check the uniqeness of actionsetname.
387 if (strcmp(pointer->actionsetName, node->actionsetName) == 0)
389 return OC_STACK_ERROR;
393 pointer = pointer->next;
402 void DeleteCapability(OCCapability *del)
404 OCFREE(del->capability)
405 del->capability = NULL;
411 void DeleteAction(OCAction** action)
413 OCCapability* pointer = (*action)->head;
414 OCCapability* pDel = NULL;
419 pointer = pointer->next;
421 DeleteCapability(pDel);
423 OCFREE((*action)->resourceUri)
424 (*action)->next = NULL;
428 void DeleteActionSet(OCActionSet** actionset)
430 if(*actionset == NULL)
433 OCAction* pointer = (*actionset)->head;
434 OCAction* pDel = NULL;
439 pointer = pointer->next;
443 // (*actionset)->head = NULL;
444 OCFREE((*actionset)->actionsetName)
448 OCStackResult FindAndDeleteActionSet(OCResource **resource,
449 const char * actionsetName)
451 if (*resource != NULL)
453 OCActionSet *pointer = NULL;
454 OCActionSet *pDel = NULL;
456 pointer = (*resource)->actionsetHead;
460 return OC_STACK_ERROR;
464 if (strcmp(pointer->actionsetName, actionsetName) == 0)
466 if (pointer->next != NULL)
467 (*resource)->actionsetHead = pointer->next;
469 (*resource)->actionsetHead = NULL;
471 DeleteActionSet(&pointer);
473 else if (pointer->next != NULL)
477 if (pointer->next != NULL)
479 if (strcmp(pointer->next->actionsetName, actionsetName)
482 pDel = pointer->next;
483 pointer->next = pointer->next->next;
485 DeleteActionSet(&pDel);
488 pointer = pointer->next;
496 return OC_STACK_ERROR;
499 OCStackResult GetActionSet(const char *actionName, OCActionSet *head,
500 OCActionSet** actionset)
502 OCActionSet *pointer = head;
506 if (strcmp(pointer->actionsetName, actionName) == 0)
508 *actionset = pointer;
512 pointer = pointer->next;
515 return OC_STACK_ERROR;
519 OCStackResult ExtractKeyValueFromRequest(OCEntityHandlerRequest *ehRequest,
520 char **key, char **value)
522 OCStackResult result = OC_STACK_OK;
524 char *actionSetStr = NULL;
526 if( NULL == ehRequest->payload )
528 result = OC_STACK_ERROR;
534 input = (OCRepPayload*)(ehRequest->payload);
536 if(OCRepPayloadGetPropString(input, ACTIONSET, &actionSetStr))
538 *key = OICStrdup(ACTIONSET);
539 VARIFY_POINTER_NULL(*key, result, exit);
541 *value = OICStrdup(actionSetStr);
542 VARIFY_POINTER_NULL(*value, result, exit);
544 else if(OCRepPayloadGetPropString(input, DO_ACTION, &actionSetStr))
546 *key = OICStrdup(DO_ACTION);
547 VARIFY_POINTER_NULL(*key, result, exit);
549 *value = OICStrdup(actionSetStr);
550 VARIFY_POINTER_NULL(*value, result, exit);
552 else if(OCRepPayloadGetPropString(input, GET_ACTIONSET, &actionSetStr))
554 *key = OICStrdup(GET_ACTIONSET);
555 VARIFY_POINTER_NULL(*key, result, exit);
557 *value = OICStrdup(actionSetStr);
558 VARIFY_POINTER_NULL(*value, result, exit);
560 else if(OCRepPayloadGetPropString(input, DELETE_ACTIONSET, &actionSetStr))
562 *key = OICStrdup(DELETE_ACTIONSET);
563 VARIFY_POINTER_NULL(*key, result, exit);
565 *value = OICStrdup(actionSetStr);
566 VARIFY_POINTER_NULL(*value, result, exit);
568 else if(OCRepPayloadGetPropString(input, CANCEL_ACTIONSET, &actionSetStr))
570 *key = OICStrdup(CANCEL_ACTIONSET);
571 VARIFY_POINTER_NULL(*key, result, exit);
573 *value = OICStrdup(actionSetStr);
574 VARIFY_POINTER_NULL(*value, result, exit);
578 result = OC_STACK_ERROR;
582 if (result != OC_STACK_OK)
588 OCFREE(actionSetStr);
593 OCStackResult ExtractActionSetNameAndDelaytime(char *pChar, char **setName,
596 char *token = NULL, *tokenPtr = NULL;
597 OCStackResult result = OC_STACK_OK;
599 token = (char*) strtok_r(pChar, ACTION_DELIMITER, &tokenPtr);
600 VARIFY_POINTER_NULL(token, result, exit)
602 *setName = (char *) OICMalloc(strlen(token) + 1);
603 VARIFY_POINTER_NULL(*setName, result, exit)
604 VARIFY_PARAM_NULL(token, result, exit)
605 strncpy(*setName, token, strlen(token) + 1);
607 token = strtok_r(NULL, ACTION_DELIMITER, &tokenPtr);
608 VARIFY_POINTER_NULL(pa, result, exit)
609 VARIFY_PARAM_NULL(token, result, exit)
619 OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc)
621 OCStackResult result = OC_STACK_OK;
623 char *iterToken = NULL, *iterTokenPtr = NULL;
624 char *descIterToken = NULL, *descIterTokenPtr = NULL;
625 char *attrIterToken = NULL, *attrIterTokenPtr = NULL;
626 char *desc = NULL, *attr = NULL;
627 char *key = NULL, *value = NULL;
629 OCAction *action = NULL;
630 OCCapability *capa = NULL;
632 OIC_LOG(INFO, TAG, "Build ActionSet Instance.");
634 *set = (OCActionSet*) OICMalloc(sizeof(OCActionSet));
635 VARIFY_POINTER_NULL(*set, result, exit)
637 iterToken = (char *) strtok_r(actiondesc, ACTION_DELIMITER, &iterTokenPtr);
638 VARIFY_POINTER_NULL(iterToken, result, exit);
641 memset(*set, 0, sizeof(OCActionSet));
642 (*set)->actionsetName = (char *) OICMalloc(strlen(iterToken) + 1);
643 VARIFY_POINTER_NULL((*set)->actionsetName, result, exit)
644 VARIFY_PARAM_NULL(iterToken, result, exit)
645 strncpy((*set)->actionsetName, iterToken, strlen(iterToken) + 1);
647 // Time info. for Scheduled/Recursive Group action.
648 // d is meant Day of the week.
649 // T is meant ActionType.
650 // yyyy-mm-dd hh:mm:ss d
651 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
652 VARIFY_PARAM_NULL(iterToken, result, exit)
654 if( 2 != sscanf(iterToken, "%ld %u", &(*set)->timesteps, &(*set)->type) )
656 // If the return value should be 2, the number of items in the argument. Otherwise, it fails.
661 OIC_LOG_V(INFO, TAG, "ActionSet Name : %s", (*set)->actionsetName);
663 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
666 desc = (char *) OICMalloc(strlen(iterToken) + 1);
667 VARIFY_POINTER_NULL(desc, result, exit)
668 VARIFY_PARAM_NULL(desc, result, exit)
669 strncpy(desc, iterToken, strlen(iterToken) + 1);
670 descIterToken = (char *) strtok_r(desc, ATTR_DELIMITER,
672 while (descIterToken)
674 attr = (char *) OICMalloc(strlen(descIterToken) + 1);
675 VARIFY_POINTER_NULL(attr, result, exit)
676 VARIFY_PARAM_NULL(descIterToken, result, exit)
677 strncpy(attr, descIterToken, strlen(descIterToken) + 1);
679 attrIterToken = (char *) strtok_r(attr, ATTR_ASSIGN,
681 VARIFY_POINTER_NULL(attrIterToken, result, exit);
683 key = (char *) OICMalloc(strlen(attrIterToken) + 1);
684 VARIFY_POINTER_NULL(key, result, exit)
685 VARIFY_PARAM_NULL(attrIterToken, result, exit)
686 strncpy(key, attrIterToken, strlen(attrIterToken) + 1);
688 attrIterToken = (char *) strtok_r(NULL, ATTR_ASSIGN,
690 VARIFY_POINTER_NULL(attrIterToken, result, exit);
691 value = (char *) OICMalloc(strlen(attrIterToken) + 1);
692 VARIFY_POINTER_NULL(value, result, exit)
693 VARIFY_PARAM_NULL(attrIterToken, result, exit)
694 strncpy(value, attrIterToken, strlen(attrIterToken) + 1);
696 if (strcmp(key, "uri") == 0)
698 OIC_LOG(INFO, TAG, "Build OCAction Instance.");
700 action = (OCAction*) OICMalloc(sizeof(OCAction));
701 VARIFY_POINTER_NULL(action, result, exit)
702 memset(action, 0, sizeof(OCAction));
703 action->resourceUri = (char *) OICMalloc(strlen(value) + 1);
704 VARIFY_POINTER_NULL(action->resourceUri, result, exit)
705 VARIFY_PARAM_NULL(value, result, exit)
706 strncpy(action->resourceUri, value, strlen(value) + 1);
710 if ((key != NULL) && (value != NULL))
712 OIC_LOG(INFO, TAG, "Build OCCapability Instance.");
714 capa = (OCCapability*) OICMalloc(sizeof(OCCapability));
715 VARIFY_POINTER_NULL(capa, result, exit)
716 memset(capa, 0, sizeof(OCCapability));
718 capa->capability = (char *) OICMalloc(strlen(key) + 1);
719 VARIFY_POINTER_NULL(capa->capability, result, exit)
720 VARIFY_PARAM_NULL(key, result, exit)
721 strncpy(capa->capability, key, strlen(key) + 1);
723 capa->status = (char *) OICMalloc(strlen(value) + 1);
724 VARIFY_POINTER_NULL(capa->status, result, exit)
725 VARIFY_PARAM_NULL(value, result, exit)
726 strncpy(capa->status, value, strlen(value) + 1);
728 VARIFY_POINTER_NULL(action, result, exit)
730 AddCapability(&action->head, capa);
738 descIterToken = (char *) strtok_r(NULL, ATTR_DELIMITER,
742 AddAction(&(*set)->head, action);
743 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
761 OCStackResult BuildStringFromActionSet(OCActionSet* actionset, char** desc)
763 // Can't use the macros here as they are hardcoded to 'exit' and will
764 // result in dereferencing a null pointer.
765 if (!actionset || !desc)
767 return OC_STACK_INVALID_PARAM;
769 char temp[1024] = { 0 };
770 size_t remaining = sizeof(temp) - 1;
771 OCStackResult res = OC_STACK_ERROR;
772 char* actionTypeStr = NULL;
774 OCAction *action = actionset->head;
776 if (remaining >= strlen(actionset->actionsetName) + 1)
778 strncat(temp, actionset->actionsetName, strlen(actionset->actionsetName));
779 remaining -= strlen(actionset->actionsetName);
780 strncat(temp, ACTION_DELIMITER, strlen(ACTION_DELIMITER));
785 res = OC_STACK_ERROR;
789 actionTypeStr = (char *)malloc(1024);
790 if(actionTypeStr != NULL)
792 sprintf(actionTypeStr, "%ld %u", actionset->timesteps, actionset->type);
793 if(remaining >= strlen(actionTypeStr) + strlen(ACTION_DELIMITER) + 1)
795 strncat(temp, actionTypeStr, strlen(actionTypeStr));
796 remaining -= strlen(actionTypeStr);
797 strncat(temp, ACTION_DELIMITER, strlen(ACTION_DELIMITER));
798 remaining -= strlen(ACTION_DELIMITER);
804 res = OC_STACK_ERROR;
810 res = OC_STACK_ERROR;
814 while (action != NULL)
816 if (remaining < (strlen("uri=") + strlen(action->resourceUri) + 1))
818 res = OC_STACK_ERROR;
822 strcat(temp, "uri=");
823 remaining -= strlen("uri=");
824 strcat(temp, action->resourceUri);
825 remaining -= strlen(action->resourceUri);
829 OCCapability *capas = action->head;
830 while (capas != NULL)
832 if (remaining < (strlen(capas->capability)
833 + 1 + strlen(capas->status)))
835 res = OC_STACK_ERROR;
839 strcat(temp, capas->capability);
840 remaining -= strlen(capas->capability);
843 strcat(temp, capas->status);
844 remaining -= strlen(capas->status);
851 res = OC_STACK_ERROR;
859 action = action->next;
862 if (remaining < strlen(ACTION_DELIMITER))
864 res = OC_STACK_ERROR;
867 strcat(temp, ACTION_DELIMITER);
872 *desc = OICStrdup(temp);
873 VARIFY_POINTER_NULL(*desc, res, exit);
882 OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
883 OCClientResponse* clientResponse)
886 (void)clientResponse;
887 OIC_LOG(INFO, TAG, "Entering ActionSetCB");
889 ClientRequestInfo *info = GetClientRequestInfo(clientRequstList, handle);
893 OCEntityHandlerResponse response = { 0 };
895 response.ehResult = OC_EH_OK;
897 if(NULL == clientResponse->payload)
899 OIC_LOG(ERROR, TAG, "Error sending response");
900 return OC_STACK_DELETE_TRANSACTION;
903 // Format the response. Note this requires some info about the request
904 response.requestHandle = info->ehRequest;
905 response.resourceHandle = info->collResource;
906 response.payload = clientResponse->payload;
907 response.numSendVendorSpecificHeaderOptions = 0;
908 memset(response.sendVendorSpecificHeaderOptions, 0,
909 sizeof response.sendVendorSpecificHeaderOptions);
910 memset(response.resourceUri, 0, sizeof response.resourceUri);
911 // Indicate that response is NOT in a persistent buffer
912 response.persistentBufferFlag = 0;
915 if (OCDoResponse(&response) != OC_STACK_OK)
917 OIC_LOG(ERROR, TAG, "Error sending response");
918 return OC_STACK_DELETE_TRANSACTION;
921 RemoveClientRequestInfo(&clientRequstList, info);
925 return OC_STACK_KEEP_TRANSACTION;
928 void ActionSetCD(void *context)
933 OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr,
936 OCStackResult ret = OC_STACK_ERROR;
943 OIC_LOG(INFO, TAG, "Entering BuildActionJSON");
944 json = cJSON_CreateObject();
946 cJSON_AddItemToObject(json, "rep", body = cJSON_CreateObject());
948 OCCapability* pointerCapa = action->head;
951 cJSON_AddStringToObject(body, pointerCapa->capability,
952 pointerCapa->status);
953 pointerCapa = pointerCapa->next;
956 jsonStr = cJSON_PrintUnformatted(json);
958 jsonLen = strlen(jsonStr);
959 if (jsonLen < *remaining)
961 strncat((char*) bufferPtr, jsonStr, jsonLen);
962 *remaining -= jsonLen;
963 bufferPtr += jsonLen;
973 OCPayload* BuildActionCBOR(OCAction* action)
975 OCRepPayload* payload = OCRepPayloadCreate();
979 OIC_LOG(INFO, TAG, "Failed to create put payload object");
983 OCCapability* pointerCapa = action->head;
986 OCRepPayloadSetPropString(payload, pointerCapa->capability, pointerCapa->status);
987 pointerCapa = pointerCapa->next;
990 return (OCPayload*) payload;
993 unsigned int GetNumOfTargetResource(OCAction *actionset)
995 int numOfResource = 0;
997 OCAction *pointerAction = actionset;
999 while (pointerAction != NULL)
1002 pointerAction = pointerAction->next;
1005 return numOfResource;
1008 OCStackResult SendAction(OCDoHandle *handle, OCServerRequest* requestHandle, const char *targetUri,
1012 OCCallbackData cbData;
1013 cbData.cb = &ActionSetCB;
1014 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
1017 return OCDoResource(handle, OC_REST_PUT, targetUri, &requestHandle->devAddr,
1018 payload, CT_ADAPTER_IP, OC_NA_QOS, &cbData, NULL, 0);
1021 OCStackResult DoAction(OCResource* resource, OCActionSet* actionset,
1022 OCServerRequest* requestHandle)
1024 OCStackResult result = OC_STACK_ERROR;
1026 if( NULL == actionset->head)
1031 OCAction *pointerAction = actionset->head;
1033 while (pointerAction != NULL)
1036 payload = BuildActionCBOR(pointerAction);
1043 ClientRequestInfo *info = (ClientRequestInfo *) OICMalloc(
1044 sizeof(ClientRequestInfo));
1049 return OC_STACK_NO_MEMORY;
1052 memset(info, 0, sizeof(ClientRequestInfo));
1054 info->collResource = resource;
1055 info->ehRequest = requestHandle;
1057 result = SendAction(&info->required, info->ehRequest, pointerAction->resourceUri,
1060 if (result != OC_STACK_OK)
1066 AddClientRequestInfo(&clientRequstList, info);
1068 pointerAction = pointerAction->next;
1074 void DoScheduledGroupAction()
1076 OIC_LOG(INFO, TAG, "DoScheduledGroupAction Entering...");
1077 ScheduledResourceInfo* info = GetScheduledResource(scheduleResourceList);
1081 OIC_LOG(INFO, TAG, "Target resource is NULL");
1084 else if (info->resource == NULL)
1086 OIC_LOG(INFO, TAG, "Target resource is NULL");
1089 else if (info->actionset == NULL)
1091 OIC_LOG(INFO, TAG, "Target ActionSet is NULL");
1094 else if (info->ehRequest == NULL)
1096 OIC_LOG(INFO, TAG, "Target ActionSet is NULL");
1099 #ifndef WITH_ARDUINO
1100 pthread_mutex_lock(&lock);
1102 DoAction(info->resource, info->actionset, info->ehRequest);
1103 #ifndef WITH_ARDUINO
1104 pthread_mutex_unlock(&lock);
1107 if (info->actionset->type == RECURSIVE)
1109 ScheduledResourceInfo *schedule;
1110 schedule = (ScheduledResourceInfo *) OICMalloc(
1111 sizeof(ScheduledResourceInfo));
1115 OIC_LOG(INFO, TAG, "Building New Call Info.");
1116 memset(schedule, 0, sizeof(ScheduledResourceInfo));
1118 if (info->actionset->timesteps > 0)
1120 #ifndef WITH_ARDUINO
1121 pthread_mutex_lock(&lock);
1123 schedule->resource = info->resource;
1124 schedule->actionset = info->actionset;
1125 schedule->ehRequest = info->ehRequest;
1127 schedule->time = registerTimer(info->actionset->timesteps,
1128 &schedule->timer_id,
1129 &DoScheduledGroupAction);
1131 OIC_LOG(INFO, TAG, "Reregisteration.");
1132 #ifndef WITH_ARDUINO
1133 pthread_mutex_unlock(&lock);
1135 AddScheduledResource(&scheduleResourceList, schedule);
1144 RemoveScheduledResource(&scheduleResourceList, info);
1151 OCStackResult BuildCollectionGroupActionCBORResponse(
1152 OCMethod method/*OCEntityHandlerFlag flag*/, OCResource *resource,
1153 OCEntityHandlerRequest *ehRequest)
1155 OCStackResult stackRet = OC_STACK_ERROR;
1157 OIC_LOG(INFO, TAG, "Group Action is requested.");
1159 char *doWhat = NULL;
1160 char *details = NULL;
1162 stackRet = ExtractKeyValueFromRequest(ehRequest, &doWhat, &details);
1164 if(stackRet != OC_STACK_OK)
1166 OIC_LOG_V(ERROR, TAG, "ExtractKeyValueFromRequest failed: %d", stackRet);
1170 stackRet = OC_STACK_ERROR;
1172 if (method == OC_REST_PUT)
1174 OIC_LOG(INFO, TAG, "Group Action[PUT].");
1176 if (strcmp(doWhat, ACTIONSET) == 0)
1178 OCActionSet *actionSet = NULL;
1179 stackRet = BuildActionSetFromString(&actionSet, details);
1181 if(stackRet == OC_STACK_OK)
1183 if (actionSet != NULL)
1185 stackRet = AddActionSet(&resource->actionsetHead,
1187 if (stackRet == OC_STACK_ERROR)
1189 if(actionSet != NULL)
1191 DeleteActionSet( &actionSet );
1193 OIC_LOG(INFO, TAG, "Duplicated ActionSet ");
1198 stackRet = OC_STACK_ERROR;
1204 stackRet = OC_STACK_ERROR;
1208 else if (strcmp(doWhat, DELETE_ACTIONSET) == 0)
1210 if (FindAndDeleteActionSet(&resource, details) == OC_STACK_OK)
1212 stackRet = OC_STACK_OK;
1216 stackRet = OC_STACK_ERROR;
1220 OCRepPayload* payload = OCRepPayloadCreate();
1224 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
1225 stackRet = OC_STACK_ERROR;
1229 OCEntityHandlerResponse response = { 0 };
1231 if(stackRet == OC_STACK_OK)
1232 response.ehResult = OC_EH_OK;
1234 response.ehResult = OC_EH_ERROR;
1236 // Format the response. Note this requires some info about the request
1237 response.requestHandle = ehRequest->requestHandle;
1238 response.resourceHandle = ehRequest->resource;
1239 response.payload = (OCPayload*) payload;
1240 response.numSendVendorSpecificHeaderOptions = 0;
1241 memset(response.sendVendorSpecificHeaderOptions, 0,
1242 sizeof response.sendVendorSpecificHeaderOptions);
1243 memset(response.resourceUri, 0, sizeof response. resourceUri);
1244 // Indicate that response is NOT in a persistent buffer
1245 response.persistentBufferFlag = 0;
1246 response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR;
1248 // Send the response
1249 if (OCDoResponse(&response) != OC_STACK_OK)
1251 OIC_LOG(ERROR, TAG, "Error sending response");
1252 stackRet = OC_STACK_ERROR;
1256 else if (method == OC_REST_POST)
1258 OCActionSet *actionset = NULL;
1260 OCRepPayload* payload = OCRepPayloadCreate();
1261 OCRepPayloadSetUri(payload, resource->uri);
1263 if ((strcmp(doWhat, DO_ACTION) == 0)
1264 || (strcmp(doWhat, "DoScheduledAction") == 0))
1266 char *pActionsetName = NULL;
1267 long int delay = -1;
1269 if (strcmp(doWhat, "DoScheduledAction") == 0)
1271 stackRet = ExtractActionSetNameAndDelaytime(details,
1272 &pActionsetName, &delay);
1275 details = pActionsetName;
1279 stackRet = OC_STACK_OK;
1282 if (stackRet == OC_STACK_OK)
1284 if (GetActionSet(details, resource->actionsetHead,
1285 &actionset) != OC_STACK_OK)
1287 OIC_LOG(INFO, TAG, "ERROR");
1288 stackRet = OC_STACK_ERROR;
1291 if (actionset == NULL)
1293 OIC_LOG(INFO, TAG, "Cannot Find ActionSet");
1294 stackRet = OC_STACK_ERROR;
1298 OIC_LOG(INFO, TAG, "Group Action[POST].");
1299 if (actionset->type == NONE)
1301 OIC_LOG_V(INFO, TAG, "Execute ActionSet : %s",
1302 actionset->actionsetName);
1303 unsigned int num = GetNumOfTargetResource(
1306 ((OCServerRequest *) ehRequest->requestHandle)->ehResponseHandler =
1307 HandleAggregateResponse;
1308 ((OCServerRequest *) ehRequest->requestHandle)->numResponses =
1311 DoAction(resource, actionset,
1312 (OCServerRequest*) ehRequest->requestHandle);
1313 stackRet = OC_STACK_OK;
1317 OIC_LOG_V(INFO, TAG, "Execute Scheduled ActionSet : %s",
1318 actionset->actionsetName);
1321 (delay == -1 ? actionset->timesteps : delay);
1323 ScheduledResourceInfo *schedule;
1324 schedule = (ScheduledResourceInfo *) OICMalloc(
1325 sizeof(ScheduledResourceInfo));
1329 OIC_LOG(INFO, TAG, "Building New Call Info.");
1331 sizeof(ScheduledResourceInfo));
1332 #ifndef WITH_ARDUINO
1333 pthread_mutex_lock(&lock);
1335 schedule->resource = resource;
1336 schedule->actionset = actionset;
1337 schedule->ehRequest =
1338 (OCServerRequest*) ehRequest->requestHandle;
1339 #ifndef WITH_ARDUINO
1340 pthread_mutex_unlock(&lock);
1344 OIC_LOG_V(INFO, TAG, "delay_time is %ld seconds.",
1345 actionset->timesteps);
1346 #ifndef WITH_ARDUINO
1347 pthread_mutex_lock(&lock);
1349 schedule->time = registerTimer(delay,
1350 &schedule->timer_id,
1351 &DoScheduledGroupAction);
1352 #ifndef WITH_ARDUINO
1353 pthread_mutex_unlock(&lock);
1355 AddScheduledResource(&scheduleResourceList,
1357 stackRet = OC_STACK_OK;
1361 stackRet = OC_STACK_ERROR;
1368 else if (strcmp(doWhat, "CancelAction") == 0)
1370 ScheduledResourceInfo *info =
1371 GetScheduledResourceByActionSetName(scheduleResourceList, details);
1375 unregisterTimer(info->timer_id);
1377 RemoveScheduledResource(&scheduleResourceList, info);
1378 stackRet = OC_STACK_OK;
1382 stackRet = OC_STACK_ERROR;
1386 else if (strcmp(doWhat, GET_ACTIONSET) == 0)
1388 char *plainText = NULL;
1389 OCActionSet *actionset = NULL;
1391 GetActionSet(details, resource->actionsetHead, &actionset);
1392 if (actionset != NULL)
1394 BuildStringFromActionSet(actionset, &plainText);
1396 if (plainText != NULL)
1398 OCRepPayloadSetPropString(payload, ACTIONSET, plainText);
1401 stackRet = OC_STACK_OK;
1407 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
1408 stackRet = OC_STACK_ERROR;
1412 OCEntityHandlerResponse response = { 0 };
1413 if(stackRet == OC_STACK_OK)
1414 response.ehResult = OC_EH_OK;
1416 response.ehResult = OC_EH_ERROR;
1418 // Format the response. Note this requires some info about the request
1419 response.requestHandle = ehRequest->requestHandle;
1420 response.resourceHandle = ehRequest->resource;
1421 response.payload = (OCPayload*) payload;
1422 response.numSendVendorSpecificHeaderOptions = 0;
1423 memset(response.sendVendorSpecificHeaderOptions, 0,
1424 sizeof response.sendVendorSpecificHeaderOptions);
1425 memset(response.resourceUri, 0, sizeof response.resourceUri);
1426 // Indicate that response is NOT in a persistent buffer
1427 response.persistentBufferFlag = 0;
1428 response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR;
1430 // Send the response
1431 if (OCDoResponse(&response) != OC_STACK_OK)
1433 OIC_LOG(ERROR, TAG, "Error sending response");
1434 stackRet = OC_STACK_ERROR;