Fix infinite loop in GroupAction.
[platform/upstream/iotivity.git] / resource / csdk / stack / src / oicgroup.c
1 //******************************************************************
2 //
3 // Copyright 2014 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #define _POSIX_C_SOURCE 200112L
22 #include <string.h>
23
24 #include "cJSON.h"
25 #include "ocmalloc.h"
26 #include "oicgroup.h"
27 #include "ocresource.h"
28 #include "occollection.h"
29 #include "logger.h"
30
31 #define TAG PCF("OICGROUP")
32
33 #define DESC_DELIMITER "\""
34 #define ACTION_DELIMITER "*"
35 #define ATTR_DELIMITER "|"
36
37 typedef struct aggregatehandleinfo
38 {
39     OCServerRequest *ehRequest;
40     OCDoHandle required;
41     OCResource *collResource;
42
43     struct aggregatehandleinfo *next;
44 } ClientRequstInfo;
45
46 // unsigned int nHandleIdx = 0;
47 // ClientRequstInfo g_AggregateResponseHandle[10];
48
49 ClientRequstInfo *clientRequstList = NULL;
50
51 void AddClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* add)
52 {
53     ClientRequstInfo *tmp = NULL;
54
55     if (*head != NULL)
56     {
57         tmp = *head;
58
59         while (tmp->next)
60         {
61             tmp = tmp->next;
62         }
63         tmp->next = add;
64     }
65     else
66     {
67         *head = add;
68     }
69 }
70
71 ClientRequstInfo* GetClientRequestInfo(ClientRequstInfo *head, OCDoHandle handle)
72 {
73     ClientRequstInfo *tmp = NULL;
74
75     tmp = head;
76
77     if (tmp)
78     {
79         while (tmp)
80         {
81 //            printf("%p :: %p\n", tmp->required, handle);
82             if (tmp->required == handle)
83             {
84                 break;
85             }
86
87             tmp = tmp->next;
88         }
89
90         return tmp;
91     }
92     return NULL;
93 }
94
95 void RemoveClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* del)
96 {
97     ClientRequstInfo *tmp = NULL;
98
99     if (*head == del)
100     {
101         *head = (*head)->next;
102     }
103     else
104     {
105         tmp = *head;
106         while (tmp->next && (tmp->next != del))
107         {
108             tmp = tmp->next;
109         }
110         if (tmp->next)
111         {
112             tmp->next = del->next;
113         }
114     }
115 }
116
117
118
119 void AddCapability(OCCapability** head, OCCapability* node)
120 {
121     OCCapability *pointer = *head;
122     if (NULL == pointer)
123     {
124         *head = node;
125     }
126     else
127     {
128         while (pointer->next != NULL)
129         {
130             pointer = pointer->next;
131         }
132
133         pointer->next = node;
134     }
135 }
136
137 void AddAction(OCAction** head, OCAction* node)
138 {
139     OCAction *pointer = *head;
140     if (NULL == pointer)
141     {
142         *head = node;
143     }
144     else
145     {
146
147         while (pointer->next != NULL)
148         {
149             pointer = pointer->next;
150         }
151
152         pointer->next = node;
153     }
154 }
155
156 void AddActionSet(OCActionSet **head, OCActionSet* node)
157 {
158     OCActionSet *pointer = *head;
159     if (NULL == pointer)
160     {
161         *head = node;
162     }
163     else
164     {
165
166         while (pointer->next != NULL)
167         {
168             pointer = pointer->next;
169         }
170
171         pointer->next = node;
172     }
173 }
174
175 void DeleteCapability(OCCapability *del)
176 {
177     free(del->capability);
178     del->capability = NULL;
179     free(del->status);
180     del->status = NULL;
181 }
182
183 void DeleteAction(OCAction** action)
184 {
185     OCCapability* pointer = (*action)->head;
186     OCCapability* pDel = NULL;
187
188     while (pointer)
189     {
190         pDel = pointer;
191         pointer = pointer->next;
192
193         DeleteCapability(pDel);
194         pDel->next = NULL;
195     }
196     OCFree((*action)->resourceUri);
197     (*action)->resourceUri = NULL;
198     (*action)->next = NULL;
199 }
200
201 void DeleteActionSet(OCActionSet** actionset)
202 {
203     OCAction* pointer = (*actionset)->head;
204     OCAction* pDel = NULL;
205
206     while (pointer)
207     {
208         pDel = pointer;
209         pointer = pointer->next;
210
211         DeleteAction(&pDel);
212         pDel->next = NULL;
213     }
214
215     OCFree((*actionset)->actionsetName);
216     (*actionset)->head = NULL;
217 }
218
219 OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actionsetName)
220 {
221     if (*resource != NULL)
222     {
223         OCActionSet *pointer = NULL;
224         OCActionSet *pDel = NULL;
225
226         pointer = (*resource)->actionsetHead;
227
228         if (pointer == NULL)
229         {
230             return OC_STACK_ERROR;
231         }
232         else
233         {
234             if (strcmp(pointer->actionsetName, actionsetName) == 0)
235             {
236                 if (pointer->next != NULL)
237                     (*resource)->actionsetHead = pointer->next;
238                 else
239                     (*resource)->actionsetHead = NULL;
240                 DeleteActionSet(&pointer);
241             }
242             else if (pointer->next != NULL)
243             {
244                 while (pointer)
245                 {
246                     if (pointer->next != NULL)
247                     {
248                         if (strcmp(pointer->next->actionsetName, actionsetName) == 0)
249                         {
250                             pDel = pointer->next;
251                             pointer->next = pointer->next->next;
252
253                             DeleteActionSet(&pDel);
254                         }
255                     }
256                     pointer = pointer->next;
257                 }
258             }
259
260             return OC_STACK_OK;
261         }
262
263     }
264     return OC_STACK_ERROR;
265 }
266
267 OCStackResult DeleteActionSets(OCResource** resource)
268 {
269     OCActionSet *pointer = (*resource)->actionsetHead;
270     OCActionSet *pDel = pointer;
271
272     while (pointer)
273     {
274         pDel = pointer;
275         pointer = pointer->next;
276
277         DeleteActionSet(&pDel);
278         pDel->next = NULL;
279     }
280
281     (*resource)->actionsetHead = NULL;
282     return OC_STACK_OK;
283 }
284
285 OCStackResult GetActionSet(const char *actionName, OCActionSet *head, OCActionSet** actionset)
286 {
287     OCActionSet *pointer = head;
288
289     while (pointer)
290     {
291         if (strcmp(pointer->actionsetName, actionName) == 0)
292         {
293             *actionset = pointer;
294             return OC_STACK_OK;
295         }
296
297         pointer = pointer->next;
298     }
299
300     return OC_STACK_ERROR;
301
302 }
303
304 OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method,
305         char **actionsetName)
306 {
307     char *acitonRequest;
308     char *iterTokenPtr = NULL;
309     char *iterToken = NULL;
310     char *description = NULL;
311     char *iterDescPtr = NULL;
312
313     char *attributes = NULL;
314     char *iterAttrbutesPtr = NULL;
315
316     char *attr = NULL;
317     char *iterAttrPtr = NULL;
318
319     OCActionSet* actionset = NULL;
320     OCAction* action = NULL;
321
322     acitonRequest = (char *) OCMalloc(strlen((char *) request) + 1);
323     strncpy(acitonRequest, (char *) request, strlen((char *) request) + 1);
324
325     //printf("\t%s\n", acitonRequest);
326     if (acitonRequest != NULL)
327     {
328         iterToken = (char *) strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr);
329
330         while (iterToken != NULL)
331         {
332             if (strcmp(iterToken, "ActionSet") == 0)
333             { // if iterToken is ActionSet, will be created and added a new action set.
334
335                 *method = (char *) OCMalloc(strlen(iterToken) + 1);
336                 strncpy(*method, iterToken, strlen(iterToken) + 1);
337
338                 //GetActionName(iterToken, &actionsetName);
339                 // printf("%s\n", iterToken, &iterTokenPtr);
340                 // it is mean ':'.
341                 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
342
343                 // printf("%s\n", iterToken);
344                 // it is body of action description.
345                 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
346
347                 // printf("%s\n", iterToken);
348
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);
353
354                 // Find the action name from description.
355                 iterDescPtr = NULL;
356                 iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
357                 //while(iterToken != NULL)
358                 if (iterToken != NULL)
359                 {
360                     if (*actionsetName != NULL)
361                     {
362                         // printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
363                         return OC_STACK_ERROR; // ERROR OCCURED.
364                     }
365                     else
366                     {
367                         //  Actionset name.
368                         // printf("ACTION SET NAME :: %s\n", iterToken);
369                         *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
370
371                         strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
372                         // printf("ACTION SET NAME :: %s\n", *actionsetName);
373                         // break;
374                     }
375
376                     iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
377                 }
378                 else
379                 {
380                     return OC_STACK_ERROR;
381
382                 } // end Action Set Name.
383
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);
392
393                 while (iterToken != NULL)
394                 {
395                     action = (OCAction *) OCMalloc(sizeof(OCAction));
396                     memset(action, 0, sizeof(OCAction));
397
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);
402
403                     iterToken = (char *) strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr);
404                     while (iterToken != NULL)
405                     {
406                         attr = (char *) OCMalloc(strlen(iterToken) + 1);
407                         strncpy(attr, iterToken, strlen(iterToken) + 1);
408
409                         iterToken = (char *) strtok_r(attr, "=", &iterAttrPtr);
410                         while (iterToken != NULL)
411                         {
412                             // Find the URI from description.
413                             if (strcmp(iterToken, "uri") == 0)
414                             {
415                                 iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
416                                 action->resourceUri = (char *) OCMalloc(strlen(iterToken) + 1);
417                                 strncpy(action->resourceUri, iterToken, strlen(iterToken) + 1);
418                             }
419                             else
420                             {
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);
430
431                                 AddCapability(&action->head, capa);
432                             }
433
434                             iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
435                         }
436
437                         iterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr);
438                     } // End of Action
439
440                     AddAction(&actionset->head, action);
441
442                     iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
443                 }
444
445                 // 3. Add the pointer OCResource's ActionSet list.
446                 AddActionSet(&(*resource)->actionsetHead, actionset);
447                 return OC_STACK_OK;
448             }
449             else if (strcmp(iterToken, "DoAction") == 0 || strcmp(iterToken, "DelActionSet") == 0
450                     || strcmp(iterToken, "GetActionSet") == 0)
451             {
452                 *method = (char *) OCMalloc(strlen(iterToken) + 1);
453                 strncpy(*method, iterToken, strlen(iterToken) + 1);
454
455                 // it is mean ':'.
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);
461
462                 description = (char *) OCMalloc(strlen(iterToken) + 1);
463                 strncpy(description, iterToken, strlen(iterToken) + 1);
464
465                 // Find the action name from description.
466                 iterDescPtr = NULL;
467                 iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
468                 if (iterToken != NULL)
469                 {
470                     if (*actionsetName != NULL)
471                     {
472                         // printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
473                         return OC_STACK_ERROR; // ERROR OCCURED.
474                     }
475                     else
476                     {
477                         //  Actionset name.
478                         // printf("ACTION SET NAME :: %s\n", iterToken);
479                         *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
480
481                         strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
482                         // printf("ACTION SET NAME :: %s\n", *actionsetName);
483                     }
484
485                     iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
486                     return OC_STACK_OK;
487                 }
488                 else
489                 {
490                     return OC_STACK_ERROR;
491
492                 } // end Action Set Name.
493                 break;
494             }
495
496             iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
497         }
498     }
499
500     return OC_STACK_ERROR;
501 }
502
503 OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc)
504 {
505     char temp[1024] =
506     { 0 };
507     int remaining = 1023;
508
509     // OCActionSet *as = resource->actionsetHead;
510     // while(as != NULL)
511     // {
512     printf("\n\n\nAction Set Name :: %s\n", actionset->actionsetName);
513     OCAction *action = actionset->head;
514
515     if (remaining >= strlen(actionset->actionsetName) + 1)
516     {
517         strcat(temp, actionset->actionsetName);
518         remaining -= strlen(actionset->actionsetName);
519         strcat(temp, "*");
520         remaining--;
521     }
522     else
523     {
524         return OC_STACK_ERROR;
525     }
526
527     while (action != NULL)
528     {
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);
534         strcat(temp, "|");
535         remaining--;
536
537         OCCapability *capas = action->head;
538         while (capas != NULL)
539         {
540             printf("\t\t%s = %s\n", capas->capability, capas->status);
541             strcat(temp, capas->capability);
542             remaining -= strlen(capas->capability);
543             strcat(temp, "=");
544             remaining--;
545             strcat(temp, capas->status);
546             remaining -= strlen(capas->capability);
547
548             capas = capas->next;
549             if (capas != NULL)
550             {
551                 strcat(temp, "|");
552             }
553         }
554
555         action = action->next;
556         if (action != NULL)
557         {
558             strcat(temp, "*");
559             remaining--;
560         }
561     }
562     //     as = as->next;
563     // }
564
565     *desc = (char *) OCMalloc(1024 - remaining);
566     strcpy(*desc, temp);
567     // printf("\t\tPlain Text = %s(%i)\n", *desc, 1024 - remaining);
568
569     return OC_STACK_OK;
570 }
571
572 OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
573         OCClientResponse* clientResponse)
574 {
575     printf("\n\n\tcallback is called\n\n");
576
577     ClientRequstInfo *info = GetClientRequestInfo(clientRequstList, handle);
578
579     if (info)
580     {
581         int idx;
582
583         unsigned char *responseJson;
584         responseJson = (unsigned char *) OCMalloc(
585                 (unsigned int) (strlen((char *) clientResponse->resJSONPayload) + 1));
586
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;
594
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;
602
603         OCDoResponse(&response);
604
605         RemoveClientRequestInfo(&clientRequstList, info);
606         OCFree(responseJson);
607     }
608
609     // g_AggregateResponseHandle
610
611     return OC_STACK_KEEP_TRANSACTION;
612 }
613
614 void ActionSetCD(void *context)
615 {
616     // printf("\n\t\tCD is called\n");
617
618     // free( context );
619 }
620
621 OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr, uint16_t *remaining)
622 {
623     OCStackResult ret = OC_STACK_ERROR;
624     cJSON *json;
625     cJSON *body;
626
627     char *jsonStr;
628     uint16_t jsonLen;
629
630     OC_LOG(INFO, TAG, PCF("Entering BuildActionJSON"));
631     json = cJSON_CreateObject();
632
633     cJSON_AddItemToObject(json, "rep", body = cJSON_CreateObject());
634
635     OCCapability* pointerCapa = action->head;
636     while (pointerCapa)
637     {
638         cJSON_AddStringToObject(body, pointerCapa->capability, pointerCapa->status);
639         pointerCapa = pointerCapa->next;
640     }
641
642     jsonStr = cJSON_PrintUnformatted(json);
643
644     jsonLen = strlen(jsonStr);
645     if (jsonLen < *remaining)
646     {
647         strcat((char*) bufferPtr, jsonStr);
648         *remaining -= jsonLen;
649         bufferPtr += jsonLen;
650         ret = OC_STACK_OK;
651     }
652
653     cJSON_Delete(json);
654     free(jsonStr);
655
656     return ret;
657 }
658
659 unsigned int GetNumOfTargetResource(OCAction *actionset)
660 {
661     int numOfREsource = 0;
662
663     OCAction *pointerAction = actionset;
664
665     while (pointerAction != NULL)
666     {
667         numOfREsource++;
668         pointerAction = pointerAction->next;
669     }
670
671     return numOfREsource;
672 }
673
674 OCStackResult SendAction(OCDoHandle *handle, const char *targetUri, const unsigned char *action)
675 {
676     OCCallbackData cbdata =
677     { 0 };
678     cbdata.cb = &ActionSetCB;
679     cbdata.cd = &ActionSetCD;
680     cbdata.context = (void *) 0x99;
681
682     return OCDoResource(handle, OC_REST_PUT, targetUri,
683     //temp->rsrcType->resourcetypename,
684             NULL, (char *) action, OC_NA_QOS, &cbdata, NULL, 0);
685 }
686
687 OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/,
688         OCResource *resource, OCEntityHandlerRequest *ehRequest)
689 {
690     OCStackResult stackRet = OC_STACK_ERROR;
691
692     OC_LOG(INFO, TAG, PCF("Group Action is requested."));
693     // if (stackRet == OC_STACK_OK)
694     {
695
696         char *doWhat = NULL;
697         char *actionName = NULL;
698
699         size_t bufferLength = 0;
700         unsigned char buffer[MAX_RESPONSE_LENGTH] =
701         { 0 };
702         unsigned char *bufferPtr = NULL;
703
704         bufferPtr = buffer;
705
706         OCResource * collResource = (OCResource *) ehRequest->resource;
707
708         char *jsonResponse;
709
710         cJSON *json;
711         cJSON *format;
712
713         if (method == OC_REST_PUT)
714         {
715             json = cJSON_CreateObject();
716             cJSON_AddStringToObject(json, "href", resource->uri);
717             cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
718
719             OC_LOG(INFO, TAG, PCF("Group Action[PUT]."));
720
721             unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
722             GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
723
724             if (strcmp(doWhat, "DelActionSet") == 0)
725             {
726                 if (FindAndDeleteActionSet(&resource, actionName) == OC_STACK_OK)
727                 {
728                     stackRet = OC_STACK_OK;
729                 }
730                 else
731                 {
732                     stackRet = OC_STACK_ERROR;
733                 }
734             }
735
736             jsonResponse = cJSON_Print(json);
737             cJSON_Delete(json);
738
739             strcat((char *) bufferPtr, jsonResponse);
740
741             bufferLength = strlen((const char *) buffer);
742             if (bufferLength > 0)
743             {
744                 OCEntityHandlerResponse response =
745                 { 0 };
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);
753             }
754
755             stackRet = OC_STACK_OK;
756         }
757
758         if (method == OC_REST_POST)
759         {
760             OC_LOG(INFO, TAG, PCF("Group Action[POST]."));
761
762             OCActionSet *actionset = NULL;
763             unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
764
765             GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
766
767             json = cJSON_CreateObject();
768             cJSON_AddStringToObject(json, "href", resource->uri);
769
770             if (strcmp(doWhat, "DoAction") == 0)
771             {
772                 if (GetActionSet(actionName, resource->actionsetHead, &actionset) != OC_STACK_OK)
773                 {
774                     OC_LOG(INFO, TAG, PCF("ERROR"));
775                     stackRet = OC_STACK_ERROR;
776                 }
777
778                 if (actionset == NULL)
779                 {
780                     OC_LOG(INFO, TAG, PCF("ERROR"));
781                     stackRet = OC_STACK_ERROR;
782                 }
783                 else
784                 {
785
786                     OCAction *pointerAction = actionset->head;
787
788                     unsigned int num = GetNumOfTargetResource(pointerAction);
789
790                     ((OCServerRequest *) ehRequest->requestHandle)->ehResponseHandler =
791                             HandleAggregateResponse;
792                     ((OCServerRequest *) ehRequest->requestHandle)->numResponses = num + 1;
793
794 //                    printf("ActionSet Name :: %s\n", actionset->actionsetName);
795                     while (pointerAction != NULL)
796                     {
797                         unsigned char actionDesc[MAX_RESPONSE_LENGTH] = { 0 };
798                         unsigned char* actionDescPtr = actionDesc;
799                         uint16_t remaining = MAX_RESPONSE_LENGTH;
800
801                         strcpy((char *) actionDescPtr, (const char *) OC_JSON_PREFIX);
802                         BuildActionJSON(pointerAction, actionDescPtr, &remaining);
803                         strcat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX);
804
805                         ClientRequstInfo *info = (ClientRequstInfo *) OCMalloc(
806                                 sizeof(ClientRequstInfo));
807                         memset(info, 0, sizeof(ClientRequstInfo));
808
809                         info->collResource = resource;
810                         info->ehRequest = (OCServerRequest *) ehRequest->requestHandle;
811
812                         SendAction(&info->required, pointerAction->resourceUri, actionDescPtr);
813
814                         AddClientRequestInfo(&clientRequstList, info);
815
816
817                         pointerAction = pointerAction->next;
818                     }
819
820
821                     stackRet = OC_STACK_OK;
822                 }
823             }
824             else if (strcmp(doWhat, "GetActionSet") == 0)
825             {
826                 char *plainText = NULL;
827                 OCActionSet *actionset = NULL;
828
829                 cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
830                 GetActionSet(actionName, resource->actionsetHead, &actionset);
831                 if (actionset != NULL)
832                 {
833                     GetStringFromActionSet(actionset, &plainText);
834
835                     if (plainText != NULL)
836                     {
837                         cJSON_AddStringToObject(format, "ActionSet", plainText);
838                     }
839
840                     stackRet = OC_STACK_OK;
841                 }
842             }
843
844             jsonResponse = cJSON_Print(json);
845             cJSON_Delete(json);
846
847             strcat((char *) bufferPtr, jsonResponse);
848
849             bufferLength = strlen((const char *) buffer);
850             if (bufferLength > 0)
851             {
852                 OCEntityHandlerResponse response =
853                 { 0 };
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);
861             }
862         }
863     }
864
865     return stackRet;
866 }