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());
130 cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_ID,
131 cJSON_CreateString(info.platformID));
134 if (info.manufacturerName)
136 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME,
137 cJSON_CreateString(info.manufacturerName));
140 if (info.manufacturerUrl)
142 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
143 cJSON_CreateString(info.manufacturerUrl));
146 if (info.modelNumber)
148 cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
149 cJSON_CreateString(info.modelNumber));
152 if (info.dateOfManufacture)
154 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
155 cJSON_CreateString(info.dateOfManufacture));
158 if (info.platformVersion)
160 cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
161 cJSON_CreateString(info.platformVersion));
164 if (info.operatingSystemVersion)
166 cJSON_AddItemToObject (repObj, OC_RSRVD_OS_VERSION,
167 cJSON_CreateString(info.operatingSystemVersion));
170 if (info.hardwareVersion)
172 cJSON_AddItemToObject (repObj, OC_RSRVD_HARDWARE_VERSION,
173 cJSON_CreateString(info.hardwareVersion));
176 if (info.firmwareVersion)
178 cJSON_AddItemToObject (repObj, OC_RSRVD_FIRMWARE_VERSION,
179 cJSON_CreateString(info.firmwareVersion));
184 cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
185 cJSON_CreateString(info.supportUrl));
190 cJSON_AddItemToObject (repObj, OC_RSRVD_SYSTEM_TIME,
191 cJSON_CreateString(info.systemTime));
194 jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
196 cJSON_Delete(rootObj);
198 return jsonEncodedInfo;
201 static char* GetJSONStringFromDeviceInfo(OCDeviceInfo info)
203 cJSON *rootObj = cJSON_CreateObject();
210 cJSON *repObj = NULL;
211 char *jsonEncodedInfo = NULL;
213 cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
214 cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
216 cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
223 cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_ID,
224 cJSON_CreateString(OCGetServerInstanceIDString()));
228 cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_NAME,
229 cJSON_CreateString(info.deviceName));
232 cJSON_AddItemToObject (repObj, OC_RSRVD_SPEC_VERSION,
233 cJSON_CreateString(OC_SPEC_VERSION));
235 cJSON_AddItemToObject (repObj, OC_RSRVD_DATA_MODEL_VERSION,
236 cJSON_CreateString(OC_DATA_MODEL_VERSION));
238 jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
240 cJSON_Delete(rootObj);
242 return jsonEncodedInfo;
245 static OCStackResult ValidateUrlQuery (char *url, char *query,
246 uint8_t *filterOn, char **filterValue)
248 if(!filterOn || !filterValue)
250 return OC_STACK_INVALID_PARAM;
253 char *filterParam = NULL;
255 OC_LOG(INFO, TAG, PCF("Entering ValidateUrlQuery"));
258 return OC_STACK_INVALID_URI;
261 if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
262 strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0 ||
263 strcmp((char *)url, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
265 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
268 char* strTokPtr = NULL;
269 filterParam = strtok_r((char *)query, "=", &strTokPtr);
270 *filterValue = strtok_r(NULL, " ", &strTokPtr);
272 if (!(*filterValue) || ! filterParam)
274 return OC_STACK_INVALID_QUERY;
276 else if (strcmp (filterParam, OC_RSRVD_INTERFACE) == 0)
278 // Resource discovery with interface filter
279 *filterOn = STACK_RES_DISCOVERY_IF_FILTER;
281 else if (strcmp (filterParam, OC_RSRVD_RESOURCE_TYPE) == 0)
283 // Resource discovery with resource type filter
284 *filterOn = STACK_RES_DISCOVERY_RT_FILTER;
286 else if (strcmp (filterParam, OC_RSRVD_DEVICE_ID) == 0)
289 *filterOn = STACK_DEVICE_DISCOVERY_DI_FILTER;
291 else if (strcmp (filterParam, OC_RSRVD_DEVICE_NAME) == 0)
294 *filterOn = STACK_DEVICE_DISCOVERY_DN_FILTER;
298 // Other filter types not supported
299 return OC_STACK_INVALID_QUERY;
304 else if (strcmp((char *)url, GetVirtualResourceUri(OC_PRESENCE)) == 0)
306 //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
307 OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request"));
308 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
313 // Other URIs not yet supported
314 return OC_STACK_INVALID_URI;
316 OC_LOG(INFO, TAG, PCF("Exiting ValidateUrlQuery"));
322 BuildVirtualResourceResponse(const OCResource *resourcePtr, uint8_t filterOn,
323 const char *filterValue, char *out, uint16_t *remaining,
324 CATransportAdapter_t adapter)
326 if(!resourcePtr || !out || !remaining)
328 return OC_STACK_INVALID_PARAM;
331 OCResourceType *resourceTypePtr = NULL;
332 OCResourceInterface *interfacePtr = NULL;
333 cJSON *resObj = NULL;
334 cJSON *propObj = NULL;
335 cJSON *policyObj = NULL;
336 cJSON *rtArray = NULL;
337 char *jsonStr = NULL;
338 uint8_t encodeRes = 0;
339 OCStackResult ret = OC_STACK_OK;
340 uint16_t jsonLen = 0;
342 OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponse"));
343 resObj = cJSON_CreateObject();
348 if ((filterOn == STACK_RES_DISCOVERY_RT_FILTER) && filterValue)
350 resourceTypePtr = resourcePtr->rsrcType;
351 while (resourceTypePtr)
353 if (strcmp (resourceTypePtr->resourcetypename, filterValue) == 0)
358 resourceTypePtr = resourceTypePtr->next;
361 else if ((filterOn == STACK_RES_DISCOVERY_IF_FILTER) && filterValue)
363 interfacePtr = resourcePtr->rsrcInterface;
366 if (strcmp (interfacePtr->name, filterValue) == 0)
371 interfacePtr = interfacePtr->next;
374 else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
380 //TODO: Unsupported query filter
381 return OC_STACK_INVALID_QUERY;
387 cJSON_AddItemToObject(resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
389 // Add server instance id
390 cJSON_AddItemToObject(resObj,
391 OC_RSRVD_SERVER_INSTANCE_ID,
392 cJSON_CreateString(OCGetServerInstanceIDString()));
395 cJSON_AddItemToObject (resObj, OC_RSRVD_PROPERTY, propObj = cJSON_CreateObject());
396 // Add resource types
397 cJSON_AddItemToObject(propObj, OC_RSRVD_RESOURCE_TYPE, rtArray = cJSON_CreateArray());
398 resourceTypePtr = resourcePtr->rsrcType;
399 while (resourceTypePtr)
401 cJSON_AddItemToArray(rtArray,
402 cJSON_CreateString(resourceTypePtr->resourcetypename));
403 resourceTypePtr = resourceTypePtr->next;
405 // Add interface types
406 cJSON_AddItemToObject(propObj, OC_RSRVD_INTERFACE, rtArray = cJSON_CreateArray());
407 interfacePtr = resourcePtr->rsrcInterface;
410 cJSON_AddItemToArray(rtArray, cJSON_CreateString(interfacePtr->name));
411 interfacePtr = interfacePtr->next;
415 cJSON_AddItemToObject(propObj, OC_RSRVD_POLICY, policyObj = cJSON_CreateObject());
419 // Policy Property Bitmap
420 // If resource is discoverable, set discoverability flag.
421 // Resources that are not discoverable will not have the flag.
422 cJSON_AddNumberToObject(policyObj, OC_RSRVD_BITMAP,
423 resourcePtr->resourceProperties & (OC_OBSERVABLE|OC_DISCOVERABLE));
425 // Set secure flag for secure resources
426 if (resourcePtr->resourceProperties & OC_SECURE)
428 cJSON_AddNumberToObject(policyObj, OC_RSRVD_SECURE, OC_RESOURCE_SECURE);
429 //Set the IP port also as secure resources are hosted on a different port
431 if (GetSecurePortInfo(adapter, &port) == OC_STACK_OK)
433 cJSON_AddNumberToObject(policyObj, OC_RSRVD_HOSTING_PORT, port);
439 cJSON_Delete(resObj);
440 return OC_STACK_NO_MEMORY;
444 jsonStr = cJSON_PrintUnformatted (resObj);
448 cJSON_Delete(resObj);
449 return OC_STACK_NO_MEMORY;
452 jsonLen = strlen(jsonStr);
453 if (jsonLen < *remaining)
455 OICStrcpy(out, *remaining, jsonStr);
456 *remaining = *remaining - jsonLen;
460 ret = OC_STACK_ERROR;
462 cJSON_Delete (resObj);
465 OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponse"));
469 OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
470 char *out, uint16_t *remaining)
472 if(!out || !remaining)
474 return OC_STACK_INVALID_PARAM;
477 OCStackResult ret = OC_STACK_ERROR;
478 char *jsonStr = NULL;
479 uint16_t jsonLen = 0;
481 jsonStr = GetJSONStringFromDeviceInfo(savedDeviceInfo);
485 jsonLen = strlen(jsonStr);
487 if (jsonLen < *remaining)
489 OICStrcpy(out, *remaining, jsonStr);
490 *remaining = *remaining - jsonLen;
495 ret = OC_STACK_ERROR;
502 OC_LOG(ERROR, TAG, PCF("Error encoding save device info."));
503 ret = OC_STACK_ERROR;
508 OCStackResult BuildVirtualResourceResponseForPlatform(char *out, uint16_t *remaining)
510 OCStackResult ret = OC_STACK_OK;
512 char *jsonStr = GetJSONStringFromPlatformInfo(savedPlatformInfo);
516 size_t jsonLen = strlen(jsonStr);
518 if (jsonLen < *remaining)
520 OICStrcpy(out, *remaining, jsonStr);
521 *remaining = *remaining - jsonLen;
526 OC_LOG_V(ERROR, TAG, PCF("Platform info string too big. len: %u"), jsonLen);
527 ret = OC_STACK_ERROR;
533 OC_LOG(ERROR, TAG, PCF("Error encoding save platform info."));
534 ret = OC_STACK_ERROR;
541 const char * GetVirtualResourceUri( OCVirtualResources resource)
543 if (resource < OC_MAX_VIRTUAL_RESOURCES)
545 return VIRTUAL_RSRCS[resource];
551 bool IsVirtualResource(const char* resourceUri)
558 for (int i = 0; i < OC_MAX_VIRTUAL_RESOURCES; i++)
560 if (strcmp(resourceUri, GetVirtualResourceUri((OCVirtualResources)i)) == 0)
568 uint8_t IsCollectionResource (OCResource *resource)
575 for (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
577 if (resource->rsrcResources[i])
585 OCResource *FindResourceByUri(const char* resourceUri)
592 OCResource * pointer = headResource;
595 if (strcmp(resourceUri, pointer->uri) == 0)
599 pointer = pointer->next;
601 OC_LOG(INFO, TAG, PCF("Resource not found"));
606 OCStackResult DetermineResourceHandling (const OCServerRequest *request,
607 ResourceHandling *handling,
608 OCResource **resource)
610 if(!request || !handling || !resource)
612 return OC_STACK_INVALID_PARAM;
615 OC_LOG(INFO, TAG, PCF("Entering DetermineResourceHandling"));
617 const OCDevAddr *devAddr = &request->devAddr;
619 // Check if virtual resource
620 if (IsVirtualResource((const char*)request->resourceUrl))
622 *handling = OC_RESOURCE_VIRTUAL;
623 *resource = headResource;
626 if (strlen((const char*)(request->resourceUrl)) == 0)
628 // Resource URL not specified
629 *handling = OC_RESOURCE_NOT_SPECIFIED;
630 return OC_STACK_NO_RESOURCE;
634 OCResource *resourcePtr = NULL;
635 resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
636 *resource = resourcePtr;
639 if(defaultDeviceHandler)
641 *handling = OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER;
645 // Resource does not exist
646 // and default device handler does not exist
647 *handling = OC_RESOURCE_NOT_SPECIFIED;
648 return OC_STACK_NO_RESOURCE;
651 // secure resource will entertain only authorized requests
652 if ((resourcePtr->resourceProperties & OC_SECURE) && ((devAddr->flags & OC_FLAG_SECURE) == 0))
654 OC_LOG(ERROR, TAG, PCF("Un-authorized request. Ignoring"));
655 return OC_STACK_RESOURCE_ERROR;
658 if (IsCollectionResource (resourcePtr))
660 // Collection resource
661 if (resourcePtr->entityHandler != defaultResourceEHandler)
663 *handling = OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER;
668 *handling = OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER;
674 // Resource not a collection
675 if (resourcePtr->entityHandler != defaultResourceEHandler)
677 *handling = OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER;
682 *handling = OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER;
689 OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
691 OCStackResult result;
696 result = OC_STACK_OK;
699 result = OC_STACK_SLOW_RESOURCE;
702 result = OC_STACK_ERROR;
704 case OC_EH_FORBIDDEN:
705 result = OC_STACK_RESOURCE_ERROR;
707 case OC_EH_RESOURCE_CREATED:
708 result = OC_STACK_RESOURCE_CREATED;
710 case OC_EH_RESOURCE_DELETED:
711 result = OC_STACK_RESOURCE_DELETED;
713 case OC_EH_RESOURCE_NOT_FOUND:
714 result = OC_STACK_NO_RESOURCE;
717 result = OC_STACK_ERROR;
724 HandleVirtualResource(OCServerRequest *request, OCResource *resource)
726 if (!request || !resource)
728 return OC_STACK_INVALID_PARAM;
731 OCStackResult result = OC_STACK_ERROR;
732 char *filterValue = NULL;
733 uint8_t filterOn = 0;
734 uint16_t remaining = 0;
736 uint8_t firstLoopDone = 0;
737 char discoveryResBuf[MAX_RESPONSE_LENGTH] = {};
739 OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
741 result = ValidateUrlQuery (request->resourceUrl,
742 request->query, &filterOn,
745 if (result == OC_STACK_OK)
747 if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0)
749 ptr = discoveryResBuf;
750 remaining = MAX_RESPONSE_LENGTH;
752 // Check if valid resource and enough space in buffer for atleast
753 // the null character.
754 while(resource && (remaining > 1))
756 if((resource->resourceProperties & OC_ACTIVE)
757 && (resource->resourceProperties & OC_DISCOVERABLE))
759 // if there is data on the buffer, we have already added a response,
760 // so we need to add a comma before we do anything
762 && remaining >= (sizeof(OC_JSON_SEPARATOR)+1))
764 *ptr = OC_JSON_SEPARATOR;
769 result = BuildVirtualResourceResponse(resource, filterOn,
770 filterValue, (char*)ptr, &remaining,
771 (CATransportAdapter_t)request->devAddr.adapter);
773 if (result != OC_STACK_OK)
775 // if this failed, we need to remove the comma added above.
784 ptr += strlen((char *)ptr);
786 resource = resource->next;
789 if(strlen((const char *)discoveryResBuf) > 0)
791 OCEntityHandlerResponse response = {};
793 response.ehResult = OC_EH_OK;
794 response.payload = discoveryResBuf;
795 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
796 response.persistentBufferFlag = 0;
797 response.requestHandle = (OCRequestHandle) request;
798 response.resourceHandle = (OCResourceHandle) resource;
800 result = OCDoResponse(&response);
803 else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
805 remaining = MAX_RESPONSE_LENGTH;
806 ptr = discoveryResBuf;
808 result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
809 (char*)ptr, &remaining);
811 if(result == OC_STACK_OK)
813 ptr += strlen((char*)ptr);
816 if(remaining < MAX_RESPONSE_LENGTH)
818 OCEntityHandlerResponse response = {0};
820 response.ehResult = OC_EH_OK;
821 response.payload = discoveryResBuf;
822 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
823 response.persistentBufferFlag = 0;
824 response.requestHandle = (OCRequestHandle) request;
825 response.resourceHandle = (OCResourceHandle) resource;
827 result = OCDoResponse(&response);
830 else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
832 remaining = MAX_RESPONSE_LENGTH;
833 ptr = discoveryResBuf;
835 result = BuildVirtualResourceResponseForPlatform((char*)ptr, &remaining);
837 if(result == OC_STACK_OK)
839 ptr += strlen((char*)ptr);
842 if(remaining < MAX_RESPONSE_LENGTH)
844 OCEntityHandlerResponse response = {0};
846 response.ehResult = OC_EH_OK;
847 response.payload = discoveryResBuf;
848 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
849 response.persistentBufferFlag = 0;
850 response.requestHandle = (OCRequestHandle) request;
851 response.resourceHandle = (OCResourceHandle) resource;
853 result = OCDoResponse(&response);
859 if(resource->resourceProperties & OC_ACTIVE){
860 SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
865 result = OC_STACK_OK;
870 HandleDefaultDeviceEntityHandler (OCServerRequest *request)
874 return OC_STACK_INVALID_PARAM;
877 OCStackResult result = OC_STACK_OK;
878 OCEntityHandlerResult ehResult = OC_EH_ERROR;
879 OCEntityHandlerRequest ehRequest = {};
881 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
882 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
883 request->method, (OCResourceHandle) NULL, request->query,
884 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
885 request->rcvdVendorSpecificHeaderOptions,
886 (OCObserveAction)request->observationOption, (OCObservationId)0);
887 VERIFY_SUCCESS(result, OC_STACK_OK);
889 // At this point we know for sure that defaultDeviceHandler exists
890 ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
891 (char*) request->resourceUrl, defaultDeviceHandlerCallbackParameter);
892 if(ehResult == OC_EH_SLOW)
894 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
895 request->slowFlag = 1;
897 else if(ehResult == OC_EH_ERROR)
899 FindAndDeleteServerRequest(request);
901 result = EntityHandlerCodeToOCStackCode(ehResult);
907 HandleResourceWithEntityHandler (OCServerRequest *request,
908 OCResource *resource,
909 uint8_t collectionResource)
911 if(!request || ! resource)
913 return OC_STACK_INVALID_PARAM;
916 OCStackResult result = OC_STACK_ERROR;
917 OCEntityHandlerResult ehResult = OC_EH_ERROR;
918 OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
919 ResourceObserver *resObs = NULL;
921 OCEntityHandlerRequest ehRequest = {};
923 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
924 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
925 request->method, (OCResourceHandle) resource, request->query,
926 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
927 request->rcvdVendorSpecificHeaderOptions,
928 (OCObserveAction)request->observationOption, 0);
929 VERIFY_SUCCESS(result, OC_STACK_OK);
931 if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
933 OC_LOG(INFO, TAG, PCF("No observation requested"));
934 ehFlag = OC_REQUEST_FLAG;
936 else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER &&
939 OC_LOG(INFO, TAG, PCF("Registering observation requested"));
940 result = GenerateObserverId(&ehRequest.obsInfo.obsId);
941 VERIFY_SUCCESS(result, OC_STACK_OK);
943 result = AddObserver ((const char*)(request->resourceUrl),
944 (const char *)(request->query),
945 ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
946 resource, request->qos,
949 if(result == OC_STACK_OK)
951 OC_LOG(INFO, TAG, PCF("Added observer successfully"));
952 request->observeResult = OC_STACK_OK;
953 ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
957 result = OC_STACK_OK;
958 // The error in observeResult for the request will be
959 // used when responding to this request by omitting
960 // the observation option/sequence number.
961 request->observeResult = OC_STACK_ERROR;
962 OC_LOG(ERROR, TAG, PCF("Observer Addition failed"));
963 ehFlag = OC_REQUEST_FLAG;
967 else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
970 OC_LOG(INFO, TAG, PCF("Deregistering observation requested"));
972 resObs = GetObserverUsingToken (request->requestToken, request->tokenLength);
976 // Stack does not contain this observation request
977 // Either token is incorrect or observation list is corrupted
978 result = OC_STACK_ERROR;
981 ehRequest.obsInfo.obsId = resObs->observeId;
982 ehFlag = (OCEntityHandlerFlag)(ehFlag | OC_OBSERVE_FLAG);
984 result = DeleteObserverUsingToken (request->requestToken, request->tokenLength);
986 if(result == OC_STACK_OK)
988 OC_LOG(INFO, TAG, PCF("Removed observer successfully"));
989 request->observeResult = OC_STACK_OK;
993 result = OC_STACK_OK;
994 request->observeResult = OC_STACK_ERROR;
995 OC_LOG(ERROR, TAG, PCF("Observer Removal failed"));
1000 result = OC_STACK_ERROR;
1004 ehResult = resource->entityHandler(ehFlag, &ehRequest, resource->entityHandlerCallbackParam);
1005 if(ehResult == OC_EH_SLOW)
1007 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
1008 request->slowFlag = 1;
1010 else if(ehResult == OC_EH_ERROR)
1012 FindAndDeleteServerRequest(request);
1014 result = EntityHandlerCodeToOCStackCode(ehResult);
1019 static OCStackResult
1020 HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
1021 OCResource *resource)
1023 if(!request || !resource)
1025 return OC_STACK_INVALID_PARAM;
1028 OCStackResult result = OC_STACK_ERROR;
1029 OCEntityHandlerRequest ehRequest = {};
1031 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
1032 request->method, (OCResourceHandle) resource, request->query,
1033 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
1034 request->rcvdVendorSpecificHeaderOptions,
1035 (OCObserveAction)request->observationOption, (OCObservationId) 0);
1036 if(result != OC_STACK_OK)
1041 return (DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest));
1045 ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerRequest *request)
1047 OCStackResult ret = OC_STACK_OK;
1049 switch (resHandling)
1051 case OC_RESOURCE_VIRTUAL:
1053 ret = HandleVirtualResource (request, resource);
1056 case OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER:
1058 ret = HandleDefaultDeviceEntityHandler(request);
1061 case OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER:
1063 OC_LOG(INFO, TAG, PCF("OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER"));
1064 return OC_STACK_ERROR;
1066 case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
1068 ret = HandleResourceWithEntityHandler (request, resource, 0);
1071 case OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER:
1073 ret = HandleResourceWithEntityHandler (request, resource, 1);
1076 case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER:
1078 ret = HandleCollectionResourceDefaultEntityHandler (request, resource);
1081 case OC_RESOURCE_NOT_SPECIFIED:
1083 ret = OC_STACK_NO_RESOURCE;
1088 OC_LOG(INFO, TAG, PCF("Invalid Resource Determination"));
1089 return OC_STACK_ERROR;
1095 void DeletePlatformInfo()
1097 OC_LOG(INFO, TAG, PCF("Deleting platform info."));
1099 OICFree(savedPlatformInfo.platformID);
1100 savedPlatformInfo.platformID = NULL;
1102 OICFree(savedPlatformInfo.manufacturerName);
1103 savedPlatformInfo.manufacturerName = NULL;
1105 OICFree(savedPlatformInfo.manufacturerUrl);
1106 savedPlatformInfo.manufacturerUrl = NULL;
1108 OICFree(savedPlatformInfo.modelNumber);
1109 savedPlatformInfo.modelNumber = NULL;
1111 OICFree(savedPlatformInfo.dateOfManufacture);
1112 savedPlatformInfo.dateOfManufacture = NULL;
1114 OICFree(savedPlatformInfo.platformVersion);
1115 savedPlatformInfo.platformVersion = NULL;
1117 OICFree(savedPlatformInfo.operatingSystemVersion);
1118 savedPlatformInfo.operatingSystemVersion = NULL;
1120 OICFree(savedPlatformInfo.hardwareVersion);
1121 savedPlatformInfo.hardwareVersion = NULL;
1123 OICFree(savedPlatformInfo.firmwareVersion);
1124 savedPlatformInfo.firmwareVersion = NULL;
1126 OICFree(savedPlatformInfo.supportUrl);
1127 savedPlatformInfo.supportUrl = NULL;
1129 OICFree(savedPlatformInfo.systemTime);
1130 savedPlatformInfo.systemTime = NULL;
1133 static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
1135 savedPlatformInfo.platformID = OICStrdup(info.platformID);
1136 savedPlatformInfo.manufacturerName = OICStrdup(info.manufacturerName);
1137 savedPlatformInfo.manufacturerUrl = OICStrdup(info.manufacturerUrl);
1138 savedPlatformInfo.modelNumber = OICStrdup(info.modelNumber);
1139 savedPlatformInfo.dateOfManufacture = OICStrdup(info.dateOfManufacture);
1140 savedPlatformInfo.platformVersion = OICStrdup(info.platformVersion);
1141 savedPlatformInfo.operatingSystemVersion = OICStrdup(info.operatingSystemVersion);
1142 savedPlatformInfo.hardwareVersion = OICStrdup(info.hardwareVersion);
1143 savedPlatformInfo.firmwareVersion = OICStrdup(info.firmwareVersion);
1144 savedPlatformInfo.supportUrl = OICStrdup(info.supportUrl);
1145 savedPlatformInfo.systemTime = OICStrdup(info.systemTime);
1147 if ((!savedPlatformInfo.platformID && info.platformID)||
1148 (!savedPlatformInfo.manufacturerName && info.manufacturerName)||
1149 (!savedPlatformInfo.manufacturerUrl && info.manufacturerUrl)||
1150 (!savedPlatformInfo.modelNumber && info.modelNumber)||
1151 (!savedPlatformInfo.dateOfManufacture && info.dateOfManufacture)||
1152 (!savedPlatformInfo.platformVersion && info.platformVersion)||
1153 (!savedPlatformInfo.operatingSystemVersion && info.operatingSystemVersion)||
1154 (!savedPlatformInfo.hardwareVersion && info.hardwareVersion)||
1155 (!savedPlatformInfo.firmwareVersion && info.firmwareVersion)||
1156 (!savedPlatformInfo.supportUrl && info.supportUrl)||
1157 (!savedPlatformInfo.systemTime && info.systemTime))
1159 DeletePlatformInfo();
1160 return OC_STACK_INVALID_PARAM;
1167 OCStackResult SavePlatformInfo(OCPlatformInfo info)
1169 DeletePlatformInfo();
1171 OCStackResult res = DeepCopyPlatFormInfo(info);
1173 if (res != OC_STACK_OK)
1175 OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
1179 OC_LOG(ERROR, TAG, PCF("Platform info saved."));
1185 void DeleteDeviceInfo()
1187 OC_LOG(INFO, TAG, PCF("Deleting device info."));
1189 OICFree(savedDeviceInfo.deviceName);
1190 savedDeviceInfo.deviceName = NULL;
1193 static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
1195 savedDeviceInfo.deviceName = OICStrdup(info.deviceName);
1197 if(!savedDeviceInfo.deviceName && info.deviceName)
1200 return OC_STACK_NO_MEMORY;
1206 OCStackResult SaveDeviceInfo(OCDeviceInfo info)
1208 OCStackResult res = OC_STACK_OK;
1212 res = DeepCopyDeviceInfo(info);
1214 VERIFY_SUCCESS(res, OC_STACK_OK);
1216 if(OCGetServerInstanceID() == NULL)
1218 OC_LOG(INFO, TAG, PCF("Device ID generation failed"));
1219 res = OC_STACK_ERROR;
1223 OC_LOG(INFO, TAG, PCF("Device initialized successfully."));