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"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
39 #include "cainterface.h"
43 #define TAG PCF("ocresource")
44 #define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
45 {OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
47 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
48 TAG, PCF(#arg " is NULL")); return (retVal); } }
50 extern OCResource *headResource;
51 static OCPlatformInfo savedPlatformInfo = {};
52 static OCDeviceInfo savedDeviceInfo = {};
54 static const char * VIRTUAL_RSRCS[] =
65 //-----------------------------------------------------------------------------
66 // Default resource entity handler function
67 //-----------------------------------------------------------------------------
68 OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
69 OCEntityHandlerRequest * request, void* callbackParam)
71 //TODO ("Implement me!!!!");
72 // TODO: remove silence unused param warnings
76 return OC_EH_OK; // Making sure that the Default EH and the Vendor EH have matching signatures
79 /* This method will retrieve the port at which the secure resource is hosted */
80 static OCStackResult GetSecurePortInfo(CATransportAdapter_t connType, uint16_t *port)
82 CAEndpoint_t* info = NULL;
84 OCStackResult ret = OC_STACK_ERROR;
86 CAResult_t caResult = CAGetNetworkInformation(&info, &size);
87 if ((caResult == CA_STATUS_OK) && info && size)
91 if ((info[size].flags & CA_SECURE) && info[size].adapter == connType)
93 if (info[size].adapter == CA_ADAPTER_IP)
95 *port = info[size].port;
107 static char* GetJSONStringFromPlatformInfo(OCPlatformInfo info)
109 cJSON *rootObj = cJSON_CreateObject();
116 cJSON *repObj = NULL;
117 char *jsonEncodedInfo = NULL;
119 cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
120 cJSON_CreateString(GetVirtualResourceUri(OC_PLATFORM_URI)));
122 cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
124 cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_ID, cJSON_CreateString(info.platformID));
125 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME, cJSON_CreateString(info.manufacturerName));
126 if (info.manufacturerUrl)
128 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
129 cJSON_CreateString(info.manufacturerUrl));
132 if (info.modelNumber)
134 cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
135 cJSON_CreateString(info.modelNumber));
138 if (info.dateOfManufacture)
140 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
141 cJSON_CreateString(info.dateOfManufacture));
144 if (info.platformVersion)
146 cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
147 cJSON_CreateString(info.platformVersion));
150 if (info.operatingSystemVersion)
152 cJSON_AddItemToObject (repObj, OC_RSRVD_OS_VERSION,
153 cJSON_CreateString(info.operatingSystemVersion));
156 if (info.hardwareVersion)
158 cJSON_AddItemToObject (repObj, OC_RSRVD_HARDWARE_VERSION,
159 cJSON_CreateString(info.hardwareVersion));
162 if (info.firmwareVersion)
164 cJSON_AddItemToObject (repObj, OC_RSRVD_FIRMWARE_VERSION,
165 cJSON_CreateString(info.firmwareVersion));
170 cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
171 cJSON_CreateString(info.supportUrl));
176 cJSON_AddItemToObject (repObj, OC_RSRVD_SYSTEM_TIME,
177 cJSON_CreateString(info.systemTime));
180 jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
182 cJSON_Delete(rootObj);
184 return jsonEncodedInfo;
187 static char* GetJSONStringFromDeviceInfo(OCDeviceInfo info)
189 cJSON *rootObj = cJSON_CreateObject();
196 cJSON *repObj = NULL;
197 char *jsonEncodedInfo = NULL;
199 cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
200 cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
202 cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
204 cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_ID,
205 cJSON_CreateString(OCGetServerInstanceIDString()));
207 cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_NAME,
208 cJSON_CreateString(info.deviceName));
210 cJSON_AddItemToObject (repObj, OC_RSRVD_SPEC_VERSION,
211 cJSON_CreateString(OC_SPEC_VERSION));
213 cJSON_AddItemToObject (repObj, OC_RSRVD_DATA_MODEL_VERSION,
214 cJSON_CreateString(OC_DATA_MODEL_VERSION));
216 jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
218 cJSON_Delete(rootObj);
220 return jsonEncodedInfo;
223 static OCStackResult ValidateUrlQuery (char *url, char *query,
224 uint8_t *filterOn, char **filterValue)
226 if(!filterOn || !filterValue)
228 return OC_STACK_INVALID_PARAM;
231 char *filterParam = NULL;
233 OC_LOG(INFO, TAG, PCF("Entering ValidateUrlQuery"));
236 return OC_STACK_INVALID_URI;
239 if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
240 strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0 ||
241 strcmp((char *)url, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
243 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
246 char* strTokPtr = NULL;
247 filterParam = strtok_r((char *)query, "=", &strTokPtr);
248 *filterValue = strtok_r(NULL, " ", &strTokPtr);
250 if (!(*filterValue) || ! filterParam)
252 return OC_STACK_INVALID_QUERY;
254 else if (strcmp (filterParam, OC_RSRVD_INTERFACE) == 0)
256 // Resource discovery with interface filter
257 *filterOn = STACK_RES_DISCOVERY_IF_FILTER;
259 else if (strcmp (filterParam, OC_RSRVD_RESOURCE_TYPE) == 0)
261 // Resource discovery with resource type filter
262 *filterOn = STACK_RES_DISCOVERY_RT_FILTER;
264 else if (strcmp (filterParam, OC_RSRVD_DEVICE_ID) == 0)
267 *filterOn = STACK_DEVICE_DISCOVERY_DI_FILTER;
269 else if (strcmp (filterParam, OC_RSRVD_DEVICE_NAME) == 0)
272 *filterOn = STACK_DEVICE_DISCOVERY_DN_FILTER;
276 // Other filter types not supported
277 return OC_STACK_INVALID_QUERY;
282 else if (strcmp((char *)url, GetVirtualResourceUri(OC_PRESENCE)) == 0)
284 //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
285 OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request"));
286 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
291 // Other URIs not yet supported
292 return OC_STACK_INVALID_URI;
294 OC_LOG(INFO, TAG, PCF("Exiting ValidateUrlQuery"));
300 BuildVirtualResourceResponse(const OCResource *resourcePtr, uint8_t filterOn,
301 const char *filterValue, char *out, uint16_t *remaining,
302 CATransportAdapter_t adapter)
304 if(!resourcePtr || !out || !remaining)
306 return OC_STACK_INVALID_PARAM;
309 OCResourceType *resourceTypePtr = NULL;
310 OCResourceInterface *interfacePtr = NULL;
311 cJSON *resObj = NULL;
312 cJSON *propObj = NULL;
313 cJSON *policyObj = NULL;
314 cJSON *rtArray = NULL;
315 char *jsonStr = NULL;
316 uint8_t encodeRes = 0;
317 OCStackResult ret = OC_STACK_OK;
318 uint16_t jsonLen = 0;
320 OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponse"));
321 resObj = cJSON_CreateObject();
326 if ((filterOn == STACK_RES_DISCOVERY_RT_FILTER) && filterValue)
328 resourceTypePtr = resourcePtr->rsrcType;
329 while (resourceTypePtr)
331 if (strcmp (resourceTypePtr->resourcetypename, filterValue) == 0)
336 resourceTypePtr = resourceTypePtr->next;
339 else if ((filterOn == STACK_RES_DISCOVERY_IF_FILTER) && filterValue)
341 interfacePtr = resourcePtr->rsrcInterface;
344 if (strcmp (interfacePtr->name, filterValue) == 0)
349 interfacePtr = interfacePtr->next;
352 else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
358 //TODO: Unsupported query filter
359 return OC_STACK_INVALID_QUERY;
365 cJSON_AddItemToObject(resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
367 // Add server instance id
368 cJSON_AddItemToObject(resObj,
369 OC_RSRVD_SERVER_INSTANCE_ID,
370 cJSON_CreateString(OCGetServerInstanceIDString()));
373 cJSON_AddItemToObject (resObj, OC_RSRVD_PROPERTY, propObj = cJSON_CreateObject());
374 // Add resource types
375 cJSON_AddItemToObject(propObj, OC_RSRVD_RESOURCE_TYPE, rtArray = cJSON_CreateArray());
376 resourceTypePtr = resourcePtr->rsrcType;
377 while (resourceTypePtr)
379 cJSON_AddItemToArray(rtArray,
380 cJSON_CreateString(resourceTypePtr->resourcetypename));
381 resourceTypePtr = resourceTypePtr->next;
383 // Add interface types
384 cJSON_AddItemToObject(propObj, OC_RSRVD_INTERFACE, rtArray = cJSON_CreateArray());
385 interfacePtr = resourcePtr->rsrcInterface;
388 cJSON_AddItemToArray(rtArray, cJSON_CreateString(interfacePtr->name));
389 interfacePtr = interfacePtr->next;
393 cJSON_AddItemToObject(propObj, OC_RSRVD_POLICY, policyObj = cJSON_CreateObject());
397 // Policy Property Bitmap
398 // If resource is discoverable, set discoverability flag.
399 // Resources that are not discoverable will not have the flag.
400 cJSON_AddNumberToObject(policyObj, OC_RSRVD_BITMAP,
401 resourcePtr->resourceProperties & (OC_OBSERVABLE|OC_DISCOVERABLE));
403 // Set secure flag for secure resources
404 if (resourcePtr->resourceProperties & OC_SECURE)
406 cJSON_AddNumberToObject(policyObj, OC_RSRVD_SECURE, OC_RESOURCE_SECURE);
407 //Set the IP port also as secure resources are hosted on a different port
409 if (GetSecurePortInfo(adapter, &port) == OC_STACK_OK)
411 cJSON_AddNumberToObject(policyObj, OC_RSRVD_HOSTING_PORT, port);
417 cJSON_Delete(resObj);
418 return OC_STACK_NO_MEMORY;
422 jsonStr = cJSON_PrintUnformatted (resObj);
426 cJSON_Delete(resObj);
427 return OC_STACK_NO_MEMORY;
430 jsonLen = strlen(jsonStr);
431 if (jsonLen < *remaining)
433 OICStrcpy(out, *remaining, jsonStr);
434 *remaining = *remaining - jsonLen;
438 ret = OC_STACK_ERROR;
440 cJSON_Delete (resObj);
443 OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponse"));
447 OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
448 char *out, uint16_t *remaining)
450 if(!out || !remaining)
452 return OC_STACK_INVALID_PARAM;
455 OCStackResult ret = OC_STACK_ERROR;
456 char *jsonStr = NULL;
457 uint16_t jsonLen = 0;
459 jsonStr = GetJSONStringFromDeviceInfo(savedDeviceInfo);
463 jsonLen = strlen(jsonStr);
465 if (jsonLen < *remaining)
467 OICStrcpy(out, *remaining, jsonStr);
468 *remaining = *remaining - jsonLen;
473 ret = OC_STACK_ERROR;
480 OC_LOG(ERROR, TAG, PCF("Error encoding save device info."));
481 ret = OC_STACK_ERROR;
486 OCStackResult BuildVirtualResourceResponseForPlatform(char *out, uint16_t *remaining)
488 OCStackResult ret = OC_STACK_OK;
490 char *jsonStr = GetJSONStringFromPlatformInfo(savedPlatformInfo);
494 size_t jsonLen = strlen(jsonStr);
496 if (jsonLen < *remaining)
498 OICStrcpy(out, *remaining, jsonStr);
499 *remaining = *remaining - jsonLen;
504 OC_LOG_V(ERROR, TAG, PCF("Platform info string too big. len: %u"), jsonLen);
505 ret = OC_STACK_ERROR;
511 OC_LOG(ERROR, TAG, PCF("Error encoding save platform info."));
512 ret = OC_STACK_ERROR;
519 const char * GetVirtualResourceUri( OCVirtualResources resource)
521 if (resource < OC_MAX_VIRTUAL_RESOURCES)
523 return VIRTUAL_RSRCS[resource];
529 bool IsVirtualResource(const char* resourceUri)
536 for (int i = 0; i < OC_MAX_VIRTUAL_RESOURCES; i++)
538 if (strcmp(resourceUri, GetVirtualResourceUri((OCVirtualResources)i)) == 0)
546 uint8_t IsCollectionResource (OCResource *resource)
553 for (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
555 if (resource->rsrcResources[i])
563 OCResource *FindResourceByUri(const char* resourceUri)
570 OCResource * pointer = headResource;
573 if (strcmp(resourceUri, pointer->uri) == 0)
577 pointer = pointer->next;
579 OC_LOG(INFO, TAG, PCF("Resource not found"));
584 OCStackResult DetermineResourceHandling (const OCServerRequest *request,
585 ResourceHandling *handling,
586 OCResource **resource)
588 if(!request || !handling || !resource)
590 return OC_STACK_INVALID_PARAM;
593 OC_LOG(INFO, TAG, PCF("Entering DetermineResourceHandling"));
595 const OCDevAddr *devAddr = &request->devAddr;
597 // Check if virtual resource
598 if (IsVirtualResource((const char*)request->resourceUrl))
600 *handling = OC_RESOURCE_VIRTUAL;
601 *resource = headResource;
604 if (strlen((const char*)(request->resourceUrl)) == 0)
606 // Resource URL not specified
607 *handling = OC_RESOURCE_NOT_SPECIFIED;
608 return OC_STACK_NO_RESOURCE;
612 OCResource *resourcePtr = NULL;
613 resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
614 *resource = resourcePtr;
617 if(defaultDeviceHandler)
619 *handling = OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER;
623 // Resource does not exist
624 // and default device handler does not exist
625 *handling = OC_RESOURCE_NOT_SPECIFIED;
626 return OC_STACK_NO_RESOURCE;
629 // secure resource will entertain only authorized requests
630 if ((resourcePtr->resourceProperties & OC_SECURE) && ((devAddr->flags & OC_FLAG_SECURE) == 0))
632 OC_LOG(ERROR, TAG, PCF("Un-authorized request. Ignoring"));
633 return OC_STACK_RESOURCE_ERROR;
636 if (IsCollectionResource (resourcePtr))
638 // Collection resource
639 if (resourcePtr->entityHandler != defaultResourceEHandler)
641 *handling = OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER;
646 *handling = OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER;
652 // Resource not a collection
653 if (resourcePtr->entityHandler != defaultResourceEHandler)
655 *handling = OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER;
660 *handling = OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER;
667 OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
669 OCStackResult result;
674 result = OC_STACK_OK;
677 result = OC_STACK_SLOW_RESOURCE;
680 result = OC_STACK_ERROR;
682 case OC_EH_FORBIDDEN:
683 result = OC_STACK_RESOURCE_ERROR;
685 case OC_EH_RESOURCE_CREATED:
686 result = OC_STACK_RESOURCE_CREATED;
688 case OC_EH_RESOURCE_DELETED:
689 result = OC_STACK_RESOURCE_DELETED;
691 case OC_EH_RESOURCE_NOT_FOUND:
692 result = OC_STACK_NO_RESOURCE;
695 result = OC_STACK_ERROR;
702 HandleVirtualResource(OCServerRequest *request, OCResource *resource)
704 if (!request || !resource)
706 return OC_STACK_INVALID_PARAM;
709 OCStackResult result = OC_STACK_ERROR;
710 char *filterValue = NULL;
711 uint8_t filterOn = 0;
712 uint16_t remaining = 0;
714 uint8_t firstLoopDone = 0;
715 char discoveryResBuf[MAX_RESPONSE_LENGTH] = {};
717 OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
719 result = ValidateUrlQuery (request->resourceUrl,
720 request->query, &filterOn,
723 if (result == OC_STACK_OK)
725 if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0)
727 ptr = discoveryResBuf;
728 remaining = MAX_RESPONSE_LENGTH;
730 // Check if valid resource and enough space in buffer for atleast
731 // the null character.
732 while(resource && (remaining > 1))
734 if((resource->resourceProperties & OC_ACTIVE)
735 && (resource->resourceProperties & OC_DISCOVERABLE))
737 // if there is data on the buffer, we have already added a response,
738 // so we need to add a comma before we do anything
740 && remaining >= (sizeof(OC_JSON_SEPARATOR)+1))
742 *ptr = OC_JSON_SEPARATOR;
747 result = BuildVirtualResourceResponse(resource, filterOn,
748 filterValue, (char*)ptr, &remaining,
749 (CATransportAdapter_t)request->devAddr.adapter);
751 if (result != OC_STACK_OK)
753 // if this failed, we need to remove the comma added above.
762 ptr += strlen((char *)ptr);
764 resource = resource->next;
767 if(strlen((const char *)discoveryResBuf) > 0)
769 OCEntityHandlerResponse response = {};
771 response.ehResult = OC_EH_OK;
772 response.payload = discoveryResBuf;
773 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
774 response.persistentBufferFlag = 0;
775 response.requestHandle = (OCRequestHandle) request;
776 response.resourceHandle = (OCResourceHandle) resource;
778 result = OCDoResponse(&response);
781 else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
783 remaining = MAX_RESPONSE_LENGTH;
784 ptr = discoveryResBuf;
786 result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
787 (char*)ptr, &remaining);
789 if(result == OC_STACK_OK)
791 ptr += strlen((char*)ptr);
794 if(remaining < MAX_RESPONSE_LENGTH)
796 OCEntityHandlerResponse response = {0};
798 response.ehResult = OC_EH_OK;
799 response.payload = discoveryResBuf;
800 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
801 response.persistentBufferFlag = 0;
802 response.requestHandle = (OCRequestHandle) request;
803 response.resourceHandle = (OCResourceHandle) resource;
805 result = OCDoResponse(&response);
808 else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
810 remaining = MAX_RESPONSE_LENGTH;
811 ptr = discoveryResBuf;
813 result = BuildVirtualResourceResponseForPlatform((char*)ptr, &remaining);
815 if(result == OC_STACK_OK)
817 ptr += strlen((char*)ptr);
820 if(remaining < MAX_RESPONSE_LENGTH)
822 OCEntityHandlerResponse response = {0};
824 response.ehResult = OC_EH_OK;
825 response.payload = discoveryResBuf;
826 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
827 response.persistentBufferFlag = 0;
828 response.requestHandle = (OCRequestHandle) request;
829 response.resourceHandle = (OCResourceHandle) resource;
831 result = OCDoResponse(&response);
837 if(resource->resourceProperties & OC_ACTIVE){
838 SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
843 result = OC_STACK_OK;
848 HandleDefaultDeviceEntityHandler (OCServerRequest *request)
852 return OC_STACK_INVALID_PARAM;
855 OCStackResult result = OC_STACK_OK;
856 OCEntityHandlerResult ehResult = OC_EH_ERROR;
857 OCEntityHandlerRequest ehRequest = {};
859 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
860 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
861 request->method, (OCResourceHandle) NULL, request->query,
862 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
863 request->rcvdVendorSpecificHeaderOptions,
864 (OCObserveAction)request->observationOption, (OCObservationId)0);
865 VERIFY_SUCCESS(result, OC_STACK_OK);
867 // At this point we know for sure that defaultDeviceHandler exists
868 ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
869 (char*) request->resourceUrl, defaultDeviceHandlerCallbackParameter);
870 if(ehResult == OC_EH_SLOW)
872 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
873 request->slowFlag = 1;
875 else if(ehResult == OC_EH_ERROR)
877 FindAndDeleteServerRequest(request);
879 result = EntityHandlerCodeToOCStackCode(ehResult);
885 HandleResourceWithEntityHandler (OCServerRequest *request,
886 OCResource *resource,
887 uint8_t collectionResource)
889 if(!request || ! resource)
891 return OC_STACK_INVALID_PARAM;
894 OCStackResult result = OC_STACK_ERROR;
895 OCEntityHandlerResult ehResult = OC_EH_ERROR;
896 OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
897 ResourceObserver *resObs = NULL;
899 OCEntityHandlerRequest ehRequest = {};
901 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
902 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
903 request->method, (OCResourceHandle) resource, request->query,
904 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
905 request->rcvdVendorSpecificHeaderOptions,
906 (OCObserveAction)request->observationOption, 0);
907 VERIFY_SUCCESS(result, OC_STACK_OK);
909 if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
911 OC_LOG(INFO, TAG, PCF("No observation requested"));
912 ehFlag = OC_REQUEST_FLAG;
914 else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER &&
917 OC_LOG(INFO, TAG, PCF("Registering observation requested"));
918 result = GenerateObserverId(&ehRequest.obsInfo.obsId);
919 VERIFY_SUCCESS(result, OC_STACK_OK);
921 result = AddObserver ((const char*)(request->resourceUrl),
922 (const char *)(request->query),
923 ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
924 resource, request->qos,
927 if(result == OC_STACK_OK)
929 OC_LOG(INFO, TAG, PCF("Added observer successfully"));
930 request->observeResult = OC_STACK_OK;
931 ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
935 result = OC_STACK_OK;
936 // The error in observeResult for the request will be
937 // used when responding to this request by omitting
938 // the observation option/sequence number.
939 request->observeResult = OC_STACK_ERROR;
940 OC_LOG(ERROR, TAG, PCF("Observer Addition failed"));
941 ehFlag = OC_REQUEST_FLAG;
945 else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
948 OC_LOG(INFO, TAG, PCF("Deregistering observation requested"));
950 resObs = GetObserverUsingToken (request->requestToken, request->tokenLength);
954 // Stack does not contain this observation request
955 // Either token is incorrect or observation list is corrupted
956 result = OC_STACK_ERROR;
959 ehRequest.obsInfo.obsId = resObs->observeId;
960 ehFlag = (OCEntityHandlerFlag)(ehFlag | OC_OBSERVE_FLAG);
962 result = DeleteObserverUsingToken (request->requestToken, request->tokenLength);
964 if(result == OC_STACK_OK)
966 OC_LOG(INFO, TAG, PCF("Removed observer successfully"));
967 request->observeResult = OC_STACK_OK;
971 result = OC_STACK_OK;
972 request->observeResult = OC_STACK_ERROR;
973 OC_LOG(ERROR, TAG, PCF("Observer Removal failed"));
978 result = OC_STACK_ERROR;
982 ehResult = resource->entityHandler(ehFlag, &ehRequest, resource->entityHandlerCallbackParam);
983 if(ehResult == OC_EH_SLOW)
985 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
986 request->slowFlag = 1;
988 else if(ehResult == OC_EH_ERROR)
990 FindAndDeleteServerRequest(request);
992 result = EntityHandlerCodeToOCStackCode(ehResult);
998 HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
999 OCResource *resource)
1001 if(!request || !resource)
1003 return OC_STACK_INVALID_PARAM;
1006 OCStackResult result = OC_STACK_ERROR;
1007 OCEntityHandlerRequest ehRequest = {};
1009 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
1010 request->method, (OCResourceHandle) resource, request->query,
1011 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
1012 request->rcvdVendorSpecificHeaderOptions,
1013 (OCObserveAction)request->observationOption, (OCObservationId) 0);
1014 if(result != OC_STACK_OK)
1019 return (DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest));
1023 ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerRequest *request)
1025 OCStackResult ret = OC_STACK_OK;
1027 switch (resHandling)
1029 case OC_RESOURCE_VIRTUAL:
1031 ret = HandleVirtualResource (request, resource);
1034 case OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER:
1036 ret = HandleDefaultDeviceEntityHandler(request);
1039 case OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER:
1041 OC_LOG(INFO, TAG, PCF("OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER"));
1042 return OC_STACK_ERROR;
1044 case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
1046 ret = HandleResourceWithEntityHandler (request, resource, 0);
1049 case OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER:
1051 ret = HandleResourceWithEntityHandler (request, resource, 1);
1054 case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER:
1056 ret = HandleCollectionResourceDefaultEntityHandler (request, resource);
1059 case OC_RESOURCE_NOT_SPECIFIED:
1061 ret = OC_STACK_NO_RESOURCE;
1066 OC_LOG(INFO, TAG, PCF("Invalid Resource Determination"));
1067 return OC_STACK_ERROR;
1073 void DeletePlatformInfo()
1075 OC_LOG(INFO, TAG, PCF("Deleting platform info."));
1077 OICFree(savedPlatformInfo.platformID);
1078 savedPlatformInfo.platformID = NULL;
1080 OICFree(savedPlatformInfo.manufacturerName);
1081 savedPlatformInfo.manufacturerName = NULL;
1083 OICFree(savedPlatformInfo.manufacturerUrl);
1084 savedPlatformInfo.manufacturerUrl = NULL;
1086 OICFree(savedPlatformInfo.modelNumber);
1087 savedPlatformInfo.modelNumber = NULL;
1089 OICFree(savedPlatformInfo.dateOfManufacture);
1090 savedPlatformInfo.dateOfManufacture = NULL;
1092 OICFree(savedPlatformInfo.platformVersion);
1093 savedPlatformInfo.platformVersion = NULL;
1095 OICFree(savedPlatformInfo.operatingSystemVersion);
1096 savedPlatformInfo.operatingSystemVersion = NULL;
1098 OICFree(savedPlatformInfo.hardwareVersion);
1099 savedPlatformInfo.hardwareVersion = NULL;
1101 OICFree(savedPlatformInfo.firmwareVersion);
1102 savedPlatformInfo.firmwareVersion = NULL;
1104 OICFree(savedPlatformInfo.supportUrl);
1105 savedPlatformInfo.supportUrl = NULL;
1107 OICFree(savedPlatformInfo.systemTime);
1108 savedPlatformInfo.systemTime = NULL;
1111 static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
1113 savedPlatformInfo.platformID = OICStrdup(info.platformID);
1114 savedPlatformInfo.manufacturerName = OICStrdup(info.manufacturerName);
1115 savedPlatformInfo.manufacturerUrl = OICStrdup(info.manufacturerUrl);
1116 savedPlatformInfo.modelNumber = OICStrdup(info.modelNumber);
1117 savedPlatformInfo.dateOfManufacture = OICStrdup(info.dateOfManufacture);
1118 savedPlatformInfo.platformVersion = OICStrdup(info.platformVersion);
1119 savedPlatformInfo.operatingSystemVersion = OICStrdup(info.operatingSystemVersion);
1120 savedPlatformInfo.hardwareVersion = OICStrdup(info.hardwareVersion);
1121 savedPlatformInfo.firmwareVersion = OICStrdup(info.firmwareVersion);
1122 savedPlatformInfo.supportUrl = OICStrdup(info.supportUrl);
1123 savedPlatformInfo.systemTime = OICStrdup(info.systemTime);
1125 if ((!savedPlatformInfo.platformID && info.platformID)||
1126 (!savedPlatformInfo.manufacturerName && info.manufacturerName)||
1127 (!savedPlatformInfo.manufacturerUrl && info.manufacturerUrl)||
1128 (!savedPlatformInfo.modelNumber && info.modelNumber)||
1129 (!savedPlatformInfo.dateOfManufacture && info.dateOfManufacture)||
1130 (!savedPlatformInfo.platformVersion && info.platformVersion)||
1131 (!savedPlatformInfo.operatingSystemVersion && info.operatingSystemVersion)||
1132 (!savedPlatformInfo.hardwareVersion && info.hardwareVersion)||
1133 (!savedPlatformInfo.firmwareVersion && info.firmwareVersion)||
1134 (!savedPlatformInfo.supportUrl && info.supportUrl)||
1135 (!savedPlatformInfo.systemTime && info.systemTime))
1137 DeletePlatformInfo();
1138 return OC_STACK_INVALID_PARAM;
1145 OCStackResult SavePlatformInfo(OCPlatformInfo info)
1147 DeletePlatformInfo();
1149 OCStackResult res = DeepCopyPlatFormInfo(info);
1151 if (res != OC_STACK_OK)
1153 OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
1157 OC_LOG(ERROR, TAG, PCF("Platform info saved."));
1163 void DeleteDeviceInfo()
1165 OC_LOG(INFO, TAG, PCF("Deleting device info."));
1167 OICFree(savedDeviceInfo.deviceName);
1168 savedDeviceInfo.deviceName = NULL;
1171 static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
1173 savedDeviceInfo.deviceName = OICStrdup(info.deviceName);
1175 if(!savedDeviceInfo.deviceName && info.deviceName)
1178 return OC_STACK_NO_MEMORY;
1184 OCStackResult SaveDeviceInfo(OCDeviceInfo info)
1186 OCStackResult res = OC_STACK_OK;
1190 res = DeepCopyDeviceInfo(info);
1192 VERIFY_SUCCESS(res, OC_STACK_OK);
1194 if(OCGetServerInstanceID() == NULL)
1196 OC_LOG(INFO, TAG, PCF("Device ID generation failed"));
1197 res = OC_STACK_ERROR;
1201 OC_LOG(INFO, TAG, PCF("Device initialized successfully."));