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
27 #include "ocresource.h"
28 #include "occollection.h"
31 #define TAG PCF("OICGROUP")
33 #define DESC_DELIMITER "\""
34 #define ACTION_DELIMITER "*"
35 #define ATTR_DELIMITER "|"
37 typedef struct aggregatehandleinfo
39 OCServerRequest *ehRequest;
41 OCResource *collResource;
43 struct aggregatehandleinfo *next;
46 // unsigned int nHandleIdx = 0;
47 // ClientRequstInfo g_AggregateResponseHandle[10];
49 ClientRequstInfo *clientRequstList = NULL;
51 void AddClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* add)
53 ClientRequstInfo *tmp = NULL;
71 ClientRequstInfo* GetClientRequestInfo(ClientRequstInfo *head, OCDoHandle handle)
73 ClientRequstInfo *tmp = NULL;
81 // printf("%p :: %p\n", tmp->required, handle);
82 if (tmp->required == handle)
95 void RemoveClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* del)
97 ClientRequstInfo *tmp = NULL;
101 *head = (*head)->next;
106 while (tmp->next && (tmp->next != del))
112 tmp->next = del->next;
119 void AddCapability(OCCapability** head, OCCapability* node)
121 OCCapability *pointer = *head;
128 while (pointer->next != NULL)
130 pointer = pointer->next;
133 pointer->next = node;
137 void AddAction(OCAction** head, OCAction* node)
139 OCAction *pointer = *head;
147 while (pointer->next != NULL)
149 pointer = pointer->next;
152 pointer->next = node;
156 void AddActionSet(OCActionSet **head, OCActionSet* node)
158 OCActionSet *pointer = *head;
166 while (pointer->next != NULL)
168 pointer = pointer->next;
171 pointer->next = node;
175 void DeleteCapability(OCCapability *del)
177 free(del->capability);
178 del->capability = NULL;
183 void DeleteAction(OCAction** action)
185 OCCapability* pointer = (*action)->head;
186 OCCapability* pDel = NULL;
191 pointer = pointer->next;
193 DeleteCapability(pDel);
196 OCFree((*action)->resourceUri);
197 (*action)->resourceUri = NULL;
198 (*action)->next = NULL;
201 void DeleteActionSet(OCActionSet** actionset)
203 OCAction* pointer = (*actionset)->head;
204 OCAction* pDel = NULL;
209 pointer = pointer->next;
215 OCFree((*actionset)->actionsetName);
216 (*actionset)->head = NULL;
219 OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actionsetName)
221 if (*resource != NULL)
223 OCActionSet *pointer = NULL;
224 OCActionSet *pDel = NULL;
226 pointer = (*resource)->actionsetHead;
230 return OC_STACK_ERROR;
234 if (strcmp(pointer->actionsetName, actionsetName) == 0)
236 if (pointer->next != NULL)
237 (*resource)->actionsetHead = pointer->next;
239 (*resource)->actionsetHead = NULL;
240 DeleteActionSet(&pointer);
242 else if (pointer->next != NULL)
246 if (pointer->next != NULL)
248 if (strcmp(pointer->next->actionsetName, actionsetName) == 0)
250 pDel = pointer->next;
251 pointer->next = pointer->next->next;
253 DeleteActionSet(&pDel);
256 pointer = pointer->next;
264 return OC_STACK_ERROR;
267 OCStackResult DeleteActionSets(OCResource** resource)
269 OCActionSet *pointer = (*resource)->actionsetHead;
270 OCActionSet *pDel = pointer;
275 pointer = pointer->next;
277 DeleteActionSet(&pDel);
281 (*resource)->actionsetHead = NULL;
285 OCStackResult GetActionSet(const char *actionName, OCActionSet *head, OCActionSet** actionset)
287 OCActionSet *pointer = head;
291 if (strcmp(pointer->actionsetName, actionName) == 0)
293 *actionset = pointer;
297 pointer = pointer->next;
300 return OC_STACK_ERROR;
304 OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method,
305 char **actionsetName)
308 char *iterTokenPtr = NULL;
309 char *iterToken = NULL;
310 char *description = NULL;
311 char *iterDescPtr = NULL;
313 char *attributes = NULL;
314 char *iterAttrbutesPtr = NULL;
317 char *iterAttrPtr = NULL;
319 OCActionSet* actionset = NULL;
320 OCAction* action = NULL;
322 acitonRequest = (char *) OCMalloc(strlen((char *) request) + 1);
323 strncpy(acitonRequest, (char *) request, strlen((char *) request) + 1);
325 //printf("\t%s\n", acitonRequest);
326 if (acitonRequest != NULL)
328 iterToken = (char *) strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr);
330 while (iterToken != NULL)
332 if (strcmp(iterToken, "ActionSet") == 0)
333 { // if iterToken is ActionSet, will be created and added a new action set.
335 *method = (char *) OCMalloc(strlen(iterToken) + 1);
336 strncpy(*method, iterToken, strlen(iterToken) + 1);
338 //GetActionName(iterToken, &actionsetName);
339 // printf("%s\n", iterToken, &iterTokenPtr);
341 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
343 // printf("%s\n", iterToken);
344 // it is body of action description.
345 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
347 // printf("%s\n", iterToken);
349 // printf("DESC :: %s\n", iterToken);
350 description = (char *) OCMalloc(strlen(iterToken) + 1);
351 strncpy(description, iterToken, strlen(iterToken) + 1);
352 // printf("DESC Copied :: %s\n", description);
354 // Find the action name from description.
356 iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
357 //while(iterToken != NULL)
358 if (iterToken != NULL)
360 if (*actionsetName != NULL)
362 // printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
363 return OC_STACK_ERROR; // ERROR OCCURED.
368 // printf("ACTION SET NAME :: %s\n", iterToken);
369 *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
371 strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
372 // printf("ACTION SET NAME :: %s\n", *actionsetName);
376 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
380 return OC_STACK_ERROR;
382 } // end Action Set Name.
384 // New ActionSet Add to OCResource's ActionSet list.
385 // 1. Allocate a new pointer for actionset.
386 actionset = (OCActionSet*) OCMalloc(sizeof(OCActionSet));
387 // 2. Initiate actionset.
388 memset(actionset, 0, sizeof(OCActionSet));
389 actionset->actionsetName = (char *) OCMalloc(strlen(*actionsetName) + 1);
390 strncpy(actionset->actionsetName, *actionsetName, strlen(*actionsetName) + 1);
391 // printf("ACTION SET NAME :: %s\n", actionset->actionsetName);
393 while (iterToken != NULL)
395 action = (OCAction *) OCMalloc(sizeof(OCAction));
396 memset(action, 0, sizeof(OCAction));
398 // printf("ATTR Copied :: %s\n", iterToken);
399 attributes = (char *) OCMalloc(strlen(iterToken) + 1);
400 strncpy(attributes, iterToken, strlen(iterToken) + 1);
401 // printf("ATTR Copied :: %s\n", attributes);
403 iterToken = (char *) strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr);
404 while (iterToken != NULL)
406 attr = (char *) OCMalloc(strlen(iterToken) + 1);
407 strncpy(attr, iterToken, strlen(iterToken) + 1);
409 iterToken = (char *) strtok_r(attr, "=", &iterAttrPtr);
410 while (iterToken != NULL)
412 // Find the URI from description.
413 if (strcmp(iterToken, "uri") == 0)
415 iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
416 action->resourceUri = (char *) OCMalloc(strlen(iterToken) + 1);
417 strncpy(action->resourceUri, iterToken, strlen(iterToken) + 1);
421 OCCapability* capa = (OCCapability*) OCMalloc(sizeof(OCCapability));
422 memset(capa, 0, sizeof(OCCapability));
423 //printf("%s :: ", iterToken);
424 capa->capability = (char *) OCMalloc(strlen(iterToken) + 1);
425 strncpy(capa->capability, iterToken, strlen(iterToken) + 1);
426 iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
427 //printf("%s\n", iterToken);
428 capa->status = (char *) OCMalloc(strlen(iterToken) + 1);
429 strncpy(capa->status, iterToken, strlen(iterToken) + 1);
431 AddCapability(&action->head, capa);
434 iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
437 iterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr);
440 AddAction(&actionset->head, action);
442 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
445 // 3. Add the pointer OCResource's ActionSet list.
446 AddActionSet(&(*resource)->actionsetHead, actionset);
449 else if (strcmp(iterToken, "DoAction") == 0 || strcmp(iterToken, "DelActionSet") == 0
450 || strcmp(iterToken, "GetActionSet") == 0)
452 *method = (char *) OCMalloc(strlen(iterToken) + 1);
453 strncpy(*method, iterToken, strlen(iterToken) + 1);
456 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
457 // printf("%s\n", iterToken);
458 // it is body of action description.
459 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
460 // printf("%s\n", iterToken);
462 description = (char *) OCMalloc(strlen(iterToken) + 1);
463 strncpy(description, iterToken, strlen(iterToken) + 1);
465 // Find the action name from description.
467 iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
468 if (iterToken != NULL)
470 if (*actionsetName != NULL)
472 // printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
473 return OC_STACK_ERROR; // ERROR OCCURED.
478 // printf("ACTION SET NAME :: %s\n", iterToken);
479 *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
481 strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
482 // printf("ACTION SET NAME :: %s\n", *actionsetName);
485 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
490 return OC_STACK_ERROR;
492 } // end Action Set Name.
496 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
500 return OC_STACK_ERROR;
503 OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc)
507 int remaining = 1023;
509 // OCActionSet *as = resource->actionsetHead;
512 printf("\n\n\nAction Set Name :: %s\n", actionset->actionsetName);
513 OCAction *action = actionset->head;
515 if (remaining >= strlen(actionset->actionsetName) + 1)
517 strcat(temp, actionset->actionsetName);
518 remaining -= strlen(actionset->actionsetName);
524 return OC_STACK_ERROR;
527 while (action != NULL)
529 printf("\tURI :: %s\n", action->resourceUri);
530 strcat(temp, "uri=");
531 remaining -= strlen("uri=");
532 strcat(temp, action->resourceUri);
533 remaining -= strlen(action->resourceUri);
537 OCCapability *capas = action->head;
538 while (capas != NULL)
540 printf("\t\t%s = %s\n", capas->capability, capas->status);
541 strcat(temp, capas->capability);
542 remaining -= strlen(capas->capability);
545 strcat(temp, capas->status);
546 remaining -= strlen(capas->capability);
555 action = action->next;
565 *desc = (char *) OCMalloc(1024 - remaining);
567 // printf("\t\tPlain Text = %s(%i)\n", *desc, 1024 - remaining);
572 OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
573 OCClientResponse* clientResponse)
575 printf("\n\n\tcallback is called\n\n");
577 ClientRequstInfo *info = GetClientRequestInfo(clientRequstList, handle);
583 unsigned char *responseJson;
584 responseJson = (unsigned char *) OCMalloc(
585 (unsigned int) (strlen((char *) clientResponse->resJSONPayload) + 1));
587 // We need the body of response.
588 // Copy the body from the response
589 strcpy((char *) responseJson, ((char *) clientResponse->resJSONPayload
590 + OC_JSON_PREFIX_LEN));
591 idx = strlen((char *) responseJson) - OC_JSON_SUFFIX_LEN;
592 // And insert NULL at the end of body.
593 (responseJson[idx]) = 0;
595 OCEntityHandlerResponse response = { 0 };
596 response.ehResult = OC_EH_OK;
597 response.payload = responseJson;
598 response.payloadSize = (unsigned int) strlen((char *) responseJson) + 1;
599 response.persistentBufferFlag = 0;
600 response.requestHandle = (OCRequestHandle) info->ehRequest;
601 response.resourceHandle = (OCResourceHandle) info->collResource;
603 OCDoResponse(&response);
605 RemoveClientRequestInfo(&clientRequstList, info);
606 OCFree(responseJson);
609 // g_AggregateResponseHandle
611 return OC_STACK_KEEP_TRANSACTION;
614 void ActionSetCD(void *context)
616 // printf("\n\t\tCD is called\n");
621 OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr, uint16_t *remaining)
623 OCStackResult ret = OC_STACK_ERROR;
630 OC_LOG(INFO, TAG, PCF("Entering BuildActionJSON"));
631 json = cJSON_CreateObject();
633 cJSON_AddItemToObject(json, "rep", body = cJSON_CreateObject());
635 OCCapability* pointerCapa = action->head;
638 cJSON_AddStringToObject(body, pointerCapa->capability, pointerCapa->status);
639 pointerCapa = pointerCapa->next;
642 jsonStr = cJSON_PrintUnformatted(json);
644 jsonLen = strlen(jsonStr);
645 if (jsonLen < *remaining)
647 strcat((char*) bufferPtr, jsonStr);
648 *remaining -= jsonLen;
649 bufferPtr += jsonLen;
659 unsigned int GetNumOfTargetResource(OCAction *actionset)
661 int numOfREsource = 0;
663 OCAction *pointerAction = actionset;
665 while (pointerAction != NULL)
668 pointerAction = pointerAction->next;
671 return numOfREsource;
674 OCStackResult SendAction(OCDoHandle *handle, const char *targetUri, const unsigned char *action)
676 OCCallbackData cbdata =
678 cbdata.cb = &ActionSetCB;
679 cbdata.cd = &ActionSetCD;
680 cbdata.context = (void *) 0x99;
682 return OCDoResource(handle, OC_REST_PUT, targetUri,
683 //temp->rsrcType->resourcetypename,
684 NULL, (char *) action, OC_NA_QOS, &cbdata, NULL, 0);
687 OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/,
688 OCResource *resource, OCEntityHandlerRequest *ehRequest)
690 OCStackResult stackRet = OC_STACK_ERROR;
692 OC_LOG(INFO, TAG, PCF("Group Action is requested."));
693 // if (stackRet == OC_STACK_OK)
697 char *actionName = NULL;
699 size_t bufferLength = 0;
700 unsigned char buffer[MAX_RESPONSE_LENGTH] =
702 unsigned char *bufferPtr = NULL;
706 OCResource * collResource = (OCResource *) ehRequest->resource;
713 if (method == OC_REST_PUT)
715 json = cJSON_CreateObject();
716 cJSON_AddStringToObject(json, "href", resource->uri);
717 cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
719 OC_LOG(INFO, TAG, PCF("Group Action[PUT]."));
721 unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
722 GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
724 if (strcmp(doWhat, "DelActionSet") == 0)
726 if (FindAndDeleteActionSet(&resource, actionName) == OC_STACK_OK)
728 stackRet = OC_STACK_OK;
732 stackRet = OC_STACK_ERROR;
736 jsonResponse = cJSON_Print(json);
739 strcat((char *) bufferPtr, jsonResponse);
741 bufferLength = strlen((const char *) buffer);
742 if (bufferLength > 0)
744 OCEntityHandlerResponse response =
746 response.ehResult = OC_EH_OK;
747 response.payload = buffer;
748 response.payloadSize = bufferLength + 1;
749 response.persistentBufferFlag = 0;
750 response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
751 response.resourceHandle = (OCResourceHandle) collResource;
752 stackRet = OCDoResponse(&response);
755 stackRet = OC_STACK_OK;
758 if (method == OC_REST_POST)
760 OC_LOG(INFO, TAG, PCF("Group Action[POST]."));
762 OCActionSet *actionset = NULL;
763 unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
765 GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
767 json = cJSON_CreateObject();
768 cJSON_AddStringToObject(json, "href", resource->uri);
770 if (strcmp(doWhat, "DoAction") == 0)
772 if (GetActionSet(actionName, resource->actionsetHead, &actionset) != OC_STACK_OK)
774 OC_LOG(INFO, TAG, PCF("ERROR"));
775 stackRet = OC_STACK_ERROR;
778 if (actionset == NULL)
780 OC_LOG(INFO, TAG, PCF("ERROR"));
781 stackRet = OC_STACK_ERROR;
786 OCAction *pointerAction = actionset->head;
788 unsigned int num = GetNumOfTargetResource(pointerAction);
790 ((OCServerRequest *) ehRequest->requestHandle)->ehResponseHandler =
791 HandleAggregateResponse;
792 ((OCServerRequest *) ehRequest->requestHandle)->numResponses = num + 1;
794 // printf("ActionSet Name :: %s\n", actionset->actionsetName);
795 while (pointerAction != NULL)
797 unsigned char actionDesc[MAX_RESPONSE_LENGTH] = { 0 };
798 unsigned char* actionDescPtr = actionDesc;
799 uint16_t remaining = MAX_RESPONSE_LENGTH;
801 strcpy((char *) actionDescPtr, (const char *) OC_JSON_PREFIX);
802 BuildActionJSON(pointerAction, actionDescPtr, &remaining);
803 strcat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX);
805 ClientRequstInfo *info = (ClientRequstInfo *) OCMalloc(
806 sizeof(ClientRequstInfo));
807 memset(info, 0, sizeof(ClientRequstInfo));
809 info->collResource = resource;
810 info->ehRequest = (OCServerRequest *) ehRequest->requestHandle;
812 SendAction(&info->required, pointerAction->resourceUri, actionDescPtr);
814 AddClientRequestInfo(&clientRequstList, info);
817 pointerAction = pointerAction->next;
821 stackRet = OC_STACK_OK;
824 else if (strcmp(doWhat, "GetActionSet") == 0)
826 char *plainText = NULL;
827 OCActionSet *actionset = NULL;
829 cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
830 GetActionSet(actionName, resource->actionsetHead, &actionset);
831 if (actionset != NULL)
833 GetStringFromActionSet(actionset, &plainText);
835 if (plainText != NULL)
837 cJSON_AddStringToObject(format, "ActionSet", plainText);
840 stackRet = OC_STACK_OK;
844 jsonResponse = cJSON_Print(json);
847 strcat((char *) bufferPtr, jsonResponse);
849 bufferLength = strlen((const char *) buffer);
850 if (bufferLength > 0)
852 OCEntityHandlerResponse response =
854 response.ehResult = OC_EH_OK;
855 response.payload = buffer;
856 response.payloadSize = bufferLength + 1;
857 response.persistentBufferFlag = 0;
858 response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
859 response.resourceHandle = (OCResourceHandle) collResource;
860 stackRet = OCDoResponse(&response);