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
23 #include "iotivity_config.h"
28 #if defined (__TIZENRT__)
29 #include <apps/netutils/cJSON.h>
34 #include "ocpayload.h"
35 #include "oic_malloc.h"
36 #include "oic_string.h"
37 #include "occollection.h"
41 #define TAG "OIC_RI_GROUP"
43 #define DESC_DELIMITER "\""
44 #define ACTION_DELIMITER "*"
45 #define ATTR_DELIMITER "|"
46 #define ATTR_ASSIGN "="
48 // Definitions for operations related to actions
49 #define DO_ACTION "DoAction"
50 #define GET_ACTIONSET "GetActionSet"
51 #define ACTIONSET "ActionSet"
52 #define CANCEL_ACTIONSET "CancelAction"
53 #define DELETE_ACTIONSET "DelActionSet"
55 #define DEFAULT_CONTEXT_VALUE 0x99
57 #define VARIFY_POINTER_NULL(pointer, result, toExit) \
60 result = OC_STACK_NO_MEMORY;\
63 #define VARIFY_PARAM_NULL(pointer, result, toExit) \
66 result = OC_STACK_INVALID_PARAM;\
70 #define OCFREE(pointer) \
76 // Mutex implementation macros
77 #if defined(HAVE_PTHREAD_H)
80 pthread_mutex_t g_scheduledResourceLock;
81 #define MUTEX_LOCK(ARG_NAME) { pthread_mutex_lock(ARG_NAME); }
82 #define MUTEX_UNLOCK(ARG_NAME) { pthread_mutex_unlock(ARG_NAME); }
83 #define MUTEX_INITIALIZE(ARG_NAME) { }
84 #define MUTEX_TERMINATE(ARG_NAME) { }
86 #elif defined(HAVE_WINDOWS_H)
89 CRITICAL_SECTION g_scheduledResourceLock;
90 bool g_initializedScheduledResourceLock = false;
91 #define MUTEX_LOCK(ARG_NAME) { EnterCriticalSection(ARG_NAME); }
92 #define MUTEX_UNLOCK(ARG_NAME) { LeaveCriticalSection(ARG_NAME); }
93 #define MUTEX_INITIALIZE(ARG_NAME) { assert(!g_initializedScheduledResourceLock); \
94 InitializeCriticalSection(ARG_NAME); \
95 g_initializedScheduledResourceLock = true; \
97 #define MUTEX_TERMINATE(ARG_NAME) { if (g_initializedScheduledResourceLock) \
99 DeleteCriticalSection(ARG_NAME); \
100 g_initializedScheduledResourceLock = false; \
104 #elif defined(WITH_ARDUINO)
106 #define MUTEX_LOCK(ARG_NAME) { }
107 #define MUTEX_UNLOCK(ARG_NAME) { }
108 #define MUTEX_INITIALIZE(ARG_NAME) { }
109 #define MUTEX_TERMINATE(ARG_NAME) { }
113 ERROR Need mutex implementation on this platform
119 NONE = 0, SCHEDULED, RECURSIVE
122 typedef struct scheduledresourceinfo
124 OCResource *resource;
125 OCActionSet *actionset;
129 OCServerRequest *ehRequest;
132 struct scheduledresourceinfo* next;
133 } ScheduledResourceInfo;
135 ScheduledResourceInfo *g_scheduleResourceList = NULL;
137 void AddScheduledResource(ScheduledResourceInfo **head,
138 ScheduledResourceInfo* add)
140 OIC_LOG(INFO, TAG, "AddScheduledResource Entering...");
142 MUTEX_LOCK(&g_scheduledResourceLock);
143 ScheduledResourceInfo *tmp = NULL;
159 MUTEX_UNLOCK(&g_scheduledResourceLock);
162 ScheduledResourceInfo* GetScheduledResource(ScheduledResourceInfo *head)
164 OIC_LOG(INFO, TAG, "GetScheduledResource Entering...");
166 MUTEX_LOCK(&g_scheduledResourceLock);
170 ScheduledResourceInfo *tmp = NULL;
173 #if !defined(WITH_ARDUINO)
184 diffTm = timespec_diff(tmp->time, t_now);
186 if (diffTm <= (time_t) 0)
188 OIC_LOG(INFO, TAG, "return Call INFO.");
198 MUTEX_UNLOCK(&g_scheduledResourceLock);
202 OIC_LOG(INFO, TAG, "Cannot Find Call Info.");
207 ScheduledResourceInfo* GetScheduledResourceByActionSetName(ScheduledResourceInfo *head, char *setName)
209 OIC_LOG(INFO, TAG, "GetScheduledResourceByActionSetName Entering...");
211 MUTEX_LOCK(&g_scheduledResourceLock);
213 ScheduledResourceInfo *tmp = NULL;
220 if (strcmp(tmp->actionset->actionsetName, setName) == 0)
222 OIC_LOG(INFO, TAG, "return Call INFO.");
231 MUTEX_UNLOCK(&g_scheduledResourceLock);
235 OIC_LOG(INFO, TAG, "Cannot Find Call Info.");
240 void RemoveScheduledResource(ScheduledResourceInfo **head,
241 ScheduledResourceInfo* del)
244 MUTEX_LOCK(&g_scheduledResourceLock);
246 OIC_LOG(INFO, TAG, "RemoveScheduledResource Entering...");
247 ScheduledResourceInfo *tmp = NULL;
252 MUTEX_UNLOCK(&g_scheduledResourceLock);
259 *head = (*head)->next;
264 while (tmp->next && (tmp->next != del))
270 tmp->next = del->next;
276 MUTEX_UNLOCK(&g_scheduledResourceLock);
279 typedef struct aggregatehandleinfo
281 OCServerRequest *ehRequest;
283 OCResource *collResource;
285 struct aggregatehandleinfo *next;
288 ClientRequestInfo *clientRequstList = NULL;
290 void AddClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* add)
292 ClientRequestInfo *tmp = NULL;
310 ClientRequestInfo* GetClientRequestInfo(ClientRequestInfo *head,
313 ClientRequestInfo *tmp = NULL;
321 if (tmp->required == handle)
334 void RemoveClientRequestInfo(ClientRequestInfo **head, ClientRequestInfo* del)
336 ClientRequestInfo *tmp = NULL;
343 *head = (*head)->next;
348 while (tmp->next && (tmp->next != del))
354 tmp->next = del->next;
359 void AddCapability(OCCapability** head, OCCapability* node)
361 OCCapability *pointer = *head;
368 while (pointer->next != NULL)
370 pointer = pointer->next;
373 pointer->next = node;
377 void AddAction(OCAction** head, OCAction* node)
379 OCAction *pointer = *head;
387 while (pointer->next != NULL)
389 pointer = pointer->next;
392 pointer->next = node;
396 OCStackResult AddActionSet(OCActionSet **head, OCActionSet* node)
398 OCActionSet *pointer = *head;
399 OCActionSet *prev = NULL;
402 return OC_STACK_ERROR;
411 while (pointer != NULL)
413 // check the uniqeness of actionsetname.
414 if (strcmp(pointer->actionsetName, node->actionsetName) == 0)
416 return OC_STACK_ERROR;
420 pointer = pointer->next;
429 void DeleteCapability(OCCapability *del)
431 OCFREE(del->capability)
432 del->capability = NULL;
438 void DeleteAction(OCAction** action)
440 OCCapability* pointer = (*action)->head;
441 OCCapability* pDel = NULL;
446 pointer = pointer->next;
448 DeleteCapability(pDel);
450 OCFREE((*action)->resourceUri)
451 (*action)->next = NULL;
455 void DeleteActionSet(OCActionSet** actionset)
457 OCAction* pointer = NULL;
458 OCAction* pDel = NULL;
460 if(*actionset == NULL)
463 pointer = (*actionset)->head;
468 pointer = pointer->next;
472 // (*actionset)->head = NULL;
473 OCFREE((*actionset)->actionsetName)
477 OCStackResult FindAndDeleteActionSet(OCResource **resource,
478 const char * actionsetName)
480 if (*resource != NULL)
482 OCActionSet *pointer = NULL;
483 OCActionSet *pDel = NULL;
485 pointer = (*resource)->actionsetHead;
489 return OC_STACK_ERROR;
493 if (strcmp(pointer->actionsetName, actionsetName) == 0)
495 if (pointer->next != NULL)
496 (*resource)->actionsetHead = pointer->next;
498 (*resource)->actionsetHead = NULL;
500 DeleteActionSet(&pointer);
502 else if (pointer->next != NULL)
506 if (pointer->next != NULL)
508 if (strcmp(pointer->next->actionsetName, actionsetName)
511 pDel = pointer->next;
512 pointer->next = pointer->next->next;
514 DeleteActionSet(&pDel);
517 pointer = pointer->next;
525 return OC_STACK_ERROR;
528 OCStackResult GetActionSet(const char *actionName, OCActionSet *head,
529 OCActionSet** actionset)
531 OCActionSet *pointer = head;
535 if (strcmp(pointer->actionsetName, actionName) == 0)
537 *actionset = pointer;
541 pointer = pointer->next;
544 return OC_STACK_ERROR;
548 OCStackResult ExtractKeyValueFromRequest(OCEntityHandlerRequest *ehRequest,
549 char **key, char **value)
551 OCStackResult result = OC_STACK_OK;
553 char *actionSetStr = NULL;
555 if( NULL == ehRequest->payload )
557 result = OC_STACK_ERROR;
563 input = (OCRepPayload*)(ehRequest->payload);
565 if(OCRepPayloadGetPropString(input, ACTIONSET, &actionSetStr))
567 *key = OICStrdup(ACTIONSET);
568 VARIFY_POINTER_NULL(*key, result, exit);
570 *value = OICStrdup(actionSetStr);
571 VARIFY_POINTER_NULL(*value, result, exit);
573 else if(OCRepPayloadGetPropString(input, DO_ACTION, &actionSetStr))
575 *key = OICStrdup(DO_ACTION);
576 VARIFY_POINTER_NULL(*key, result, exit);
578 *value = OICStrdup(actionSetStr);
579 VARIFY_POINTER_NULL(*value, result, exit);
581 else if(OCRepPayloadGetPropString(input, GET_ACTIONSET, &actionSetStr))
583 *key = OICStrdup(GET_ACTIONSET);
584 VARIFY_POINTER_NULL(*key, result, exit);
586 *value = OICStrdup(actionSetStr);
587 VARIFY_POINTER_NULL(*value, result, exit);
589 else if(OCRepPayloadGetPropString(input, DELETE_ACTIONSET, &actionSetStr))
591 *key = OICStrdup(DELETE_ACTIONSET);
592 VARIFY_POINTER_NULL(*key, result, exit);
594 *value = OICStrdup(actionSetStr);
595 VARIFY_POINTER_NULL(*value, result, exit);
597 else if(OCRepPayloadGetPropString(input, CANCEL_ACTIONSET, &actionSetStr))
599 *key = OICStrdup(CANCEL_ACTIONSET);
600 VARIFY_POINTER_NULL(*key, result, exit);
602 *value = OICStrdup(actionSetStr);
603 VARIFY_POINTER_NULL(*value, result, exit);
607 result = OC_STACK_ERROR;
611 if (result != OC_STACK_OK)
617 OCFREE(actionSetStr);
622 OCStackResult ExtractActionSetNameAndDelaytime(char *pChar, char **setName,
625 char *token = NULL, *tokenPtr = NULL;
626 OCStackResult result = OC_STACK_OK;
628 token = (char*) strtok_r(pChar, ACTION_DELIMITER, &tokenPtr);
629 VARIFY_POINTER_NULL(token, result, exit)
631 *setName = (char *) OICMalloc(strlen(token) + 1);
632 VARIFY_POINTER_NULL(*setName, result, exit)
633 VARIFY_PARAM_NULL(token, result, exit)
634 strncpy(*setName, token, strlen(token) + 1);
636 token = strtok_r(NULL, ACTION_DELIMITER, &tokenPtr);
637 VARIFY_POINTER_NULL(pa, result, exit)
638 VARIFY_PARAM_NULL(token, result, exit)
648 OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc)
650 OCStackResult result = OC_STACK_OK;
652 char *iterToken = NULL, *iterTokenPtr = NULL;
653 char *descIterToken = NULL, *descIterTokenPtr = NULL;
654 char *attrIterToken = NULL, *attrIterTokenPtr = NULL;
655 char *desc = NULL, *attr = NULL;
656 char *key = NULL, *value = NULL;
658 OCAction *action = NULL;
659 OCCapability *capa = NULL;
661 OIC_LOG(INFO, TAG, "Build ActionSet Instance.");
663 *set = (OCActionSet*) OICMalloc(sizeof(OCActionSet));
664 VARIFY_POINTER_NULL(*set, result, exit)
666 iterToken = (char *) strtok_r(actiondesc, ACTION_DELIMITER, &iterTokenPtr);
667 VARIFY_POINTER_NULL(iterToken, result, exit);
670 memset(*set, 0, sizeof(OCActionSet));
671 (*set)->actionsetName = (char *) OICMalloc(strlen(iterToken) + 1);
672 VARIFY_POINTER_NULL((*set)->actionsetName, result, exit)
673 VARIFY_PARAM_NULL(iterToken, result, exit)
674 strncpy((*set)->actionsetName, iterToken, strlen(iterToken) + 1);
676 // Time info. for Scheduled/Recursive Group action.
677 // d is meant Day of the week.
678 // T is meant ActionType.
679 // yyyy-mm-dd hh:mm:ss d
680 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
681 VARIFY_PARAM_NULL(iterToken, result, exit)
682 #if !defined(WITH_ARDUINO)
683 if( 2 != sscanf(iterToken, "%ld %u", &(*set)->timesteps, &(*set)->type) )
685 // If the return value should be 2, the number of items in the argument. Otherwise, it fails.
690 OIC_LOG_V(INFO, TAG, "ActionSet Name : %s", (*set)->actionsetName);
692 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
695 desc = (char *) OICMalloc(strlen(iterToken) + 1);
696 VARIFY_POINTER_NULL(desc, result, exit)
697 VARIFY_PARAM_NULL(desc, result, exit)
698 strncpy(desc, iterToken, strlen(iterToken) + 1);
699 descIterToken = (char *) strtok_r(desc, ATTR_DELIMITER,
701 while (descIterToken)
703 attr = (char *) OICMalloc(strlen(descIterToken) + 1);
704 VARIFY_POINTER_NULL(attr, result, exit)
705 VARIFY_PARAM_NULL(descIterToken, result, exit)
706 strncpy(attr, descIterToken, strlen(descIterToken) + 1);
708 attrIterToken = (char *) strtok_r(attr, ATTR_ASSIGN,
710 VARIFY_POINTER_NULL(attrIterToken, result, exit);
712 key = (char *) OICMalloc(strlen(attrIterToken) + 1);
713 VARIFY_POINTER_NULL(key, result, exit)
714 VARIFY_PARAM_NULL(attrIterToken, result, exit)
715 strncpy(key, attrIterToken, strlen(attrIterToken) + 1);
717 attrIterToken = (char *) strtok_r(NULL, ATTR_ASSIGN,
719 VARIFY_POINTER_NULL(attrIterToken, result, exit);
720 value = (char *) OICMalloc(strlen(attrIterToken) + 1);
721 VARIFY_POINTER_NULL(value, result, exit)
722 VARIFY_PARAM_NULL(attrIterToken, result, exit)
723 strncpy(value, attrIterToken, strlen(attrIterToken) + 1);
725 if (strcmp(key, "uri") == 0)
727 OIC_LOG(INFO, TAG, "Build OCAction Instance.");
729 action = (OCAction*) OICMalloc(sizeof(OCAction));
730 VARIFY_POINTER_NULL(action, result, exit)
731 memset(action, 0, sizeof(OCAction));
732 action->resourceUri = (char *) OICMalloc(strlen(value) + 1);
733 VARIFY_POINTER_NULL(action->resourceUri, result, exit)
734 VARIFY_PARAM_NULL(value, result, exit)
735 strncpy(action->resourceUri, value, strlen(value) + 1);
739 if ((key != NULL) && (value != NULL))
741 OIC_LOG(INFO, TAG, "Build OCCapability Instance.");
743 capa = (OCCapability*) OICMalloc(sizeof(OCCapability));
744 VARIFY_POINTER_NULL(capa, result, exit)
745 memset(capa, 0, sizeof(OCCapability));
747 capa->capability = (char *) OICMalloc(strlen(key) + 1);
748 VARIFY_POINTER_NULL(capa->capability, result, exit)
749 VARIFY_PARAM_NULL(key, result, exit)
750 strncpy(capa->capability, key, strlen(key) + 1);
752 capa->status = (char *) OICMalloc(strlen(value) + 1);
753 VARIFY_POINTER_NULL(capa->status, result, exit)
754 VARIFY_PARAM_NULL(value, result, exit)
755 strncpy(capa->status, value, strlen(value) + 1);
757 VARIFY_POINTER_NULL(action, result, exit)
759 AddCapability(&action->head, capa);
767 descIterToken = (char *) strtok_r(NULL, ATTR_DELIMITER,
771 AddAction(&(*set)->head, action);
772 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
782 OCFREE((*set)->actionsetName)
791 OCStackResult BuildStringFromActionSet(OCActionSet* actionset, char** desc)
793 // Can't use the macros here as they are hardcoded to 'exit' and will
794 // result in dereferencing a null pointer.
795 if (!actionset || !desc)
797 return OC_STACK_INVALID_PARAM;
799 char temp[1024] = { 0 };
800 size_t remaining = sizeof(temp) - 1;
801 OCStackResult res = OC_STACK_ERROR;
802 char* actionTypeStr = NULL;
804 OCAction *action = actionset->head;
806 if (remaining >= strlen(actionset->actionsetName) + 1)
808 strncat(temp, actionset->actionsetName, strlen(actionset->actionsetName));
809 remaining -= strlen(actionset->actionsetName);
810 strncat(temp, ACTION_DELIMITER, strlen(ACTION_DELIMITER));
815 res = OC_STACK_ERROR;
819 actionTypeStr = (char *)OICMalloc(1024);
820 if(actionTypeStr != NULL)
822 sprintf(actionTypeStr, "%ld %u", actionset->timesteps, actionset->type);
823 if(remaining >= strlen(actionTypeStr) + strlen(ACTION_DELIMITER) + 1)
825 strncat(temp, actionTypeStr, strlen(actionTypeStr));
826 remaining -= strlen(actionTypeStr);
827 strncat(temp, ACTION_DELIMITER, strlen(ACTION_DELIMITER));
828 remaining -= strlen(ACTION_DELIMITER);
829 OICFree(actionTypeStr);
833 OICFree(actionTypeStr);
834 res = OC_STACK_ERROR;
840 res = OC_STACK_ERROR;
844 while (action != NULL)
846 if (remaining < (strlen("uri=") + strlen(action->resourceUri) + 1))
848 res = OC_STACK_ERROR;
852 strcat(temp, "uri=");
853 remaining -= strlen("uri=");
854 strcat(temp, action->resourceUri);
855 remaining -= strlen(action->resourceUri);
859 OCCapability *capas = action->head;
860 while (capas != NULL)
862 if (remaining < (strlen(capas->capability)
863 + 1 + strlen(capas->status)))
865 res = OC_STACK_ERROR;
869 strcat(temp, capas->capability);
870 remaining -= strlen(capas->capability);
873 strcat(temp, capas->status);
874 remaining -= strlen(capas->status);
881 res = OC_STACK_ERROR;
889 action = action->next;
892 if (remaining < strlen(ACTION_DELIMITER))
894 res = OC_STACK_ERROR;
897 strcat(temp, ACTION_DELIMITER);
902 *desc = OICStrdup(temp);
903 VARIFY_POINTER_NULL(*desc, res, exit);
912 OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
913 OCClientResponse* clientResponse)
916 (void)clientResponse;
917 OIC_LOG(INFO, TAG, "Entering ActionSetCB");
919 ClientRequestInfo *info = GetClientRequestInfo(clientRequstList, handle);
923 OCEntityHandlerResponse response = { 0 };
925 response.ehResult = OC_EH_OK;
927 if(NULL == clientResponse->payload)
929 OIC_LOG(ERROR, TAG, "Error sending response");
930 return OC_STACK_DELETE_TRANSACTION;
933 // Format the response. Note this requires some info about the request
934 response.requestHandle = info->ehRequest->requestId;
935 response.resourceHandle = info->collResource;
936 response.payload = clientResponse->payload;
937 response.numSendVendorSpecificHeaderOptions = 0;
938 memset(response.sendVendorSpecificHeaderOptions, 0,
939 sizeof response.sendVendorSpecificHeaderOptions);
940 memset(response.resourceUri, 0, sizeof response.resourceUri);
941 // Indicate that response is NOT in a persistent buffer
942 response.persistentBufferFlag = 0;
945 if (OCDoResponse(&response) != OC_STACK_OK)
947 OIC_LOG(ERROR, TAG, "Error sending response");
948 return OC_STACK_DELETE_TRANSACTION;
951 RemoveClientRequestInfo(&clientRequstList, info);
955 return OC_STACK_KEEP_TRANSACTION;
958 void ActionSetCD(void *context)
963 OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr,
966 OCStackResult ret = OC_STACK_ERROR;
973 OIC_LOG(INFO, TAG, "Entering BuildActionJSON");
974 json = cJSON_CreateObject();
976 cJSON_AddItemToObject(json, "rep", body = cJSON_CreateObject());
978 OCCapability* pointerCapa = action->head;
981 cJSON_AddStringToObject(body, pointerCapa->capability,
982 pointerCapa->status);
983 pointerCapa = pointerCapa->next;
986 jsonStr = cJSON_PrintUnformatted(json);
988 jsonLen = strlen(jsonStr);
989 if (jsonLen < *remaining)
991 strncat((char*) bufferPtr, jsonStr, jsonLen);
992 *remaining -= jsonLen;
993 bufferPtr += jsonLen;
1003 OCPayload* BuildActionCBOR(OCAction* action)
1005 OCRepPayload* payload = OCRepPayloadCreate();
1009 OIC_LOG(INFO, TAG, "Failed to create put payload object");
1013 OCCapability* pointerCapa = action->head;
1016 OCRepPayloadSetPropString(payload, pointerCapa->capability, pointerCapa->status);
1017 pointerCapa = pointerCapa->next;
1020 return (OCPayload*) payload;
1023 unsigned int GetNumOfTargetResource(OCAction *actionset)
1025 int numOfResource = 0;
1027 OCAction *pointerAction = actionset;
1029 while (pointerAction != NULL)
1032 pointerAction = pointerAction->next;
1035 return numOfResource;
1038 OCStackResult SendAction(OCDoHandle *handle, OCServerRequest* requestHandle, const char *targetUri,
1042 OCCallbackData cbData;
1043 cbData.cb = &ActionSetCB;
1044 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
1047 return OCDoResource(handle, OC_REST_PUT, targetUri, &requestHandle->devAddr,
1048 payload, CT_ADAPTER_IP, OC_NA_QOS, &cbData, NULL, 0);
1051 OCStackResult DoAction(OCResource* resource, OCActionSet* actionset,
1052 OCServerRequest* requestHandle)
1054 OCStackResult result = OC_STACK_ERROR;
1056 if( NULL == actionset->head)
1061 OCAction *pointerAction = actionset->head;
1063 while (pointerAction != NULL)
1066 payload = BuildActionCBOR(pointerAction);
1073 ClientRequestInfo *info = (ClientRequestInfo *) OICMalloc(
1074 sizeof(ClientRequestInfo));
1079 return OC_STACK_NO_MEMORY;
1082 memset(info, 0, sizeof(ClientRequestInfo));
1084 info->collResource = resource;
1085 info->ehRequest = requestHandle;
1087 result = SendAction(&info->required, info->ehRequest, pointerAction->resourceUri,
1090 if (result != OC_STACK_OK)
1096 AddClientRequestInfo(&clientRequstList, info);
1098 pointerAction = pointerAction->next;
1104 void DoScheduledGroupAction()
1106 OIC_LOG(INFO, TAG, "DoScheduledGroupAction Entering...");
1107 ScheduledResourceInfo* info = GetScheduledResource(g_scheduleResourceList);
1111 OIC_LOG(INFO, TAG, "Target resource is NULL");
1114 else if (info->resource == NULL)
1116 OIC_LOG(INFO, TAG, "Target resource is NULL");
1119 else if (info->actionset == NULL)
1121 OIC_LOG(INFO, TAG, "Target ActionSet is NULL");
1124 else if (info->ehRequest == NULL)
1126 OIC_LOG(INFO, TAG, "Target ActionSet is NULL");
1130 MUTEX_LOCK(&g_scheduledResourceLock);
1132 DoAction(info->resource, info->actionset, info->ehRequest);
1134 MUTEX_UNLOCK(&g_scheduledResourceLock);
1137 if (info->actionset->type == RECURSIVE)
1139 ScheduledResourceInfo *schedule;
1140 schedule = (ScheduledResourceInfo *) OICMalloc(
1141 sizeof(ScheduledResourceInfo));
1145 OIC_LOG(INFO, TAG, "Building New Call Info.");
1146 memset(schedule, 0, sizeof(ScheduledResourceInfo));
1148 if (info->actionset->timesteps > 0)
1150 MUTEX_LOCK(&g_scheduledResourceLock);
1151 schedule->resource = info->resource;
1152 schedule->actionset = info->actionset;
1153 schedule->ehRequest = info->ehRequest;
1155 schedule->time = registerTimer(info->actionset->timesteps,
1156 &schedule->timer_id,
1157 &DoScheduledGroupAction);
1159 OIC_LOG(INFO, TAG, "Reregistration.");
1160 MUTEX_UNLOCK(&g_scheduledResourceLock);
1161 AddScheduledResource(&g_scheduleResourceList, schedule);
1170 RemoveScheduledResource(&g_scheduleResourceList, info);
1177 OCStackResult BuildCollectionGroupActionCBORResponse(
1178 OCMethod method/*OCEntityHandlerFlag flag*/, OCResource *resource,
1179 OCEntityHandlerRequest *ehRequest)
1181 OCStackResult stackRet = OC_STACK_ERROR;
1183 OIC_LOG(INFO, TAG, "Group Action is requested.");
1185 char *doWhat = NULL;
1186 char *details = NULL;
1188 stackRet = ExtractKeyValueFromRequest(ehRequest, &doWhat, &details);
1190 if(stackRet != OC_STACK_OK)
1192 OIC_LOG_V(ERROR, TAG, "ExtractKeyValueFromRequest failed: %d", stackRet);
1196 stackRet = OC_STACK_ERROR;
1198 if (method == OC_REST_PUT)
1200 OIC_LOG(INFO, TAG, "Group Action[PUT].");
1202 if (strcmp(doWhat, ACTIONSET) == 0)
1204 OCActionSet *actionSet = NULL;
1205 stackRet = BuildActionSetFromString(&actionSet, details);
1207 if(stackRet == OC_STACK_OK)
1209 if (actionSet != NULL)
1211 stackRet = AddActionSet(&resource->actionsetHead,
1213 if (stackRet == OC_STACK_ERROR)
1215 if(actionSet != NULL)
1217 DeleteActionSet( &actionSet );
1219 OIC_LOG(INFO, TAG, "Duplicated ActionSet ");
1224 stackRet = OC_STACK_ERROR;
1230 stackRet = OC_STACK_ERROR;
1234 else if (strcmp(doWhat, DELETE_ACTIONSET) == 0)
1236 if (FindAndDeleteActionSet(&resource, details) == OC_STACK_OK)
1238 stackRet = OC_STACK_OK;
1242 stackRet = OC_STACK_ERROR;
1246 OCRepPayload* payload = OCRepPayloadCreate();
1250 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
1251 stackRet = OC_STACK_ERROR;
1255 OCEntityHandlerResponse response = { 0 };
1257 if(stackRet == OC_STACK_OK)
1258 response.ehResult = OC_EH_OK;
1260 response.ehResult = OC_EH_ERROR;
1262 // Format the response. Note this requires some info about the request
1263 response.requestHandle = ehRequest->requestHandle;
1264 response.resourceHandle = ehRequest->resource;
1265 response.payload = (OCPayload*) payload;
1266 response.numSendVendorSpecificHeaderOptions = 0;
1267 memset(response.sendVendorSpecificHeaderOptions, 0,
1268 sizeof response.sendVendorSpecificHeaderOptions);
1269 memset(response.resourceUri, 0, sizeof response. resourceUri);
1270 // Indicate that response is NOT in a persistent buffer
1271 response.persistentBufferFlag = 0;
1272 response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR;
1274 // Send the response
1275 if (OCDoResponse(&response) != OC_STACK_OK)
1277 OIC_LOG(ERROR, TAG, "Error sending response");
1278 stackRet = OC_STACK_ERROR;
1281 OCRepPayloadDestroy(payload);
1283 else if (method == OC_REST_POST)
1285 OCActionSet *actionset = NULL;
1287 OCRepPayload* payload = OCRepPayloadCreate();
1288 OCRepPayloadSetUri(payload, resource->uri);
1290 if ((strcmp(doWhat, DO_ACTION) == 0)
1291 || (strcmp(doWhat, "DoScheduledAction") == 0))
1293 char *pActionsetName = NULL;
1294 long int delay = -1;
1296 if (strcmp(doWhat, "DoScheduledAction") == 0)
1298 stackRet = ExtractActionSetNameAndDelaytime(details,
1299 &pActionsetName, &delay);
1302 details = pActionsetName;
1306 stackRet = OC_STACK_OK;
1309 if (stackRet == OC_STACK_OK)
1311 if (GetActionSet(details, resource->actionsetHead,
1312 &actionset) != OC_STACK_OK)
1314 OIC_LOG(INFO, TAG, "ERROR");
1315 stackRet = OC_STACK_ERROR;
1318 if (actionset == NULL)
1320 OIC_LOG(INFO, TAG, "Cannot Find ActionSet");
1321 stackRet = OC_STACK_ERROR;
1325 OIC_LOG(INFO, TAG, "Group Action[POST].");
1326 OCServerRequest *request =
1327 GetServerRequestUsingHandle(ehRequest->requestHandle);
1328 if (NULL == request)
1330 stackRet = OC_STACK_ERROR;
1334 if (actionset->type == NONE)
1336 OIC_LOG_V(INFO, TAG, "Execute ActionSet : %s",
1337 actionset->actionsetName);
1338 unsigned int num = GetNumOfTargetResource(
1341 request->ehResponseHandler = HandleAggregateResponse;
1342 request->numResponses = num + 1;
1344 DoAction(resource, actionset, request);
1346 stackRet = OC_STACK_OK;
1350 OIC_LOG_V(INFO, TAG, "Execute Scheduled ActionSet : %s",
1351 actionset->actionsetName);
1354 (delay == -1 ? actionset->timesteps : delay);
1356 ScheduledResourceInfo *schedule;
1357 schedule = (ScheduledResourceInfo *) OICMalloc(
1358 sizeof(ScheduledResourceInfo));
1362 OIC_LOG(INFO, TAG, "Building New Call Info.");
1364 sizeof(ScheduledResourceInfo));
1365 MUTEX_LOCK(&g_scheduledResourceLock);
1366 schedule->resource = resource;
1367 schedule->actionset = actionset;
1368 schedule->ehRequest = request;
1370 MUTEX_UNLOCK(&g_scheduledResourceLock);
1373 OIC_LOG_V(INFO, TAG, "delay_time is %ld seconds.",
1374 actionset->timesteps);
1375 MUTEX_LOCK(&g_scheduledResourceLock);
1376 schedule->time = registerTimer(delay,
1377 &schedule->timer_id,
1378 &DoScheduledGroupAction);
1379 MUTEX_UNLOCK(&g_scheduledResourceLock);
1380 AddScheduledResource(&g_scheduleResourceList,
1382 stackRet = OC_STACK_OK;
1386 stackRet = OC_STACK_ERROR;
1393 else if (strcmp(doWhat, "CancelAction") == 0)
1395 ScheduledResourceInfo *info =
1396 GetScheduledResourceByActionSetName(g_scheduleResourceList, details);
1400 MUTEX_LOCK(&g_scheduledResourceLock);
1401 unregisterTimer(info->timer_id);
1402 MUTEX_UNLOCK(&g_scheduledResourceLock);
1404 RemoveScheduledResource(&g_scheduleResourceList, info);
1405 stackRet = OC_STACK_OK;
1409 stackRet = OC_STACK_ERROR;
1413 else if (strcmp(doWhat, GET_ACTIONSET) == 0)
1415 char *plainText = NULL;
1416 OCActionSet *actionset = NULL;
1418 GetActionSet(details, resource->actionsetHead, &actionset);
1419 if (actionset != NULL)
1421 BuildStringFromActionSet(actionset, &plainText);
1423 if (plainText != NULL)
1425 OCRepPayloadSetPropString(payload, ACTIONSET, plainText);
1428 stackRet = OC_STACK_OK;
1434 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
1435 stackRet = OC_STACK_ERROR;
1439 OCEntityHandlerResponse response = { 0 };
1440 if(stackRet == OC_STACK_OK)
1441 response.ehResult = OC_EH_OK;
1443 response.ehResult = OC_EH_ERROR;
1445 // Format the response. Note this requires some info about the request
1446 response.requestHandle = ehRequest->requestHandle;
1447 response.resourceHandle = ehRequest->resource;
1448 response.payload = (OCPayload*) payload;
1449 response.numSendVendorSpecificHeaderOptions = 0;
1450 memset(response.sendVendorSpecificHeaderOptions, 0,
1451 sizeof response.sendVendorSpecificHeaderOptions);
1452 memset(response.resourceUri, 0, sizeof response.resourceUri);
1453 // Indicate that response is NOT in a persistent buffer
1454 response.persistentBufferFlag = 0;
1455 response.ehResult = (stackRet == OC_STACK_OK)?OC_EH_OK:OC_EH_ERROR;
1457 // Send the response
1458 if (OCDoResponse(&response) != OC_STACK_OK)
1460 OIC_LOG(ERROR, TAG, "Error sending response");
1461 stackRet = OC_STACK_ERROR;
1464 OCRepPayloadDestroy(payload);
1475 OCStackResult InitializeScheduleResourceList()
1477 MUTEX_INITIALIZE(&g_scheduledResourceLock);
1479 g_scheduleResourceList = NULL;
1483 void TerminateScheduleResourceList()
1485 assert(g_scheduleResourceList == NULL);
1487 MUTEX_TERMINATE(&g_scheduledResourceLock);