// Refer http://pubs.opengroup.org/onlinepubs/009695399/
#define _POSIX_C_SOURCE 200112L
#include <string.h>
-#include "ocstack.h"
-#include "ocstackconfig.h"
-#include "ocstackinternal.h"
+#include "ocresource.h"
#include "ocresourcehandler.h"
#include "ocobserve.h"
#include "occollection.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
#include "logger.h"
#include "cJSON.h"
-
+#include "ocpayload.h"
+#include "secureresourcemanager.h"
#include "cacommon.h"
#include "cainterface.h"
-
+#ifdef ROUTING_GATEWAY
+#include "routingmanager.h"
+#endif
/// Module Name
-#define TAG PCF("ocresource")
+#define TAG "ocresource"
#define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
{OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
#define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
- TAG, PCF(#arg " is NULL")); return (retVal); } }
+ TAG, #arg " is NULL"); return (retVal); } }
extern OCResource *headResource;
-static cJSON *savedDeviceInfo = NULL;
-
-static const char * VIRTUAL_RSRCS[] = {
- "/oc/core",
- "/oc/core/d",
- "/oc/core/types/d",
- #ifdef WITH_PRESENCE
- "/oc/presence"
- #endif
-};
+static OCPlatformInfo savedPlatformInfo = {0};
+static OCDeviceInfo savedDeviceInfo = {0};
//-----------------------------------------------------------------------------
// Default resource entity handler function
//-----------------------------------------------------------------------------
OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * request) {
+ OCEntityHandlerRequest * request, void* callbackParam)
+{
//TODO ("Implement me!!!!");
// TODO: remove silence unused param warnings
(void) flag;
(void) request;
+ (void) callbackParam;
return OC_EH_OK; // Making sure that the Default EH and the Vendor EH have matching signatures
}
/* This method will retrieve the port at which the secure resource is hosted */
-static OCStackResult GetSecurePortInfo(CAConnectivityType_t connType, uint16_t *port)
+static OCStackResult GetSecurePortInfo(OCDevAddr *endpoint, uint16_t *port)
{
- CALocalConnectivity_t* info = NULL;
- uint32_t size = 0;
- OCStackResult ret = OC_STACK_ERROR;
+ uint16_t p = 0;
- CAResult_t caResult = CAGetNetworkInformation(&info, &size);
- if ((caResult == CA_STATUS_OK) && info && size)
+ if (endpoint->adapter == OC_ADAPTER_IP)
{
- while (size--)
+ if (endpoint->flags & OC_IP_USE_V6)
{
- if (info[size].isSecured && info[size].type == connType)
- {
- if (info[size].type == CA_ETHERNET ||
- info[size].type == CA_WIFI)
- {
- *port = info[size].addressInfo.IP.port;
- ret = OC_STACK_OK;
- break;
- }
- }
+ p = caglobals.ip.u6s.port;
+ }
+ else if (endpoint->flags & OC_IP_USE_V4)
+ {
+ p = caglobals.ip.u4s.port;
}
}
- OCFree(info);
- return ret;
+ *port = p;
+ return OC_STACK_OK;
}
-static OCStackResult ValidateUrlQuery (char *url, char *query,
- uint8_t *filterOn, char **filterValue)
+/*
+ * Function will extract 0, 1 or 2 filters from query.
+ * More than 2 filters or unsupported filters will result in error.
+ * If both filters are of the same supported type, the 2nd one will be picked.
+ * Resource and device filters in the SAME query are NOT validated
+ * and resources will likely not clear filters.
+ */
+static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char **filterTwo)
{
- if(!filterOn || !filterValue)
- {
- return OC_STACK_INVALID_PARAM;
- }
- char *filterParam = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ char *restOfQuery = NULL;
+ int numKeyValuePairsParsed = 0;
- OC_LOG(INFO, TAG, PCF("Entering ValidateUrlQuery"));
- if (!url)
- {
- return OC_STACK_INVALID_URI;
- }
+ *filterOne = NULL;
+ *filterTwo = NULL;
- if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
- strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
- {
- *filterOn = STACK_RES_DISCOVERY_NOFILTER;
- if (query && *query)
- {
- char* strTokPtr = NULL;
- filterParam = strtok_r((char *)query, "=", &strTokPtr);
- *filterValue = strtok_r(NULL, " ", &strTokPtr);
+ OC_LOG_V(INFO, TAG, "Extracting params from %s", query);
- if (!(*filterValue) || ! filterParam)
- {
- return OC_STACK_INVALID_QUERY;
- }
- else if (strcmp (filterParam, OC_RSRVD_INTERFACE) == 0)
- {
- // Resource discovery with interface filter
- *filterOn = STACK_RES_DISCOVERY_IF_FILTER;
- }
- else if (strcmp (filterParam, OC_RSRVD_RESOURCE_TYPE) == 0)
- {
- // Resource discovery with resource type filter
- *filterOn = STACK_RES_DISCOVERY_RT_FILTER;
- }
- else if (strcmp (filterParam, OC_RSRVD_DEVICE_ID) == 0)
- {
- //Device ID filter
- *filterOn = STACK_DEVICE_DISCOVERY_DI_FILTER;
- }
- else if (strcmp (filterParam, OC_RSRVD_DEVICE_NAME) == 0)
- {
- //Device Name filter
- *filterOn = STACK_DEVICE_DISCOVERY_DN_FILTER;
- }
- else
- {
- // Other filter types not supported
- return OC_STACK_INVALID_QUERY;
- }
- }
- }
- #ifdef WITH_PRESENCE
- else if (strcmp((char *)url, GetVirtualResourceUri(OC_PRESENCE)) == 0)
- {
- //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
- OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request"));
- *filterOn = STACK_RES_DISCOVERY_NOFILTER;
- }
- #endif
- else
- {
- // Other URIs not yet supported
- return OC_STACK_INVALID_URI;
- }
- OC_LOG(INFO, TAG, PCF("Exiting ValidateUrlQuery"));
- return OC_STACK_OK;
-}
+ char *keyValuePair = strtok_r (query, OC_QUERY_SEPARATOR, &restOfQuery);
-
-OCStackResult
-BuildVirtualResourceResponse(const OCResource *resourcePtr, uint8_t filterOn,
- const char *filterValue, char *out, uint16_t *remaining,
- CAConnectivityType_t connType )
-{
- if(!resourcePtr || !out || !remaining)
+ while(keyValuePair)
{
- return OC_STACK_INVALID_PARAM;
- }
-
- OCResourceType *resourceTypePtr = NULL;
- OCResourceInterface *interfacePtr = NULL;
- cJSON *resObj = NULL;
- cJSON *propObj = NULL;
- cJSON *rtArray = NULL;
- char *jsonStr = NULL;
- uint8_t encodeRes = 0;
- OCStackResult ret = OC_STACK_OK;
- uint16_t jsonLen = 0;
+ if (numKeyValuePairsParsed >= 2)
+ {
+ OC_LOG(ERROR, TAG, "More than 2 queries params in URI.");
+ return OC_STACK_INVALID_QUERY;
+ }
- OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponse"));
- resObj = cJSON_CreateObject();
+ key = strtok_r(keyValuePair, OC_KEY_VALUE_DELIMITER, &value);
- if (resourcePtr)
- {
- encodeRes = 0;
- if ((filterOn == STACK_RES_DISCOVERY_RT_FILTER) && filterValue)
+ if (!key || !value)
{
- resourceTypePtr = resourcePtr->rsrcType;
- while (resourceTypePtr)
- {
- if (strcmp (resourceTypePtr->resourcetypename, filterValue) == 0)
- {
- encodeRes = 1;
- break;
- }
- resourceTypePtr = resourceTypePtr->next;
- }
+ return OC_STACK_INVALID_QUERY;
}
- else if ((filterOn == STACK_RES_DISCOVERY_IF_FILTER) && filterValue)
+ else if (strcmp (key, OC_RSRVD_INTERFACE) == 0)
{
- interfacePtr = resourcePtr->rsrcInterface;
- while (interfacePtr)
- {
- if (strcmp (interfacePtr->name, filterValue) == 0)
- {
- encodeRes = 1;
- break;
- }
- interfacePtr = interfacePtr->next;
- }
+ *filterOne = value; // if
}
- else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
+ else if (strcmp (key, OC_RSRVD_RESOURCE_TYPE) == 0)
{
- encodeRes = 1;
+ *filterTwo = value; // rt
}
else
{
- //TODO: Unsupported query filter
+ OC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
return OC_STACK_INVALID_QUERY;
}
+ ++numKeyValuePairsParsed;
- if (encodeRes)
- {
- // Add URIs
- cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
-
- // Add server instance id
- cJSON_AddItemToObject (resObj,
- OC_RSRVD_SERVER_INSTANCE_ID,
- cJSON_CreateString(OCGetServerInstanceIDString()));
-
- cJSON_AddItemToObject (resObj, OC_RSRVD_PROPERTY, propObj = cJSON_CreateObject());
- // Add resource types
- cJSON_AddItemToObject (propObj, OC_RSRVD_RESOURCE_TYPE, rtArray = cJSON_CreateArray());
- resourceTypePtr = resourcePtr->rsrcType;
- while (resourceTypePtr)
- {
- cJSON_AddItemToArray (rtArray,
- cJSON_CreateString(resourceTypePtr->resourcetypename));
- resourceTypePtr = resourceTypePtr->next;
- }
- // Add interface types
- cJSON_AddItemToObject (propObj, OC_RSRVD_INTERFACE, rtArray = cJSON_CreateArray());
- interfacePtr = resourcePtr->rsrcInterface;
- while (interfacePtr)
- {
- cJSON_AddItemToArray (rtArray, cJSON_CreateString(interfacePtr->name));
- interfacePtr = interfacePtr->next;
- }
- // If resource is observable, set observability flag.
- // Resources that are not observable will not have the flag.
- if (resourcePtr->resourceProperties & OC_OBSERVABLE)
- {
- cJSON_AddItemToObject (propObj, OC_RSRVD_OBSERVABLE,
- cJSON_CreateNumber(OC_RESOURCE_OBSERVABLE));
- }
- // Set secure flag for secure resources
- if (resourcePtr->resourceProperties & OC_SECURE)
- {
- cJSON_AddNumberToObject (propObj, OC_RSRVD_SECURE, OC_RESOURCE_SECURE);
- //Set the IP port also as secure resources are hosted on a different port
- uint16_t port = 0;
- if (GetSecurePortInfo (connType, &port) == OC_STACK_OK)
- {
- cJSON_AddNumberToObject (propObj, OC_RSRVD_HOSTING_PORT, port);
- }
- }
-
- }
+ keyValuePair = strtok_r(NULL, OC_QUERY_SEPARATOR, &restOfQuery);
}
- jsonStr = cJSON_PrintUnformatted (resObj);
- jsonLen = strlen(jsonStr);
- if (jsonLen < *remaining)
+ OC_LOG_V(INFO, TAG, "Extracted params %s and %s.", *filterOne, *filterTwo);
+ return OC_STACK_OK;
+}
+
+static OCVirtualResources GetTypeOfVirtualURI(const char *uriInRequest)
+{
+ if (strcmp(uriInRequest, OC_RSRVD_WELL_KNOWN_URI) == 0)
{
- strcpy(out, jsonStr);
- *remaining = *remaining - jsonLen;
+ return OC_WELL_KNOWN_URI;
}
- else
+ else if (strcmp(uriInRequest, OC_RSRVD_DEVICE_URI) == 0)
{
- ret = OC_STACK_ERROR;
+ return OC_DEVICE_URI;
}
- cJSON_Delete (resObj);
- OCFree (jsonStr);
-
- OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponse"));
- return ret;
+ else if (strcmp(uriInRequest, OC_RSRVD_PLATFORM_URI) == 0)
+ {
+ return OC_PLATFORM_URI;
+ }
+ else if (strcmp(uriInRequest, OC_RSRVD_RESOURCE_TYPES_URI) == 0)
+ {
+ return OC_RESOURCE_TYPES_URI;
+ }
+#ifdef ROUTING_GATEWAY
+ else if (0 == strcmp(uriInRequest, OC_RSRVD_GATEWAY_URI))
+ {
+ return OC_GATEWAY_URI;
+ }
+#endif
+#ifdef WITH_PRESENCE
+ else if (strcmp(uriInRequest, OC_RSRVD_PRESENCE_URI) == 0)
+ {
+ return OC_PRESENCE;
+ }
+#endif //WITH_PRESENCE
+ return OC_UNKNOWN_URI;
}
-OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
- char *out, uint16_t *remaining)
+static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *query,
+ char **filterOne, char **filterTwo)
{
- if(!out || !remaining)
+ if(!filterOne || !filterTwo)
{
return OC_STACK_INVALID_PARAM;
}
- OCStackResult ret = OC_STACK_ERROR;
+ *filterOne = NULL;
+ *filterTwo = NULL;
- if (savedDeviceInfo != NULL)
+ #ifdef WITH_PRESENCE
+ if (uri == OC_PRESENCE)
{
- char *jsonStr = NULL;
- uint16_t jsonLen = 0;
- cJSON *repObj = cJSON_GetObjectItem(savedDeviceInfo, OC_RSRVD_REPRESENTATION);
+ //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
+ OC_LOG(INFO, TAG, "OC_PRESENCE Request for virtual resource.");
+ return OC_STACK_OK;
+ }
+ #endif
- OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponseForDevice"));
+ OCStackResult result = OC_STACK_OK;
- if ((filterOn == STACK_DEVICE_DISCOVERY_DI_FILTER) && filterValue)
- {
- if((cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_ID) != NULL) &&
- strcmp(cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_ID)->valuestring, filterValue)
- == 0)
- {
- ret = OC_STACK_OK;
- }
- }
- else if ((filterOn == STACK_DEVICE_DISCOVERY_DN_FILTER) && filterValue)
- {
- if((cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_NAME) != NULL) &&
- strcmp(cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_NAME)->valuestring,
- filterValue) == 0)
- {
- ret = OC_STACK_OK;
- }
- }
- else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
- {
- ret = OC_STACK_OK;
- }
- else
- {
- ret = OC_STACK_INVALID_QUERY;
- }
+ if (query && *query)
+ {
+ result = ExtractFiltersFromQuery(query, filterOne, filterTwo);
+ }
- if (ret == OC_STACK_OK)
- {
- jsonStr = cJSON_PrintUnformatted (savedDeviceInfo);
+ return result;
+}
- if(jsonStr)
- {
- jsonLen = strlen(jsonStr);
+OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
+ OCRepPayload** payload)
+{
+ OCRepPayload *tempPayload = OCRepPayloadCreate();
- if (jsonLen < *remaining)
- {
- strncpy(out, jsonStr, (jsonLen + 1));
- *remaining = *remaining - jsonLen;
- ret = OC_STACK_OK;
- }
- else
- {
- ret = OC_STACK_ERROR;
- }
+ if (!resourcePtr)
+ {
+ OCRepPayloadDestroy(tempPayload);
+ return OC_STACK_INVALID_PARAM;
+ }
- OCFree(jsonStr);
- }
- else
- {
- ret = OC_STACK_ERROR;
- }
- }
- else
- {
- ret = OC_STACK_INVALID_DEVICE_INFO;
- }
+ if(!tempPayload)
+ {
+ return OC_STACK_NO_MEMORY;
}
- else
+
+ OCRepPayloadSetUri(tempPayload, resourcePtr->uri);
+
+ OCResourceType *resType = resourcePtr->rsrcType;
+ while(resType)
{
- //error so that stack won't respond with empty payload
- ret = OC_STACK_INVALID_DEVICE_INFO;
+ OCRepPayloadAddResourceType(tempPayload, resType->resourcetypename);
+ resType = resType->next;
}
- OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponseForDevice"));
- return ret;
-}
+ OCResourceInterface *resInterface = resourcePtr->rsrcInterface;
+ while(resInterface)
+ {
+ OCRepPayloadAddInterface(tempPayload, resInterface->name);
+ resInterface = resInterface->next;
+ }
-const char * GetVirtualResourceUri( OCVirtualResources resource)
-{
- if (resource < OC_MAX_VIRTUAL_RESOURCES)
+ OCAttribute *resAttrib = resourcePtr->rsrcAttributes;
+ while(resAttrib)
{
- return VIRTUAL_RSRCS[resource];
+ OCRepPayloadSetPropString(tempPayload, resAttrib->attrName,
+ resAttrib->attrValue);
+ resAttrib = resAttrib->next;
}
- return NULL;
+ if(!*payload)
+ {
+ *payload = tempPayload;
+ }
+ else
+ {
+ OCRepPayloadAppend(*payload, tempPayload);
+ }
+
+ return OC_STACK_OK;
}
-bool IsVirtualResource(const char* resourceUri)
+OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
+ OCDiscoveryPayload *payload, OCDevAddr *devAddr)
{
- if(!resourceUri)
+ if (!resourcePtr || !payload)
{
- return false;
+ return OC_STACK_INVALID_PARAM;
}
-
- for (int i = 0; i < OC_MAX_VIRTUAL_RESOURCES; i++)
+ uint16_t port = 0;
+ if (resourcePtr->resourceProperties & OC_SECURE)
{
- if (strcmp(resourceUri, GetVirtualResourceUri((OCVirtualResources)i)) == 0)
- {
- return true;
- }
+ if (GetSecurePortInfo(devAddr, &port) != OC_STACK_OK)
+ {
+ port = 0;
+ }
}
- return false;
+
+ OCDiscoveryPayloadAddResource(payload, resourcePtr, port);
+ return OC_STACK_OK;
}
+
uint8_t IsCollectionResource (OCResource *resource)
{
if(!resource)
}
OCResource * pointer = headResource;
- while (pointer) {
- if (strcmp(resourceUri, pointer->uri) == 0) {
+ while (pointer)
+ {
+ if (strcmp(resourceUri, pointer->uri) == 0)
+ {
return pointer;
}
pointer = pointer->next;
}
- OC_LOG(INFO, TAG, PCF("Resource not found"));
+ OC_LOG_V(INFO, TAG, "Resource %s not found", resourceUri);
return NULL;
}
return OC_STACK_INVALID_PARAM;
}
- OC_LOG(INFO, TAG, PCF("Entering DetermineResourceHandling"));
+ OC_LOG_V(INFO, TAG, "DetermineResourceHandling for %s", request->resourceUrl);
// Check if virtual resource
- if (IsVirtualResource((const char*)request->resourceUrl))
+ if (GetTypeOfVirtualURI(request->resourceUrl) != OC_UNKNOWN_URI)
{
+ OC_LOG_V (INFO, TAG, "%s is virtual", request->resourceUrl);
*handling = OC_RESOURCE_VIRTUAL;
*resource = headResource;
return OC_STACK_OK;
}
- if (NULL == request->resourceUrl || (strlen((const char*)(request->resourceUrl)) == 0))
+ if (strlen((const char*)(request->resourceUrl)) == 0)
{
// Resource URL not specified
*handling = OC_RESOURCE_NOT_SPECIFIED;
}
else
{
- OCResource *resourcePtr = NULL;
- resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
+ OCResource *resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
*resource = resourcePtr;
if (!resourcePtr)
{
return OC_STACK_NO_RESOURCE;
}
- // secure resource will entertain only authorized requests
- if ((resourcePtr->resourceProperties & OC_SECURE) && (request->secured == 0))
- {
- OC_LOG(ERROR, TAG, PCF("Un-authorized request. Ignoring"));
- return OC_STACK_RESOURCE_ERROR;
- }
-
if (IsCollectionResource (resourcePtr))
{
// Collection resource
return result;
}
-static OCStackResult
-HandleVirtualResource (OCServerRequest *request, OCResource* resource)
+static bool resourceMatchesRTFilter(OCResource *resource, char *resourceTypeFilter)
{
- if(!request || !resource)
+ if (!resource)
+ {
+ return false;
+ }
+
+ // Null or empty is analogous to no filter.
+ if (resourceTypeFilter == NULL || *resourceTypeFilter == 0)
+ {
+ return true;
+ }
+
+ OCResourceType *resourceTypePtr = resource->rsrcType;
+
+ while (resourceTypePtr)
+ {
+ if (strcmp (resourceTypePtr->resourcetypename, resourceTypeFilter) == 0)
+ {
+ return true;
+ }
+ resourceTypePtr = resourceTypePtr->next;
+ }
+
+ OC_LOG_V(INFO, TAG, "%s does not contain rt=%s.", resource->uri, resourceTypeFilter);
+ return false;
+}
+
+static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter)
+{
+ if (!resource)
+ {
+ return false;
+ }
+
+ // Null or empty is analogous to no filter.
+ if (interfaceFilter == NULL || *interfaceFilter == 0)
+ {
+ return true;
+ }
+
+ OCResourceInterface *interfacePtr = resource->rsrcInterface;
+
+ while (interfacePtr)
+ {
+ if (strcmp (interfacePtr->name, interfaceFilter) == 0)
+ {
+ return true;
+ }
+ interfacePtr = interfacePtr->next;
+ }
+
+ OC_LOG_V(INFO, TAG, "%s does not contain if=%s.", resource->uri, interfaceFilter);
+ return false;
+}
+
+/*
+ * If the filters are null, they will be assumed to NOT be present
+ * and the resource will not be matched against them.
+ * Function will return true if all non null AND non empty filters passed in find a match.
+ */
+static bool includeThisResourceInResponse(OCResource *resource,
+ char *interfaceFilter,
+ char *resourceTypeFilter)
+{
+ if (!resource)
+ {
+ OC_LOG(ERROR, TAG, "Invalid resource");
+ return false;
+ }
+
+ if ( resource->resourceProperties & OC_EXPLICIT_DISCOVERABLE)
+ {
+ /*
+ * At least one valid filter should be available to
+ * include the resource in discovery response
+ */
+ if (!((interfaceFilter && *interfaceFilter ) ||
+ (resourceTypeFilter && *resourceTypeFilter)))
+ {
+ OC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE \
+ resource", resource->uri);
+ return false;
+ }
+ }
+ else if ( !(resource->resourceProperties & OC_ACTIVE) ||
+ !(resource->resourceProperties & OC_DISCOVERABLE))
+ {
+ OC_LOG_V(INFO, TAG, "%s not ACTIVE or DISCOVERABLE", resource->uri);
+ return false;
+ }
+
+ return resourceMatchesIFFilter(resource, interfaceFilter) &&
+ resourceMatchesRTFilter(resource, resourceTypeFilter);
+
+}
+
+OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCResource *resource,
+ OCPayload *discoveryPayload, OCEntityHandlerResult ehResult)
+{
+ OCEntityHandlerResponse response = {0};
+
+ response.ehResult = ehResult;
+ response.payload = discoveryPayload;
+ response.persistentBufferFlag = 0;
+ response.requestHandle = (OCRequestHandle) request;
+ response.resourceHandle = (OCResourceHandle) resource;
+
+ return OCDoResponse(&response);
+}
+
+static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
+{
+ if (!request || !resource)
{
return OC_STACK_INVALID_PARAM;
}
- OCStackResult result = OC_STACK_ERROR;
- char *filterValue = NULL;
- uint8_t filterOn = 0;
- uint16_t remaining = 0;
- char * ptr = NULL;
- uint8_t firstLoopDone = 0;
- char discoveryResBuf[MAX_RESPONSE_LENGTH] = {};
+ OCStackResult discoveryResult = OC_STACK_ERROR;
- OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
+ bool bMulticast = false; // Was the discovery request a multicast request?
+ OCPayload* payload = NULL;
- result = ValidateUrlQuery (request->resourceUrl,
- request->query, &filterOn,
- &filterValue);
+ OC_LOG(INFO, TAG, "Entering HandleVirtualResource");
- if (result == OC_STACK_OK)
+ OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
+
+ // Step 1: Generate the response to discovery request
+ if (virtualUriInRequest == OC_WELL_KNOWN_URI)
{
- if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0)
+ char *filterOne = NULL;
+ char *filterTwo = NULL;
+
+ discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
+ &filterOne, &filterTwo);
+
+ if (discoveryResult == OC_STACK_OK)
{
- ptr = discoveryResBuf;
- remaining = MAX_RESPONSE_LENGTH;
+ payload = (OCPayload*)OCDiscoveryPayloadCreate();
- // Check if valid resource and enough space in buffer for atleast
- // the null character.
- while(resource && (remaining > 1))
+ if(payload)
{
- if((resource->resourceProperties & OC_ACTIVE)
- && (resource->resourceProperties & OC_DISCOVERABLE))
+ for(;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
{
- // if there is data on the buffer, we have already added a response,
- // so we need to add a comma before we do anything
- if(firstLoopDone
- && remaining >= (sizeof(OC_JSON_SEPARATOR)+1))
- {
- *ptr = OC_JSON_SEPARATOR;
- ptr++;
- remaining--;
- }
- firstLoopDone = 1;
- result = BuildVirtualResourceResponse(resource, filterOn, filterValue,
- (char*)ptr, &remaining, request->connectivityType );
-
- if (result != OC_STACK_OK)
+ if(includeThisResourceInResponse(resource, filterOne, filterTwo))
{
- // if this failed, we need to remove the comma added above.
- if(!firstLoopDone)
- {
- ptr--;
- *ptr = '\0';
- remaining++;
- }
- break;
+ discoveryResult = BuildVirtualResourceResponse(resource,
+ (OCDiscoveryPayload*)payload,
+ &request->devAddr);
}
- ptr += strlen((char *)ptr);
}
- resource = resource->next;
+ // Set discoveryResult appropriately if no 'valid' resources are available.
+ if (((OCDiscoveryPayload*)payload)->resources == NULL)
+ {
+ discoveryResult = OC_STACK_NO_RESOURCE;
+ }
}
-
- if(strlen((const char *)discoveryResBuf) > 0)
+ else
{
- OCEntityHandlerResponse response = {};
-
- response.ehResult = OC_EH_OK;
- response.payload = discoveryResBuf;
- response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
- response.persistentBufferFlag = 0;
- response.requestHandle = (OCRequestHandle) request;
- response.resourceHandle = (OCResourceHandle) resource;
-
- result = OCDoResponse(&response);
+ discoveryResult = OC_STACK_NO_MEMORY;
}
}
- else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
+ else
{
- remaining = MAX_RESPONSE_LENGTH;
- ptr = discoveryResBuf;
-
- result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
- (char*)ptr, &remaining);
-
- if(result == OC_STACK_OK)
+ OC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
+ }
+ }
+ else if (virtualUriInRequest == OC_DEVICE_URI)
+ {
+ const OicUuid_t* deviceId = OCGetServerInstanceID();
+ if (!deviceId)
+ {
+ discoveryResult = OC_STACK_ERROR;
+ }
+ else
+ {
+ payload = (OCPayload*) OCDevicePayloadCreate(OC_RSRVD_DEVICE_URI,
+ (const uint8_t*) &deviceId->id, savedDeviceInfo.deviceName,
+ OC_SPEC_VERSION, OC_DATA_MODEL_VERSION);
+ if (!payload)
{
- ptr += strlen((char*)ptr);
+ discoveryResult = OC_STACK_NO_MEMORY;
}
-
- if(remaining < MAX_RESPONSE_LENGTH)
+ else
{
- OCEntityHandlerResponse response = {0};
-
- response.ehResult = OC_EH_OK;
- response.payload = discoveryResBuf;
- response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
- response.persistentBufferFlag = 0;
- response.requestHandle = (OCRequestHandle) request;
- response.resourceHandle = (OCResourceHandle) resource;
-
- result = OCDoResponse(&response);
+ discoveryResult = OC_STACK_OK;
}
}
- else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
+ }
+ else if (virtualUriInRequest == OC_PLATFORM_URI)
+ {
+ payload = (OCPayload*)OCPlatformPayloadCreate(
+ OC_RSRVD_PLATFORM_URI,
+ &savedPlatformInfo);
+ if (!payload)
{
- remaining = MAX_RESPONSE_LENGTH;
- ptr = discoveryResBuf;
-
- result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
- (char*)ptr, &remaining);
-
- if(result == OC_STACK_OK)
- {
- ptr += strlen((char*)ptr);
- }
-
- if(remaining < MAX_RESPONSE_LENGTH)
- {
- OCEntityHandlerResponse response = {0};
-
- response.ehResult = OC_EH_OK;
- response.payload = discoveryResBuf;
- response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
- response.persistentBufferFlag = 0;
- response.requestHandle = (OCRequestHandle) request;
- response.resourceHandle = (OCResourceHandle) resource;
+ discoveryResult = OC_STACK_NO_MEMORY;
+ }
+ else
+ {
+ discoveryResult = OC_STACK_OK;
+ }
+ }
+#ifdef ROUTING_GATEWAY
+ else if (OC_GATEWAY_URI == virtualUriInRequest)
+ {
+ // Received request for a gateway
+ OC_LOG(INFO, TAG, "Request is for Gateway Virtual Request");
+ discoveryResult = RMHandleGatewayRequest(request, resource);
- result = OCDoResponse(&response);
- }
+ }
+#endif
+
+ /**
+ * Step 2: Send the discovery response
+ *
+ * Iotivity should respond to discovery requests in below manner:
+ * 1)If query filter matching fails and discovery request is multicast,
+ * it should NOT send any response.
+ * 2)If query filter matching fails and discovery request is unicast,
+ * it should send an error(RESOURCE_NOT_FOUND - 404) response.
+ * 3)If Server does not have any 'DISCOVERABLE' resources and discovery
+ * request is multicast, it should NOT send any response.
+ * 4)If Server does not have any 'DISCOVERABLE' resources and discovery
+ * request is unicast, it should send an error(RESOURCE_NOT_FOUND - 404) response.
+ */
+
+#ifdef WITH_PRESENCE
+ if ((virtualUriInRequest == OC_PRESENCE) &&
+ (resource->resourceProperties & OC_ACTIVE))
+ {
+ // Presence uses observer notification api to respond via SendPresenceNotification.
+ SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
+ }
+ else
+ #endif
+#ifdef ROUTING_GATEWAY
+ // Gateway uses the RMHandleGatewayRequest to respond to the request.
+ if (OC_GATEWAY != virtualUriInRequest)
+#endif
+ {
+ if(discoveryResult == OC_STACK_OK)
+ {
+ SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK);
+ }
+ else if(bMulticast == false)
+ {
+ OC_LOG_V(ERROR, TAG, "Sending a (%d) error to (%d) \
+ discovery request", discoveryResult, virtualUriInRequest);
+ SendNonPersistantDiscoveryResponse(request, resource, NULL,
+ (discoveryResult == OC_STACK_NO_RESOURCE) ? OC_EH_RESOURCE_NOT_FOUND : OC_EH_ERROR);
}
- #ifdef WITH_PRESENCE
else
{
- if(resource->resourceProperties & OC_ACTIVE){
- SendPresenceNotification(NULL);
- }
+ // Ignoring the discovery request as per RFC 7252, Section #8.2
+ OC_LOG(INFO, TAG, "Silently ignoring the request since device does not have \
+ any useful data to send");
}
- #endif
}
- result = OC_STACK_OK;
- return result;
+
+ OCPayloadDestroy(payload);
+
+ return OC_STACK_OK;
}
static OCStackResult
OCStackResult result = OC_STACK_OK;
OCEntityHandlerResult ehResult = OC_EH_ERROR;
- OCEntityHandlerRequest ehRequest = {};
-
- OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
- result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
- request->method, (OCResourceHandle) NULL, request->query,
- request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
- request->rcvdVendorSpecificHeaderOptions,
- (OCObserveAction)request->observationOption, (OCObservationId)0);
+ OCEntityHandlerRequest ehRequest = {0};
+
+ OC_LOG(INFO, TAG, "Entering HandleResourceWithDefaultDeviceEntityHandler");
+ result = FormOCEntityHandlerRequest(&ehRequest,
+ (OCRequestHandle) request,
+ request->method,
+ &request->devAddr,
+ (OCResourceHandle) NULL, request->query,
+ PAYLOAD_TYPE_REPRESENTATION,
+ request->payload,
+ request->payloadSize,
+ request->numRcvdVendorSpecificHeaderOptions,
+ request->rcvdVendorSpecificHeaderOptions,
+ (OCObserveAction)request->observationOption,
+ (OCObservationId)0);
VERIFY_SUCCESS(result, OC_STACK_OK);
// At this point we know for sure that defaultDeviceHandler exists
ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
- (char*) request->resourceUrl);
+ (char*) request->resourceUrl, defaultDeviceHandlerCallbackParameter);
if(ehResult == OC_EH_SLOW)
{
- OC_LOG(INFO, TAG, PCF("This is a slow resource"));
+ OC_LOG(INFO, TAG, "This is a slow resource");
request->slowFlag = 1;
}
else if(ehResult == OC_EH_ERROR)
}
result = EntityHandlerCodeToOCStackCode(ehResult);
exit:
+ OCPayloadDestroy(ehRequest.payload);
return result;
}
OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
ResourceObserver *resObs = NULL;
- OCEntityHandlerRequest ehRequest = {};
+ OCEntityHandlerRequest ehRequest = {0};
- OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
- result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
- request->method, (OCResourceHandle) resource, request->query,
- request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
- request->rcvdVendorSpecificHeaderOptions,
- (OCObserveAction)request->observationOption, 0);
+ OC_LOG(INFO, TAG, "Entering HandleResourceWithEntityHandler");
+ OCPayloadType type = PAYLOAD_TYPE_REPRESENTATION;
+ // check the security resource
+ if (request && request->resourceUrl && SRMIsSecurityResourceURI(request->resourceUrl))
+ {
+ type = PAYLOAD_TYPE_SECURITY;
+
+ }
+ result = FormOCEntityHandlerRequest(&ehRequest,
+ (OCRequestHandle)request,
+ request->method,
+ &request->devAddr,
+ (OCResourceHandle)resource,
+ request->query,
+ type,
+ request->payload,
+ request->payloadSize,
+ request->numRcvdVendorSpecificHeaderOptions,
+ request->rcvdVendorSpecificHeaderOptions,
+ (OCObserveAction)request->observationOption,
+ 0);
VERIFY_SUCCESS(result, OC_STACK_OK);
if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
{
- OC_LOG(INFO, TAG, PCF("No observation requested"));
+ OC_LOG(INFO, TAG, "No observation requested");
ehFlag = OC_REQUEST_FLAG;
}
- else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER &&
- !collectionResource)
+ else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER && !collectionResource)
{
- OC_LOG(INFO, TAG, PCF("Registering observation requested"));
+ OC_LOG(INFO, TAG, "Observation registration requested");
+
result = GenerateObserverId(&ehRequest.obsInfo.obsId);
VERIFY_SUCCESS(result, OC_STACK_OK);
result = AddObserver ((const char*)(request->resourceUrl),
(const char *)(request->query),
ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
- resource, request->qos,
- &request->addressInfo, request->connectivityType);
+ resource, request->qos, request->acceptFormat,
+ &request->devAddr);
if(result == OC_STACK_OK)
{
- OC_LOG(INFO, TAG, PCF("Added observer successfully"));
+ OC_LOG(INFO, TAG, "Added observer successfully");
request->observeResult = OC_STACK_OK;
ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
}
else
{
result = OC_STACK_OK;
- // The error in observeResult for the request will be
- // used when responding to this request by omitting
- // the observation option/sequence number.
+
+ // The error in observeResult for the request will be used when responding to this
+ // request by omitting the observation option/sequence number.
request->observeResult = OC_STACK_ERROR;
- OC_LOG(ERROR, TAG, PCF("Observer Addition failed"));
+ OC_LOG(ERROR, TAG, "Observer Addition failed");
ehFlag = OC_REQUEST_FLAG;
}
else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
!collectionResource)
{
- OC_LOG(INFO, TAG, PCF("Deregistering observation requested"));
+ OC_LOG(INFO, TAG, "Deregistering observation requested");
resObs = GetObserverUsingToken (request->requestToken, request->tokenLength);
if(result == OC_STACK_OK)
{
- OC_LOG(INFO, TAG, PCF("Removed observer successfully"));
+ OC_LOG(INFO, TAG, "Removed observer successfully");
request->observeResult = OC_STACK_OK;
}
else
{
result = OC_STACK_OK;
request->observeResult = OC_STACK_ERROR;
- OC_LOG(ERROR, TAG, PCF("Observer Removal failed"));
+ OC_LOG(ERROR, TAG, "Observer Removal failed");
}
}
else
goto exit;
}
- ehResult = resource->entityHandler(ehFlag, &ehRequest);
+ ehResult = resource->entityHandler(ehFlag, &ehRequest, resource->entityHandlerCallbackParam);
if(ehResult == OC_EH_SLOW)
{
- OC_LOG(INFO, TAG, PCF("This is a slow resource"));
+ OC_LOG(INFO, TAG, "This is a slow resource");
request->slowFlag = 1;
}
else if(ehResult == OC_EH_ERROR)
}
result = EntityHandlerCodeToOCStackCode(ehResult);
exit:
+ OCPayloadDestroy(ehRequest.payload);
return result;
}
}
OCStackResult result = OC_STACK_ERROR;
- OCEntityHandlerRequest ehRequest = {};
-
- result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
- request->method, (OCResourceHandle) resource, request->query,
- request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
- request->rcvdVendorSpecificHeaderOptions,
- (OCObserveAction)request->observationOption, (OCObservationId) 0);
- if(result != OC_STACK_OK)
+ OCEntityHandlerRequest ehRequest = {0};
+
+ result = FormOCEntityHandlerRequest(&ehRequest,
+ (OCRequestHandle)request,
+ request->method,
+ &request->devAddr,
+ (OCResourceHandle)resource,
+ request->query,
+ PAYLOAD_TYPE_REPRESENTATION,
+ request->payload,
+ request->payloadSize,
+ request->numRcvdVendorSpecificHeaderOptions,
+ request->rcvdVendorSpecificHeaderOptions,
+ (OCObserveAction)request->observationOption,
+ (OCObservationId)0);
+ if(result == OC_STACK_OK)
{
- return result;
+ result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest);
}
- return (DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest));
+ OCPayloadDestroy(ehRequest.payload);
+ return result;
}
OCStackResult
}
case OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER:
{
- OC_LOG(INFO, TAG, PCF("OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER"));
+ OC_LOG(INFO, TAG, "OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER");
return OC_STACK_ERROR;
}
case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
}
default:
{
- OC_LOG(INFO, TAG, PCF("Invalid Resource Determination"));
+ OC_LOG(INFO, TAG, "Invalid Resource Determination");
return OC_STACK_ERROR;
}
}
return ret;
}
-void DeleteDeviceInfo()
+void DeletePlatformInfo()
{
- if(savedDeviceInfo)
- {
- cJSON_Delete(savedDeviceInfo);
- }
-}
+ OC_LOG(INFO, TAG, "Deleting platform info.");
-OCStackResult SaveDeviceInfo(OCDeviceInfo deviceInfo)
-{
- DeleteDeviceInfo();
+ OICFree(savedPlatformInfo.platformID);
+ savedPlatformInfo.platformID = NULL;
- savedDeviceInfo = cJSON_CreateObject();
- cJSON *repObj = NULL;
+ OICFree(savedPlatformInfo.manufacturerName);
+ savedPlatformInfo.manufacturerName = NULL;
- cJSON_AddItemToObject (savedDeviceInfo, OC_RSRVD_HREF,
- cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
+ OICFree(savedPlatformInfo.manufacturerUrl);
+ savedPlatformInfo.manufacturerUrl = NULL;
- cJSON_AddItemToObject (savedDeviceInfo, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
+ OICFree(savedPlatformInfo.modelNumber);
+ savedPlatformInfo.modelNumber = NULL;
- if (deviceInfo.contentType)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_CONTENT_TYPE,
- cJSON_CreateString(deviceInfo.contentType));
- }
+ OICFree(savedPlatformInfo.dateOfManufacture);
+ savedPlatformInfo.dateOfManufacture = NULL;
- if (deviceInfo.dateOfManufacture)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
- cJSON_CreateString(deviceInfo.dateOfManufacture));
- }
+ OICFree(savedPlatformInfo.platformVersion);
+ savedPlatformInfo.platformVersion = NULL;
- if (deviceInfo.deviceName)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_NAME,
- cJSON_CreateString(deviceInfo.deviceName));
- }
+ OICFree(savedPlatformInfo.operatingSystemVersion);
+ savedPlatformInfo.operatingSystemVersion = NULL;
- if (deviceInfo.deviceUUID)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_ID,
- cJSON_CreateString(deviceInfo.deviceUUID));
- }
+ OICFree(savedPlatformInfo.hardwareVersion);
+ savedPlatformInfo.hardwareVersion = NULL;
- if (deviceInfo.firmwareVersion)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_FW_VERSION,
- cJSON_CreateString(deviceInfo.firmwareVersion));
- }
+ OICFree(savedPlatformInfo.firmwareVersion);
+ savedPlatformInfo.firmwareVersion = NULL;
+
+ OICFree(savedPlatformInfo.supportUrl);
+ savedPlatformInfo.supportUrl = NULL;
+
+ OICFree(savedPlatformInfo.systemTime);
+ savedPlatformInfo.systemTime = NULL;
+}
- if (deviceInfo.hostName)
+static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
+{
+ savedPlatformInfo.platformID = OICStrdup(info.platformID);
+ savedPlatformInfo.manufacturerName = OICStrdup(info.manufacturerName);
+ savedPlatformInfo.manufacturerUrl = OICStrdup(info.manufacturerUrl);
+ savedPlatformInfo.modelNumber = OICStrdup(info.modelNumber);
+ savedPlatformInfo.dateOfManufacture = OICStrdup(info.dateOfManufacture);
+ savedPlatformInfo.platformVersion = OICStrdup(info.platformVersion);
+ savedPlatformInfo.operatingSystemVersion = OICStrdup(info.operatingSystemVersion);
+ savedPlatformInfo.hardwareVersion = OICStrdup(info.hardwareVersion);
+ savedPlatformInfo.firmwareVersion = OICStrdup(info.firmwareVersion);
+ savedPlatformInfo.supportUrl = OICStrdup(info.supportUrl);
+ savedPlatformInfo.systemTime = OICStrdup(info.systemTime);
+
+ if ((!savedPlatformInfo.platformID && info.platformID)||
+ (!savedPlatformInfo.manufacturerName && info.manufacturerName)||
+ (!savedPlatformInfo.manufacturerUrl && info.manufacturerUrl)||
+ (!savedPlatformInfo.modelNumber && info.modelNumber)||
+ (!savedPlatformInfo.dateOfManufacture && info.dateOfManufacture)||
+ (!savedPlatformInfo.platformVersion && info.platformVersion)||
+ (!savedPlatformInfo.operatingSystemVersion && info.operatingSystemVersion)||
+ (!savedPlatformInfo.hardwareVersion && info.hardwareVersion)||
+ (!savedPlatformInfo.firmwareVersion && info.firmwareVersion)||
+ (!savedPlatformInfo.supportUrl && info.supportUrl)||
+ (!savedPlatformInfo.systemTime && info.systemTime))
{
- cJSON_AddItemToObject (repObj, OC_RSRVD_HOST_NAME,
- cJSON_CreateString(deviceInfo.hostName));
+ DeletePlatformInfo();
+ return OC_STACK_INVALID_PARAM;
}
- if (deviceInfo.manufacturerName)
- {
- if(strlen(deviceInfo.manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH)
- {
- DeleteDeviceInfo();
- return OC_STACK_INVALID_PARAM;
- }
+ return OC_STACK_OK;
- cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME,
- cJSON_CreateString(deviceInfo.manufacturerName));
- }
+}
- if (deviceInfo.manufacturerUrl)
- {
- if(strlen(deviceInfo.manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH)
- {
- DeleteDeviceInfo();
- return OC_STACK_INVALID_PARAM;
- }
+OCStackResult SavePlatformInfo(OCPlatformInfo info)
+{
+ DeletePlatformInfo();
- cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
- cJSON_CreateString(deviceInfo.manufacturerUrl));
- }
+ OCStackResult res = DeepCopyPlatFormInfo(info);
- if (deviceInfo.modelNumber)
+ if (res != OC_STACK_OK)
{
- cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
- cJSON_CreateString(deviceInfo.modelNumber));
+ OC_LOG_V(ERROR, TAG, "Failed to save platform info. errno(%d)", res);
}
-
- if (deviceInfo.platformVersion)
+ else
{
- cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
- cJSON_CreateString(deviceInfo.platformVersion));
+ OC_LOG(INFO, TAG, "Platform info saved.");
}
- if (deviceInfo.supportUrl)
+ return res;
+}
+
+void DeleteDeviceInfo()
+{
+ OC_LOG(INFO, TAG, "Deleting device info.");
+
+ OICFree(savedDeviceInfo.deviceName);
+ savedDeviceInfo.deviceName = NULL;
+}
+
+static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
+{
+ savedDeviceInfo.deviceName = OICStrdup(info.deviceName);
+
+ if(!savedDeviceInfo.deviceName && info.deviceName)
{
- cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
- cJSON_CreateString(deviceInfo.supportUrl));
+ DeleteDeviceInfo();
+ return OC_STACK_NO_MEMORY;
}
- if (deviceInfo.version)
+ return OC_STACK_OK;
+}
+
+OCStackResult SaveDeviceInfo(OCDeviceInfo info)
+{
+ OCStackResult res = OC_STACK_OK;
+
+ DeleteDeviceInfo();
+
+ res = DeepCopyDeviceInfo(info);
+
+ VERIFY_SUCCESS(res, OC_STACK_OK);
+
+ if(OCGetServerInstanceID() == NULL)
{
- cJSON_AddItemToObject (repObj, OC_RSRVD_VERSION,
- cJSON_CreateString(deviceInfo.version));
+ OC_LOG(INFO, TAG, "Device ID generation failed");
+ res = OC_STACK_ERROR;
+ goto exit;
}
+ OC_LOG(INFO, TAG, "Device initialized successfully.");
return OC_STACK_OK;
+
+exit:
+ DeleteDeviceInfo();
+ return res;
}