//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// Defining _POSIX_C_SOURCE macro with 200112L (or greater) as value
+// causes header files to expose definitions
+// corresponding to the POSIX.1-2001 base
+// specification (excluding the XSI extension).
+// For POSIX.1-2001 base specification,
+// 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 "occoap.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
#include "logger.h"
-#include "debug.h"
#include "cJSON.h"
-
-#ifdef CA_INT
- #include "cacommon.h"
- #include "cainterface.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) {
- TODO ("Implement me!!!!");
+ 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
}
-#ifdef CA_INT
-/* This method will return the port at which the secure resource is hosted */
-static OCStackResult GetSecurePortInfo(CAConnectivityType_t connType, uint32_t *port)
+/* This method will retrieve the port at which the secure resource is hosted */
+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 == CA_TRUE && 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;
}
}
- free(info);
- return ret;
+ *port = p;
+ return OC_STACK_OK;
}
-#endif
-static OCStackResult ValidateUrlQuery (unsigned char *url, unsigned 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)
{
- char *filterParam;
-
- OC_LOG(INFO, TAG, PCF("Entering ValidateUrlQuery"));
- if (!url)
- return OC_STACK_INVALID_URI;
-
- 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;
- filterParam = strtok_r((char *)query, "=", &strTokPtr);
- *filterValue = strtok_r(NULL, " ", &strTokPtr);
- if (!(*filterValue)) {
- 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 *key = NULL;
+ char *value = NULL;
+ char *restOfQuery = NULL;
+ int numKeyValuePairsParsed = 0;
-#ifdef CA_INT
-OCStackResult
-BuildVirtualResourceResponse(OCResource *resourcePtr, uint8_t filterOn,
- char *filterValue, char * out, uint16_t *remaining,
- CAConnectivityType_t connType )
-#else
-OCStackResult
-BuildVirtualResourceResponse(OCResource *resourcePtr, uint8_t filterOn,
- char *filterValue, char * out, uint16_t *remaining)
-#endif
-{
- OCResourceType *resourceTypePtr;
- OCResourceInterface *interfacePtr;
- cJSON *resObj, *propObj, *rtArray;
- char *jsonStr;
- uint8_t encodeRes = 0;
- OCStackResult ret = OC_STACK_OK;
- uint16_t jsonLen;
+ *filterOne = NULL;
+ *filterTwo = NULL;
- OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponse"));
- resObj = cJSON_CreateObject();
+ OC_LOG_V(INFO, TAG, "Extracting params from %s", query);
- if (resourcePtr)
+ char *keyValuePair = strtok_r (query, OC_QUERY_SEPARATOR, &restOfQuery);
+
+ while(keyValuePair)
{
- encodeRes = 0;
- if (filterOn == STACK_RES_DISCOVERY_RT_FILTER) {
- resourceTypePtr = resourcePtr->rsrcType;
- while (resourceTypePtr) {
- if (strcmp (resourceTypePtr->resourcetypename, filterValue) == 0) {
- encodeRes = 1;
- break;
- }
- resourceTypePtr = resourceTypePtr->next;
- }
- } else if (filterOn == STACK_RES_DISCOVERY_IF_FILTER) {
- interfacePtr = resourcePtr->rsrcInterface;
- while (interfacePtr) {
- if (strcmp (interfacePtr->name, filterValue) == 0) {
- encodeRes = 1;
- break;
- }
- interfacePtr = interfacePtr->next;
- }
- } else if (filterOn == STACK_RES_DISCOVERY_NOFILTER) {
- encodeRes = 1;
- } else {
- //TODO: Unsupported query filter
+ if (numKeyValuePairsParsed >= 2)
+ {
+ OC_LOG(ERROR, TAG, "More than 2 queries params in URI.");
return OC_STACK_INVALID_QUERY;
}
- if (encodeRes) {
- // Add URIs
- cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
-
- // Add server instance id
- const char* serverInstanceId = OCGetServerInstanceIDString();
- cJSON_AddItemToObject (resObj,
- OC_RSRVD_SERVER_INSTANCE_ID,
- cJSON_CreateString(serverInstanceId));
- serverInstanceId = NULL;
-
- cJSON_AddItemToObject (resObj, "prop", 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
-#ifdef CA_INT
- uint32_t port;
- if (GetSecurePortInfo (connType, &port) == OC_STACK_OK) {
-#else
- uint16_t port;
- if (OCGetResourceEndPointInfo (resourcePtr, &port) == OC_STACK_OK) {
-#endif
- cJSON_AddNumberToObject (propObj, OC_RSRVD_HOSTING_PORT, port);
- }
- }
+ key = strtok_r(keyValuePair, OC_KEY_VALUE_DELIMITER, &value);
+ if (!key || !value)
+ {
+ return OC_STACK_INVALID_QUERY;
+ }
+ else if (strcmp (key, OC_RSRVD_INTERFACE) == 0)
+ {
+ *filterOne = value; // if
+ }
+ else if (strcmp (key, OC_RSRVD_RESOURCE_TYPE) == 0)
+ {
+ *filterTwo = value; // rt
}
+ else
+ {
+ OC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
+ return OC_STACK_INVALID_QUERY;
+ }
+ ++numKeyValuePairsParsed;
+
+ 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)
+ {
+ return OC_DEVICE_URI;
+ }
+ 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)
{
- ret = OC_STACK_ERROR;
+ return OC_PRESENCE;
}
- cJSON_Delete (resObj);
- free (jsonStr);
+#endif //WITH_PRESENCE
+ return OC_UNKNOWN_URI;
+}
- OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponse"));
- return ret;
+static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *query,
+ char **filterOne, char **filterTwo)
+{
+ if(!filterOne || !filterTwo)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ *filterOne = NULL;
+ *filterTwo = NULL;
+
+ #ifdef WITH_PRESENCE
+ if (uri == OC_PRESENCE)
+ {
+ //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
+
+ OCStackResult result = OC_STACK_OK;
+
+ if (query && *query)
+ {
+ result = ExtractFiltersFromQuery(query, filterOne, filterTwo);
+ }
+
+ return result;
}
-OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
- char *out, uint16_t *remaining)
+OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
+ OCRepPayload** payload)
{
- OCStackResult ret = OC_STACK_ERROR;
+ OCRepPayload *tempPayload = OCRepPayloadCreate();
- if (savedDeviceInfo != NULL)
+ if (!resourcePtr)
{
- char *jsonStr = NULL;
- uint16_t jsonLen = 0;
- cJSON *repObj = cJSON_GetObjectItem(savedDeviceInfo, "rep");
+ OCRepPayloadDestroy(tempPayload);
+ return OC_STACK_INVALID_PARAM;
+ }
- OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponseForDevice"));
+ if(!tempPayload)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
- if (filterOn == STACK_DEVICE_DISCOVERY_DI_FILTER)
- {
- if((cJSON_GetObjectItem(repObj,"di") != NULL) &&
- strcmp(cJSON_GetObjectItem(repObj,"di")->valuestring, filterValue) == 0)
- {
- ret = OC_STACK_OK;
- }
- }
- else if (filterOn == STACK_DEVICE_DISCOVERY_DN_FILTER)
- {
- if((cJSON_GetObjectItem(repObj,"dn") != NULL) &&
- strcmp(cJSON_GetObjectItem(repObj,"dn")->valuestring, filterValue) == 0)
- {
- ret = OC_STACK_OK;
- }
- }
- else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
- {
- ret = OC_STACK_OK;
- }
- else
- {
- ret = OC_STACK_INVALID_QUERY;
- }
+ OCRepPayloadSetUri(tempPayload, resourcePtr->uri);
- if (ret == OC_STACK_OK)
- {
- jsonStr = cJSON_PrintUnformatted (savedDeviceInfo);
+ OCResourceType *resType = resourcePtr->rsrcType;
+ while(resType)
+ {
+ OCRepPayloadAddResourceType(tempPayload, resType->resourcetypename);
+ resType = resType->next;
+ }
- if(jsonStr)
- {
- jsonLen = strlen(jsonStr);
+ OCResourceInterface *resInterface = resourcePtr->rsrcInterface;
+ while(resInterface)
+ {
+ OCRepPayloadAddInterface(tempPayload, resInterface->name);
+ resInterface = resInterface->next;
+ }
- if (jsonLen < *remaining)
- {
- strncpy(out, jsonStr, (jsonLen + 1));
- *remaining = *remaining - jsonLen;
- ret = OC_STACK_OK;
- }
- else
- {
- ret = OC_STACK_ERROR;
- }
+ OCAttribute *resAttrib = resourcePtr->rsrcAttributes;
+ while(resAttrib)
+ {
+ OCRepPayloadSetPropString(tempPayload, resAttrib->attrName,
+ resAttrib->attrValue);
+ resAttrib = resAttrib->next;
+ }
- free(jsonStr);
- }
- else
- {
- ret = OC_STACK_ERROR;
- }
- }
- else
- {
- ret = OC_STACK_INVALID_DEVICE_INFO;
- }
+ if(!*payload)
+ {
+ *payload = tempPayload;
}
else
{
- //error so that stack won't respond with empty payload
- ret = OC_STACK_INVALID_DEVICE_INFO;
+ OCRepPayloadAppend(*payload, tempPayload);
}
- OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponseForDevice"));
- return ret;
+ return OC_STACK_OK;
}
-TODO ("Does it make sense to make this method as inline")
-const char * GetVirtualResourceUri( OCVirtualResources resource)
+OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
+ OCDiscoveryPayload *payload, OCDevAddr *devAddr)
{
- if (resource < OC_MAX_VIRTUAL_RESOURCES)
+ if (!resourcePtr || !payload)
{
- return VIRTUAL_RSRCS[resource];
+ return OC_STACK_INVALID_PARAM;
+ }
+ uint16_t port = 0;
+ if (resourcePtr->resourceProperties & OC_SECURE)
+ {
+ if (GetSecurePortInfo(devAddr, &port) != OC_STACK_OK)
+ {
+ port = 0;
+ }
}
- return NULL;
+ OCDiscoveryPayloadAddResource(payload, resourcePtr, port);
+ return OC_STACK_OK;
}
-uint8_t IsVirtualResource(const char* resourceUri)
+
+uint8_t IsCollectionResource (OCResource *resource)
{
- for (int i = 0; i < OC_MAX_VIRTUAL_RESOURCES; i++)
+ if(!resource)
{
- if (strcmp(resourceUri, GetVirtualResourceUri((OCVirtualResources)i)) == 0)
- {
- return 1;
- }
+ return 0;
}
- return 0;
-}
-uint8_t IsCollectionResource (OCResource *resource)
-{
for (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
{
if (resource->rsrcResources[i])
OCResource *FindResourceByUri(const char* resourceUri)
{
+ if(!resourceUri)
+ {
+ return NULL;
+ }
+
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;
}
-OCStackResult DetermineResourceHandling (OCServerRequest *request,
+OCStackResult DetermineResourceHandling (const OCServerRequest *request,
ResourceHandling *handling,
OCResource **resource)
{
+ if(!request || !handling || !resource)
+ {
+ 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;
- return OC_STACK_OK;
+ return OC_STACK_NO_RESOURCE;
}
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(INFO, TAG, PCF("Un-authorized request. Ignore it!"));
- return OC_STACK_RESOURCE_ERROR;
- }
-
if (IsCollectionResource (resourcePtr))
{
// Collection resource
{
*handling = OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER;
return OC_STACK_OK;
- } else {
+ }
+ else
+ {
*handling = OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER;
return OC_STACK_OK;
}
- } else {
+ }
+ else
+ {
// Resource not a collection
if (resourcePtr->entityHandler != defaultResourceEHandler)
{
*handling = OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER;
return OC_STACK_OK;
- } else {
+ }
+ else
+ {
*handling = OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER;
return OC_STACK_OK;
}
case OC_EH_RESOURCE_DELETED:
result = OC_STACK_RESOURCE_DELETED;
break;
+ case OC_EH_RESOURCE_NOT_FOUND:
+ result = OC_STACK_NO_RESOURCE;
+ break;
default:
result = OC_STACK_ERROR;
}
return result;
}
-static OCStackResult
-HandleVirtualResource (OCServerRequest *request, OCResource* resource)
+static bool resourceMatchesRTFilter(OCResource *resource, char *resourceTypeFilter)
{
- OCStackResult result = OC_STACK_ERROR;
- char *filterValue = NULL;
- uint8_t filterOn = 0;
- uint16_t remaining = 0;
- unsigned char * ptr = NULL;
- uint8_t firstLoopDone = 0;
- unsigned char discoveryResBuf[MAX_RESPONSE_LENGTH] = {0};
+ if (!resource)
+ {
+ return false;
+ }
- OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
+ // Null or empty is analogous to no filter.
+ if (resourceTypeFilter == NULL || *resourceTypeFilter == 0)
+ {
+ return true;
+ }
- result = ValidateUrlQuery (request->resourceUrl,
- request->query, &filterOn,
- &filterValue);
+ OCResourceType *resourceTypePtr = resource->rsrcType;
- if (result == OC_STACK_OK)
+ while (resourceTypePtr)
{
- if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0)
+ if (strcmp (resourceTypePtr->resourcetypename, resourceTypeFilter) == 0)
{
- ptr = discoveryResBuf;
- remaining = MAX_RESPONSE_LENGTH;
+ 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;
+ }
- while(resource)
+ // 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 discoveryResult = OC_STACK_ERROR;
+
+ bool bMulticast = false; // Was the discovery request a multicast request?
+ OCPayload* payload = NULL;
+
+ OC_LOG(INFO, TAG, "Entering HandleVirtualResource");
+
+ OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
+
+ // Step 1: Generate the response to discovery request
+ if (virtualUriInRequest == OC_WELL_KNOWN_URI)
+ {
+ char *filterOne = NULL;
+ char *filterTwo = NULL;
+
+ discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
+ &filterOne, &filterTwo);
+
+ if (discoveryResult == OC_STACK_OK)
+ {
+ payload = (OCPayload*)OCDiscoveryPayloadCreate();
+
+ 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))
+ if(includeThisResourceInResponse(resource, filterOne, filterTwo))
{
- *ptr = OC_JSON_SEPARATOR;
- ptr++;
- remaining--;
+ discoveryResult = BuildVirtualResourceResponse(resource,
+ (OCDiscoveryPayload*)payload,
+ &request->devAddr);
}
- firstLoopDone = 1;
-#ifdef CA_INT
- result = BuildVirtualResourceResponse(resource, filterOn, filterValue,
- (char*)ptr, &remaining, request->connectivityType );
-#else
- result = BuildVirtualResourceResponse(resource, filterOn, filterValue,
- (char*)ptr, &remaining);
-#endif
-
- if (result != OC_STACK_OK)
- {
- // if this failed, we need to remove the comma added above.
- if(!firstLoopDone)
- {
- ptr--;
- *ptr = '\0';
- remaining++;
- }
- break;
- }
- ptr += strlen((char *)ptr);
- *(ptr + 1) = '\0';
}
- 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 = {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_NO_MEMORY;
}
}
- else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
+ else
+ {
+ OC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
+ }
+ }
+ else if (virtualUriInRequest == OC_DEVICE_URI)
+ {
+ const OicUuid_t* deviceId = OCGetServerInstanceID();
+ if (!deviceId)
{
- remaining = MAX_RESPONSE_LENGTH;
- ptr = discoveryResBuf;
-
- result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
- (char*)ptr, &remaining);
-
- if(result == OC_STACK_OK)
+ 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};
+ discoveryResult = OC_STACK_OK;
+ }
+ }
+ }
+ else if (virtualUriInRequest == OC_PLATFORM_URI)
+ {
+ payload = (OCPayload*)OCPlatformPayloadCreate(
+ OC_RSRVD_PLATFORM_URI,
+ &savedPlatformInfo);
+ if (!payload)
+ {
+ 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);
- 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;
+ }
+#endif
- result = OCDoResponse(&response);
- }
+ /**
+ * 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_VIRTUAL_DO_NOT_HANDLE;
- return result;
+
+ OCPayloadDestroy(payload);
+
+ return OC_STACK_OK;
}
static OCStackResult
HandleDefaultDeviceEntityHandler (OCServerRequest *request)
{
+ if(!request)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
OCStackResult result = OC_STACK_OK;
OCEntityHandlerResult ehResult = OC_EH_ERROR;
OCEntityHandlerRequest ehRequest = {0};
- 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);
+ 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;
}
OCResource *resource,
uint8_t collectionResource)
{
+ if(!request || ! resource)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
OCStackResult result = OC_STACK_ERROR;
OCEntityHandlerResult ehResult = OC_EH_ERROR;
OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
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);
-#ifdef CA_INT
- result = AddCAObserver ((const char*)(request->resourceUrl),
- (const char *)(request->query),
- ehRequest.obsInfo.obsId, &request->requestToken,
- &request->requesterAddr, resource, request->qos,
- &request->addressInfo, request->connectivityType,
- request->token);
-#else
+
result = AddObserver ((const char*)(request->resourceUrl),
(const char *)(request->query),
- ehRequest.obsInfo.obsId, &request->requestToken,
- &request->requesterAddr, resource, request->qos);
-#endif //CA_INT
+ ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
+ resource, request->qos, request->acceptFormat,
+ &request->devAddr);
+
if(result == OC_STACK_OK)
{
- OC_LOG(DEBUG, 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.
request->observeResult = OC_STACK_ERROR;
- OC_LOG(DEBUG, 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"));
- #ifdef CA_INT
- resObs = GetObserverUsingToken (request->token);
- #else
- resObs = GetObserverUsingToken (&request->requestToken);
- #endif
+ OC_LOG(INFO, TAG, "Deregistering observation requested");
+
+ resObs = GetObserverUsingToken (request->requestToken, request->tokenLength);
+
if (NULL == resObs)
{
// Stack does not contain this observation request
ehRequest.obsInfo.obsId = resObs->observeId;
ehFlag = (OCEntityHandlerFlag)(ehFlag | OC_OBSERVE_FLAG);
- #ifdef CA_INT
- resObs = GetObserverUsingToken (request->token);
- #else
- result = DeleteObserverUsingToken (&request->requestToken);
- #endif
+ result = DeleteObserverUsingToken (request->requestToken, request->tokenLength);
+
if(result == OC_STACK_OK)
{
- OC_LOG(DEBUG, 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(DEBUG, 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;
}
HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
OCResource *resource)
{
+ if(!request || !resource)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
OCStackResult result = OC_STACK_ERROR;
OCEntityHandlerRequest ehRequest = {0};
- 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)
+ 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, "rep", repObj = cJSON_CreateObject());
+ OICFree(savedPlatformInfo.modelNumber);
+ savedPlatformInfo.modelNumber = NULL;
- if (deviceInfo.contentType)
- {
- cJSON_AddItemToObject (repObj, "ct",
- cJSON_CreateString(deviceInfo.contentType));
- }
+ OICFree(savedPlatformInfo.dateOfManufacture);
+ savedPlatformInfo.dateOfManufacture = NULL;
- if (deviceInfo.dateOfManufacture)
- {
- cJSON_AddItemToObject (repObj, "mndt",
- cJSON_CreateString(deviceInfo.dateOfManufacture));
- }
+ OICFree(savedPlatformInfo.platformVersion);
+ savedPlatformInfo.platformVersion = NULL;
- if (deviceInfo.deviceName)
- {
- cJSON_AddItemToObject (repObj, "dn",
- cJSON_CreateString(deviceInfo.deviceName));
- }
+ OICFree(savedPlatformInfo.operatingSystemVersion);
+ savedPlatformInfo.operatingSystemVersion = NULL;
- if (deviceInfo.deviceUUID)
- {
- cJSON_AddItemToObject (repObj, "di",
- cJSON_CreateString(deviceInfo.deviceUUID));
- }
+ OICFree(savedPlatformInfo.hardwareVersion);
+ savedPlatformInfo.hardwareVersion = NULL;
- if (deviceInfo.firmwareVersion)
- {
- cJSON_AddItemToObject (repObj, "mnfv",
- cJSON_CreateString(deviceInfo.firmwareVersion));
- }
+ OICFree(savedPlatformInfo.firmwareVersion);
+ savedPlatformInfo.firmwareVersion = NULL;
+
+ OICFree(savedPlatformInfo.supportUrl);
+ savedPlatformInfo.supportUrl = NULL;
- if (deviceInfo.hostName)
+ OICFree(savedPlatformInfo.systemTime);
+ savedPlatformInfo.systemTime = NULL;
+}
+
+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, "hn", 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, "mnmn",
- 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, "mnml",
- cJSON_CreateString(deviceInfo.manufacturerUrl));
- }
+ OCStackResult res = DeepCopyPlatFormInfo(info);
- if (deviceInfo.modelNumber)
+ if (res != OC_STACK_OK)
{
- cJSON_AddItemToObject (repObj, "mnmo",
- cJSON_CreateString(deviceInfo.modelNumber));
+ OC_LOG_V(ERROR, TAG, "Failed to save platform info. errno(%d)", res);
}
-
- if (deviceInfo.platformVersion)
+ else
{
- cJSON_AddItemToObject (repObj, "mnpv",
- 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, "mnsl",
- 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, "icv",
- 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;
+}