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 #define _POSIX_C_SOURCE 200112L
24 #include "ocstackconfig.h"
25 #include "ocstackinternal.h"
26 #include "ocresourcehandler.h"
27 #include "ocobserve.h"
28 #include "occollection.h"
33 #include "cainterface.h"
37 #define TAG PCF("ocresource")
38 #define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
39 {OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
41 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
42 TAG, PCF(#arg " is NULL")); return (retVal); } }
44 extern OCResource *headResource;
45 static cJSON *savedDeviceInfo = NULL;
47 static const char * VIRTUAL_RSRCS[] = {
56 //-----------------------------------------------------------------------------
57 // Default resource entity handler function
58 //-----------------------------------------------------------------------------
59 OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
60 OCEntityHandlerRequest * request) {
61 //TODO ("Implement me!!!!");
62 // TODO: remove silence unused param warnings
65 return OC_EH_OK; // Making sure that the Default EH and the Vendor EH have matching signatures
68 /* This method will return the port at which the secure resource is hosted */
69 static OCStackResult GetSecurePortInfo(CAConnectivityType_t connType, uint32_t *port)
71 CALocalConnectivity_t* info = NULL;
73 OCStackResult ret = OC_STACK_ERROR;
75 CAResult_t caResult = CAGetNetworkInformation(&info, &size);
76 if ((caResult == CA_STATUS_OK) && info && size)
80 if (info[size].isSecured == true && info[size].type == connType)
82 if (info[size].type == CA_ETHERNET ||
83 info[size].type == CA_WIFI)
85 *port = info[size].addressInfo.IP.port;
97 static OCStackResult ValidateUrlQuery (unsigned char *url, unsigned char *query,
98 uint8_t *filterOn, char **filterValue)
102 OC_LOG(INFO, TAG, PCF("Entering ValidateUrlQuery"));
104 return OC_STACK_INVALID_URI;
106 if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
107 strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0) {
108 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
109 if (query && *query) {
111 filterParam = strtok_r((char *)query, "=", &strTokPtr);
112 *filterValue = strtok_r(NULL, " ", &strTokPtr);
113 if (!(*filterValue)) {
114 return OC_STACK_INVALID_QUERY;
115 } else if (strcmp (filterParam, OC_RSRVD_INTERFACE) == 0) {
116 // Resource discovery with interface filter
117 *filterOn = STACK_RES_DISCOVERY_IF_FILTER;
118 } else if (strcmp (filterParam, OC_RSRVD_RESOURCE_TYPE) == 0) {
119 // Resource discovery with resource type filter
120 *filterOn = STACK_RES_DISCOVERY_RT_FILTER;
121 } else if (strcmp (filterParam, OC_RSRVD_DEVICE_ID) == 0) {
123 *filterOn = STACK_DEVICE_DISCOVERY_DI_FILTER;
124 } else if (strcmp (filterParam, OC_RSRVD_DEVICE_NAME) == 0) {
126 *filterOn = STACK_DEVICE_DISCOVERY_DN_FILTER;
128 // Other filter types not supported
129 return OC_STACK_INVALID_QUERY;
134 else if (strcmp((char *)url, GetVirtualResourceUri(OC_PRESENCE)) == 0) {
135 //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
136 OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request"));
137 *filterOn = STACK_RES_DISCOVERY_NOFILTER;
141 // Other URIs not yet supported
142 return OC_STACK_INVALID_URI;
144 OC_LOG(INFO, TAG, PCF("Exiting ValidateUrlQuery"));
150 BuildVirtualResourceResponse(OCResource *resourcePtr, uint8_t filterOn,
151 char *filterValue, char * out, uint16_t *remaining,
152 CAConnectivityType_t connType )
154 OCResourceType *resourceTypePtr;
155 OCResourceInterface *interfacePtr;
156 cJSON *resObj, *propObj, *rtArray;
158 uint8_t encodeRes = 0;
159 OCStackResult ret = OC_STACK_OK;
162 OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponse"));
163 resObj = cJSON_CreateObject();
168 if (filterOn == STACK_RES_DISCOVERY_RT_FILTER) {
169 resourceTypePtr = resourcePtr->rsrcType;
170 while (resourceTypePtr) {
171 if (strcmp (resourceTypePtr->resourcetypename, filterValue) == 0) {
175 resourceTypePtr = resourceTypePtr->next;
177 } else if (filterOn == STACK_RES_DISCOVERY_IF_FILTER) {
178 interfacePtr = resourcePtr->rsrcInterface;
179 while (interfacePtr) {
180 if (strcmp (interfacePtr->name, filterValue) == 0) {
184 interfacePtr = interfacePtr->next;
186 } else if (filterOn == STACK_RES_DISCOVERY_NOFILTER) {
189 //TODO: Unsupported query filter
190 return OC_STACK_INVALID_QUERY;
195 cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
197 // Add server instance id
198 const char* serverInstanceId = OCGetServerInstanceIDString();
199 cJSON_AddItemToObject (resObj,
200 OC_RSRVD_SERVER_INSTANCE_ID,
201 cJSON_CreateString(serverInstanceId));
202 serverInstanceId = NULL;
204 cJSON_AddItemToObject (resObj, "prop", propObj = cJSON_CreateObject());
205 // Add resource types
206 cJSON_AddItemToObject (propObj, OC_RSRVD_RESOURCE_TYPE, rtArray = cJSON_CreateArray());
207 resourceTypePtr = resourcePtr->rsrcType;
208 while (resourceTypePtr) {
209 cJSON_AddItemToArray (rtArray,
210 cJSON_CreateString(resourceTypePtr->resourcetypename));
211 resourceTypePtr = resourceTypePtr->next;
213 // Add interface types
214 cJSON_AddItemToObject (propObj, OC_RSRVD_INTERFACE, rtArray = cJSON_CreateArray());
215 interfacePtr = resourcePtr->rsrcInterface;
216 while (interfacePtr) {
217 cJSON_AddItemToArray (rtArray, cJSON_CreateString(interfacePtr->name));
218 interfacePtr = interfacePtr->next;
220 // If resource is observable, set observability flag.
221 // Resources that are not observable will not have the flag.
222 if (resourcePtr->resourceProperties & OC_OBSERVABLE) {
223 cJSON_AddItemToObject (propObj, OC_RSRVD_OBSERVABLE,
224 cJSON_CreateNumber(OC_RESOURCE_OBSERVABLE));
226 // Set secure flag for secure resources
227 if (resourcePtr->resourceProperties & OC_SECURE) {
228 cJSON_AddNumberToObject (propObj, OC_RSRVD_SECURE, OC_RESOURCE_SECURE);
229 //Set the IP port also as secure resources are hosted on a different port
231 if (GetSecurePortInfo (connType, &port) == OC_STACK_OK) {
232 cJSON_AddNumberToObject (propObj, OC_RSRVD_HOSTING_PORT, port);
238 jsonStr = cJSON_PrintUnformatted (resObj);
240 jsonLen = strlen(jsonStr);
241 if (jsonLen < *remaining)
243 strcpy(out, jsonStr);
244 *remaining = *remaining - jsonLen;
248 ret = OC_STACK_ERROR;
250 cJSON_Delete (resObj);
253 OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponse"));
257 OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
258 char *out, uint16_t *remaining)
260 OCStackResult ret = OC_STACK_ERROR;
262 if (savedDeviceInfo != NULL)
264 char *jsonStr = NULL;
265 uint16_t jsonLen = 0;
266 cJSON *repObj = cJSON_GetObjectItem(savedDeviceInfo, "rep");
268 OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponseForDevice"));
270 if (filterOn == STACK_DEVICE_DISCOVERY_DI_FILTER)
272 if((cJSON_GetObjectItem(repObj,"di") != NULL) &&
273 strcmp(cJSON_GetObjectItem(repObj,"di")->valuestring, filterValue) == 0)
278 else if (filterOn == STACK_DEVICE_DISCOVERY_DN_FILTER)
280 if((cJSON_GetObjectItem(repObj,"dn") != NULL) &&
281 strcmp(cJSON_GetObjectItem(repObj,"dn")->valuestring, filterValue) == 0)
286 else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
292 ret = OC_STACK_INVALID_QUERY;
295 if (ret == OC_STACK_OK)
297 jsonStr = cJSON_PrintUnformatted (savedDeviceInfo);
301 jsonLen = strlen(jsonStr);
303 if (jsonLen < *remaining)
305 strncpy(out, jsonStr, (jsonLen + 1));
306 *remaining = *remaining - jsonLen;
311 ret = OC_STACK_ERROR;
318 ret = OC_STACK_ERROR;
323 ret = OC_STACK_INVALID_DEVICE_INFO;
328 //error so that stack won't respond with empty payload
329 ret = OC_STACK_INVALID_DEVICE_INFO;
332 OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponseForDevice"));
336 //TODO ("Does it make sense to make this method as inline")
337 const char * GetVirtualResourceUri( OCVirtualResources resource)
339 if (resource < OC_MAX_VIRTUAL_RESOURCES)
341 return VIRTUAL_RSRCS[resource];
347 uint8_t IsVirtualResource(const char* resourceUri)
349 for (int i = 0; i < OC_MAX_VIRTUAL_RESOURCES; i++)
351 if (strcmp(resourceUri, GetVirtualResourceUri((OCVirtualResources)i)) == 0)
359 uint8_t IsCollectionResource (OCResource *resource)
361 for (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
363 if (resource->rsrcResources[i])
371 OCResource *FindResourceByUri(const char* resourceUri)
373 OCResource * pointer = headResource;
375 if (strcmp(resourceUri, pointer->uri) == 0) {
378 pointer = pointer->next;
380 OC_LOG(INFO, TAG, PCF("Resource not found"));
385 OCStackResult DetermineResourceHandling (OCServerRequest *request,
386 ResourceHandling *handling,
387 OCResource **resource)
390 OC_LOG(INFO, TAG, PCF("Entering DetermineResourceHandling"));
392 // Check if virtual resource
393 if (IsVirtualResource((const char*)request->resourceUrl))
395 *handling = OC_RESOURCE_VIRTUAL;
396 *resource = headResource;
399 if (NULL == request->resourceUrl || (strlen((const char*)(request->resourceUrl)) == 0))
401 // Resource URL not specified
402 *handling = OC_RESOURCE_NOT_SPECIFIED;
407 OCResource *resourcePtr = NULL;
408 resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
409 *resource = resourcePtr;
412 if(defaultDeviceHandler)
414 *handling = OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER;
418 // Resource does not exist
419 // and default device handler does not exist
420 *handling = OC_RESOURCE_NOT_SPECIFIED;
421 return OC_STACK_NO_RESOURCE;
424 // secure resource will entertain only authorized requests
425 if ((resourcePtr->resourceProperties & OC_SECURE) && (request->secured == 0))
427 OC_LOG(INFO, TAG, PCF("Un-authorized request. Ignore it!"));
428 return OC_STACK_RESOURCE_ERROR;
431 if (IsCollectionResource (resourcePtr))
433 // Collection resource
434 if (resourcePtr->entityHandler != defaultResourceEHandler)
436 *handling = OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER;
439 *handling = OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER;
443 // Resource not a collection
444 if (resourcePtr->entityHandler != defaultResourceEHandler)
446 *handling = OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER;
449 *handling = OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER;
456 OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
458 OCStackResult result;
463 result = OC_STACK_OK;
466 result = OC_STACK_SLOW_RESOURCE;
469 result = OC_STACK_ERROR;
471 case OC_EH_FORBIDDEN:
472 result = OC_STACK_RESOURCE_ERROR;
474 case OC_EH_RESOURCE_CREATED:
475 result = OC_STACK_RESOURCE_CREATED;
477 case OC_EH_RESOURCE_DELETED:
478 result = OC_STACK_RESOURCE_DELETED;
481 result = OC_STACK_ERROR;
488 HandleVirtualResource (OCServerRequest *request, OCResource* resource)
490 OCStackResult result = OC_STACK_ERROR;
491 char *filterValue = NULL;
492 uint8_t filterOn = 0;
493 uint16_t remaining = 0;
494 unsigned char * ptr = NULL;
495 uint8_t firstLoopDone = 0;
496 unsigned char discoveryResBuf[MAX_RESPONSE_LENGTH] = {0};
498 OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
500 result = ValidateUrlQuery (request->resourceUrl,
501 request->query, &filterOn,
504 if (result == OC_STACK_OK)
506 if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0)
508 ptr = discoveryResBuf;
509 remaining = MAX_RESPONSE_LENGTH;
513 if((resource->resourceProperties & OC_ACTIVE)
514 && (resource->resourceProperties & OC_DISCOVERABLE))
516 // if there is data on the buffer, we have already added a response,
517 // so we need to add a comma before we do anything
519 && remaining >= (sizeof(OC_JSON_SEPARATOR)+1))
521 *ptr = OC_JSON_SEPARATOR;
526 result = BuildVirtualResourceResponse(resource, filterOn, filterValue,
527 (char*)ptr, &remaining, request->connectivityType );
529 if (result != OC_STACK_OK)
531 // if this failed, we need to remove the comma added above.
540 ptr += strlen((char *)ptr);
543 resource = resource->next;
546 if(strlen((const char *)discoveryResBuf) > 0)
548 OCEntityHandlerResponse response = {0};
550 response.ehResult = OC_EH_OK;
551 response.payload = discoveryResBuf;
552 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
553 response.persistentBufferFlag = 0;
554 response.requestHandle = (OCRequestHandle) request;
555 response.resourceHandle = (OCResourceHandle) resource;
557 result = OCDoResponse(&response);
560 else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
562 remaining = MAX_RESPONSE_LENGTH;
563 ptr = discoveryResBuf;
565 result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
566 (char*)ptr, &remaining);
568 if(result == OC_STACK_OK)
570 ptr += strlen((char*)ptr);
573 if(remaining < MAX_RESPONSE_LENGTH)
575 OCEntityHandlerResponse response = {0};
577 response.ehResult = OC_EH_OK;
578 response.payload = discoveryResBuf;
579 response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
580 response.persistentBufferFlag = 0;
581 response.requestHandle = (OCRequestHandle) request;
582 response.resourceHandle = (OCResourceHandle) resource;
584 result = OCDoResponse(&response);
590 if(resource->resourceProperties & OC_ACTIVE){
591 SendPresenceNotification(NULL);
596 result = OC_STACK_VIRTUAL_DO_NOT_HANDLE;
601 HandleDefaultDeviceEntityHandler (OCServerRequest *request)
603 OCStackResult result = OC_STACK_OK;
604 OCEntityHandlerResult ehResult = OC_EH_ERROR;
605 OCEntityHandlerRequest ehRequest = {0};
607 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
608 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
609 request->method, (OCResourceHandle) NULL, request->query,
610 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
611 request->rcvdVendorSpecificHeaderOptions, (OCObserveAction)request->observationOption, (OCObservationId)0);
612 VERIFY_SUCCESS(result, OC_STACK_OK);
614 // At this point we know for sure that defaultDeviceHandler exists
615 ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
616 (char*) request->resourceUrl);
617 if(ehResult == OC_EH_SLOW)
619 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
620 request->slowFlag = 1;
622 else if(ehResult == OC_EH_ERROR)
624 FindAndDeleteServerRequest(request);
626 result = EntityHandlerCodeToOCStackCode(ehResult);
632 HandleResourceWithEntityHandler (OCServerRequest *request,
633 OCResource *resource,
634 uint8_t collectionResource)
636 OCStackResult result = OC_STACK_ERROR;
637 OCEntityHandlerResult ehResult = OC_EH_ERROR;
638 OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
639 ResourceObserver *resObs = NULL;
641 OCEntityHandlerRequest ehRequest = {0};
643 OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
644 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
645 request->method, (OCResourceHandle) resource, request->query,
646 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
647 request->rcvdVendorSpecificHeaderOptions,
648 (OCObserveAction)request->observationOption, 0);
649 VERIFY_SUCCESS(result, OC_STACK_OK);
651 if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
653 OC_LOG(INFO, TAG, PCF("No observation requested"));
654 ehFlag = OC_REQUEST_FLAG;
656 else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER &&
659 OC_LOG(INFO, TAG, PCF("Registering observation requested"));
660 result = GenerateObserverId(&ehRequest.obsInfo.obsId);
661 VERIFY_SUCCESS(result, OC_STACK_OK);
662 result = AddObserver ((const char*)(request->resourceUrl),
663 (const char *)(request->query),
664 ehRequest.obsInfo.obsId, &request->requestToken,
665 resource, request->qos,
666 &request->addressInfo, request->connectivityType);
667 if(result == OC_STACK_OK)
669 OC_LOG(DEBUG, TAG, PCF("Added observer successfully"));
670 request->observeResult = OC_STACK_OK;
671 ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
675 result = OC_STACK_OK;
676 request->observeResult = OC_STACK_ERROR;
677 OC_LOG(DEBUG, TAG, PCF("Observer Addition failed"));
678 ehFlag = OC_REQUEST_FLAG;
682 else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
685 OC_LOG(INFO, TAG, PCF("Deregistering observation requested"));
687 resObs = GetObserverUsingToken (&request->requestToken);
691 // Stack does not contain this observation request
692 // Either token is incorrect or observation list is corrupted
693 result = OC_STACK_ERROR;
696 ehRequest.obsInfo.obsId = resObs->observeId;
697 ehFlag = (OCEntityHandlerFlag)(ehFlag | OC_OBSERVE_FLAG);
699 result = DeleteObserverUsingToken (&request->requestToken);
701 if(result == OC_STACK_OK)
703 OC_LOG(DEBUG, TAG, PCF("Removed observer successfully"));
704 request->observeResult = OC_STACK_OK;
708 result = OC_STACK_OK;
709 request->observeResult = OC_STACK_ERROR;
710 OC_LOG(DEBUG, TAG, PCF("Observer Removal failed"));
715 result = OC_STACK_ERROR;
719 ehResult = resource->entityHandler(ehFlag, &ehRequest);
720 if(ehResult == OC_EH_SLOW)
722 OC_LOG(INFO, TAG, PCF("This is a slow resource"));
723 request->slowFlag = 1;
725 else if(ehResult == OC_EH_ERROR)
727 FindAndDeleteServerRequest(request);
729 result = EntityHandlerCodeToOCStackCode(ehResult);
735 HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
736 OCResource *resource)
738 OCStackResult result = OC_STACK_ERROR;
739 OCEntityHandlerRequest ehRequest = {0};
741 result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
742 request->method, (OCResourceHandle) resource, request->query,
743 request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
744 request->rcvdVendorSpecificHeaderOptions,
745 (OCObserveAction)request->observationOption, (OCObservationId) 0);
746 if(result != OC_STACK_OK)
751 return (DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest));
755 ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerRequest *request)
757 OCStackResult ret = OC_STACK_OK;
761 case OC_RESOURCE_VIRTUAL:
763 ret = HandleVirtualResource (request, resource);
766 case OC_RESOURCE_DEFAULT_DEVICE_ENTITYHANDLER:
768 ret = HandleDefaultDeviceEntityHandler(request);
771 case OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER:
773 OC_LOG(INFO, TAG, PCF("OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER"));
774 return OC_STACK_ERROR;
776 case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
778 ret = HandleResourceWithEntityHandler (request, resource, 0);
781 case OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER:
783 ret = HandleResourceWithEntityHandler (request, resource, 1);
786 case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER:
788 ret = HandleCollectionResourceDefaultEntityHandler (request, resource);
791 case OC_RESOURCE_NOT_SPECIFIED:
793 ret = OC_STACK_NO_RESOURCE;
798 OC_LOG(INFO, TAG, PCF("Invalid Resource Determination"));
799 return OC_STACK_ERROR;
805 void DeleteDeviceInfo()
809 cJSON_Delete(savedDeviceInfo);
813 OCStackResult SaveDeviceInfo(OCDeviceInfo deviceInfo)
817 savedDeviceInfo = cJSON_CreateObject();
818 cJSON *repObj = NULL;
820 cJSON_AddItemToObject (savedDeviceInfo, OC_RSRVD_HREF,
821 cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
823 cJSON_AddItemToObject (savedDeviceInfo, "rep", repObj = cJSON_CreateObject());
825 if (deviceInfo.contentType)
827 cJSON_AddItemToObject (repObj, "ct",
828 cJSON_CreateString(deviceInfo.contentType));
831 if (deviceInfo.dateOfManufacture)
833 cJSON_AddItemToObject (repObj, "mndt",
834 cJSON_CreateString(deviceInfo.dateOfManufacture));
837 if (deviceInfo.deviceName)
839 cJSON_AddItemToObject (repObj, "dn",
840 cJSON_CreateString(deviceInfo.deviceName));
843 if (deviceInfo.deviceUUID)
845 cJSON_AddItemToObject (repObj, "di",
846 cJSON_CreateString(deviceInfo.deviceUUID));
849 if (deviceInfo.firmwareVersion)
851 cJSON_AddItemToObject (repObj, "mnfv",
852 cJSON_CreateString(deviceInfo.firmwareVersion));
855 if (deviceInfo.hostName)
857 cJSON_AddItemToObject (repObj, "hn", cJSON_CreateString(deviceInfo.hostName));
860 if (deviceInfo.manufacturerName)
862 if(strlen(deviceInfo.manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH)
865 return OC_STACK_INVALID_PARAM;
868 cJSON_AddItemToObject (repObj, "mnmn",
869 cJSON_CreateString(deviceInfo.manufacturerName));
872 if (deviceInfo.manufacturerUrl)
874 if(strlen(deviceInfo.manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH)
877 return OC_STACK_INVALID_PARAM;
880 cJSON_AddItemToObject (repObj, "mnml",
881 cJSON_CreateString(deviceInfo.manufacturerUrl));
884 if (deviceInfo.modelNumber)
886 cJSON_AddItemToObject (repObj, "mnmo",
887 cJSON_CreateString(deviceInfo.modelNumber));
890 if (deviceInfo.platformVersion)
892 cJSON_AddItemToObject (repObj, "mnpv",
893 cJSON_CreateString(deviceInfo.platformVersion));
896 if (deviceInfo.supportUrl)
898 cJSON_AddItemToObject (repObj, "mnsl",
899 cJSON_CreateString(deviceInfo.supportUrl));
902 if (deviceInfo.version)
904 cJSON_AddItemToObject (repObj, "icv",
905 cJSON_CreateString(deviceInfo.version));