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