1 //******************************************************************
3 // Copyright 2015 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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 #include "virtualResource.h"
29 * internal function & static variable
31 ///////////////////////////////////////////////////////////////////////////////////////////////////
32 static MirrorResourceList *s_mirrorResourceList = NULL;
33 static RequestHandleList *s_requestHandleList = NULL;
35 #define OIC_COORDINATING_FLAG "/hosting"
36 #define OIC_STRING_MAX_VALUE 100
38 #define OC_DEFAULT_ADDRESS "224.0.1.187"
39 #define OC_WELL_KNOWN_COORDINATING_QUERY "coap://224.0.1.187:5683/oc/core?rt=Resource.Hosting"
40 #define OC_COORDINATING_QUERY "/oc/core?rt=Resource.Hosting"
41 #define DEFAULT_CONTEXT_VALUE 0x99
44 * Presence Func for hosting
49 * request presence for coordinating
51 * @param[in] originResourceAddr - pointer of address string of original resource
57 OCStackResult requestPresence(char *originResourceAddr);
61 * callback function that call when response of presence request received
63 * @param[in] originResourceAddr - pointer of address string of original resource
69 OCStackApplicationResult requestPresenceCB(void *context, OCDoHandle handle,
70 OCClientResponse *clientResponse);
74 * build mirror resource list by clientResponse
76 * @param[in] handle - not using...
77 * @param[in] clientResponse - client response that mirror resources are stored
80 * pointer of result MirrorResourceList
82 MirrorResourceList *buildMirrorResourceList(OCDoHandle handle, OCClientResponse *clientResponse);
86 * build mirror resource by JSON payload
88 * @param[in] ocArray_sub - pointer of json payload string
91 * pointer of result MirrorResource
93 MirrorResource *buildMirrorResource(cJSON *ocArray_sub);
97 * This method is used when setting queryUri, registering callback function and starting OCDoResource() Function in order to find Coordinatee Candidate
99 * @brief discover coordinatee candidate
102 * OC_STACK_OK - no errors
103 * OC_STACK_INVALID_CALLBACK - invalid callback function pointer
104 * OC_STACK_INVALID_METHOD - invalid resource method
105 * OC_STACK_INVALID_URI - invalid required or reference URI
106 * OC_STACK_INVALID_QUERY - number of resource types specified for filtering presence
107 * notifications exceeds @ref MAX_PRESENCE_FILTERS.
108 * OC_STACK_ERROR - otherwise error(initialized value)
110 int requestCoordinateeCandidateDiscovery(char *address);
114 * This method is used to add a coordinator resource callback method in mirrorResourceList when host resource discovered.
117 * Context for callback method
119 * Handle to an @ref OCDoResource invocation.
120 * @param[in] clientResponse
121 * Response from queries to remote servers. Queries are made by calling the @ref OCDoResource API.
123 * @brief callback for receiving response of discoverCoordinateeCandidate()
126 * PRINT("Callback Context for DISCOVER query recvd successfully") - context is DEFAULT_CONTEXT_VALUE
127 * call the buildMirrorResource() method - clientResponse is not NULL && clientResponse->result is OC_STACK_OK
128 * OC_STACK_KEEP_TRANSACTION - otherwise case
130 OCStackApplicationResult requestCoordinateeCandidateDiscoveryCB(void *context, OCDoHandle handle,
131 OCClientResponse *clientResponse);
135 * This method is used when setting queryUri, registering callback function and starting OCDoResource() Function in order to request resource coordination
139 * @param[in] mirrorResource
140 * mirrorResource for using in order to request resource coordination
143 * OC_STACK_OK - no errors
144 * OC_STACK_INVALID_CALLBACK - invalid callback function pointer
145 * OC_STACK_INVALID_METHOD - invalid resource method
146 * OC_STACK_INVALID_URI - invalid required or reference URI
147 * OC_STACK_INVALID_QUERY - number of resource types specified for filtering presence
148 * notifications exceeds @ref MAX_PRESENCE_FILTERS.
149 * OC_STACK_ERROR - otherwise error(initialized value)
151 OCStackResult requestResourceObservation(MirrorResource *mirrorResource);
155 * This method is used to handle callback of requestCoordination method.
158 * Context for callback method
160 * Handle to update mirror resource and check errorResponse
161 * @param[in] clientResponse
162 * Response from queries to remote servers. Queries are made by calling the @ref OCDoResource API.
164 * @brief callback when receiving response of coordinating requestion.
166 * @todo diverge return value
170 * OC_STACK_KEEP_TRANSACTION - otherwise case
172 OCStackApplicationResult requestResourceObservationCB(void *context, OCDoHandle handle,
173 OCClientResponse *clientResponse);
177 * This method is used to check resource validation and delete resource if it is not exist(not alive).
179 * @brief check mirror resource is alive
181 * @param[in] requestHandle
182 * Handle to check mirror resource
186 * OC_STACK_DELETE_TRANSACTION - otherwise case
188 OCStackApplicationResult checkResourceValidation(OCDoHandle requestHandle);
192 * register Mirror resource in the base resource list
194 * @param[in] requestHandle
195 * Handle to check mirror resource
201 OCStackResult registerMirrorResource(MirrorResource *node);
207 * @param[in] sourceHandle - handle of source resource
208 * @param[in] payload - pointer of json payload string that update items stored
211 * pointer of mirror resource. return NULL if there is any error.
213 MirrorResource *updateMirrorResource(OCDoHandle sourceHandle, const char *payload);
217 * build response payload
219 * @param[in] ehRequest - pointer of handler of entity handler request that to be responded
225 char *buildResponsePayload (OCEntityHandlerRequest *ehRequest);
229 * handle "Get" request
231 * @param[in] ehRequest - pointer of handler of entity handler request
232 * @param[out] payload - pointer of payload to be responded
233 * @param[in] maxPayloadSize - size of payload
236 * OC_EH_OK - success to copy response payload
237 * OC_EH_ERROR - error to copy response payload
239 OCEntityHandlerResult handleGetRequest (OCEntityHandlerRequest *ehRequest,
240 char *payload, uint16_t maxPayloadSize);
244 * handle request for non-existing resource
246 * @param[in] ehRequest - pointer of handler of entity handler request
247 * @param[out] payload - pointer of payload to be responded
248 * @param[in] maxPayloadSize - size of payload
251 * OC_EH_RESOURCE_DELETED - resource deleted
253 OCEntityHandlerResult handleNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest,
254 char *payload, uint16_t maxPayloadSize);
258 * callback function that called when source resource changed
260 * @param[in] flag - entity handler flag
261 * @param[in] entityHandlerRequest - pointer of entity handler request
267 OCEntityHandlerResult resourceEntityHandlerCB (OCEntityHandlerFlag flag,
268 OCEntityHandlerRequest *entityHandlerRequest);
272 * request that address is alive
274 * @param[in] address - pointer of address string
280 OCStackResult requestIsAlive(const char *address);
284 * get string value of OCStackResult code
286 * @param[in] result - OCStringResult code
289 * pointer of result string value
291 const char *getResultString(OCStackResult result);
293 OCStackResult requestQuery(RequestHandle *request, OCMethod method,
294 const char *queryAddress, const char *queryUri);
295 OCStackApplicationResult requestQueryCB(void *context, OCDoHandle handle,
296 OCClientResponse *clientResponse);
297 OCEntityHandlerResponse buildEntityHandlerResponse(OCEntityHandlerRequest *entityHandlerRequest,
298 const char *clientPayload);
299 OCEntityHandlerResult handleRequestPayload (OCEntityHandlerRequest *entityHandlerRequest,
300 char *payload, uint16_t maxPayloadSize);
303 * for Lite Device Side
308 * register resource as coordinatable
310 * @param[in] handle - resource handle
311 * @param[in] resourceTypeName - resource type name
312 * @param[in] resourceInterfaceName - resource interface name
313 * @param[in] resourceUri - resource URI
314 * @param[in] entityHandler - entity handler
315 * @param[in] resourceProperties - resource properties
318 * pointer of result string value
320 OCStackResult registerResourceAsCoordinatable(OCResourceHandle *handle,
321 const char *resourceTypeName, const char *resourceInterfaceName,
322 const char *resourceUri, OCEntityHandler entityHandler, uint8_t resourceProperties);
324 OCStackResult registerResourceAsCoordinatable(OCResourceHandle *handle,
325 const char *resourceTypeName,
326 const char *resourceInterfaceName,
327 const char *resourceUri,
328 OCEntityHandler entityHandler,
329 uint8_t resourceProperties)
331 OCStackResult ret = OC_STACK_OK;
332 size_t coordinateUriLen = sizeof(char) * (strlen(resourceUri) +
333 strlen(OIC_COORDINATING_FLAG) + 1);
334 char *coordinatingURI = (char *)malloc(coordinateUriLen);
335 if(coordinatingURI == NULL)
337 OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail : coordinatingURI");
338 return OC_STACK_NO_MEMORY;
341 snprintf(coordinatingURI, coordinateUriLen,"%s%s", resourceUri, OIC_COORDINATING_FLAG);
343 OC_LOG_V(DEBUG, HOSTING_TAG, "requiredUri+coordinatingFlag = %s", coordinatingURI);
345 ret = OCCreateResource(handle, resourceTypeName, resourceInterfaceName,
346 coordinatingURI, entityHandler, resourceProperties);
347 free(coordinatingURI);
352 * for Hosting Device Side
354 OCStackResult OICStartCoordinate()
356 OCStackResult ret = OC_STACK_ERROR;
357 if (OCInit((char *) NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
359 OC_LOG(ERROR, HOSTING_TAG, PCF("OCStack init ERROR"));
363 s_mirrorResourceList = createMirrorResourceList();
364 s_requestHandleList = createRequestHandleList();
365 ret = requestPresence(OC_MULTICAST_PREFIX);
371 OCStackResult OICStopCoordinate()
373 OCStackResult result = OC_STACK_ERROR;
375 if (OCStop() == OC_STACK_OK)
377 OC_LOG_V(DEBUG, HOSTING_TAG, "OCStack Stop OK");
380 result = destroyMirrorResourceList(s_mirrorResourceList);
381 s_mirrorResourceList = NULL;
382 if(result != OC_STACK_OK)
384 return OC_STACK_ERROR;
390 int requestCoordinateeCandidateDiscovery(char *sourceResourceAddress)
392 OCStackResult result;
393 OCCallbackData cbData;
396 /* Start a discovery query*/
397 char queryUri[OIC_STRING_MAX_VALUE] = { '\0' };
398 if (sourceResourceAddress == NULL)
400 strncpy(queryUri, OC_WELL_KNOWN_COORDINATING_QUERY, sizeof(queryUri));
404 snprintf(queryUri, sizeof(queryUri), "coap://%s%s",
405 sourceResourceAddress , OC_COORDINATING_QUERY);
408 cbData.cb = requestCoordinateeCandidateDiscoveryCB;
409 cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
412 result = OCDoResource(&handle, OC_REST_GET, queryUri, OIC_COORDINATING_FLAG, 0,
413 OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
414 if (result != OC_STACK_OK)
416 OC_LOG_V(DEBUG, HOSTING_TAG, "OCStack resource error");
420 OC_LOG_V(DEBUG, HOSTING_TAG, "Host Resource Finding...");
425 OCStackResult requestPresence(char *sourceResourceAddress)
427 OCStackResult result = OC_STACK_ERROR;
428 OCCallbackData cbData;
431 if (sourceResourceAddress == NULL)
433 OC_LOG_V(DEBUG, HOSTING_TAG, "SourceResourceAddress is not available.");
437 cbData.cb = requestPresenceCB;
438 cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
441 char queryUri[OIC_STRING_MAX_VALUE] = { '\0' };
442 snprintf(queryUri, sizeof(queryUri), "coap://%s%s", sourceResourceAddress , OC_PRESENCE_URI);
443 OC_LOG_V(DEBUG, HOSTING_TAG, "initializePresenceForCoordinating Query : %s", queryUri);
445 result = OCDoResource(&handle, OC_REST_PRESENCE, queryUri, 0, 0,
446 OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
448 if (result != OC_STACK_OK)
450 OC_LOG_V(DEBUG, HOSTING_TAG, "initializePresenceForCoordinating error");
451 result = OC_STACK_ERROR;
455 OC_LOG_V(DEBUG, HOSTING_TAG, "Success initializePresenceForCoordinating");
461 OCStackApplicationResult requestPresenceCB(void *context, OCDoHandle handle,
462 OCClientResponse *clientResponse)
464 uint8_t remoteIpAddress[4];
465 uint16_t remotePortNumber;
466 char address[OIC_STRING_MAX_VALUE] = { '\0' };
468 if (context == (void *) DEFAULT_CONTEXT_VALUE)
470 OC_LOG_V(DEBUG, HOSTING_TAG, "\tCallback Context for presence CB recv successfully");
474 OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddress,
475 remoteIpAddress + 1, remoteIpAddress + 2, remoteIpAddress + 3);
476 OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNumber);
477 OC_LOG_V(DEBUG, HOSTING_TAG, "\tStackResult: %s", getResultString(clientResponse->result));
478 OC_LOG_V(DEBUG, HOSTING_TAG, "\tStackResult: %d", clientResponse->result);
479 OC_LOG_V(DEBUG, HOSTING_TAG,
480 "\tPresence Device =============> Presence %s @ %d.%d.%d.%d:%d",
481 clientResponse->resJSONPayload, remoteIpAddress[0], remoteIpAddress[1],
482 remoteIpAddress[2], remoteIpAddress[3], remotePortNumber);
484 snprintf(address, sizeof(address), "%d.%d.%d.%d:%d", remoteIpAddress[0], remoteIpAddress[1],
485 remoteIpAddress[2], remoteIpAddress[3], remotePortNumber);
486 if (clientResponse->result == OC_STACK_OK)
488 requestCoordinateeCandidateDiscovery(address);
490 if (clientResponse->result == OC_STACK_PRESENCE_STOPPED
491 || clientResponse->result == OC_STACK_PRESENCE_TIMEOUT
492 || clientResponse->result == OC_STACK_PRESENCE_DO_NOT_HANDLE)
494 requestIsAlive(address);
498 return OC_STACK_KEEP_TRANSACTION;
501 OCStackApplicationResult requestCoordinateeCandidateDiscoveryCB(void *ctx, OCDoHandle handle,
502 OCClientResponse *clientResponse)
504 OC_LOG(DEBUG, HOSTING_TAG, "Found Host Resource");
505 OCStackResult ret = OC_STACK_DELETE_TRANSACTION;
507 if (ctx == (void *) DEFAULT_CONTEXT_VALUE)
509 OC_LOG(DEBUG, HOSTING_TAG, "Callback Context for DISCOVER query recvd successfully");
511 if (clientResponse && clientResponse->result == OC_STACK_OK)
513 MirrorResourceList *vList = buildMirrorResourceList(handle, clientResponse);
517 if (vList->headerNode == NULL)
519 OC_LOG(DEBUG, HOSTING_TAG, "This Discover Response is empty");
520 destroyMirrorResourceList(vList);
524 // register All of VirtualResource
525 while (vList->headerNode)
527 MirrorResource *mirrorResource = vList->headerNode;
528 ret = ejectMirrorResource(vList, mirrorResource);
529 mirrorResource->next = NULL;
530 OC_LOG_V(DEBUG, HOSTING_TAG,
531 "register virtual resource uri : %s", mirrorResource->uri);
532 if (ret != OC_STACK_OK)
537 ret = registerMirrorResource(mirrorResource);
538 if (ret != OC_STACK_OK)
543 ret = insertMirrorResource(s_mirrorResourceList, mirrorResource);
544 if (ret != OC_STACK_OK)
546 OCDeleteResource(mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]);
549 printMirrorResourceList(s_mirrorResourceList);
551 ret = requestResourceObservation(mirrorResource);
552 if (ret != OC_STACK_OK)
554 OCDeleteResource(mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]);
555 deleteMirrorResourceFromList(s_mirrorResourceList, mirrorResource);
559 destroyMirrorResourceList(vList);
560 if (ret != OC_STACK_OK)
565 ret = OC_STACK_KEEP_TRANSACTION;
570 MirrorResourceList *buildMirrorResourceList(OCDoHandle handle, OCClientResponse *clientResponse)
573 cJSON *discoveryJson = cJSON_CreateObject();
574 discoveryJson = cJSON_Parse((char *)clientResponse->resJSONPayload);
576 cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, "oc");
577 char *ocArray_str = cJSON_PrintUnformatted(ocArray);
579 if ( strstr(ocArray_str, "[{}") == ocArray_str )
581 OC_LOG_V(DEBUG, HOSTING_TAG, "invalid payload : %s", ocArray_str);
582 cJSON_Delete(discoveryJson);
586 MirrorResourceList *retList = createMirrorResourceList();
588 uint8_t remoteIpAddr[4];
589 uint16_t remotePortNum;
591 OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
592 remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
593 OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNum);
595 char sourceaddr[OIC_STRING_MAX_VALUE] = {'\0'};
596 snprintf(sourceaddr, sizeof(sourceaddr), "%d.%d.%d.%d:%d", remoteIpAddr[0], remoteIpAddr[1],
597 remoteIpAddr[2], remoteIpAddr[3], remotePortNum);
599 OC_LOG_V(DEBUG, HOSTING_TAG, "Host Device =============> Discovered %s @ %s",
600 clientResponse->resJSONPayload, sourceaddr);
602 int arraySize = cJSON_GetArraySize(ocArray);
603 for (int i = 0; i < arraySize; ++i)
605 cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, i);
606 MirrorResource *mirrorResource = buildMirrorResource(ocArray_sub);
608 if (mirrorResource == NULL)
612 mirrorResource->address[OIC_SOURCE_ADDRESS] =
613 (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
614 if(mirrorResource->address[OIC_SOURCE_ADDRESS] == NULL)
616 OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail : mirrorResource address_source");
617 destroyMirrorResource(mirrorResource);
620 snprintf(mirrorResource->address[OIC_SOURCE_ADDRESS],
621 sizeof(char) * OIC_STRING_MAX_VALUE, "%s", sourceaddr);
623 mirrorResource->address[OIC_MIRROR_ADDRESS] =
624 (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
625 if(mirrorResource->address[OIC_MIRROR_ADDRESS] == NULL)
627 OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail : mirrorResource address_mirror");
628 destroyMirrorResource(mirrorResource);
631 snprintf(mirrorResource->address[OIC_MIRROR_ADDRESS],
632 sizeof(char) * OIC_STRING_MAX_VALUE, "0.0.0.0:00");
634 if (OC_STACK_OK != insertMirrorResource(retList, mirrorResource))
636 OC_LOG_V(DEBUG, HOSTING_TAG, "buildVirtualResourceList : insert resource fail");
637 destroyMirrorResource(mirrorResource);
641 cJSON_Delete(discoveryJson);
645 MirrorResource *buildMirrorResource(cJSON *ocArray_sub)
647 MirrorResource *mirrorResource = NULL;
648 const char *curValuestring = cJSON_GetObjectItem(ocArray_sub, "href")->valuestring;
650 if ( strstr(curValuestring, OIC_COORDINATING_FLAG) )
652 mirrorResource = createMirrorResource();
653 if(mirrorResource == NULL)
655 OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail for mirrorResource");
659 mirrorResource->uri = (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
660 if(mirrorResource->uri == NULL)
662 OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail for mirrorResource uri");
665 strncpy(mirrorResource->uri, curValuestring, strlen(curValuestring) - strlen(OIC_COORDINATING_FLAG));
666 mirrorResource->uri[strlen(curValuestring) - strlen(OIC_COORDINATING_FLAG)] = '\0';
667 OC_LOG_V(DEBUG, HOSTING_TAG, "VirtualResource URI : %s", mirrorResource->uri);
669 cJSON *inArray_sub = cJSON_GetObjectItem(ocArray_sub, "prop");
671 cJSON *tmpJSON = NULL;
674 tmpJSON = cJSON_GetObjectItem(inArray_sub, "rt");
675 sizetemp = cJSON_GetArraySize(tmpJSON);
676 mirrorResource->prop.countResourceType = sizetemp;
677 mirrorResource->prop.resourceType = (char **)malloc(sizeof(char *)*sizetemp);
678 if (mirrorResource->prop.resourceType == NULL)
680 OC_LOG_V(DEBUG, HOSTING_TAG,
681 "memory alloc fail for mirrorResource number of resourceType");
686 for (int k = 0; k < sizetemp; ++k)
688 mirrorResource->prop.resourceType[k] =
689 (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
690 if (mirrorResource->prop.resourceType[k] == NULL)
692 OC_LOG_V(DEBUG, HOSTING_TAG,
693 "memory alloc fail for mirrorResource resourceType[n]");
696 memset(mirrorResource->prop.resourceType[k], '\0', OIC_STRING_MAX_VALUE);
697 strncpy(mirrorResource->prop.resourceType[k],
698 cJSON_GetArrayItem(tmpJSON, k)->valuestring,
699 sizeof(char) * OIC_STRING_MAX_VALUE);
703 tmpJSON = cJSON_GetObjectItem(inArray_sub, "if");
704 sizetemp = cJSON_GetArraySize(tmpJSON);
705 mirrorResource->prop.countInterface = sizetemp;
706 mirrorResource->prop.resourceInterfaceName = (char **)malloc(sizeof(char *)*sizetemp);
707 if (mirrorResource->prop.resourceInterfaceName == NULL)
709 OC_LOG_V(DEBUG, HOSTING_TAG,
710 "memory alloc fail for mirrorResource number of resourceInterfaceName");
714 for (int k = 0; k < sizetemp; ++k)
716 mirrorResource->prop.resourceInterfaceName[k] =
717 (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
718 if (mirrorResource->prop.resourceInterfaceName[k] == NULL)
720 OC_LOG_V(DEBUG, HOSTING_TAG,
721 "memory alloc fail for mirrorResource resourceInterfaceName[n]");
725 memset(mirrorResource->prop.resourceInterfaceName[k], '\0', OIC_STRING_MAX_VALUE);
726 strncpy(mirrorResource->prop.resourceInterfaceName[k],
727 cJSON_GetArrayItem(tmpJSON, k)->valuestring,
728 sizeof(char) * OIC_STRING_MAX_VALUE);
732 return mirrorResource;
735 destroyMirrorResource(mirrorResource);
739 OCStackResult registerMirrorResource(MirrorResource *mirrorResource)
741 OCStackResult result = OC_STACK_ERROR;
743 MirrorResource *foundMirrorResource = findMirrorResourceUsingAddressAndURI(s_mirrorResourceList,
744 mirrorResource->address[OIC_MIRROR_ADDRESS], OIC_MIRROR_ADDRESS, mirrorResource->uri);
745 if (foundMirrorResource != NULL)
747 OC_LOG_V(DEBUG, HOSTING_TAG, "Already registered resource");
751 result = OCCreateResource(&(mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]),
752 mirrorResource->prop.resourceType[0],
753 mirrorResource->prop.resourceInterfaceName[0],
755 resourceEntityHandlerCB,
756 OC_DISCOVERABLE | OC_OBSERVABLE);
758 OC_LOG_V(DEBUG, HOSTING_TAG, "created mirror resource Handle : %u",mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]);
760 if (result != OC_STACK_OK)
762 OC_LOG_V(DEBUG, HOSTING_TAG, "error return = %s", getResultString(result));
763 mirrorResource->next = NULL;
764 destroyMirrorResource(mirrorResource);
768 if (mirrorResource->prop.countResourceType > 1)
771 for (i = 1; i < mirrorResource->prop.countResourceType; ++i)
773 result = OCBindResourceTypeToResource(
774 mirrorResource->resourceHandle[OIC_MIRROR_HANDLE],
775 mirrorResource->prop.resourceType[i]);
776 if (result != OC_STACK_OK)
778 OC_LOG_V(DEBUG, HOSTING_TAG, "Virtual Resource Registration Fail : BindResourceType");
784 if (mirrorResource->prop.countInterface > 1)
787 for (i = 1; i < mirrorResource->prop.countInterface; ++i)
789 result = OCBindResourceInterfaceToResource(
790 mirrorResource->resourceHandle[OIC_MIRROR_HANDLE],
791 mirrorResource->prop.resourceInterfaceName[i]);
792 if (result != OC_STACK_OK)
794 OC_LOG_V(DEBUG, HOSTING_TAG,
795 "Virtual Resource Registration Fail : BindResourceInterfaceName");
801 OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource Registration Success");
802 OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource uri : %s", mirrorResource->uri);
803 OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource source address : %s",
804 mirrorResource->address[OIC_SOURCE_ADDRESS]);
805 OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource virtual address : %s",
806 mirrorResource->address[OIC_MIRROR_ADDRESS]);
810 OCDeleteResource(mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]);
811 mirrorResource->next = NULL;
812 destroyMirrorResource(mirrorResource);
817 OCStackResult requestResourceObservation(MirrorResource *mirrorResource)
819 OCStackResult result;
820 OCCallbackData cbData;
822 cbData.cb = requestResourceObservationCB;
823 cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
826 char query[OIC_STRING_MAX_VALUE] = {'\0'};
827 snprintf(query, sizeof(query), "coap://%s%s%s", mirrorResource->address[OIC_SOURCE_ADDRESS], mirrorResource->uri,
828 OIC_COORDINATING_FLAG);
830 result = OCDoResource(&mirrorResource->resourceHandle[OIC_REQUEST_HANDLE], OC_REST_OBSERVE, query,
831 0, NULL, OC_TRANSPORT,
832 OC_HIGH_QOS, &cbData, NULL, 0);
834 if (result != OC_STACK_OK)
836 OC_LOG_V(DEBUG, HOSTING_TAG, "OCDoResource returns error %s with method %d",
837 getResultString(result), OC_REST_OBSERVE);
843 OCStackApplicationResult requestResourceObservationCB(void *context, OCDoHandle handle,
844 OCClientResponse *clientResponse)
846 OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
848 if (context == (void *)DEFAULT_CONTEXT_VALUE)
850 OC_LOG_V(DEBUG, HOSTING_TAG, "Callback Context for OBS query recvd successfully");
853 if (clientResponse && clientResponse->result != OC_STACK_OK)
855 OC_LOG_V(DEBUG, HOSTING_TAG, "observeCB result error = %s",
856 getResultString(clientResponse->result));
857 return checkResourceValidation(handle);
860 if (clientResponse && clientResponse->result == OC_STACK_OK)
862 OC_LOG_V(DEBUG, HOSTING_TAG,
863 "<=============Callback Context for OBSERVE notification recvd successfully");
864 OC_LOG_V(DEBUG, HOSTING_TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
865 OC_LOG_V(DEBUG, HOSTING_TAG, "JSON = %s =============> Obs Response",
866 clientResponse->resJSONPayload);
868 MirrorResource *foundMirrorResource = updateMirrorResource(handle, clientResponse->resJSONPayload);
869 if (foundMirrorResource == NULL)
871 OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found Mirror Resource : Fail");
875 if ( OC_STACK_OK != OCNotifyAllObservers(foundMirrorResource->resourceHandle[OIC_MIRROR_HANDLE],
878 OC_LOG_V(DEBUG, HOSTING_TAG, "Notify Mirror Resource's Subscriber : Fail");
882 OC_LOG_V(DEBUG, HOSTING_TAG, "Notify Mirror Resource's Subscriber : Success");
885 if (clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)
887 OC_LOG_V(DEBUG, HOSTING_TAG, "This also serves as a registration confirmation");
889 else if (clientResponse->sequenceNumber == OC_OBSERVE_DEREGISTER)
891 OC_LOG_V(DEBUG, HOSTING_TAG, "This also serves as a deregistration confirmation");
894 else if (clientResponse->sequenceNumber == OC_OBSERVE_NO_OPTION)
896 OC_LOG_V(DEBUG, HOSTING_TAG, "This also tells you that registration/deregistration failed");
899 ret = OC_STACK_KEEP_TRANSACTION;
904 OCStackApplicationResult checkResourceValidation(OCDoHandle handle)
906 OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
908 RequestHandle *foundRequestHandle = findRequestHandle(s_requestHandleList, handle,
909 OIC_REQUEST_BY_COORDINATOR);
911 if (foundRequestHandle == NULL)
913 OC_LOG_V(DEBUG, HOSTING_TAG, "Not found any request.");
917 if (foundRequestHandle->isAliveCheck)
919 OC_LOG_V(DEBUG, HOSTING_TAG, "This response is Alive Check : Expired resource");
920 OCDeleteResource(foundRequestHandle->requestHandle[OIC_REQUEST_BY_CLIENT]);
922 deleteRequestHandleFromList(s_requestHandleList, foundRequestHandle);
926 MirrorResource *updateMirrorResource(OCDoHandle handle, const char *payload)
928 MirrorResource *foundMirrorResource = findMirrorResourceUsingHandle(
929 s_mirrorResourceList, handle, OIC_REQUEST_HANDLE);
931 if (!foundMirrorResource)
934 OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found Mirror Resource. In updateMirrorResource");
938 cJSON *repData = NULL;
939 cJSON *observeJson = cJSON_Parse(payload);
943 cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oc");
944 cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
945 cJSON *tempData = cJSON_GetObjectItem(ocArray_sub, "rep");
946 char *temp = cJSON_PrintUnformatted(tempData);
948 repData = cJSON_Parse(temp);
953 cJSON_Delete(observeJson);
957 OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror resource payload is not correct");
961 if (foundMirrorResource->rep)
963 cJSON_Delete(foundMirrorResource->rep);
964 foundMirrorResource->rep = NULL;
966 foundMirrorResource->rep = repData;
968 cJSON *json = cJSON_CreateObject();
970 char nodeData[OIC_STRING_MAX_VALUE] = {'\0'};
971 snprintf(nodeData, sizeof(nodeData), "%s", foundMirrorResource->uri);
972 cJSON_AddStringToObject(json, "href", nodeData);
974 cJSON *nodeRep = cJSON_Parse(cJSON_PrintUnformatted(foundMirrorResource->rep));
975 cJSON_AddItemToObject(json, "rep", nodeRep);
976 OC_LOG_V(DEBUG, HOSTING_TAG, "It will notify resource : %s", cJSON_PrintUnformatted(json));
980 return foundMirrorResource;
983 char *buildResponsePayload (OCEntityHandlerRequest *entityHandlerRequest)
985 MirrorResource *mirrorResource = findMirrorResourceUsingHandle(s_mirrorResourceList,
986 entityHandlerRequest->resource, OIC_MIRROR_HANDLE);
989 OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found Mirror Resource. In buildResponsePayload()");
990 OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource's Handle : %x.", entityHandlerRequest->resource);
994 if (entityHandlerRequest->method == OC_REST_PUT)
996 OC_LOG_V(DEBUG, HOSTING_TAG, "oc_rest_put");
997 if (mirrorResource->rep)
999 cJSON_Delete(mirrorResource->rep);
1000 mirrorResource->rep = NULL;
1002 mirrorResource->rep = cJSON_CreateObject();
1003 mirrorResource->rep = cJSON_Parse(entityHandlerRequest->reqJSONPayload);
1006 OC_LOG_V(DEBUG, HOSTING_TAG, "node's uri : %s", mirrorResource->uri);
1007 OC_LOG_V(DEBUG, HOSTING_TAG, "node's source address : %s", mirrorResource->address[0]);
1008 OC_LOG_V(DEBUG, HOSTING_TAG, "node's mirror address : %s", mirrorResource->address[1]);
1009 OC_LOG_V(DEBUG, HOSTING_TAG, "node's rep : %s", cJSON_PrintUnformatted(mirrorResource->rep));
1011 cJSON *jsonObject = cJSON_CreateObject();
1013 char uriString[OIC_STRING_MAX_VALUE] = {'\0'};
1014 snprintf(uriString, sizeof(uriString), "%s", mirrorResource->uri);
1015 cJSON_AddStringToObject(jsonObject, "href", uriString);
1017 cJSON *itemRep = cJSON_Parse(cJSON_PrintUnformatted(mirrorResource->rep));
1018 cJSON_AddItemToObject(jsonObject, "rep", itemRep);
1019 OC_LOG_V(DEBUG, HOSTING_TAG, "Will response resource : %s", cJSON_PrintUnformatted(jsonObject));
1021 char *jsonResponse = cJSON_Print(jsonObject);
1022 cJSON_Delete(jsonObject);
1024 return jsonResponse;
1027 OCEntityHandlerResult
1028 resourceEntityHandlerCB (OCEntityHandlerFlag entifyHandlerFlag,
1029 OCEntityHandlerRequest *entityHandlerRequest)
1031 OC_LOG_V(DEBUG, HOSTING_TAG, "Inside device default entity handler - flags: 0x%x",
1034 OCEntityHandlerResult entityHandlerResult = OC_EH_OK;
1035 OCEntityHandlerResponse entityHandlerResponse;
1036 char payload[MAX_RESPONSE_LENGTH] = {0};
1039 if (!entityHandlerRequest)
1041 OC_LOG_V(DEBUG, HOSTING_TAG, "Invalid request pointer");
1045 // Initialize certain response fields
1046 entityHandlerResponse.numSendVendorSpecificHeaderOptions = 0;
1047 memset(entityHandlerResponse.sendVendorSpecificHeaderOptions, 0,
1048 sizeof entityHandlerResponse.sendVendorSpecificHeaderOptions);
1049 memset(entityHandlerResponse.resourceUri, 0, sizeof entityHandlerResponse.resourceUri);
1051 if (entifyHandlerFlag & OC_REQUEST_FLAG)
1053 OC_LOG_V(DEBUG, HOSTING_TAG, "Flag includes OC_REQUEST_FLAG");
1054 if (entityHandlerRequest->resource == NULL)
1056 OC_LOG_V(DEBUG, HOSTING_TAG, "Received request from client to a non-existing resource");
1057 entityHandlerResult = handleNonExistingResourceRequest(entityHandlerRequest, payload,
1058 sizeof(payload) - 1);
1060 else if (OC_REST_GET == entityHandlerRequest->method)
1062 OC_LOG_V(DEBUG, HOSTING_TAG, "Received OC_REST_GET from client");
1063 entityHandlerResult = handleGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
1065 else if (OC_REST_PUT == entityHandlerRequest->method ||
1066 OC_REST_DELETE == entityHandlerRequest->method )
1068 OC_LOG_V(DEBUG, HOSTING_TAG, "Received OC_REST_PUT/DELETE from client");
1070 RequestHandle *request = createRequestHandle();
1072 request->requestHandle[OIC_REQUEST_BY_CLIENT] = entityHandlerRequest;
1073 request->resourceHandle = entityHandlerRequest->resource;
1074 request->method = entityHandlerRequest->method;
1075 request->entityRequestHandle = entityHandlerRequest->requestHandle;
1077 OCStackResult result = insertRequestHandle(s_requestHandleList, request);
1078 if (result != OC_STACK_OK)
1080 OC_LOG_V(DEBUG, HOSTING_TAG, "Insert request list : fail2(%d)", result);
1084 MirrorResource *mirrorResource = findMirrorResourceUsingHandle(s_mirrorResourceList,
1085 entityHandlerRequest->resource, OIC_MIRROR_HANDLE);
1086 if (mirrorResource == NULL)
1088 OC_LOG_V(DEBUG, HOSTING_TAG, "Not found requested resource");
1092 result = requestQuery(request,
1093 entityHandlerRequest->method, mirrorResource->address[OIC_SOURCE_ADDRESS],
1094 mirrorResource->uri);
1095 if (result != OC_STACK_OK)
1097 OC_LOG_V(DEBUG, HOSTING_TAG, "Request query failed");
1098 deleteRequestHandleFromList(s_requestHandleList, request);
1104 OC_LOG_V(DEBUG, HOSTING_TAG, "Received unsupported method %d from client",
1105 entityHandlerRequest->method);
1106 entityHandlerResult = OC_EH_ERROR;
1109 // If the result isn't an error or forbidden, send response
1110 if (!((entityHandlerResult == OC_EH_ERROR) || (entityHandlerResult == OC_EH_FORBIDDEN)))
1112 // Format the response. Note this requires some info about the request
1113 entityHandlerResponse.requestHandle = entityHandlerRequest->requestHandle;
1114 entityHandlerResponse.resourceHandle = entityHandlerRequest->resource;
1115 entityHandlerResponse.ehResult = entityHandlerResult;
1116 entityHandlerResponse.payload = (char *)payload;
1117 entityHandlerResponse.payloadSize = strlen(payload);
1118 // Indicate that response is NOT in a persistent buffer
1119 entityHandlerResponse.persistentBufferFlag = 0;
1121 // Handle vendor specific options
1122 if (entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
1123 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
1125 OC_LOG_V(DEBUG, HOSTING_TAG, "Received vendor specific options");
1126 OCHeaderOption *receivedVenderSpecificHeaderOptions =
1127 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
1128 for ( int i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
1130 if (((OCHeaderOption)receivedVenderSpecificHeaderOptions[i]).protocolID == OC_COAP_ID)
1132 OC_LOG_V(DEBUG, HOSTING_TAG, "Received option with OC_COAP_ID and ID %u with",
1133 ((OCHeaderOption)receivedVenderSpecificHeaderOptions[i]).optionID );
1136 OCHeaderOption *sendVenderSpecificHeaderOptions =
1137 entityHandlerResponse.sendVendorSpecificHeaderOptions;
1138 uint8_t option2[] = {21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
1139 uint8_t option3[] = {31, 32, 33, 34, 35, 36, 37, 38, 39, 40};
1140 sendVenderSpecificHeaderOptions[0].protocolID = OC_COAP_ID;
1141 sendVenderSpecificHeaderOptions[0].optionID = 2248;
1142 memcpy(sendVenderSpecificHeaderOptions[0].optionData, option2, sizeof(option2));
1143 sendVenderSpecificHeaderOptions[0].optionLength = 10;
1144 sendVenderSpecificHeaderOptions[1].protocolID = OC_COAP_ID;
1145 sendVenderSpecificHeaderOptions[1].optionID = 2600;
1146 memcpy(sendVenderSpecificHeaderOptions[1].optionData, option3, sizeof(option3));
1147 sendVenderSpecificHeaderOptions[1].optionLength = 10;
1148 entityHandlerResponse.numSendVendorSpecificHeaderOptions = 2;
1151 // Send the response
1152 if (OCDoResponse(&entityHandlerResponse) != OC_STACK_OK)
1154 OC_LOG(ERROR, HOSTING_TAG, "Error sending response");
1155 entityHandlerResult = OC_EH_ERROR;
1159 if (entifyHandlerFlag & OC_OBSERVE_FLAG)
1161 OC_LOG_V(DEBUG, HOSTING_TAG, "Flag includes OC_OBSERVE_FLAG");
1162 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
1164 OC_LOG_V(DEBUG, HOSTING_TAG, "Received OC_OBSERVE_REGISTER from client");
1166 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
1168 OC_LOG_V(DEBUG, HOSTING_TAG, "Received OC_OBSERVE_DEREGISTER from client");
1172 return entityHandlerResult;
1174 OCEntityHandlerResult
1175 handleGetRequest (OCEntityHandlerRequest *entityHandlerRequest,
1176 char *payload, uint16_t maxPayloadSize)
1178 OC_LOG_V(DEBUG, HOSTING_TAG, "ProcessGetRequest in....");
1180 OCEntityHandlerResult entityHandlerResult = OC_EH_ERROR;
1181 char *responsePayload = buildResponsePayload(entityHandlerRequest);
1182 if(!responsePayload)
1184 return entityHandlerResult;
1187 if (maxPayloadSize > strlen ((char *)responsePayload))
1189 strncpy(payload, responsePayload, strlen((char *)responsePayload));
1190 entityHandlerResult = OC_EH_OK;
1194 OC_LOG_V(DEBUG, HOSTING_TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
1197 free(responsePayload);
1199 return entityHandlerResult;
1201 OCEntityHandlerResult
1202 handleNonExistingResourceRequest(OCEntityHandlerRequest *entityHandlerRequest,
1203 char *payload, uint16_t maxPayloadSize)
1205 OC_LOG_V(INFO, HOSTING_TAG, "Executing %s ", __func__);
1207 char responsePayload[OIC_STRING_MAX_VALUE] = {'\0'};
1208 strncpy(responsePayload, "{App determines payload: The resource does not exist.}",
1209 sizeof(responsePayload));
1211 if ( (entityHandlerRequest != NULL) &&
1212 (maxPayloadSize > strlen ((char *)responsePayload)) )
1214 strncpy((char *)payload, responsePayload, strlen((char *)responsePayload));
1218 OC_LOG_V (INFO, HOSTING_TAG, "Response buffer: %d bytes is too small",
1222 return OC_EH_RESOURCE_DELETED;
1225 OCStackResult requestIsAlive(const char *address)
1227 MirrorResourceList *requestMirrorResourceList = findMirrorResourceListUsingAddress(
1228 s_mirrorResourceList, address, OIC_SOURCE_ADDRESS);
1230 if (requestMirrorResourceList == NULL)
1232 OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found any mirror resource1");
1233 return OC_STACK_ERROR;
1236 if (requestMirrorResourceList->headerNode == NULL)
1238 OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found any mirror resource2");
1239 return OC_STACK_ERROR;
1242 MirrorResource *mirrorResource = requestMirrorResourceList->headerNode;
1243 while (mirrorResource)
1245 RequestHandle *requestAlive = createRequestHandle();
1246 requestAlive->isAliveCheck = 1;
1247 requestAlive->requestHandle[OIC_REQUEST_BY_CLIENT] =
1248 mirrorResource->resourceHandle[OIC_MIRROR_HANDLE];
1250 OCStackResult result = insertRequestHandle(s_requestHandleList, requestAlive);
1251 if (result != OC_STACK_OK)
1253 OC_LOG_V(DEBUG, HOSTING_TAG, "Insert request list : fail3");
1254 destroyRequestHandle(requestAlive);
1255 mirrorResource = mirrorResource->next;
1259 result = requestQuery(requestAlive, OC_REST_GET, address, mirrorResource->uri);
1260 if (result != OC_STACK_OK)
1262 deleteRequestHandleFromList(s_requestHandleList, requestAlive);
1264 mirrorResource = mirrorResource->next;
1266 destroyMirrorResourceList(requestMirrorResourceList);
1271 const char *getResultString(OCStackResult result)
1276 return "OC_STACK_OK";
1277 case OC_STACK_RESOURCE_CREATED:
1278 return "OC_STACK_RESOURCE_CREATED";
1279 case OC_STACK_RESOURCE_DELETED:
1280 return "OC_STACK_RESOURCE_DELETED";
1281 case OC_STACK_INVALID_URI:
1282 return "OC_STACK_INVALID_URI";
1283 case OC_STACK_INVALID_QUERY:
1284 return "OC_STACK_INVALID_QUERY";
1285 case OC_STACK_INVALID_IP:
1286 return "OC_STACK_INVALID_IP";
1287 case OC_STACK_INVALID_PORT:
1288 return "OC_STACK_INVALID_PORT";
1289 case OC_STACK_INVALID_CALLBACK:
1290 return "OC_STACK_INVALID_CALLBACK";
1291 case OC_STACK_INVALID_METHOD:
1292 return "OC_STACK_INVALID_METHOD";
1293 case OC_STACK_NO_MEMORY:
1294 return "OC_STACK_NO_MEMORY";
1295 case OC_STACK_COMM_ERROR:
1296 return "OC_STACK_COMM_ERROR";
1297 case OC_STACK_INVALID_PARAM:
1298 return "OC_STACK_INVALID_PARAM";
1299 case OC_STACK_NOTIMPL:
1300 return "OC_STACK_NOTIMPL";
1301 case OC_STACK_NO_RESOURCE:
1302 return "OC_STACK_NO_RESOURCE";
1303 case OC_STACK_RESOURCE_ERROR:
1304 return "OC_STACK_RESOURCE_ERROR";
1305 case OC_STACK_SLOW_RESOURCE:
1306 return "OC_STACK_SLOW_RESOURCE";
1307 case OC_STACK_NO_OBSERVERS:
1308 return "OC_STACK_NO_OBSERVERS";
1309 case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
1310 return "OC_STACK_VIRTUAL_DO_NOT_HANDLE";
1311 case OC_STACK_PRESENCE_STOPPED:
1312 return "OC_STACK_PRESENCE_STOPPED";
1313 case OC_STACK_PRESENCE_TIMEOUT:
1314 return "OC_STACK_PRESENCE_TIMEOUT";
1315 case OC_STACK_PRESENCE_DO_NOT_HANDLE:
1316 return "OC_STACK_PRESENCE_DO_NOT_HANDLE";
1317 case OC_STACK_ERROR:
1318 return "OC_STACK_ERROR";
1324 void getJsonArrayPair(cJSON *tempData)
1326 int countofrep = cJSON_GetArraySize(tempData);
1327 OC_LOG_V(DEBUG, HOSTING_TAG,
1328 "//////////////////////////////////////////////////////////////////////////");
1329 OC_LOG_V(DEBUG, HOSTING_TAG, "//Test");
1330 OC_LOG_V(DEBUG, HOSTING_TAG, "rep Size : %d", countofrep);
1332 for (int i = 0; i < countofrep; ++i)
1334 cJSON *arrayJSON = cJSON_GetArrayItem(tempData, i);
1335 OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's name : %s", i, arrayJSON->string);
1337 switch (arrayJSON->type)
1341 OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's value : %d", i, arrayJSON->valueint);
1344 OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's value : %f", i, arrayJSON->valuedouble);
1347 OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's value : %s", i, arrayJSON->valuestring);
1351 OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's value : NULL", i);
1355 OC_LOG_V(DEBUG, HOSTING_TAG,
1356 "//////////////////////////////////////////////////////////////////////////");
1359 OCStackResult requestQuery(RequestHandle *request, OCMethod method,
1360 const char *queryAddress, const char *queryUri)
1363 OCStackResult result = OC_STACK_ERROR;
1364 OCCallbackData cbData;
1366 /* Start a discovery query*/
1367 char queryFullUri[OIC_STRING_MAX_VALUE] = {'\0'};
1368 if (queryAddress == NULL)
1374 snprintf(queryFullUri, sizeof(queryFullUri) ,"coap://%s%s%s", queryAddress , queryUri, OIC_COORDINATING_FLAG);
1377 cbData.cb = requestQueryCB;
1378 cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
1381 if(method == OC_REST_PUT)
1383 char payload[OIC_STRING_MAX_VALUE] = {'\0'};
1384 snprintf(payload , sizeof(payload), "%s" ,
1385 ((OCEntityHandlerRequest*)request->requestHandle[OIC_REQUEST_BY_CLIENT])->reqJSONPayload);
1387 result = OCDoResource(&request->requestHandle[OIC_REQUEST_BY_COORDINATOR],
1388 method, queryFullUri, NULL, payload, OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
1392 result = OCDoResource(&request->requestHandle[OIC_REQUEST_BY_COORDINATOR],
1393 method, queryFullUri, NULL, 0, OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
1396 if (result != OC_STACK_OK)
1398 OC_LOG_V(DEBUG, HOSTING_TAG, "OCStack resource error");
1404 OCStackApplicationResult requestQueryCB(void *context, OCDoHandle handle,
1405 OCClientResponse *clientResponse)
1407 OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
1409 if (context == (void *) DEFAULT_CONTEXT_VALUE)
1411 OC_LOG_V(DEBUG, HOSTING_TAG, "Callback Context for Request query recvd successfully");
1414 if (clientResponse && clientResponse->result != OC_STACK_OK && clientResponse->result != OC_STACK_RESOURCE_DELETED)
1416 OC_LOG_V(DEBUG, HOSTING_TAG, "requestQueryCB result error = %s",
1417 getResultString(clientResponse->result));
1418 return checkResourceValidation(handle);
1421 if (clientResponse && (clientResponse->result == OC_STACK_OK || clientResponse->result == OC_STACK_RESOURCE_DELETED))
1423 RequestHandle *request = findRequestHandle(s_requestHandleList, handle, OIC_REQUEST_BY_COORDINATOR);
1424 if (request == NULL)
1426 OC_LOG_V(DEBUG, HOSTING_TAG, "Not found Any request");
1429 if (request->isAliveCheck == 1)
1431 OC_LOG_V(DEBUG, HOSTING_TAG, "This response is Alive Check : Keep resource");
1435 OC_LOG_V(DEBUG, HOSTING_TAG, "requestCB's payload: %s", clientResponse->resJSONPayload);
1436 OCEntityHandlerRequest *entityHandler = (OCEntityHandlerRequest *)(
1437 request->requestHandle[OIC_REQUEST_BY_CLIENT]);
1438 OC_LOG_V(DEBUG, HOSTING_TAG, "requested resource handle : %u", entityHandler->resource
1441 entityHandler->resource = request->resourceHandle;
1442 entityHandler->method = request->method;
1443 entityHandler->requestHandle = request->entityRequestHandle;
1445 OCEntityHandlerResponse response = buildEntityHandlerResponse(
1446 entityHandler, clientResponse->resJSONPayload);
1447 if (OCDoResponse(&response) != OC_STACK_OK)
1449 OC_LOG_V(DEBUG, HOSTING_TAG, "Error sending response");
1450 deleteRequestHandleFromList(s_requestHandleList, request);
1453 if (entityHandler->method == OC_REST_DELETE)
1455 OCDeleteResource(entityHandler->resource);
1458 deleteRequestHandleFromList(s_requestHandleList, request);
1459 ret = OC_STACK_KEEP_TRANSACTION;
1465 OCEntityHandlerResponse buildEntityHandlerResponse(OCEntityHandlerRequest *entityHandlerRequest,
1466 const char *clientPayload)
1468 OC_LOG_V(DEBUG, HOSTING_TAG, "enter buildEntityHandlerResponse");
1469 OCEntityHandlerResponse response;
1470 memset(&response, 0, sizeof(response));
1471 OCEntityHandlerResult entityHandlerResult = OC_EH_OK;
1472 char payload[MAX_RESPONSE_LENGTH] = {'\0'};
1474 // Initialize certain response fields
1475 response.numSendVendorSpecificHeaderOptions = 0;
1476 memset(response.sendVendorSpecificHeaderOptions, 0,
1477 sizeof response.sendVendorSpecificHeaderOptions);
1478 memset(response.resourceUri, 0, sizeof response.resourceUri);
1481 if(entityHandlerRequest->method == OC_REST_PUT)
1483 cJSON *observeJson = cJSON_CreateObject();
1484 observeJson = cJSON_Parse(clientPayload);
1486 cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oc");
1487 cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
1489 cJSON *tempData = cJSON_GetObjectItem(ocArray_sub, "rep");
1490 temp = cJSON_PrintUnformatted(tempData);
1492 cJSON_Delete(observeJson);
1494 entityHandlerRequest->reqJSONPayload = temp;
1496 entityHandlerResult = handleRequestPayload(entityHandlerRequest, payload, sizeof(payload) - 1);
1498 // Format the response. Note this requires some info about the request
1499 response.requestHandle = entityHandlerRequest->requestHandle;
1500 response.resourceHandle = entityHandlerRequest->resource;
1501 response.ehResult = entityHandlerResult;
1503 response.payload = (char *)payload;
1504 response.payloadSize = strlen(payload);
1505 // Indicate that response is NOT in a persistent buffer
1506 response.persistentBufferFlag = 0;
1508 if(entityHandlerRequest->method == OC_REST_PUT){
1517 OCEntityHandlerResult handleRequestPayload (OCEntityHandlerRequest *entityHandlerRequest,
1518 char *payload, uint16_t maxPayloadSize)
1520 OC_LOG_V(DEBUG, HOSTING_TAG, "enter handleRequestPayload");
1521 OCEntityHandlerResult entityHandlerResult = OC_EH_ERROR;
1523 if (entityHandlerRequest->method == OC_REST_DELETE)
1525 memset(payload, '\0', sizeof(char) * (maxPayloadSize + 1));
1526 OC_LOG_V(DEBUG, HOSTING_TAG, "DELETE");
1527 return OC_EH_RESOURCE_DELETED;
1530 char *responsePayload = buildResponsePayload(entityHandlerRequest);
1531 if(!responsePayload)
1533 return entityHandlerResult;
1536 if (maxPayloadSize > strlen ((char *)responsePayload))
1538 strncpy(payload, responsePayload, strlen ((char *)responsePayload));
1539 entityHandlerResult = OC_EH_OK;
1543 OC_LOG_V(DEBUG, HOSTING_TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
1544 entityHandlerResult = OC_EH_ERROR;
1547 free(responsePayload);
1549 return entityHandlerResult;