1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH 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 // Defining _POSIX_C_SOURCE macro with 200112L (or greater) as value
22 // causes header files to expose definitions
23 // corresponding to the POSIX.1-2001 base
24 // specification (excluding the XSI extension).
25 // For POSIX.1-2001 base specification,
26 // Refer http://pubs.opengroup.org/onlinepubs/009695399/
27 #define _POSIX_C_SOURCE 200112L
28 #include "ocresource.h"
30 #include "ocresourcehandler.h"
31 #include "ocobserve.h"
32 #include "occollection.h"
38 #include "cainterface.h"
42 #define TAG PCF("ocresource")
43 #define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
44 {OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
46 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
47 TAG, PCF(#arg " is NULL")); return (retVal); } }
49 extern OCResource *headResource;
50 static OCPlatformInfo savedPlatformInfo = {};
51 static cJSON *savedDeviceInfo = NULL;
52 static const char * VIRTUAL_RSRCS[] =
63 //-----------------------------------------------------------------------------
64 // Default resource entity handler function
65 //-----------------------------------------------------------------------------
66 OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
67 OCEntityHandlerRequest * request)
69 //TODO ("Implement me!!!!");
70 // TODO: remove silence unused param warnings
73 return OC_EH_OK; // Making sure that the Default EH and the Vendor EH have matching signatures
76 /* This method will retrieve the port at which the secure resource is hosted */
77 static OCStackResult GetSecurePortInfo(CATransportType_t connType, uint16_t *port)
79 CALocalConnectivity_t* info = NULL;
81 OCStackResult ret = OC_STACK_ERROR;
83 CAResult_t caResult = CAGetNetworkInformation(&info, &size);
84 if ((caResult == CA_STATUS_OK) && info && size)
88 if (info[size].isSecured && info[size].type == connType)
90 if (info[size].type == CA_IPV4)
92 *port = info[size].addressInfo.IP.port;
104 static char* GetJSONStringFromPlatformInfo(OCPlatformInfo info)
106 cJSON *rootObj = cJSON_CreateObject();
113 cJSON *repObj = NULL;
114 char *jsonEncodedInfo = NULL;
116 cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
117 cJSON_CreateString(GetVirtualResourceUri(OC_PLATFORM_URI)));
119 cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
121 cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_ID, cJSON_CreateString(info.platformID));
122 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME, cJSON_CreateString(info.manufacturerName));
123 if (info.manufacturerUrl)
125 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
126 cJSON_CreateString(info.manufacturerUrl));
129 if (info.modelNumber)
131 cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
132 cJSON_CreateString(info.modelNumber));
135 if (info.dateOfManufacture)
137 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
138 cJSON_CreateString(info.dateOfManufacture));
141 if (info.platformVersion)
143 cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
144 cJSON_CreateString(info.platformVersion));
147 if (info.operatingSystemVersion)
149 cJSON_AddItemToObject (repObj, OC_RSRVD_OS_VERSION,
150 cJSON_CreateString(info.operatingSystemVersion));
153 if (info.hardwareVersion)
155 cJSON_AddItemToObject (repObj, OC_RSRVD_HARDWARE_VERSION,
156 cJSON_CreateString(info.hardwareVersion));
159 if (info.firmwareVersion)
161 cJSON_AddItemToObject (repObj, OC_RSRVD_FIRMWARE_VERSION,
162 cJSON_CreateString(info.firmwareVersion));
167 cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
168 cJSON_CreateString(info.supportUrl));
173 cJSON_AddItemToObject (repObj, OC_RSRVD_SYSTEM_TIME,
174 cJSON_CreateString(info.systemTime));
177 jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
179 cJSON_Delete(rootObj);
181 return jsonEncodedInfo;
184 static OCStackResult ValidateUrlQuery (char *url, char *query,
185 uint8_t *filterOn, char **filterValue)
187 if(!filterOn || !filterValue)
189 return OC_STACK_INVALID_PARAM;
192 char *filterParam = NULL;
194 OC_LOG(INFO, TAG, PCF("Entering ValidateUrlQuery"));
197 return OC_STACK_INVALID_URI;
200 if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
201 strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0 ||
202 strcmp((char *)url, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
204 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
207 char* strTokPtr = NULL;
208 filterParam = strtok_r((char *)query, "=", &strTokPtr);
209 *filterValue = strtok_r(NULL, " ", &strTokPtr);
211 if (!(*filterValue) || ! filterParam)
213 return OC_STACK_INVALID_QUERY;
215 else if (strcmp (filterParam, OC_RSRVD_INTERFACE) == 0)
217 // Resource discovery with interface filter
218 *filterOn = STACK_RES_DISCOVERY_IF_FILTER;
220 else if (strcmp (filterParam, OC_RSRVD_RESOURCE_TYPE) == 0)
222 // Resource discovery with resource type filter
223 *filterOn = STACK_RES_DISCOVERY_RT_FILTER;
225 else if (strcmp (filterParam, OC_RSRVD_DEVICE_ID) == 0)
228 *filterOn = STACK_DEVICE_DISCOVERY_DI_FILTER;
230 else if (strcmp (filterParam, OC_RSRVD_DEVICE_NAME) == 0)
233 *filterOn = STACK_DEVICE_DISCOVERY_DN_FILTER;
237 // Other filter types not supported
238 return OC_STACK_INVALID_QUERY;
243 else if (strcmp((char *)url, GetVirtualResourceUri(OC_PRESENCE)) == 0)
245 //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
246 OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request"));
247 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
252 // Other URIs not yet supported
253 return OC_STACK_INVALID_URI;
255 OC_LOG(INFO, TAG, PCF("Exiting ValidateUrlQuery"));
261 BuildVirtualResourceResponse(const OCResource *resourcePtr, uint8_t filterOn,
262 const char *filterValue, char *out, uint16_t *remaining,
263 CATransportType_t connType )
265 if(!resourcePtr || !out || !remaining)
267 return OC_STACK_INVALID_PARAM;
270 OCResourceType *resourceTypePtr = NULL;
271 OCResourceInterface *interfacePtr = NULL;
272 cJSON *resObj = NULL;
273 cJSON *propObj = NULL;
274 cJSON *rtArray = NULL;
275 char *jsonStr = NULL;
276 uint8_t encodeRes = 0;
277 OCStackResult ret = OC_STACK_OK;
278 uint16_t jsonLen = 0;
280 OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponse"));
281 resObj = cJSON_CreateObject();
286 if ((filterOn == STACK_RES_DISCOVERY_RT_FILTER) && filterValue)
288 resourceTypePtr = resourcePtr->rsrcType;
289 while (resourceTypePtr)
291 if (strcmp (resourceTypePtr->resourcetypename, filterValue) == 0)
296 resourceTypePtr = resourceTypePtr->next;
299 else if ((filterOn == STACK_RES_DISCOVERY_IF_FILTER) && filterValue)
301 interfacePtr = resourcePtr->rsrcInterface;
304 if (strcmp (interfacePtr->name, filterValue) == 0)
309 interfacePtr = interfacePtr->next;
312 else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
318 //TODO: Unsupported query filter
319 return OC_STACK_INVALID_QUERY;
325 cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
327 // Add server instance id
328 cJSON_AddItemToObject (resObj,
329 OC_RSRVD_SERVER_INSTANCE_ID,
330 cJSON_CreateString(OCGetServerInstanceIDString()));
332 cJSON_AddItemToObject (resObj, OC_RSRVD_PROPERTY, propObj = cJSON_CreateObject());
333 // Add resource types
334 cJSON_AddItemToObject (propObj, OC_RSRVD_RESOURCE_TYPE, rtArray = cJSON_CreateArray());
335 resourceTypePtr = resourcePtr->rsrcType;
336 while (resourceTypePtr)
338 cJSON_AddItemToArray (rtArray,
339 cJSON_CreateString(resourceTypePtr->resourcetypename));
340 resourceTypePtr = resourceTypePtr->next;
342 // Add interface types
343 cJSON_AddItemToObject (propObj, OC_RSRVD_INTERFACE, rtArray = cJSON_CreateArray());
344 interfacePtr = resourcePtr->rsrcInterface;
347 cJSON_AddItemToArray (rtArray, cJSON_CreateString(interfacePtr->name));
348 interfacePtr = interfacePtr->next;
350 // If resource is observable, set observability flag.
351 // Resources that are not observable will not have the flag.
352 if (resourcePtr->resourceProperties & OC_OBSERVABLE)
354 cJSON_AddItemToObject (propObj, OC_RSRVD_OBSERVABLE,
355 cJSON_CreateNumber(OC_RESOURCE_OBSERVABLE));
357 // Set secure flag for secure resources
358 if (resourcePtr->resourceProperties & OC_SECURE)
360 cJSON_AddNumberToObject (propObj, OC_RSRVD_SECURE, OC_RESOURCE_SECURE);
361 //Set the IP port also as secure resources are hosted on a different port
363 if (GetSecurePortInfo (connType, &port) == OC_STACK_OK)
365 cJSON_AddNumberToObject (propObj, OC_RSRVD_HOSTING_PORT, port);
371 jsonStr = cJSON_PrintUnformatted (resObj);
375 cJSON_Delete(resObj);
376 return OC_STACK_NO_MEMORY;
379 jsonLen = strlen(jsonStr);
380 if (jsonLen < *remaining)
382 strcpy(out, jsonStr);
383 *remaining = *remaining - jsonLen;
387 ret = OC_STACK_ERROR;
389 cJSON_Delete (resObj);
392 OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponse"));
396 OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
397 char *out, uint16_t *remaining)
399 if(!out || !remaining)
401 return OC_STACK_INVALID_PARAM;
404 OCStackResult ret = OC_STACK_ERROR;
406 if (savedDeviceInfo != NULL)
408 char *jsonStr = NULL;
409 uint16_t jsonLen = 0;
410 cJSON *repObj = cJSON_GetObjectItem(savedDeviceInfo, OC_RSRVD_REPRESENTATION);
412 OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponseForDevice"));
414 if ((filterOn == STACK_DEVICE_DISCOVERY_DI_FILTER) && filterValue)
416 if((cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_ID) != NULL) &&
417 strcmp(cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_ID)->valuestring, filterValue)
423 else if ((filterOn == STACK_DEVICE_DISCOVERY_DN_FILTER) && filterValue)
425 if((cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_NAME) != NULL) &&
426 strcmp(cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_NAME)->valuestring,
432 else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
438 ret = OC_STACK_INVALID_QUERY;
441 if (ret == OC_STACK_OK)
443 jsonStr = cJSON_PrintUnformatted (savedDeviceInfo);
447 jsonLen = strlen(jsonStr);
449 if (jsonLen < *remaining)
451 strncpy(out, jsonStr, (jsonLen + 1));
452 *remaining = *remaining - jsonLen;
457 ret = OC_STACK_ERROR;
464 ret = OC_STACK_ERROR;
469 ret = OC_STACK_INVALID_DEVICE_INFO;
474 OC_LOG(ERROR, TAG, PCF("No device info found."));
475 //error so that stack won't respond with empty payload
476 ret = OC_STACK_INVALID_DEVICE_INFO;
479 OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponseForDevice"));
483 OCStackResult BuildVirtualResourceResponseForPlatform(char *out, uint16_t *remaining)
485 OCStackResult ret = OC_STACK_OK;
487 char *jsonStr = GetJSONStringFromPlatformInfo(savedPlatformInfo);
491 size_t jsonLen = strlen(jsonStr);
493 if (jsonLen < *remaining)
495 strncpy(out, jsonStr, (jsonLen + 1));
496 *remaining = *remaining - jsonLen;
501 OC_LOG_V(ERROR, TAG, PCF("Platform info string too big. len: %u"), jsonLen);
502 ret = OC_STACK_ERROR;
508 OC_LOG(ERROR, TAG, PCF("Error encoding save platform info."));
509 ret = OC_STACK_ERROR;
516 const char * GetVirtualResourceUri( OCVirtualResources resource)
518 if (resource < OC_MAX_VIRTUAL_RESOURCES)
520 return VIRTUAL_RSRCS[resource];
526 bool IsVirtualResource(const char* resourceUri)
533 for (int i = 0; i < OC_MAX_VIRTUAL_RESOURCES; i++)
535 if (strcmp(resourceUri, GetVirtualResourceUri((OCVirtualResources)i)) == 0)
543 uint8_t IsCollectionResource (OCResource *resource)
550 for (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
552 if (resource->rsrcResources[i])
560 OCResource *FindResourceByUri(const char* resourceUri)
567 OCResource * pointer = headResource;
570 if (strcmp(resourceUri, pointer->uri) == 0)
574 pointer = pointer->next;
576 OC_LOG(INFO, TAG, PCF("Resource not found"));
581 OCStackResult DetermineResourceHandling (const OCServerRequest *request,
582 ResourceHandling *handling,
583 OCResource **resource)
585 if(!request || !handling || !resource)
587 return OC_STACK_INVALID_PARAM;
590 OC_LOG(INFO, TAG, PCF("Entering DetermineResourceHandling"));
592 // Check if virtual resource
593 if (IsVirtualResource((const char*)request->resourceUrl))
595 *handling = OC_RESOURCE_VIRTUAL;
596 *resource = headResource;
599 if (NULL == request->resourceUrl || (strlen((const char*)(request->resourceUrl)) == 0))
601 // Resource URL not specified
602 *handling = OC_RESOURCE_NOT_SPECIFIED;
603 return OC_STACK_NO_RESOURCE;
607 OCResource *resourcePtr = NULL;
608 resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
609 *resource = resourcePtr;
612 if(defaultDeviceHandler)
614 *handling = OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER;
618 // Resource does not exist
619 // and default device handler does not exist
620 *handling = OC_RESOURCE_NOT_SPECIFIED;
621 return OC_STACK_NO_RESOURCE;
624 // secure resource will entertain only authorized requests
625 if ((resourcePtr->resourceProperties & OC_SECURE) && (request->secured == 0))
627 OC_LOG(ERROR, TAG, PCF("Un-authorized request. Ignoring"));
628 return OC_STACK_RESOURCE_ERROR;
631 if (IsCollectionResource (resourcePtr))
633 // Collection resource
634 if (resourcePtr->entityHandler != defaultResourceEHandler)
636 *handling = OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER;
641 *handling = OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER;
647 // Resource not a collection
648 if (resourcePtr->entityHandler != defaultResourceEHandler)
650 *handling = OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER;
655 *handling = OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER;
662 OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
664 OCStackResult result;
669 result = OC_STACK_OK;
672 result = OC_STACK_SLOW_RESOURCE;
675 result = OC_STACK_ERROR;
677 case OC_EH_FORBIDDEN:
678 result = OC_STACK_RESOURCE_ERROR;
680 case OC_EH_RESOURCE_CREATED:
681 result = OC_STACK_RESOURCE_CREATED;
683 case OC_EH_RESOURCE_DELETED:
684 result = OC_STACK_RESOURCE_DELETED;
686 case OC_EH_RESOURCE_NOT_FOUND:
687 result = OC_STACK_NO_RESOURCE;
690 result = OC_STACK_ERROR;
697 HandleVirtualResource (OCServerRequest *request, OCResource* resource)
699 if(!request || !resource)
701 return OC_STACK_INVALID_PARAM;
704 OCStackResult result = OC_STACK_ERROR;
705 char *filterValue = NULL;
706 uint8_t filterOn = 0;
707 uint16_t remaining = 0;
709 uint8_t firstLoopDone = 0;
710 char discoveryResBuf[MAX_RESPONSE_LENGTH] = {};
712 OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
714 result = ValidateUrlQuery (request->resourceUrl,
715 request->query, &filterOn,
718 if (result == OC_STACK_OK)
720 if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0)
722 ptr = discoveryResBuf;
723 remaining = MAX_RESPONSE_LENGTH;
725 // Check if valid resource and enough space in buffer for atleast
726 // the null character.
727 while(resource && (remaining > 1))
729 if((resource->resourceProperties & OC_ACTIVE)
730 && (resource->resourceProperties & OC_DISCOVERABLE))
732 // if there is data on the buffer, we have already added a response,
733 // so we need to add a comma before we do anything
735 && remaining >= (sizeof(OC_JSON_SEPARATOR)+1))
737 *ptr = OC_JSON_SEPARATOR;
742 result = BuildVirtualResourceResponse(resource, filterOn, filterValue,
743 (char*)ptr, &remaining, request->connectivityType );
745 if (result != OC_STACK_OK)
747 // if this failed, we need to remove the comma added above.
756 ptr += strlen((char *)ptr);
758 resource = resource->next;
761 if(strlen((const char *)discoveryResBuf) > 0)
763 OCEntityHandlerResponse response = {};
765 response.ehResult = OC_EH_OK;
766 response.payload = discoveryResBuf;
767 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
768 response.persistentBufferFlag = 0;
769 response.requestHandle = (OCRequestHandle) request;
770 response.resourceHandle = (OCResourceHandle) resource;
772 result = OCDoResponse(&response);
775 else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
777 remaining = MAX_RESPONSE_LENGTH;
778 ptr = discoveryResBuf;
780 result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
781 (char*)ptr, &remaining);
783 if(result == OC_STACK_OK)
785 ptr += strlen((char*)ptr);
788 if(remaining < MAX_RESPONSE_LENGTH)
790 OCEntityHandlerResponse response = {0};
792 response.ehResult = OC_EH_OK;
793 response.payload = discoveryResBuf;
794 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
795 response.persistentBufferFlag = 0;
796 response.requestHandle = (OCRequestHandle) request;
797 response.resourceHandle = (OCResourceHandle) resource;
799 result = OCDoResponse(&response);
802 else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
804 remaining = MAX_RESPONSE_LENGTH;
805 ptr = discoveryResBuf;
807 result = BuildVirtualResourceResponseForPlatform((char*)ptr, &remaining);
809 if(result == OC_STACK_OK)
811 ptr += strlen((char*)ptr);
814 if(remaining < MAX_RESPONSE_LENGTH)
816 OCEntityHandlerResponse response = {0};
818 response.ehResult = OC_EH_OK;
819 response.payload = discoveryResBuf;
820 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
821 response.persistentBufferFlag = 0;
822 response.requestHandle = (OCRequestHandle) request;
823 response.resourceHandle = (OCResourceHandle) resource;
825 result = OCDoResponse(&response);
831 if(resource->resourceProperties & OC_ACTIVE){
832 SendPresenceNotification(NULL);
837 result = OC_STACK_OK;
842 HandleDefaultDeviceEntityHandler (OCServerRequest *request)
846 return OC_STACK_INVALID_PARAM;
849 OCStackResult result = OC_STACK_OK;
850 OCEntityHandlerResult ehResult = OC_EH_ERROR;
851 OCEntityHandlerRequest ehRequest = {};
853 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
854 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
855 request->method, (OCResourceHandle) NULL, request->query,
856 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
857 request->rcvdVendorSpecificHeaderOptions,
858 (OCObserveAction)request->observationOption, (OCObservationId)0);
859 VERIFY_SUCCESS(result, OC_STACK_OK);
861 // At this point we know for sure that defaultDeviceHandler exists
862 ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
863 (char*) request->resourceUrl);
864 if(ehResult == OC_EH_SLOW)
866 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
867 request->slowFlag = 1;
869 else if(ehResult == OC_EH_ERROR)
871 FindAndDeleteServerRequest(request);
873 result = EntityHandlerCodeToOCStackCode(ehResult);
879 HandleResourceWithEntityHandler (OCServerRequest *request,
880 OCResource *resource,
881 uint8_t collectionResource)
883 if(!request || ! resource)
885 return OC_STACK_INVALID_PARAM;
888 OCStackResult result = OC_STACK_ERROR;
889 OCEntityHandlerResult ehResult = OC_EH_ERROR;
890 OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
891 ResourceObserver *resObs = NULL;
893 OCEntityHandlerRequest ehRequest = {};
895 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
896 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
897 request->method, (OCResourceHandle) resource, request->query,
898 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
899 request->rcvdVendorSpecificHeaderOptions,
900 (OCObserveAction)request->observationOption, 0);
901 VERIFY_SUCCESS(result, OC_STACK_OK);
903 if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
905 OC_LOG(INFO, TAG, PCF("No observation requested"));
906 ehFlag = OC_REQUEST_FLAG;
908 else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER &&
911 OC_LOG(INFO, TAG, PCF("Registering observation requested"));
912 result = GenerateObserverId(&ehRequest.obsInfo.obsId);
913 VERIFY_SUCCESS(result, OC_STACK_OK);
915 result = AddObserver ((const char*)(request->resourceUrl),
916 (const char *)(request->query),
917 ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
918 resource, request->qos,
919 &request->addressInfo, request->connectivityType);
921 if(result == OC_STACK_OK)
923 OC_LOG(INFO, TAG, PCF("Added observer successfully"));
924 request->observeResult = OC_STACK_OK;
925 ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
929 result = OC_STACK_OK;
930 // The error in observeResult for the request will be
931 // used when responding to this request by omitting
932 // the observation option/sequence number.
933 request->observeResult = OC_STACK_ERROR;
934 OC_LOG(ERROR, TAG, PCF("Observer Addition failed"));
935 ehFlag = OC_REQUEST_FLAG;
939 else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
942 OC_LOG(INFO, TAG, PCF("Deregistering observation requested"));
944 resObs = GetObserverUsingToken (request->requestToken, request->tokenLength);
948 // Stack does not contain this observation request
949 // Either token is incorrect or observation list is corrupted
950 result = OC_STACK_ERROR;
953 ehRequest.obsInfo.obsId = resObs->observeId;
954 ehFlag = (OCEntityHandlerFlag)(ehFlag | OC_OBSERVE_FLAG);
956 result = DeleteObserverUsingToken (request->requestToken, request->tokenLength);
958 if(result == OC_STACK_OK)
960 OC_LOG(INFO, TAG, PCF("Removed observer successfully"));
961 request->observeResult = OC_STACK_OK;
965 result = OC_STACK_OK;
966 request->observeResult = OC_STACK_ERROR;
967 OC_LOG(ERROR, TAG, PCF("Observer Removal failed"));
972 result = OC_STACK_ERROR;
976 ehResult = resource->entityHandler(ehFlag, &ehRequest);
977 if(ehResult == OC_EH_SLOW)
979 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
980 request->slowFlag = 1;
982 else if(ehResult == OC_EH_ERROR)
984 FindAndDeleteServerRequest(request);
986 result = EntityHandlerCodeToOCStackCode(ehResult);
992 HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
993 OCResource *resource)
995 if(!request || !resource)
997 return OC_STACK_INVALID_PARAM;
1000 OCStackResult result = OC_STACK_ERROR;
1001 OCEntityHandlerRequest ehRequest = {};
1003 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
1004 request->method, (OCResourceHandle) resource, request->query,
1005 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
1006 request->rcvdVendorSpecificHeaderOptions,
1007 (OCObserveAction)request->observationOption, (OCObservationId) 0);
1008 if(result != OC_STACK_OK)
1013 return (DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest));
1017 ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerRequest *request)
1019 OCStackResult ret = OC_STACK_OK;
1021 switch (resHandling)
1023 case OC_RESOURCE_VIRTUAL:
1025 ret = HandleVirtualResource (request, resource);
1028 case OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER:
1030 ret = HandleDefaultDeviceEntityHandler(request);
1033 case OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER:
1035 OC_LOG(INFO, TAG, PCF("OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER"));
1036 return OC_STACK_ERROR;
1038 case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
1040 ret = HandleResourceWithEntityHandler (request, resource, 0);
1043 case OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER:
1045 ret = HandleResourceWithEntityHandler (request, resource, 1);
1048 case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER:
1050 ret = HandleCollectionResourceDefaultEntityHandler (request, resource);
1053 case OC_RESOURCE_NOT_SPECIFIED:
1055 ret = OC_STACK_NO_RESOURCE;
1060 OC_LOG(INFO, TAG, PCF("Invalid Resource Determination"));
1061 return OC_STACK_ERROR;
1067 void DeleteDeviceInfo()
1071 cJSON_Delete(savedDeviceInfo);
1075 void DeletePlatformInfo()
1077 OC_LOG(INFO, TAG, PCF("Deleting platform info."));
1079 OCFree(savedPlatformInfo.platformID);
1080 savedPlatformInfo.platformID = NULL;
1082 OCFree(savedPlatformInfo.manufacturerName);
1083 savedPlatformInfo.manufacturerName = NULL;
1085 OCFree(savedPlatformInfo.manufacturerUrl);
1086 savedPlatformInfo.manufacturerUrl = NULL;
1088 OCFree(savedPlatformInfo.modelNumber);
1089 savedPlatformInfo.modelNumber = NULL;
1091 OCFree(savedPlatformInfo.dateOfManufacture);
1092 savedPlatformInfo.dateOfManufacture = NULL;
1094 OCFree(savedPlatformInfo.platformVersion);
1095 savedPlatformInfo.platformVersion = NULL;
1097 OCFree(savedPlatformInfo.operatingSystemVersion);
1098 savedPlatformInfo.operatingSystemVersion = NULL;
1100 OCFree(savedPlatformInfo.hardwareVersion);
1101 savedPlatformInfo.hardwareVersion = NULL;
1103 OCFree(savedPlatformInfo.firmwareVersion);
1104 savedPlatformInfo.firmwareVersion = NULL;
1106 OCFree(savedPlatformInfo.supportUrl);
1107 savedPlatformInfo.supportUrl = NULL;
1109 OCFree(savedPlatformInfo.systemTime);
1110 savedPlatformInfo.systemTime = NULL;
1113 static OCStackResult CloneStringIfNonNull(char **dest, char *src)
1117 *dest = (char*) OCMalloc(strlen(src) + 1);
1120 return OC_STACK_NO_MEMORY;
1130 static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
1132 DeletePlatformInfo();
1134 OCStackResult ret = OC_STACK_OK;
1135 ret = CloneStringIfNonNull(&(savedPlatformInfo.platformID), info.platformID);
1136 VERIFY_SUCCESS(ret, OC_STACK_OK);
1138 ret = CloneStringIfNonNull(&(savedPlatformInfo.manufacturerName), info.manufacturerName);
1139 VERIFY_SUCCESS(ret, OC_STACK_OK);
1141 ret = CloneStringIfNonNull(&(savedPlatformInfo.manufacturerUrl), info.manufacturerUrl);
1142 VERIFY_SUCCESS(ret, OC_STACK_OK);
1144 ret = CloneStringIfNonNull(&(savedPlatformInfo.modelNumber), info.modelNumber);
1145 VERIFY_SUCCESS(ret, OC_STACK_OK);
1147 ret = CloneStringIfNonNull(&(savedPlatformInfo.dateOfManufacture), info.dateOfManufacture);
1148 VERIFY_SUCCESS(ret, OC_STACK_OK);
1150 ret = CloneStringIfNonNull(&(savedPlatformInfo.platformVersion), info.platformVersion);
1151 VERIFY_SUCCESS(ret, OC_STACK_OK);
1153 ret = CloneStringIfNonNull(&(savedPlatformInfo.operatingSystemVersion), info.operatingSystemVersion);
1154 VERIFY_SUCCESS(ret, OC_STACK_OK);
1156 ret = CloneStringIfNonNull(&(savedPlatformInfo.hardwareVersion), info.hardwareVersion);
1157 VERIFY_SUCCESS(ret, OC_STACK_OK);
1159 ret = CloneStringIfNonNull(&(savedPlatformInfo.firmwareVersion), info.firmwareVersion);
1160 VERIFY_SUCCESS(ret, OC_STACK_OK);
1162 ret = CloneStringIfNonNull(&(savedPlatformInfo.supportUrl), info.supportUrl);
1163 VERIFY_SUCCESS(ret, OC_STACK_OK);
1165 ret = CloneStringIfNonNull(&(savedPlatformInfo.systemTime), info.systemTime);
1166 VERIFY_SUCCESS(ret, OC_STACK_OK);
1171 DeletePlatformInfo();
1176 OCStackResult SavePlatformInfo(OCPlatformInfo info)
1178 OCStackResult res = DeepCopyPlatFormInfo(info);
1180 if (res != OC_STACK_OK)
1182 OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
1186 OC_LOG(ERROR, TAG, PCF("Platform info saved."));