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"
37 #include "ocpayload.h"
40 #include "cainterface.h"
43 #include "rd_server.h"
47 #define TAG PCF("ocresource")
48 #define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
49 {OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
51 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
52 TAG, PCF(#arg " is NULL")); return (retVal); } }
54 extern OCResource *headResource;
55 static OCPlatformInfo savedPlatformInfo = {0};
56 static OCDeviceInfo savedDeviceInfo = {0};
58 //-----------------------------------------------------------------------------
59 // Default resource entity handler function
60 //-----------------------------------------------------------------------------
61 OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
62 OCEntityHandlerRequest * request, void* callbackParam)
64 //TODO ("Implement me!!!!");
65 // TODO: remove silence unused param warnings
69 return OC_EH_OK; // Making sure that the Default EH and the Vendor EH have matching signatures
72 /* This method will retrieve the port at which the secure resource is hosted */
73 static OCStackResult GetSecurePortInfo(OCDevAddr *endpoint, uint16_t *port)
77 if (endpoint->adapter == OC_ADAPTER_IP)
79 if (endpoint->flags & OC_IP_USE_V6)
81 p = caglobals.ip.u6s.port;
83 else if (endpoint->flags & OC_IP_USE_V4)
85 p = caglobals.ip.u4s.port;
94 * Function will extract 0, 1 or 2 filters from query.
95 * More than 2 filters or unsupported filters will result in error.
96 * If both filters are of the same supported type, the 2nd one will be picked.
97 * Resource and device filters in the SAME query are NOT validated
98 * and resources will likely not clear filters.
100 static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char **filterTwo)
105 char *restOfQuery = NULL;
106 int numKeyValuePairsParsed = 0;
111 OC_LOG_V(INFO, TAG, "Extracting params from %s", query);
113 char *keyValuePair = strtok_r (query, OC_QUERY_SEPARATOR, &restOfQuery);
117 if (numKeyValuePairsParsed >= 2)
119 OC_LOG(ERROR, TAG, PCF("More than 2 queries params in URI."));
120 return OC_STACK_INVALID_QUERY;
123 key = strtok_r(keyValuePair, OC_KEY_VALUE_DELIMITER, &value);
127 return OC_STACK_INVALID_QUERY;
129 else if (strcmp (key, OC_RSRVD_INTERFACE) == 0)
131 *filterOne = value; // if
133 else if (strcmp (key, OC_RSRVD_RESOURCE_TYPE) == 0)
135 *filterTwo = value; // rt
139 OC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
140 return OC_STACK_INVALID_QUERY;
142 ++numKeyValuePairsParsed;
144 keyValuePair = strtok_r(NULL, OC_QUERY_SEPARATOR, &restOfQuery);
147 OC_LOG_V(INFO, TAG, "Extracted params %s and %s.", *filterOne, *filterTwo);
151 static OCVirtualResources GetTypeOfVirtualURI(const char *uriInRequest)
153 if (strcmp(uriInRequest, OC_RSRVD_WELL_KNOWN_URI) == 0)
155 return OC_WELL_KNOWN_URI;
157 else if (strcmp(uriInRequest, OC_RSRVD_DEVICE_URI) == 0)
159 return OC_DEVICE_URI;
161 else if (strcmp(uriInRequest, OC_RSRVD_PLATFORM_URI) == 0)
163 return OC_PLATFORM_URI;
165 else if (strcmp(uriInRequest, OC_RSRVD_RESOURCE_TYPES_URI) == 0)
167 return OC_RESOURCE_TYPES_URI;
170 else if (strcmp(uriInRequest, OC_RSRVD_PRESENCE_URI) == 0)
174 #endif //WITH_PRESENCE
175 return OC_UNKNOWN_URI;
178 static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *query,
179 char **filterOne, char **filterTwo)
181 if(!filterOne || !filterTwo)
183 return OC_STACK_INVALID_PARAM;
190 if (uri == OC_PRESENCE)
192 //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
193 OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request for virtual resource."));
198 OCStackResult result = OC_STACK_OK;
202 result = ExtractFiltersFromQuery(query, filterOne, filterTwo);
208 OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
209 OCRepPayload** payload)
211 OCRepPayload *tempPayload = OCRepPayloadCreate();
215 OCRepPayloadDestroy(tempPayload);
216 return OC_STACK_INVALID_PARAM;
221 return OC_STACK_NO_MEMORY;
224 OCRepPayloadSetUri(tempPayload, resourcePtr->uri);
226 OCResourceType *resType = resourcePtr->rsrcType;
229 OCRepPayloadAddResourceType(tempPayload, resType->resourcetypename);
230 resType = resType->next;
233 OCResourceInterface *resInterface = resourcePtr->rsrcInterface;
236 OCRepPayloadAddInterface(tempPayload, resInterface->name);
237 resInterface = resInterface->next;
240 OCAttribute *resAttrib = resourcePtr->rsrcAttributes;
243 OCRepPayloadSetPropString(tempPayload, resAttrib->attrName,
244 resAttrib->attrValue);
245 resAttrib = resAttrib->next;
250 *payload = tempPayload;
254 OCRepPayloadAppend(*payload, tempPayload);
260 OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
261 OCDiscoveryPayload *payload, OCDevAddr *devAddr)
263 if (!resourcePtr || !payload)
265 return OC_STACK_INVALID_PARAM;
268 if (resourcePtr->resourceProperties & OC_SECURE)
270 if (GetSecurePortInfo(devAddr, &port) != OC_STACK_OK)
276 OCDiscoveryPayloadAddResource(payload, resourcePtr, port);
281 uint8_t IsCollectionResource (OCResource *resource)
288 for (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
290 if (resource->rsrcResources[i])
298 OCResource *FindResourceByUri(const char* resourceUri)
305 OCResource * pointer = headResource;
308 if (strcmp(resourceUri, pointer->uri) == 0)
312 pointer = pointer->next;
314 OC_LOG_V(INFO, TAG, "Resource %s not found", resourceUri);
319 OCStackResult DetermineResourceHandling (const OCServerRequest *request,
320 ResourceHandling *handling,
321 OCResource **resource)
323 if(!request || !handling || !resource)
325 return OC_STACK_INVALID_PARAM;
328 OC_LOG_V(INFO, TAG, "DetermineResourceHandling for %s", request->resourceUrl);
330 // Check if virtual resource
331 if (GetTypeOfVirtualURI(request->resourceUrl) != OC_UNKNOWN_URI)
333 OC_LOG_V (INFO, TAG, "%s is virtual", request->resourceUrl);
334 *handling = OC_RESOURCE_VIRTUAL;
335 *resource = headResource;
338 if (strlen((const char*)(request->resourceUrl)) == 0)
340 // Resource URL not specified
341 *handling = OC_RESOURCE_NOT_SPECIFIED;
342 return OC_STACK_NO_RESOURCE;
346 OCResource *resourcePtr = NULL;
347 resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
348 *resource = resourcePtr;
351 if(defaultDeviceHandler)
353 *handling = OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER;
357 // Resource does not exist
358 // and default device handler does not exist
359 *handling = OC_RESOURCE_NOT_SPECIFIED;
360 return OC_STACK_NO_RESOURCE;
363 if (IsCollectionResource (resourcePtr))
365 // Collection resource
366 if (resourcePtr->entityHandler != defaultResourceEHandler)
368 *handling = OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER;
373 *handling = OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER;
379 // Resource not a collection
380 if (resourcePtr->entityHandler != defaultResourceEHandler)
382 *handling = OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER;
387 *handling = OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER;
394 OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
396 OCStackResult result;
401 result = OC_STACK_OK;
404 result = OC_STACK_SLOW_RESOURCE;
407 result = OC_STACK_ERROR;
409 case OC_EH_FORBIDDEN:
410 result = OC_STACK_RESOURCE_ERROR;
412 case OC_EH_RESOURCE_CREATED:
413 result = OC_STACK_RESOURCE_CREATED;
415 case OC_EH_RESOURCE_DELETED:
416 result = OC_STACK_RESOURCE_DELETED;
418 case OC_EH_RESOURCE_NOT_FOUND:
419 result = OC_STACK_NO_RESOURCE;
422 result = OC_STACK_ERROR;
428 static bool resourceMatchesRTFilter(OCResource *resource, char *resourceTypeFilter)
435 // Null or empty is analogous to no filter.
436 if (resourceTypeFilter == NULL || *resourceTypeFilter == 0)
441 OCResourceType *resourceTypePtr = resource->rsrcType;
443 while (resourceTypePtr)
445 if (strcmp (resourceTypePtr->resourcetypename, resourceTypeFilter) == 0)
449 resourceTypePtr = resourceTypePtr->next;
452 OC_LOG_V(INFO, TAG, PCF("%s does not contain rt=%s."), resource->uri, resourceTypeFilter);
456 static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter)
463 // Null or empty is analogous to no filter.
464 if (interfaceFilter == NULL || *interfaceFilter == 0)
469 OCResourceInterface *interfacePtr = resource->rsrcInterface;
473 if (strcmp (interfacePtr->name, interfaceFilter) == 0)
477 interfacePtr = interfacePtr->next;
480 OC_LOG_V(INFO, TAG, PCF("%s does not contain if=%s."), resource->uri, interfaceFilter);
485 * If the filters are null, they will be assumed to NOT be present
486 * and the resource will not be matched against them.
487 * Function will return true if all non null AND non empty filters passed in find a match.
489 static bool includeThisResourceInResponse(OCResource *resource,
490 char *interfaceFilter,
491 char *resourceTypeFilter)
495 OC_LOG(ERROR, TAG, PCF("Invalid resource"));
499 if ( resource->resourceProperties & OC_EXPLICIT_DISCOVERABLE)
502 * At least one valid filter should be available to
503 * include the resource in discovery response
505 if (!((interfaceFilter && *interfaceFilter ) ||
506 (resourceTypeFilter && *resourceTypeFilter)))
508 OC_LOG_V(INFO, TAG, PCF("%s no query string for EXPLICIT_DISCOVERABLE \
509 resource"), resource->uri);
513 else if ( !(resource->resourceProperties & OC_ACTIVE) ||
514 !(resource->resourceProperties & OC_DISCOVERABLE))
516 OC_LOG_V(INFO, TAG, PCF("%s not ACTIVE or DISCOVERABLE"), resource->uri);
520 return resourceMatchesIFFilter(resource, interfaceFilter) &&
521 resourceMatchesRTFilter(resource, resourceTypeFilter);
525 OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCResource *resource,
526 OCPayload *discoveryPayload, OCEntityHandlerResult ehResult)
528 OCEntityHandlerResponse response = {0};
530 response.ehResult = ehResult;
531 response.payload = discoveryPayload;
532 response.persistentBufferFlag = 0;
533 response.requestHandle = (OCRequestHandle) request;
534 response.resourceHandle = (OCResourceHandle) resource;
536 return OCDoResponse(&response);
540 static OCStackResult checkResourceExistsAtRD(const char *interfaceType, const char *resourceType, OCRepPayload **repPayload)
546 if (OCRDCheckPublishedResource(interfaceType, resourceType, &uri, &rt, &itf) == OC_STACK_OK)
548 if (!uri || !rt || !itf)
550 OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
551 // if any of the parameter has memory allocated free each one of them.
555 return OC_STACK_NO_MEMORY;
558 OCRepPayload *rdResource = OICCalloc(1, sizeof(OCRepPayload));
561 OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
565 return OC_STACK_NO_MEMORY;
568 rdResource->uri = uri;
570 rdResource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
571 if(!rdResource->types)
573 OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
578 return OC_STACK_NO_MEMORY;
580 rdResource->types->value = rt;
582 rdResource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
583 if(!rdResource->interfaces)
585 OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
590 return OC_STACK_NO_MEMORY;
592 rdResource->interfaces->value = itf;
594 *repPayload = rdResource;
600 OC_LOG_V(ERROR, TAG, "The resource type or interface type doe not exist \
601 on the resource directory");
603 return OC_STACK_ERROR;
607 static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
609 if (!request || !resource)
611 return OC_STACK_INVALID_PARAM;
614 OCStackResult discoveryResult = OC_STACK_ERROR;
616 bool bMulticast = false; // Was the discovery request a multicast request?
617 OCPayload* payload = NULL;
619 OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
621 OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
623 // Step 1: Generate the response to discovery request
624 if (virtualUriInRequest == OC_WELL_KNOWN_URI)
626 char *filterOne = NULL;
627 char *filterTwo = NULL;
629 discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
630 &filterOne, &filterTwo);
632 if (discoveryResult == OC_STACK_OK)
634 payload = (OCPayload*)OCDiscoveryPayloadCreate();
638 for(;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
640 bool foundResourceAtRD = false;
642 if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
644 OCRepPayload *repPayload = NULL;
645 discoveryResult = checkResourceExistsAtRD(filterOne, filterTwo, &repPayload);
646 if (discoveryResult != OC_STACK_OK)
650 discoveryResult = BuildVirtualResourceResponse((OCResource *)repPayload,
651 (OCDiscoveryPayload*)payload,
653 foundResourceAtRD = true;
656 if(!foundResourceAtRD && includeThisResourceInResponse(resource, filterOne, filterTwo))
658 discoveryResult = BuildVirtualResourceResponse(resource,
659 (OCDiscoveryPayload*)payload,
663 // Set discoveryResult appropriately if no 'valid' resources are available.
664 if (((OCDiscoveryPayload*)payload)->resources == NULL)
666 discoveryResult = OC_STACK_NO_RESOURCE;
671 discoveryResult = OC_STACK_NO_MEMORY;
676 OC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
679 else if (virtualUriInRequest == OC_DEVICE_URI)
681 payload = (OCPayload*)OCDevicePayloadCreate(OC_RSRVD_DEVICE_URI,
682 OCGetServerInstanceID(), savedDeviceInfo.deviceName,
683 OC_SPEC_VERSION, OC_DATA_MODEL_VERSION);
686 discoveryResult = OC_STACK_NO_MEMORY;
690 discoveryResult = OC_STACK_OK;
693 else if (virtualUriInRequest == OC_PLATFORM_URI)
695 payload = (OCPayload*)OCPlatformPayloadCreate(
696 OC_RSRVD_PLATFORM_URI,
700 discoveryResult = OC_STACK_NO_MEMORY;
704 discoveryResult = OC_STACK_OK;
709 * Step 2: Send the discovery response
711 * Iotivity should respond to discovery requests in below manner:
712 * 1)If query filter matching fails and discovery request is multicast,
713 * it should NOT send any response.
714 * 2)If query filter matching fails and discovery request is unicast,
715 * it should send an error(RESOURCE_NOT_FOUND - 404) response.
716 * 3)If Server does not have any 'DISCOVERABLE' resources and discovery
717 * request is multicast, it should NOT send any response.
718 * 4)If Server does not have any 'DISCOVERABLE' resources and discovery
719 * request is unicast, it should send an error(RESOURCE_NOT_FOUND - 404) response.
723 if ((virtualUriInRequest == OC_PRESENCE) &&
724 (resource->resourceProperties & OC_ACTIVE))
726 // Presence uses observer notification api to respond via SendPresenceNotification.
727 SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
732 if(discoveryResult == OC_STACK_OK)
734 SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK);
736 else if(bMulticast == false)
738 OC_LOG_V(ERROR, TAG, "Sending a (%d) error to (%d) \
739 discovery request", discoveryResult, virtualUriInRequest);
740 SendNonPersistantDiscoveryResponse(request, resource, NULL,
741 (discoveryResult == OC_STACK_NO_RESOURCE) ? OC_EH_RESOURCE_NOT_FOUND : OC_EH_ERROR);
745 // Ignoring the discovery request as per RFC 7252, Section #8.2
746 OC_LOG_V(INFO, TAG, "Silently ignoring the request since device does not have \
747 any useful data to send");
751 OCPayloadDestroy(payload);
757 HandleDefaultDeviceEntityHandler (OCServerRequest *request)
761 return OC_STACK_INVALID_PARAM;
764 OCStackResult result = OC_STACK_OK;
765 OCEntityHandlerResult ehResult = OC_EH_ERROR;
766 OCEntityHandlerRequest ehRequest = {0};
768 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
769 result = FormOCEntityHandlerRequest(&ehRequest,
770 (OCRequestHandle) request,
773 (OCResourceHandle) NULL, request->query,
775 request->payloadSize,
776 request->numRcvdVendorSpecificHeaderOptions,
777 request->rcvdVendorSpecificHeaderOptions,
778 (OCObserveAction)request->observationOption,
780 VERIFY_SUCCESS(result, OC_STACK_OK);
782 // At this point we know for sure that defaultDeviceHandler exists
783 ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
784 (char*) request->resourceUrl, defaultDeviceHandlerCallbackParameter);
785 if(ehResult == OC_EH_SLOW)
787 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
788 request->slowFlag = 1;
790 else if(ehResult == OC_EH_ERROR)
792 FindAndDeleteServerRequest(request);
794 result = EntityHandlerCodeToOCStackCode(ehResult);
796 OCPayloadDestroy(ehRequest.payload);
801 HandleResourceWithEntityHandler (OCServerRequest *request,
802 OCResource *resource,
803 uint8_t collectionResource)
805 if(!request || ! resource)
807 return OC_STACK_INVALID_PARAM;
810 OCStackResult result = OC_STACK_ERROR;
811 OCEntityHandlerResult ehResult = OC_EH_ERROR;
812 OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
813 ResourceObserver *resObs = NULL;
815 OCEntityHandlerRequest ehRequest = {0};
817 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
819 result = FormOCEntityHandlerRequest(&ehRequest,
820 (OCRequestHandle)request,
823 (OCResourceHandle)resource,
826 request->payloadSize,
827 request->numRcvdVendorSpecificHeaderOptions,
828 request->rcvdVendorSpecificHeaderOptions,
829 (OCObserveAction)request->observationOption,
831 VERIFY_SUCCESS(result, OC_STACK_OK);
833 if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
835 OC_LOG(INFO, TAG, PCF("No observation requested"));
836 ehFlag = OC_REQUEST_FLAG;
838 else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER && !collectionResource)
840 OC_LOG(INFO, TAG, PCF("Observation registration requested"));
842 result = GenerateObserverId(&ehRequest.obsInfo.obsId);
843 VERIFY_SUCCESS(result, OC_STACK_OK);
845 result = AddObserver ((const char*)(request->resourceUrl),
846 (const char *)(request->query),
847 ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
848 resource, request->qos,
851 if(result == OC_STACK_OK)
853 OC_LOG(INFO, TAG, PCF("Added observer successfully"));
854 request->observeResult = OC_STACK_OK;
855 ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
859 result = OC_STACK_OK;
861 // The error in observeResult for the request will be used when responding to this
862 // request by omitting the observation option/sequence number.
863 request->observeResult = OC_STACK_ERROR;
864 OC_LOG(ERROR, TAG, PCF("Observer Addition failed"));
865 ehFlag = OC_REQUEST_FLAG;
869 else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
872 OC_LOG(INFO, TAG, PCF("Deregistering observation requested"));
874 resObs = GetObserverUsingToken (request->requestToken, request->tokenLength);
878 // Stack does not contain this observation request
879 // Either token is incorrect or observation list is corrupted
880 result = OC_STACK_ERROR;
883 ehRequest.obsInfo.obsId = resObs->observeId;
884 ehFlag = (OCEntityHandlerFlag)(ehFlag | OC_OBSERVE_FLAG);
886 result = DeleteObserverUsingToken (request->requestToken, request->tokenLength);
888 if(result == OC_STACK_OK)
890 OC_LOG(INFO, TAG, PCF("Removed observer successfully"));
891 request->observeResult = OC_STACK_OK;
895 result = OC_STACK_OK;
896 request->observeResult = OC_STACK_ERROR;
897 OC_LOG(ERROR, TAG, PCF("Observer Removal failed"));
902 result = OC_STACK_ERROR;
906 ehResult = resource->entityHandler(ehFlag, &ehRequest, resource->entityHandlerCallbackParam);
907 if(ehResult == OC_EH_SLOW)
909 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
910 request->slowFlag = 1;
912 else if(ehResult == OC_EH_ERROR)
914 FindAndDeleteServerRequest(request);
916 result = EntityHandlerCodeToOCStackCode(ehResult);
918 OCPayloadDestroy(ehRequest.payload);
923 HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
924 OCResource *resource)
926 if(!request || !resource)
928 return OC_STACK_INVALID_PARAM;
931 OCStackResult result = OC_STACK_ERROR;
932 OCEntityHandlerRequest ehRequest = {0};
934 result = FormOCEntityHandlerRequest(&ehRequest,
935 (OCRequestHandle)request,
938 (OCResourceHandle)resource,
941 request->payloadSize,
942 request->numRcvdVendorSpecificHeaderOptions,
943 request->rcvdVendorSpecificHeaderOptions,
944 (OCObserveAction)request->observationOption,
946 if(result == OC_STACK_OK)
948 result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest);
951 OCPayloadDestroy(ehRequest.payload);
956 ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerRequest *request)
958 OCStackResult ret = OC_STACK_OK;
962 case OC_RESOURCE_VIRTUAL:
964 ret = HandleVirtualResource (request, resource);
967 case OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER:
969 ret = HandleDefaultDeviceEntityHandler(request);
972 case OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER:
974 OC_LOG(INFO, TAG, PCF("OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER"));
975 return OC_STACK_ERROR;
977 case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
979 ret = HandleResourceWithEntityHandler (request, resource, 0);
982 case OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER:
984 ret = HandleResourceWithEntityHandler (request, resource, 1);
987 case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER:
989 ret = HandleCollectionResourceDefaultEntityHandler (request, resource);
992 case OC_RESOURCE_NOT_SPECIFIED:
994 ret = OC_STACK_NO_RESOURCE;
999 OC_LOG(INFO, TAG, PCF("Invalid Resource Determination"));
1000 return OC_STACK_ERROR;
1006 void DeletePlatformInfo()
1008 OC_LOG(INFO, TAG, PCF("Deleting platform info."));
1010 OICFree(savedPlatformInfo.platformID);
1011 savedPlatformInfo.platformID = NULL;
1013 OICFree(savedPlatformInfo.manufacturerName);
1014 savedPlatformInfo.manufacturerName = NULL;
1016 OICFree(savedPlatformInfo.manufacturerUrl);
1017 savedPlatformInfo.manufacturerUrl = NULL;
1019 OICFree(savedPlatformInfo.modelNumber);
1020 savedPlatformInfo.modelNumber = NULL;
1022 OICFree(savedPlatformInfo.dateOfManufacture);
1023 savedPlatformInfo.dateOfManufacture = NULL;
1025 OICFree(savedPlatformInfo.platformVersion);
1026 savedPlatformInfo.platformVersion = NULL;
1028 OICFree(savedPlatformInfo.operatingSystemVersion);
1029 savedPlatformInfo.operatingSystemVersion = NULL;
1031 OICFree(savedPlatformInfo.hardwareVersion);
1032 savedPlatformInfo.hardwareVersion = NULL;
1034 OICFree(savedPlatformInfo.firmwareVersion);
1035 savedPlatformInfo.firmwareVersion = NULL;
1037 OICFree(savedPlatformInfo.supportUrl);
1038 savedPlatformInfo.supportUrl = NULL;
1040 OICFree(savedPlatformInfo.systemTime);
1041 savedPlatformInfo.systemTime = NULL;
1044 static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
1046 savedPlatformInfo.platformID = OICStrdup(info.platformID);
1047 savedPlatformInfo.manufacturerName = OICStrdup(info.manufacturerName);
1048 savedPlatformInfo.manufacturerUrl = OICStrdup(info.manufacturerUrl);
1049 savedPlatformInfo.modelNumber = OICStrdup(info.modelNumber);
1050 savedPlatformInfo.dateOfManufacture = OICStrdup(info.dateOfManufacture);
1051 savedPlatformInfo.platformVersion = OICStrdup(info.platformVersion);
1052 savedPlatformInfo.operatingSystemVersion = OICStrdup(info.operatingSystemVersion);
1053 savedPlatformInfo.hardwareVersion = OICStrdup(info.hardwareVersion);
1054 savedPlatformInfo.firmwareVersion = OICStrdup(info.firmwareVersion);
1055 savedPlatformInfo.supportUrl = OICStrdup(info.supportUrl);
1056 savedPlatformInfo.systemTime = OICStrdup(info.systemTime);
1058 if ((!savedPlatformInfo.platformID && info.platformID)||
1059 (!savedPlatformInfo.manufacturerName && info.manufacturerName)||
1060 (!savedPlatformInfo.manufacturerUrl && info.manufacturerUrl)||
1061 (!savedPlatformInfo.modelNumber && info.modelNumber)||
1062 (!savedPlatformInfo.dateOfManufacture && info.dateOfManufacture)||
1063 (!savedPlatformInfo.platformVersion && info.platformVersion)||
1064 (!savedPlatformInfo.operatingSystemVersion && info.operatingSystemVersion)||
1065 (!savedPlatformInfo.hardwareVersion && info.hardwareVersion)||
1066 (!savedPlatformInfo.firmwareVersion && info.firmwareVersion)||
1067 (!savedPlatformInfo.supportUrl && info.supportUrl)||
1068 (!savedPlatformInfo.systemTime && info.systemTime))
1070 DeletePlatformInfo();
1071 return OC_STACK_INVALID_PARAM;
1078 OCStackResult SavePlatformInfo(OCPlatformInfo info)
1080 DeletePlatformInfo();
1082 OCStackResult res = DeepCopyPlatFormInfo(info);
1084 if (res != OC_STACK_OK)
1086 OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
1090 OC_LOG(ERROR, TAG, PCF("Platform info saved."));
1096 void DeleteDeviceInfo()
1098 OC_LOG(INFO, TAG, PCF("Deleting device info."));
1100 OICFree(savedDeviceInfo.deviceName);
1101 savedDeviceInfo.deviceName = NULL;
1104 static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
1106 savedDeviceInfo.deviceName = OICStrdup(info.deviceName);
1108 if(!savedDeviceInfo.deviceName && info.deviceName)
1111 return OC_STACK_NO_MEMORY;
1117 OCStackResult SaveDeviceInfo(OCDeviceInfo info)
1119 OCStackResult res = OC_STACK_OK;
1123 res = DeepCopyDeviceInfo(info);
1125 VERIFY_SUCCESS(res, OC_STACK_OK);
1127 if(OCGetServerInstanceID() == NULL)
1129 OC_LOG(INFO, TAG, PCF("Device ID generation failed"));
1130 res = OC_STACK_ERROR;
1134 OC_LOG(INFO, TAG, PCF("Device initialized successfully."));