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 OCDeviceInfo savedDeviceInfo = {};
53 static const char * VIRTUAL_RSRCS[] =
64 //-----------------------------------------------------------------------------
65 // Default resource entity handler function
66 //-----------------------------------------------------------------------------
67 OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
68 OCEntityHandlerRequest * request)
70 //TODO ("Implement me!!!!");
71 // TODO: remove silence unused param warnings
74 return OC_EH_OK; // Making sure that the Default EH and the Vendor EH have matching signatures
77 /* This method will retrieve the port at which the secure resource is hosted */
78 static OCStackResult GetSecurePortInfo(CATransportType_t connType, uint16_t *port)
80 CALocalConnectivity_t* info = NULL;
82 OCStackResult ret = OC_STACK_ERROR;
84 CAResult_t caResult = CAGetNetworkInformation(&info, &size);
85 if ((caResult == CA_STATUS_OK) && info && size)
89 if (info[size].isSecured && info[size].type == connType)
91 if (info[size].type == CA_IPV4)
93 *port = info[size].addressInfo.IP.port;
105 static char* GetJSONStringFromPlatformInfo(OCPlatformInfo info)
107 cJSON *rootObj = cJSON_CreateObject();
114 cJSON *repObj = NULL;
115 char *jsonEncodedInfo = NULL;
117 cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
118 cJSON_CreateString(GetVirtualResourceUri(OC_PLATFORM_URI)));
120 cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
122 cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_ID, cJSON_CreateString(info.platformID));
123 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME, cJSON_CreateString(info.manufacturerName));
124 if (info.manufacturerUrl)
126 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
127 cJSON_CreateString(info.manufacturerUrl));
130 if (info.modelNumber)
132 cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
133 cJSON_CreateString(info.modelNumber));
136 if (info.dateOfManufacture)
138 cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
139 cJSON_CreateString(info.dateOfManufacture));
142 if (info.platformVersion)
144 cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
145 cJSON_CreateString(info.platformVersion));
148 if (info.operatingSystemVersion)
150 cJSON_AddItemToObject (repObj, OC_RSRVD_OS_VERSION,
151 cJSON_CreateString(info.operatingSystemVersion));
154 if (info.hardwareVersion)
156 cJSON_AddItemToObject (repObj, OC_RSRVD_HARDWARE_VERSION,
157 cJSON_CreateString(info.hardwareVersion));
160 if (info.firmwareVersion)
162 cJSON_AddItemToObject (repObj, OC_RSRVD_FIRMWARE_VERSION,
163 cJSON_CreateString(info.firmwareVersion));
168 cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
169 cJSON_CreateString(info.supportUrl));
174 cJSON_AddItemToObject (repObj, OC_RSRVD_SYSTEM_TIME,
175 cJSON_CreateString(info.systemTime));
178 jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
180 cJSON_Delete(rootObj);
182 return jsonEncodedInfo;
185 static char* GetJSONStringFromDeviceInfo(OCDeviceInfo info)
187 cJSON *rootObj = cJSON_CreateObject();
194 cJSON *repObj = NULL;
195 char *jsonEncodedInfo = NULL;
197 cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
198 cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
200 cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
202 cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_ID,
203 cJSON_CreateString(OCGetServerInstanceIDString()));
205 cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_NAME,
206 cJSON_CreateString(info.deviceName));
208 cJSON_AddItemToObject (repObj, OC_RSRVD_SPEC_VERSION,
209 cJSON_CreateString(OC_SPEC_VERSION));
211 cJSON_AddItemToObject (repObj, OC_RSRVD_DATA_MODEL_VERSION,
212 cJSON_CreateString(OC_DATA_MODEL_VERSION));
214 jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
216 cJSON_Delete(rootObj);
218 return jsonEncodedInfo;
221 static OCStackResult ValidateUrlQuery (char *url, char *query,
222 uint8_t *filterOn, char **filterValue)
224 if(!filterOn || !filterValue)
226 return OC_STACK_INVALID_PARAM;
229 char *filterParam = NULL;
231 OC_LOG(INFO, TAG, PCF("Entering ValidateUrlQuery"));
234 return OC_STACK_INVALID_URI;
237 if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
238 strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0 ||
239 strcmp((char *)url, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
241 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
244 char* strTokPtr = NULL;
245 filterParam = strtok_r((char *)query, "=", &strTokPtr);
246 *filterValue = strtok_r(NULL, " ", &strTokPtr);
248 if (!(*filterValue) || ! filterParam)
250 return OC_STACK_INVALID_QUERY;
252 else if (strcmp (filterParam, OC_RSRVD_INTERFACE) == 0)
254 // Resource discovery with interface filter
255 *filterOn = STACK_RES_DISCOVERY_IF_FILTER;
257 else if (strcmp (filterParam, OC_RSRVD_RESOURCE_TYPE) == 0)
259 // Resource discovery with resource type filter
260 *filterOn = STACK_RES_DISCOVERY_RT_FILTER;
262 else if (strcmp (filterParam, OC_RSRVD_DEVICE_ID) == 0)
265 *filterOn = STACK_DEVICE_DISCOVERY_DI_FILTER;
267 else if (strcmp (filterParam, OC_RSRVD_DEVICE_NAME) == 0)
270 *filterOn = STACK_DEVICE_DISCOVERY_DN_FILTER;
274 // Other filter types not supported
275 return OC_STACK_INVALID_QUERY;
280 else if (strcmp((char *)url, GetVirtualResourceUri(OC_PRESENCE)) == 0)
282 //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
283 OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request"));
284 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
289 // Other URIs not yet supported
290 return OC_STACK_INVALID_URI;
292 OC_LOG(INFO, TAG, PCF("Exiting ValidateUrlQuery"));
298 BuildVirtualResourceResponse(const OCResource *resourcePtr, uint8_t filterOn,
299 const char *filterValue, char *out, uint16_t *remaining,
300 CATransportType_t connType )
302 if(!resourcePtr || !out || !remaining)
304 return OC_STACK_INVALID_PARAM;
307 OCResourceType *resourceTypePtr = NULL;
308 OCResourceInterface *interfacePtr = NULL;
309 cJSON *resObj = NULL;
310 cJSON *propObj = NULL;
311 cJSON *rtArray = NULL;
312 char *jsonStr = NULL;
313 uint8_t encodeRes = 0;
314 OCStackResult ret = OC_STACK_OK;
315 uint16_t jsonLen = 0;
317 OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponse"));
318 resObj = cJSON_CreateObject();
323 if ((filterOn == STACK_RES_DISCOVERY_RT_FILTER) && filterValue)
325 resourceTypePtr = resourcePtr->rsrcType;
326 while (resourceTypePtr)
328 if (strcmp (resourceTypePtr->resourcetypename, filterValue) == 0)
333 resourceTypePtr = resourceTypePtr->next;
336 else if ((filterOn == STACK_RES_DISCOVERY_IF_FILTER) && filterValue)
338 interfacePtr = resourcePtr->rsrcInterface;
341 if (strcmp (interfacePtr->name, filterValue) == 0)
346 interfacePtr = interfacePtr->next;
349 else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
355 //TODO: Unsupported query filter
356 return OC_STACK_INVALID_QUERY;
362 cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
364 // Add server instance id
365 cJSON_AddItemToObject (resObj,
366 OC_RSRVD_SERVER_INSTANCE_ID,
367 cJSON_CreateString(OCGetServerInstanceIDString()));
369 cJSON_AddItemToObject (resObj, OC_RSRVD_PROPERTY, propObj = cJSON_CreateObject());
370 // Add resource types
371 cJSON_AddItemToObject (propObj, OC_RSRVD_RESOURCE_TYPE, rtArray = cJSON_CreateArray());
372 resourceTypePtr = resourcePtr->rsrcType;
373 while (resourceTypePtr)
375 cJSON_AddItemToArray (rtArray,
376 cJSON_CreateString(resourceTypePtr->resourcetypename));
377 resourceTypePtr = resourceTypePtr->next;
379 // Add interface types
380 cJSON_AddItemToObject (propObj, OC_RSRVD_INTERFACE, rtArray = cJSON_CreateArray());
381 interfacePtr = resourcePtr->rsrcInterface;
384 cJSON_AddItemToArray (rtArray, cJSON_CreateString(interfacePtr->name));
385 interfacePtr = interfacePtr->next;
387 // If resource is observable, set observability flag.
388 // Resources that are not observable will not have the flag.
389 if (resourcePtr->resourceProperties & OC_OBSERVABLE)
391 cJSON_AddItemToObject (propObj, OC_RSRVD_OBSERVABLE,
392 cJSON_CreateNumber(OC_RESOURCE_OBSERVABLE));
394 // Set secure flag for secure resources
395 if (resourcePtr->resourceProperties & OC_SECURE)
397 cJSON_AddNumberToObject (propObj, OC_RSRVD_SECURE, OC_RESOURCE_SECURE);
398 //Set the IP port also as secure resources are hosted on a different port
400 if (GetSecurePortInfo (connType, &port) == OC_STACK_OK)
402 cJSON_AddNumberToObject (propObj, OC_RSRVD_HOSTING_PORT, port);
408 jsonStr = cJSON_PrintUnformatted (resObj);
412 cJSON_Delete(resObj);
413 return OC_STACK_NO_MEMORY;
416 jsonLen = strlen(jsonStr);
417 if (jsonLen < *remaining)
419 strcpy(out, jsonStr);
420 *remaining = *remaining - jsonLen;
424 ret = OC_STACK_ERROR;
426 cJSON_Delete (resObj);
429 OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponse"));
433 OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
434 char *out, uint16_t *remaining)
436 if(!out || !remaining)
438 return OC_STACK_INVALID_PARAM;
441 OCStackResult ret = OC_STACK_ERROR;
442 char *jsonStr = NULL;
443 uint16_t jsonLen = 0;
445 jsonStr = GetJSONStringFromDeviceInfo(savedDeviceInfo);
449 jsonLen = strlen(jsonStr);
451 if (jsonLen < *remaining)
453 strncpy(out, jsonStr, (jsonLen + 1));
454 *remaining = *remaining - jsonLen;
459 ret = OC_STACK_ERROR;
466 OC_LOG(ERROR, TAG, PCF("Error encoding save device info."));
467 ret = OC_STACK_ERROR;
472 OCStackResult BuildVirtualResourceResponseForPlatform(char *out, uint16_t *remaining)
474 OCStackResult ret = OC_STACK_OK;
476 char *jsonStr = GetJSONStringFromPlatformInfo(savedPlatformInfo);
480 size_t jsonLen = strlen(jsonStr);
482 if (jsonLen < *remaining)
484 strncpy(out, jsonStr, (jsonLen + 1));
485 *remaining = *remaining - jsonLen;
490 OC_LOG_V(ERROR, TAG, PCF("Platform info string too big. len: %u"), jsonLen);
491 ret = OC_STACK_ERROR;
497 OC_LOG(ERROR, TAG, PCF("Error encoding save platform info."));
498 ret = OC_STACK_ERROR;
505 const char * GetVirtualResourceUri( OCVirtualResources resource)
507 if (resource < OC_MAX_VIRTUAL_RESOURCES)
509 return VIRTUAL_RSRCS[resource];
515 bool IsVirtualResource(const char* resourceUri)
522 for (int i = 0; i < OC_MAX_VIRTUAL_RESOURCES; i++)
524 if (strcmp(resourceUri, GetVirtualResourceUri((OCVirtualResources)i)) == 0)
532 uint8_t IsCollectionResource (OCResource *resource)
539 for (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
541 if (resource->rsrcResources[i])
549 OCResource *FindResourceByUri(const char* resourceUri)
556 OCResource * pointer = headResource;
559 if (strcmp(resourceUri, pointer->uri) == 0)
563 pointer = pointer->next;
565 OC_LOG(INFO, TAG, PCF("Resource not found"));
570 OCStackResult DetermineResourceHandling (const OCServerRequest *request,
571 ResourceHandling *handling,
572 OCResource **resource)
574 if(!request || !handling || !resource)
576 return OC_STACK_INVALID_PARAM;
579 OC_LOG(INFO, TAG, PCF("Entering DetermineResourceHandling"));
581 // Check if virtual resource
582 if (IsVirtualResource((const char*)request->resourceUrl))
584 *handling = OC_RESOURCE_VIRTUAL;
585 *resource = headResource;
588 if (NULL == request->resourceUrl || (strlen((const char*)(request->resourceUrl)) == 0))
590 // Resource URL not specified
591 *handling = OC_RESOURCE_NOT_SPECIFIED;
592 return OC_STACK_NO_RESOURCE;
596 OCResource *resourcePtr = NULL;
597 resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
598 *resource = resourcePtr;
601 if(defaultDeviceHandler)
603 *handling = OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER;
607 // Resource does not exist
608 // and default device handler does not exist
609 *handling = OC_RESOURCE_NOT_SPECIFIED;
610 return OC_STACK_NO_RESOURCE;
613 // secure resource will entertain only authorized requests
614 if ((resourcePtr->resourceProperties & OC_SECURE) && (request->secured == 0))
616 OC_LOG(ERROR, TAG, PCF("Un-authorized request. Ignoring"));
617 return OC_STACK_RESOURCE_ERROR;
620 if (IsCollectionResource (resourcePtr))
622 // Collection resource
623 if (resourcePtr->entityHandler != defaultResourceEHandler)
625 *handling = OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER;
630 *handling = OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER;
636 // Resource not a collection
637 if (resourcePtr->entityHandler != defaultResourceEHandler)
639 *handling = OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER;
644 *handling = OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER;
651 OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
653 OCStackResult result;
658 result = OC_STACK_OK;
661 result = OC_STACK_SLOW_RESOURCE;
664 result = OC_STACK_ERROR;
666 case OC_EH_FORBIDDEN:
667 result = OC_STACK_RESOURCE_ERROR;
669 case OC_EH_RESOURCE_CREATED:
670 result = OC_STACK_RESOURCE_CREATED;
672 case OC_EH_RESOURCE_DELETED:
673 result = OC_STACK_RESOURCE_DELETED;
675 case OC_EH_RESOURCE_NOT_FOUND:
676 result = OC_STACK_NO_RESOURCE;
679 result = OC_STACK_ERROR;
686 HandleVirtualResource (OCServerRequest *request, OCResource* resource)
688 if(!request || !resource)
690 return OC_STACK_INVALID_PARAM;
693 OCStackResult result = OC_STACK_ERROR;
694 char *filterValue = NULL;
695 uint8_t filterOn = 0;
696 uint16_t remaining = 0;
698 uint8_t firstLoopDone = 0;
699 char discoveryResBuf[MAX_RESPONSE_LENGTH] = {};
701 OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
703 result = ValidateUrlQuery (request->resourceUrl,
704 request->query, &filterOn,
707 if (result == OC_STACK_OK)
709 if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0)
711 ptr = discoveryResBuf;
712 remaining = MAX_RESPONSE_LENGTH;
714 // Check if valid resource and enough space in buffer for atleast
715 // the null character.
716 while(resource && (remaining > 1))
718 if((resource->resourceProperties & OC_ACTIVE)
719 && (resource->resourceProperties & OC_DISCOVERABLE))
721 // if there is data on the buffer, we have already added a response,
722 // so we need to add a comma before we do anything
724 && remaining >= (sizeof(OC_JSON_SEPARATOR)+1))
726 *ptr = OC_JSON_SEPARATOR;
731 result = BuildVirtualResourceResponse(resource, filterOn, filterValue,
732 (char*)ptr, &remaining, request->connectivityType );
734 if (result != OC_STACK_OK)
736 // if this failed, we need to remove the comma added above.
745 ptr += strlen((char *)ptr);
747 resource = resource->next;
750 if(strlen((const char *)discoveryResBuf) > 0)
752 OCEntityHandlerResponse response = {};
754 response.ehResult = OC_EH_OK;
755 response.payload = discoveryResBuf;
756 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
757 response.persistentBufferFlag = 0;
758 response.requestHandle = (OCRequestHandle) request;
759 response.resourceHandle = (OCResourceHandle) resource;
761 result = OCDoResponse(&response);
764 else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
766 remaining = MAX_RESPONSE_LENGTH;
767 ptr = discoveryResBuf;
769 result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
770 (char*)ptr, &remaining);
772 if(result == OC_STACK_OK)
774 ptr += strlen((char*)ptr);
777 if(remaining < MAX_RESPONSE_LENGTH)
779 OCEntityHandlerResponse response = {0};
781 response.ehResult = OC_EH_OK;
782 response.payload = discoveryResBuf;
783 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
784 response.persistentBufferFlag = 0;
785 response.requestHandle = (OCRequestHandle) request;
786 response.resourceHandle = (OCResourceHandle) resource;
788 result = OCDoResponse(&response);
791 else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
793 remaining = MAX_RESPONSE_LENGTH;
794 ptr = discoveryResBuf;
796 result = BuildVirtualResourceResponseForPlatform((char*)ptr, &remaining);
798 if(result == OC_STACK_OK)
800 ptr += strlen((char*)ptr);
803 if(remaining < MAX_RESPONSE_LENGTH)
805 OCEntityHandlerResponse response = {0};
807 response.ehResult = OC_EH_OK;
808 response.payload = discoveryResBuf;
809 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
810 response.persistentBufferFlag = 0;
811 response.requestHandle = (OCRequestHandle) request;
812 response.resourceHandle = (OCResourceHandle) resource;
814 result = OCDoResponse(&response);
820 if(resource->resourceProperties & OC_ACTIVE){
821 SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
826 result = OC_STACK_OK;
831 HandleDefaultDeviceEntityHandler (OCServerRequest *request)
835 return OC_STACK_INVALID_PARAM;
838 OCStackResult result = OC_STACK_OK;
839 OCEntityHandlerResult ehResult = OC_EH_ERROR;
840 OCEntityHandlerRequest ehRequest = {};
842 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
843 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
844 request->method, (OCResourceHandle) NULL, request->query,
845 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
846 request->rcvdVendorSpecificHeaderOptions,
847 (OCObserveAction)request->observationOption, (OCObservationId)0);
848 VERIFY_SUCCESS(result, OC_STACK_OK);
850 // At this point we know for sure that defaultDeviceHandler exists
851 ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
852 (char*) request->resourceUrl);
853 if(ehResult == OC_EH_SLOW)
855 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
856 request->slowFlag = 1;
858 else if(ehResult == OC_EH_ERROR)
860 FindAndDeleteServerRequest(request);
862 result = EntityHandlerCodeToOCStackCode(ehResult);
868 HandleResourceWithEntityHandler (OCServerRequest *request,
869 OCResource *resource,
870 uint8_t collectionResource)
872 if(!request || ! resource)
874 return OC_STACK_INVALID_PARAM;
877 OCStackResult result = OC_STACK_ERROR;
878 OCEntityHandlerResult ehResult = OC_EH_ERROR;
879 OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
880 ResourceObserver *resObs = NULL;
882 OCEntityHandlerRequest ehRequest = {};
884 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
885 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
886 request->method, (OCResourceHandle) resource, request->query,
887 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
888 request->rcvdVendorSpecificHeaderOptions,
889 (OCObserveAction)request->observationOption, 0);
890 VERIFY_SUCCESS(result, OC_STACK_OK);
892 if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
894 OC_LOG(INFO, TAG, PCF("No observation requested"));
895 ehFlag = OC_REQUEST_FLAG;
897 else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER &&
900 OC_LOG(INFO, TAG, PCF("Registering observation requested"));
901 result = GenerateObserverId(&ehRequest.obsInfo.obsId);
902 VERIFY_SUCCESS(result, OC_STACK_OK);
904 result = AddObserver ((const char*)(request->resourceUrl),
905 (const char *)(request->query),
906 ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
907 resource, request->qos,
908 &request->addressInfo, request->connectivityType);
910 if(result == OC_STACK_OK)
912 OC_LOG(INFO, TAG, PCF("Added observer successfully"));
913 request->observeResult = OC_STACK_OK;
914 ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
918 result = OC_STACK_OK;
919 // The error in observeResult for the request will be
920 // used when responding to this request by omitting
921 // the observation option/sequence number.
922 request->observeResult = OC_STACK_ERROR;
923 OC_LOG(ERROR, TAG, PCF("Observer Addition failed"));
924 ehFlag = OC_REQUEST_FLAG;
928 else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
931 OC_LOG(INFO, TAG, PCF("Deregistering observation requested"));
933 resObs = GetObserverUsingToken (request->requestToken, request->tokenLength);
937 // Stack does not contain this observation request
938 // Either token is incorrect or observation list is corrupted
939 result = OC_STACK_ERROR;
942 ehRequest.obsInfo.obsId = resObs->observeId;
943 ehFlag = (OCEntityHandlerFlag)(ehFlag | OC_OBSERVE_FLAG);
945 result = DeleteObserverUsingToken (request->requestToken, request->tokenLength);
947 if(result == OC_STACK_OK)
949 OC_LOG(INFO, TAG, PCF("Removed observer successfully"));
950 request->observeResult = OC_STACK_OK;
954 result = OC_STACK_OK;
955 request->observeResult = OC_STACK_ERROR;
956 OC_LOG(ERROR, TAG, PCF("Observer Removal failed"));
961 result = OC_STACK_ERROR;
965 ehResult = resource->entityHandler(ehFlag, &ehRequest);
966 if(ehResult == OC_EH_SLOW)
968 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
969 request->slowFlag = 1;
971 else if(ehResult == OC_EH_ERROR)
973 FindAndDeleteServerRequest(request);
975 result = EntityHandlerCodeToOCStackCode(ehResult);
981 HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
982 OCResource *resource)
984 if(!request || !resource)
986 return OC_STACK_INVALID_PARAM;
989 OCStackResult result = OC_STACK_ERROR;
990 OCEntityHandlerRequest ehRequest = {};
992 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
993 request->method, (OCResourceHandle) resource, request->query,
994 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
995 request->rcvdVendorSpecificHeaderOptions,
996 (OCObserveAction)request->observationOption, (OCObservationId) 0);
997 if(result != OC_STACK_OK)
1002 return (DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest));
1006 ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerRequest *request)
1008 OCStackResult ret = OC_STACK_OK;
1010 switch (resHandling)
1012 case OC_RESOURCE_VIRTUAL:
1014 ret = HandleVirtualResource (request, resource);
1017 case OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER:
1019 ret = HandleDefaultDeviceEntityHandler(request);
1022 case OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER:
1024 OC_LOG(INFO, TAG, PCF("OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER"));
1025 return OC_STACK_ERROR;
1027 case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
1029 ret = HandleResourceWithEntityHandler (request, resource, 0);
1032 case OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER:
1034 ret = HandleResourceWithEntityHandler (request, resource, 1);
1037 case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER:
1039 ret = HandleCollectionResourceDefaultEntityHandler (request, resource);
1042 case OC_RESOURCE_NOT_SPECIFIED:
1044 ret = OC_STACK_NO_RESOURCE;
1049 OC_LOG(INFO, TAG, PCF("Invalid Resource Determination"));
1050 return OC_STACK_ERROR;
1056 void DeletePlatformInfo()
1058 OC_LOG(INFO, TAG, PCF("Deleting platform info."));
1060 OCFree(savedPlatformInfo.platformID);
1061 savedPlatformInfo.platformID = NULL;
1063 OCFree(savedPlatformInfo.manufacturerName);
1064 savedPlatformInfo.manufacturerName = NULL;
1066 OCFree(savedPlatformInfo.manufacturerUrl);
1067 savedPlatformInfo.manufacturerUrl = NULL;
1069 OCFree(savedPlatformInfo.modelNumber);
1070 savedPlatformInfo.modelNumber = NULL;
1072 OCFree(savedPlatformInfo.dateOfManufacture);
1073 savedPlatformInfo.dateOfManufacture = NULL;
1075 OCFree(savedPlatformInfo.platformVersion);
1076 savedPlatformInfo.platformVersion = NULL;
1078 OCFree(savedPlatformInfo.operatingSystemVersion);
1079 savedPlatformInfo.operatingSystemVersion = NULL;
1081 OCFree(savedPlatformInfo.hardwareVersion);
1082 savedPlatformInfo.hardwareVersion = NULL;
1084 OCFree(savedPlatformInfo.firmwareVersion);
1085 savedPlatformInfo.firmwareVersion = NULL;
1087 OCFree(savedPlatformInfo.supportUrl);
1088 savedPlatformInfo.supportUrl = NULL;
1090 OCFree(savedPlatformInfo.systemTime);
1091 savedPlatformInfo.systemTime = NULL;
1094 static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
1096 OCStackResult ret = OC_STACK_OK;
1097 ret = CloneStringIfNonNull(&(savedPlatformInfo.platformID), info.platformID);
1098 VERIFY_SUCCESS(ret, OC_STACK_OK);
1100 ret = CloneStringIfNonNull(&(savedPlatformInfo.manufacturerName), info.manufacturerName);
1101 VERIFY_SUCCESS(ret, OC_STACK_OK);
1103 ret = CloneStringIfNonNull(&(savedPlatformInfo.manufacturerUrl), info.manufacturerUrl);
1104 VERIFY_SUCCESS(ret, OC_STACK_OK);
1106 ret = CloneStringIfNonNull(&(savedPlatformInfo.modelNumber), info.modelNumber);
1107 VERIFY_SUCCESS(ret, OC_STACK_OK);
1109 ret = CloneStringIfNonNull(&(savedPlatformInfo.dateOfManufacture), info.dateOfManufacture);
1110 VERIFY_SUCCESS(ret, OC_STACK_OK);
1112 ret = CloneStringIfNonNull(&(savedPlatformInfo.platformVersion), info.platformVersion);
1113 VERIFY_SUCCESS(ret, OC_STACK_OK);
1115 ret = CloneStringIfNonNull(&(savedPlatformInfo.operatingSystemVersion), info.operatingSystemVersion);
1116 VERIFY_SUCCESS(ret, OC_STACK_OK);
1118 ret = CloneStringIfNonNull(&(savedPlatformInfo.hardwareVersion), info.hardwareVersion);
1119 VERIFY_SUCCESS(ret, OC_STACK_OK);
1121 ret = CloneStringIfNonNull(&(savedPlatformInfo.firmwareVersion), info.firmwareVersion);
1122 VERIFY_SUCCESS(ret, OC_STACK_OK);
1124 ret = CloneStringIfNonNull(&(savedPlatformInfo.supportUrl), info.supportUrl);
1125 VERIFY_SUCCESS(ret, OC_STACK_OK);
1127 ret = CloneStringIfNonNull(&(savedPlatformInfo.systemTime), info.systemTime);
1128 VERIFY_SUCCESS(ret, OC_STACK_OK);
1133 DeletePlatformInfo();
1138 OCStackResult SavePlatformInfo(OCPlatformInfo info)
1140 DeletePlatformInfo();
1142 OCStackResult res = DeepCopyPlatFormInfo(info);
1144 if (res != OC_STACK_OK)
1146 OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
1150 OC_LOG(ERROR, TAG, PCF("Platform info saved."));
1156 void DeleteDeviceInfo()
1158 OC_LOG(INFO, TAG, PCF("Deleting device info."));
1160 OCFree(savedDeviceInfo.deviceName);
1161 savedDeviceInfo.deviceName = NULL;
1164 static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
1166 OCStackResult ret = OC_STACK_OK;
1168 ret = CloneStringIfNonNull(&(savedDeviceInfo.deviceName), info.deviceName);
1169 VERIFY_SUCCESS(ret, OC_STACK_OK);
1178 OCStackResult SaveDeviceInfo(OCDeviceInfo info)
1180 OCStackResult res = OC_STACK_OK;
1184 res = DeepCopyDeviceInfo(info);
1186 VERIFY_SUCCESS(res, OC_STACK_OK);
1188 if(OCGetServerInstanceID() == NULL)
1190 OC_LOG(INFO, TAG, PCF("Device ID generation failed"));
1191 res = OC_STACK_ERROR;
1195 OC_LOG(INFO, TAG, PCF("Device initialized successfully."));