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"
30 #define TAG PCF("OICGROUP")
32 #define DESC_DELIMITER "\""
33 #define ACTION_DELIMITER "*"
34 #define ATTR_DELIMITER "|"
36 void AddCapability(OCCapability** head, OCCapability* node)
38 OCCapability *pointer = *head;
45 while (pointer->next != NULL)
47 pointer = pointer->next;
54 void AddAction(OCAction** head, OCAction* node)
56 OCAction *pointer = *head;
64 while (pointer->next != NULL)
66 pointer = pointer->next;
73 void AddActionSet(OCActionSet **head, OCActionSet* node)
75 OCActionSet *pointer = *head;
83 while (pointer->next != NULL)
85 pointer = pointer->next;
92 void DeleteCapability(OCCapability *del)
94 free(del->capability);
95 del->capability = NULL;
100 void DeleteAction(OCAction** action)
102 OCCapability* pointer = (*action)->head;
103 OCCapability* pDel = NULL;
108 pointer = pointer->next;
110 DeleteCapability(pDel);
113 OCFree((*action)->resourceUri);
114 (*action)->resourceUri = NULL;
115 (*action)->next = NULL;
118 void DeleteActionSet(OCActionSet** actionset)
120 OCAction* pointer = (*actionset)->head;
121 OCAction* pDel = NULL;
126 pointer = pointer->next;
132 OCFree((*actionset)->actionsetName);
133 (*actionset)->head = NULL;
136 OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actionsetName)
139 if (*resource != NULL)
142 OCActionSet *pointer = NULL;
143 OCActionSet *pDel = NULL;
145 pointer = (*resource)->actionsetHead;
149 return OC_STACK_ERROR;
153 if (strcmp(pointer->actionsetName, actionsetName) == 0)
155 if (pointer->next != NULL)
156 (*resource)->actionsetHead = pointer->next;
158 (*resource)->actionsetHead = NULL;
160 DeleteActionSet(&pointer);
163 else if (pointer->next != NULL)
167 if (pointer->next != NULL)
169 if (strcmp(pointer->next->actionsetName, actionsetName) == 0)
171 pDel = pointer->next;
172 pointer->next = pointer->next->next;
174 DeleteActionSet(&pDel);
185 return OC_STACK_ERROR;
188 OCStackResult DeleteActionSets(OCResource** resource)
190 OCActionSet *pointer = (*resource)->actionsetHead;
191 OCActionSet *pDel = pointer;
196 pointer = pointer->next;
198 DeleteActionSet(&pDel);
202 (*resource)->actionsetHead = NULL;
206 OCStackResult GetActionSet(const char *actionName, OCActionSet *head, OCActionSet** actionset)
208 OCActionSet *pointer = head;
212 //printf("%s :: %s\n", pointer->actionsetName, actionsetName);
213 if (strcmp(pointer->actionsetName, actionName) == 0)
215 *actionset = pointer;
219 pointer = pointer->next;
222 return OC_STACK_ERROR;
226 OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method,
227 char **actionsetName)
230 char *iterTokenPtr = NULL;
231 char *iterToken = NULL;
232 char *description = NULL;
233 char *iterDescPtr = NULL;
235 char *attributes = NULL;
236 char *iterAttrbutesPtr = NULL;
239 char *iterAttrPtr = NULL;
241 OCActionSet* actionset = NULL;
242 OCAction* action = NULL;
244 acitonRequest = (char *) OCMalloc(strlen((char *) request) + 1);
245 strncpy(acitonRequest, (char *) request, strlen((char *) request) + 1);
247 //printf("\t%s\n", acitonRequest);
248 if (acitonRequest != NULL)
250 iterToken = (char *) strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr);
252 while (iterToken != NULL)
254 if (strcmp(iterToken, "ActionSet") == 0)
255 { // if iterToken is ActionSet, will be created and added a new action set.
257 *method = (char *) OCMalloc(strlen(iterToken) + 1);
258 strncpy(*method, iterToken, strlen(iterToken) + 1);
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);
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);
272 // Find the action name from description.
274 iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
275 //while(iterToken != NULL)
276 if (iterToken != NULL)
278 if (*actionsetName != NULL)
280 printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
281 return OC_STACK_ERROR; // ERROR OCCURED.
286 printf("ACTION SET NAME :: %s\n", iterToken);
287 *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
289 strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
290 printf("ACTION SET NAME :: %s\n", *actionsetName);
294 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
298 return OC_STACK_ERROR;
300 } // end Action Set Name.
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);
311 while (iterToken != NULL)
313 action = (OCAction *) OCMalloc(sizeof(OCAction));
314 memset(action, 0, sizeof(OCAction));
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);
321 iterToken = (char *) strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr);
322 while (iterToken != NULL)
324 attr = (char *) OCMalloc(strlen(iterToken) + 1);
325 strncpy(attr, iterToken, strlen(iterToken) + 1);
327 iterToken = (char *) strtok_r(attr, "=", &iterAttrPtr);
328 while (iterToken != NULL)
330 // Find the URI from description.
331 if (strcmp(iterToken, "uri") == 0)
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);
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);
350 AddCapability(&action->head, capa);
353 iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
356 iterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr);
359 AddAction(&actionset->head, action);
361 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
364 // 3. Add the pointer OCResource's ActionSet list.
365 AddActionSet(&(*resource)->actionsetHead, actionset);
368 else if (strcmp(iterToken, "DoAction") == 0 || strcmp(iterToken, "DelActionSet") == 0
369 || strcmp(iterToken, "GetActionSet") == 0)
371 *method = (char *) OCMalloc(strlen(iterToken) + 1);
372 strncpy(*method, iterToken, strlen(iterToken) + 1);
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);
379 description = (char *) OCMalloc(strlen(iterToken) + 1);
380 strncpy(description, iterToken, strlen(iterToken) + 1);
382 // Find the action name from description.
384 iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
385 if (iterToken != NULL)
387 if (*actionsetName != NULL)
389 printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
390 return OC_STACK_ERROR; // ERROR OCCURED.
395 printf("ACTION SET NAME :: %s\n", iterToken);
396 *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
398 strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
399 printf("ACTION SET NAME :: %s\n", *actionsetName);
402 iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
407 return OC_STACK_ERROR;
409 } // end Action Set Name.
413 iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
417 return OC_STACK_ERROR;
420 OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc)
424 int remaining = 1023;
426 // OCActionSet *as = resource->actionsetHead;
429 printf("\n\n\nAction Set Name :: %s\n", actionset->actionsetName);
430 OCAction *action = actionset->head;
432 if (remaining >= strlen(actionset->actionsetName) + 1)
434 strcat(temp, actionset->actionsetName);
435 remaining -= strlen(actionset->actionsetName);
441 return OC_STACK_ERROR;
444 while (action != NULL)
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);
454 OCCapability *capas = action->head;
455 while (capas != NULL)
457 printf("\t\t%s = %s\n", capas->capability, capas->status);
458 strcat(temp, capas->capability);
459 remaining -= strlen(capas->capability);
462 strcat(temp, capas->status);
463 remaining -= strlen(capas->capability);
472 action = action->next;
482 *desc = (char *) OCMalloc(1024 - remaining);
484 // printf("\t\tPlain Text = %s(%i)\n", *desc, 1024 - remaining);
489 OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
490 OCClientResponse* clientResponse)
493 // printf("\n\n\tcallback is called\n\n");
494 // printf("\t\tresponse JSON : %s\n", clientResponse->resJSONPayload);
496 return OC_STACK_KEEP_TRANSACTION;
499 void ActionSetCD(void *context)
501 // printf("\n\t\tCD is called\n");
506 OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr, uint16_t *remaining)
508 OCStackResult ret = OC_STACK_ERROR;
515 OC_LOG(INFO, TAG, PCF("Entering BuildActionJSON"));
516 json = cJSON_CreateObject();
518 cJSON_AddItemToObject(json, "rep", body = cJSON_CreateObject());
520 OCCapability* pointerCapa = action->head;
523 cJSON_AddStringToObject(body, pointerCapa->capability, pointerCapa->status);
524 pointerCapa = pointerCapa->next;
527 jsonStr = cJSON_PrintUnformatted(json);
529 jsonLen = strlen(jsonStr);
530 if (jsonLen < *remaining)
532 strcat((char*) bufferPtr, jsonStr);
533 *remaining -= jsonLen;
534 bufferPtr += jsonLen;
544 OCStackResult SendAction(const char *targetUri, const unsigned char *action)
546 OCCallbackData cbdata =
548 cbdata.cb = &ActionSetCB;
549 cbdata.cd = &ActionSetCD;
550 cbdata.context = (void *) 0x99;
553 return OCDoResource(&handle, OC_REST_PUT, targetUri,
554 //temp->rsrcType->resourcetypename,
555 NULL, (char *) action, OC_NA_QOS, &cbdata, NULL, 0);
558 OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/,
559 OCResource *resource, OCEntityHandlerRequest *ehRequest)
561 OCStackResult stackRet = OC_STACK_ERROR;
562 // OCEntityHandlerResult ehRet = OC_EH_ERROR;
564 OC_LOG(INFO, TAG, PCF("Group Action is requested."));
565 // if (stackRet == OC_STACK_OK)
569 char *actionName = NULL;
571 // uint16_t remaining = MAX_RESPONSE_LENGTH;
572 size_t bufferLength = 0;
573 unsigned char buffer[MAX_RESPONSE_LENGTH] =
575 unsigned char *bufferPtr = NULL;
579 OCResource * collResource = (OCResource *) ehRequest->resource;
580 // OCResourceHandle origResourceHandle = ehRequest->resource;
584 cJSON *json = cJSON_CreateObject();
587 cJSON_AddStringToObject(json, "href", resource->uri);
588 cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
590 if (method == OC_REST_GET)
592 OC_LOG(INFO, TAG, PCF("Group Action[GET]."));
594 else if (method == OC_REST_PUT)
596 OC_LOG(INFO, TAG, PCF("Group Action[PUT]."));
598 unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
600 GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
602 if (strcmp(doWhat, "DelActionSet") == 0)
604 if (FindAndDeleteActionSet(&resource, actionName) == OC_STACK_OK)
615 stackRet = OC_STACK_OK;
618 else if (method == OC_REST_POST)
620 OC_LOG(INFO, TAG, PCF("Group Action[POST]."));
622 OCActionSet *actionset = NULL;
623 unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
625 GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
627 if (strcmp(doWhat, "DoAction") == 0)
629 if (GetActionSet(actionName, resource->actionsetHead, &actionset) != OC_STACK_OK)
631 OC_LOG(INFO, TAG, PCF("ERROR"));
632 stackRet = OC_STACK_ERROR;
635 if (actionset == NULL)
637 OC_LOG(INFO, TAG, PCF("ERROR"));
638 stackRet = OC_STACK_ERROR;
641 // printf("Execute ActionSet :: %s\n", actionset->actionsetName);
643 OCAction *pointerAction = actionset->head;
644 while (pointerAction != NULL)
646 // printf("Action Target :: %s\n", pointerAction->resourceUri);
648 unsigned char actionDesc[MAX_RESPONSE_LENGTH] =
650 unsigned char* actionDescPtr = actionDesc;
651 uint16_t remaining = MAX_RESPONSE_LENGTH;
653 strcpy((char *) actionDescPtr, (const char *) OC_JSON_PREFIX);
654 BuildActionJSON(pointerAction, actionDescPtr, &remaining);
655 strcat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX);
657 SendAction(pointerAction->resourceUri, actionDescPtr);
659 pointerAction = pointerAction->next;
661 stackRet = OC_STACK_OK;
664 else if (strcmp(doWhat, "GetActionSet") == 0)
666 char *plainText = NULL;
667 OCActionSet *actionset = NULL;
669 // char *jsonResponse;
671 GetActionSet(actionName, resource->actionsetHead, &actionset);
672 if(actionset != NULL)
674 GetStringFromActionSet(actionset, &plainText);
676 if (plainText != NULL)
678 cJSON_AddStringToObject(format, "ActionSet", plainText);
680 // jsonResponse = cJSON_Print(json);
681 // cJSON_Delete(json);
683 // strcat((char *)bufferPtr, jsonResponse);
686 stackRet = OC_STACK_OK;
689 else if (actionName == NULL)
691 // printf("Cannot find actionname\n");
692 return OC_STACK_ERROR;
696 jsonResponse = cJSON_Print(json);
699 strcat((char *) bufferPtr, jsonResponse);
701 // printf("\n\tRESONSE ::\n%s\n", buffer);
702 bufferLength = strlen((const char *) buffer);
703 if (bufferLength > 0)
705 OCEntityHandlerResponse response =
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);
716 // ehRequest->resource = origResourceHandle;
721 //return OC_STACK_OK;