Removed execute permissions from non-executable files.
[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 void AddCapability(OCCapability** head, OCCapability* node)
37 {
38     OCCapability *pointer = *head;
39     if (NULL == pointer)
40     {
41         *head = node;
42     }
43     else
44     {
45         while (pointer->next != NULL)
46         {
47             pointer = pointer->next;
48         }
49
50         pointer->next = node;
51     }
52 }
53
54 void AddAction(OCAction** head, OCAction* node)
55 {
56     OCAction *pointer = *head;
57     if (NULL == pointer)
58     {
59         *head = node;
60     }
61     else
62     {
63
64         while (pointer->next != NULL)
65         {
66             pointer = pointer->next;
67         }
68
69         pointer->next = node;
70     }
71 }
72
73 void AddActionSet(OCActionSet **head, OCActionSet* node)
74 {
75     OCActionSet *pointer = *head;
76     if (NULL == pointer)
77     {
78         *head = node;
79     }
80     else
81     {
82
83         while (pointer->next != NULL)
84         {
85             pointer = pointer->next;
86         }
87
88         pointer->next = node;
89     }
90 }
91
92 void DeleteCapability(OCCapability *del)
93 {
94     free(del->capability);
95     del->capability = NULL;
96     free(del->status);
97     del->status = NULL;
98 }
99
100 void DeleteAction(OCAction** action)
101 {
102     OCCapability* pointer = (*action)->head;
103     OCCapability* pDel = NULL;
104
105     while (pointer)
106     {
107         pDel = pointer;
108         pointer = pointer->next;
109
110         DeleteCapability(pDel);
111         pDel->next = NULL;
112     }
113     OCFree((*action)->resourceUri);
114     (*action)->resourceUri = NULL;
115     (*action)->next = NULL;
116 }
117
118 void DeleteActionSet(OCActionSet** actionset)
119 {
120     OCAction* pointer = (*actionset)->head;
121     OCAction* pDel = NULL;
122
123     while (pointer)
124     {
125         pDel = pointer;
126         pointer = pointer->next;
127
128         DeleteAction(&pDel);
129         pDel->next = NULL;
130     }
131
132     OCFree((*actionset)->actionsetName);
133     (*actionset)->head = NULL;
134 }
135
136 OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actionsetName)
137 {
138
139     if (*resource != NULL)
140     {
141
142         OCActionSet *pointer = NULL;
143         OCActionSet *pDel = NULL;
144
145         pointer = (*resource)->actionsetHead;
146
147         if (pointer == NULL)
148         {
149             return OC_STACK_ERROR;
150         }
151         else
152         {
153             if (strcmp(pointer->actionsetName, actionsetName) == 0)
154             {
155                 if (pointer->next != NULL)
156                     (*resource)->actionsetHead = pointer->next;
157                 else
158                     (*resource)->actionsetHead = NULL;
159
160                 DeleteActionSet(&pointer);
161
162             }
163             else if (pointer->next != NULL)
164             {
165                 while (pointer)
166                 {
167                     if (pointer->next != NULL)
168                     {
169                         if (strcmp(pointer->next->actionsetName, actionsetName) == 0)
170                         {
171                             pDel = pointer->next;
172                             pointer->next = pointer->next->next;
173
174                             DeleteActionSet(&pDel);
175                         }
176                     }
177                 }
178             }
179
180             return OC_STACK_OK;
181         }
182
183     }
184
185     return OC_STACK_ERROR;
186 }
187
188 OCStackResult DeleteActionSets(OCResource** resource)
189 {
190     OCActionSet *pointer = (*resource)->actionsetHead;
191     OCActionSet *pDel = pointer;
192
193     while (pointer)
194     {
195         pDel = pointer;
196         pointer = pointer->next;
197
198         DeleteActionSet(&pDel);
199         pDel->next = NULL;
200     }
201
202     (*resource)->actionsetHead = NULL;
203     return OC_STACK_OK;
204 }
205
206 OCStackResult GetActionSet(const char *actionName, OCActionSet *head, OCActionSet** actionset)
207 {
208     OCActionSet *pointer = head;
209
210     while (pointer)
211     {
212         //printf("%s :: %s\n", pointer->actionsetName, actionsetName);
213         if (strcmp(pointer->actionsetName, actionName) == 0)
214         {
215             *actionset = pointer;
216             return OC_STACK_OK;
217         }
218
219         pointer = pointer->next;
220     }
221
222     return OC_STACK_ERROR;
223
224 }
225
226 OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method,
227         char **actionsetName)
228 {
229     char *acitonRequest;
230     char *iterTokenPtr = NULL;
231     char *iterToken = NULL;
232     char *description = NULL;
233     char *iterDescPtr = NULL;
234
235     char *attributes = NULL;
236     char *iterAttrbutesPtr = NULL;
237
238     char *attr = NULL;
239     char *iterAttrPtr = NULL;
240
241     OCActionSet* actionset = NULL;
242     OCAction* action = NULL;
243
244     acitonRequest = (char *) OCMalloc(strlen((char *) request) + 1);
245     strncpy(acitonRequest, (char *) request, strlen((char *) request) + 1);
246
247     //printf("\t%s\n", acitonRequest);
248     if (acitonRequest != NULL)
249     {
250         iterToken = (char *) strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr);
251
252         while (iterToken != NULL)
253         {
254             if (strcmp(iterToken, "ActionSet") == 0)
255             { // if iterToken is ActionSet, will be created and added a new action set.
256
257                 *method = (char *) OCMalloc(strlen(iterToken) + 1);
258                 strncpy(*method, iterToken, strlen(iterToken) + 1);
259
260                 //GetActionName(iterToken, &actionsetName);
261                 // printf("%s\n", iterToken, &iterTokenPtr);
262                 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is mean ':'.
263                 // printf("%s\n", iterToken);
264                 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is body of action description.
265                 // printf("%s\n", iterToken);
266
267                 printf("DESC :: %s\n", iterToken);
268                 description = (char *) OCMalloc(strlen(iterToken) + 1);
269                 strncpy(description, iterToken, strlen(iterToken) + 1);
270                 printf("DESC Copied :: %s\n", description);
271
272                 // Find the action name from description.
273                 iterDescPtr = NULL;
274                 iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
275                 //while(iterToken != NULL)
276                 if (iterToken != NULL)
277                 {
278                     if (*actionsetName != NULL)
279                     {
280                         printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
281                         return OC_STACK_ERROR; // ERROR OCCURED.
282                     }
283                     else
284                     {
285                         //  Actionset name.
286                         printf("ACTION SET NAME :: %s\n", iterToken);
287                         *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
288
289                         strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
290                         printf("ACTION SET NAME :: %s\n", *actionsetName);
291                         // break;
292                     }
293
294                     iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
295                 }
296                 else
297                 {
298                     return OC_STACK_ERROR;
299
300                 } // end Action Set Name.
301
302                 // New ActionSet Add to OCResource's ActionSet list.
303                 // 1. Allocate a new pointer for actionset.
304                 actionset = (OCActionSet*) OCMalloc(sizeof(OCActionSet));
305                 // 2. Initiate actionset.
306                 memset(actionset, 0, sizeof(OCActionSet));
307                 actionset->actionsetName = (char *) OCMalloc(strlen(*actionsetName) + 1);
308                 strncpy(actionset->actionsetName, *actionsetName, strlen(*actionsetName) + 1);
309                 printf("ACTION SET NAME :: %s\n", actionset->actionsetName);
310
311                 while (iterToken != NULL)
312                 {
313                     action = (OCAction *) OCMalloc(sizeof(OCAction));
314                     memset(action, 0, sizeof(OCAction));
315
316                     printf("ATTR Copied :: %s\n", iterToken);
317                     attributes = (char *) OCMalloc(strlen(iterToken) + 1);
318                     strncpy(attributes, iterToken, strlen(iterToken) + 1);
319                     printf("ATTR Copied :: %s\n", attributes);
320
321                     iterToken = (char *) strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr);
322                     while (iterToken != NULL)
323                     {
324                         attr = (char *) OCMalloc(strlen(iterToken) + 1);
325                         strncpy(attr, iterToken, strlen(iterToken) + 1);
326
327                         iterToken = (char *) strtok_r(attr, "=", &iterAttrPtr);
328                         while (iterToken != NULL)
329                         {
330                             // Find the URI from description.
331                             if (strcmp(iterToken, "uri") == 0)
332                             {
333                                 iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
334                                 printf("uri :: %s\n", iterToken);
335                                 action->resourceUri = (char *) OCMalloc(strlen(iterToken) + 1);
336                                 strncpy(action->resourceUri, iterToken, strlen(iterToken) + 1);
337                             }
338                             else
339                             {
340                                 OCCapability* capa = (OCCapability*) OCMalloc(sizeof(OCCapability));
341                                 memset(capa, 0, sizeof(OCCapability));
342                                 printf("%s :: ", iterToken);
343                                 capa->capability = (char *) OCMalloc(strlen(iterToken) + 1);
344                                 strncpy(capa->capability, iterToken, strlen(iterToken) + 1);
345                                 iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
346                                 printf("%s\n", iterToken);
347                                 capa->status = (char *) OCMalloc(strlen(iterToken) + 1);
348                                 strncpy(capa->status, iterToken, strlen(iterToken) + 1);
349
350                                 AddCapability(&action->head, capa);
351                             }
352
353                             iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
354                         }
355
356                         iterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr);
357                     } // End of Action
358
359                     AddAction(&actionset->head, action);
360
361                     iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
362                 }
363
364                 // 3. Add the pointer OCResource's ActionSet list.
365                 AddActionSet(&(*resource)->actionsetHead, actionset);
366                 return OC_STACK_OK;
367             }
368             else if (strcmp(iterToken, "DoAction") == 0 || strcmp(iterToken, "DelActionSet") == 0
369                     || strcmp(iterToken, "GetActionSet") == 0)
370             {
371                 *method = (char *) OCMalloc(strlen(iterToken) + 1);
372                 strncpy(*method, iterToken, strlen(iterToken) + 1);
373
374                 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is mean ':'.
375                 // printf("%s\n", iterToken);
376                 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is body of action description.
377                 // printf("%s\n", iterToken);
378
379                 description = (char *) OCMalloc(strlen(iterToken) + 1);
380                 strncpy(description, iterToken, strlen(iterToken) + 1);
381
382                 // Find the action name from description.
383                 iterDescPtr = NULL;
384                 iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
385                 if (iterToken != NULL)
386                 {
387                     if (*actionsetName != NULL)
388                     {
389                         printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
390                         return OC_STACK_ERROR; // ERROR OCCURED.
391                     }
392                     else
393                     {
394                         //  Actionset name.
395                         printf("ACTION SET NAME :: %s\n", iterToken);
396                         *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
397
398                         strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
399                         printf("ACTION SET NAME :: %s\n", *actionsetName);
400                     }
401
402                     iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
403                     return OC_STACK_OK;
404                 }
405                 else
406                 {
407                     return OC_STACK_ERROR;
408
409                 } // end Action Set Name.
410                 break;
411             }
412
413             iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
414         }
415     }
416
417     return OC_STACK_ERROR;
418 }
419
420 OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc)
421 {
422     char temp[1024] =
423     { 0 };
424     int remaining = 1023;
425
426     // OCActionSet *as = resource->actionsetHead;
427     // while(as != NULL)
428     // {
429     printf("\n\n\nAction Set Name :: %s\n", actionset->actionsetName);
430     OCAction *action = actionset->head;
431
432     if (remaining >= strlen(actionset->actionsetName) + 1)
433     {
434         strcat(temp, actionset->actionsetName);
435         remaining -= strlen(actionset->actionsetName);
436         strcat(temp, "*");
437         remaining--;
438     }
439     else
440     {
441         return OC_STACK_ERROR;
442     }
443
444     while (action != NULL)
445     {
446         printf("\tURI :: %s\n", action->resourceUri);
447         strcat(temp, "uri=");
448         remaining -= strlen("uri=");
449         strcat(temp, action->resourceUri);
450         remaining -= strlen(action->resourceUri);
451         strcat(temp, "|");
452         remaining--;
453
454         OCCapability *capas = action->head;
455         while (capas != NULL)
456         {
457             printf("\t\t%s = %s\n", capas->capability, capas->status);
458             strcat(temp, capas->capability);
459             remaining -= strlen(capas->capability);
460             strcat(temp, "=");
461             remaining--;
462             strcat(temp, capas->status);
463             remaining -= strlen(capas->capability);
464
465             capas = capas->next;
466             if (capas != NULL)
467             {
468                 strcat(temp, "|");
469             }
470         }
471
472         action = action->next;
473         if (action != NULL)
474         {
475             strcat(temp, "*");
476             remaining--;
477         }
478     }
479     //     as = as->next;
480     // }
481
482     *desc = (char *) OCMalloc(1024 - remaining);
483     strcpy(*desc, temp);
484     // printf("\t\tPlain Text = %s(%i)\n", *desc, 1024 - remaining);
485
486     return OC_STACK_OK;
487 }
488
489 OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
490         OCClientResponse* clientResponse)
491 {
492
493     // printf("\n\n\tcallback is called\n\n");
494     // printf("\t\tresponse JSON : %s\n", clientResponse->resJSONPayload);
495
496     return OC_STACK_KEEP_TRANSACTION;
497 }
498
499 void ActionSetCD(void *context)
500 {
501     // printf("\n\t\tCD is called\n");
502
503     // free( context );
504 }
505
506 OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr, uint16_t *remaining)
507 {
508     OCStackResult ret = OC_STACK_ERROR;
509     cJSON *json;
510     cJSON *body;
511
512     char *jsonStr;
513     uint16_t jsonLen;
514
515     OC_LOG(INFO, TAG, PCF("Entering BuildActionJSON"));
516     json = cJSON_CreateObject();
517
518     cJSON_AddItemToObject(json, "rep", body = cJSON_CreateObject());
519
520     OCCapability* pointerCapa = action->head;
521     while (pointerCapa)
522     {
523         cJSON_AddStringToObject(body, pointerCapa->capability, pointerCapa->status);
524         pointerCapa = pointerCapa->next;
525     }
526
527     jsonStr = cJSON_PrintUnformatted(json);
528
529     jsonLen = strlen(jsonStr);
530     if (jsonLen < *remaining)
531     {
532         strcat((char*) bufferPtr, jsonStr);
533         *remaining -= jsonLen;
534         bufferPtr += jsonLen;
535         ret = OC_STACK_OK;
536     }
537
538     cJSON_Delete(json);
539     free(jsonStr);
540
541     return ret;
542 }
543
544 OCStackResult SendAction(const char *targetUri, const unsigned char *action)
545 {
546     OCCallbackData cbdata =
547     { 0 };
548     cbdata.cb = &ActionSetCB;
549     cbdata.cd = &ActionSetCD;
550     cbdata.context = (void *) 0x99;
551
552     OCDoHandle handle;
553     return OCDoResource(&handle, OC_REST_PUT, targetUri,
554     //temp->rsrcType->resourcetypename,
555             NULL, (char *) action, OC_NA_QOS, &cbdata, NULL, 0);
556 }
557
558 OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/,
559         OCResource *resource, OCEntityHandlerRequest *ehRequest)
560 {
561     OCStackResult stackRet = OC_STACK_ERROR;
562     // OCEntityHandlerResult ehRet = OC_EH_ERROR;
563
564     OC_LOG(INFO, TAG, PCF("Group Action is requested."));
565     // if (stackRet == OC_STACK_OK)
566     {
567
568         char *doWhat = NULL;
569         char *actionName = NULL;
570
571         // uint16_t remaining = MAX_RESPONSE_LENGTH;
572         size_t bufferLength = 0;
573         unsigned char buffer[MAX_RESPONSE_LENGTH] =
574         { 0 };
575         unsigned char *bufferPtr = NULL;
576
577         bufferPtr = buffer;
578
579         OCResource * collResource = (OCResource *) ehRequest->resource;
580         // OCResourceHandle origResourceHandle = ehRequest->resource;
581
582         char *jsonResponse;
583
584         cJSON *json = cJSON_CreateObject();
585         cJSON *format;
586
587         cJSON_AddStringToObject(json, "href", resource->uri);
588         cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
589
590         if (method == OC_REST_GET)
591         {
592             OC_LOG(INFO, TAG, PCF("Group Action[GET]."));
593         }
594         else if (method == OC_REST_PUT)
595         {
596             OC_LOG(INFO, TAG, PCF("Group Action[PUT]."));
597
598             unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
599
600             GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
601
602             if (strcmp(doWhat, "DelActionSet") == 0)
603             {
604                 if (FindAndDeleteActionSet(&resource, actionName) == OC_STACK_OK)
605                 {
606                 }
607                 else
608                 {
609                 }
610             }
611             else
612             {
613             }
614
615             stackRet = OC_STACK_OK;
616
617         }
618         else if (method == OC_REST_POST)
619         {
620             OC_LOG(INFO, TAG, PCF("Group Action[POST]."));
621
622             OCActionSet *actionset = NULL;
623             unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
624
625             GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
626
627             if (strcmp(doWhat, "DoAction") == 0)
628             {
629                 if (GetActionSet(actionName, resource->actionsetHead, &actionset) != OC_STACK_OK)
630                 {
631                     OC_LOG(INFO, TAG, PCF("ERROR"));
632                     stackRet = OC_STACK_ERROR;
633                 }
634
635                 if (actionset == NULL)
636                 {
637                     OC_LOG(INFO, TAG, PCF("ERROR"));
638                     stackRet = OC_STACK_ERROR;
639                 } else {
640
641                     // printf("Execute ActionSet :: %s\n", actionset->actionsetName);
642
643                     OCAction *pointerAction = actionset->head;
644                     while (pointerAction != NULL)
645                     {
646                         // printf("Action Target :: %s\n", pointerAction->resourceUri);
647
648                         unsigned char actionDesc[MAX_RESPONSE_LENGTH] =
649                         { 0 };
650                         unsigned char* actionDescPtr = actionDesc;
651                         uint16_t remaining = MAX_RESPONSE_LENGTH;
652
653                         strcpy((char *) actionDescPtr, (const char *) OC_JSON_PREFIX);
654                         BuildActionJSON(pointerAction, actionDescPtr, &remaining);
655                         strcat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX);
656
657                         SendAction(pointerAction->resourceUri, actionDescPtr);
658
659                         pointerAction = pointerAction->next;
660                     }
661                     stackRet = OC_STACK_OK;
662                 }
663             }
664             else if (strcmp(doWhat, "GetActionSet") == 0)
665             {
666                 char *plainText = NULL;
667                 OCActionSet *actionset = NULL;
668
669                 // char *jsonResponse;
670
671                 GetActionSet(actionName, resource->actionsetHead, &actionset);
672                 if(actionset != NULL)
673                 {
674                     GetStringFromActionSet(actionset, &plainText);
675
676                     if (plainText != NULL)
677                     {
678                         cJSON_AddStringToObject(format, "ActionSet", plainText);
679
680                         // jsonResponse = cJSON_Print(json);
681                         // cJSON_Delete(json);
682
683                         // strcat((char *)bufferPtr, jsonResponse);
684                     }
685
686                     stackRet = OC_STACK_OK;
687                 }
688             }
689             else if (actionName == NULL)
690             {
691                 // printf("Cannot find actionname\n");
692                 return OC_STACK_ERROR;
693             }
694         }
695
696         jsonResponse = cJSON_Print(json);
697         cJSON_Delete(json);
698
699         strcat((char *) bufferPtr, jsonResponse);
700
701         // printf("\n\tRESONSE ::\n%s\n", buffer);
702         bufferLength = strlen((const char *) buffer);
703         if (bufferLength > 0)
704         {
705             OCEntityHandlerResponse response =
706             { 0 };
707             response.ehResult = OC_EH_OK;
708             response.payload = buffer;
709             response.payloadSize = bufferLength + 1;
710             response.persistentBufferFlag = 0;
711             response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
712             response.resourceHandle = (OCResourceHandle) collResource;
713             stackRet = OCDoResponse(&response);
714         }
715
716         // ehRequest->resource = origResourceHandle;
717     }
718
719     return stackRet;
720
721     //return OC_STACK_OK;
722 }