#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"
#include "ocpayload.h"
+#include "oickeepalive.h"
#include "platform_features.h"
#include "payload_logging.h"
#ifdef ROUTING_GATEWAY
#include "routingmanager.h"
#endif
-#ifdef RD_SERVER
-#include "rd_database.h"
-#endif
-
/// Module Name
#define TAG "OIC_RI_RESOURCE"
* 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)
+OCStackResult ExtractFiltersFromQuery(const char *query, char **filterOne, char **filterTwo)
{
+ if (!query)
+ {
+ OIC_LOG_V(ERROR, TAG, "Query is empty!");
+ return OC_STACK_INVALID_QUERY;
+ }
char *key = NULL;
char *value = NULL;
char *queryDup = NULL;
*filterOne = NULL;
*filterTwo = NULL;
- #ifdef WITH_PRESENCE
+#ifdef WITH_PRESENCE
if (uri == OC_PRESENCE)
{
//Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
OIC_LOG(INFO, TAG, "OC_PRESENCE Request for virtual resource.");
return OC_STACK_OK;
}
- #endif
+#endif
OCStackResult result = OC_STACK_OK;
return false;
}
-OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
- OCRepPayload** payload, OCDevAddr *devAddr, bool addDeviceId)
+static OCStackResult BuildDevicePlatformPayload(const OCResource *resourcePtr, OCRepPayload** payload, bool addDeviceId)
{
- OCRepPayload *tempPayload = OCRepPayloadCreate();
-
if (!resourcePtr)
{
- OCRepPayloadDestroy(tempPayload);
return OC_STACK_INVALID_PARAM;
}
- if(!tempPayload)
+ OCRepPayload *tempPayload = OCRepPayloadCreate();
+ if (!tempPayload)
{
return OC_STACK_NO_MEMORY;
}
- OCRepPayloadSetUri(tempPayload, resourcePtr->uri);
if (addDeviceId)
{
const char *deviceId = OCGetServerInstanceIDString();
}
OCRepPayloadSetPropString(tempPayload, OC_RSRVD_DEVICE_ID, deviceId);
}
+
OCResourceType *resType = resourcePtr->rsrcType;
while(resType)
{
resAttrib = resAttrib->next;
}
+ if(!*payload)
+ {
+ *payload = tempPayload;
+ }
+ else
+ {
+ OCRepPayloadAppend(*payload, tempPayload);
+ }
+
+ return OC_STACK_OK;
+}
+
+OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
+ OCRepPayload** payload, OCDevAddr *devAddr)
+{
+ OCRepPayload *tempPayload = OCRepPayloadCreate();
+
+ if (!resourcePtr)
+ {
+ OCRepPayloadDestroy(tempPayload);
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if(!tempPayload)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+
+ OCRepPayloadSetPropString(tempPayload, OC_RSRVD_HREF, resourcePtr->uri);
+
+ uint8_t numElement = 0;
+ if (OC_STACK_OK == OCGetNumberOfResourceTypes((OCResource *)resourcePtr, &numElement))
+ {
+ size_t rtDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
+ char **rt = (char **)OICMalloc(sizeof(char *) * numElement);
+ for (uint8_t i = 0; i < numElement; ++i)
+ {
+ const char *value = OCGetResourceTypeName((OCResource *)resourcePtr, i);
+ OIC_LOG_V(DEBUG, TAG, "value: %s", value);
+ rt[i] = OICStrdup(value);
+ }
+ OCRepPayloadSetStringArrayAsOwner(tempPayload, OC_RSRVD_RESOURCE_TYPE, rt, rtDim);
+ }
+
+ numElement = 0;
+ if (OC_STACK_OK == OCGetNumberOfResourceInterfaces((OCResource *)resourcePtr, &numElement))
+ {
+ size_t ifDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
+ char **itf = (char **)OICMalloc(sizeof(char *) * numElement);
+ for (uint8_t i = 0; i < numElement; ++i)
+ {
+ const char *value = OCGetResourceInterfaceName((OCResource *)resourcePtr, i);
+ OIC_LOG_V(DEBUG, TAG, "value: %s", value);
+ itf[i] = OICStrdup(value);
+ }
+ OCRepPayloadSetStringArrayAsOwner(tempPayload, OC_RSRVD_INTERFACE, itf, ifDim);
+ }
+
+ for (OCAttribute *resAttrib = resourcePtr->rsrcAttributes; resAttrib; resAttrib = resAttrib->next)
+ {
+ if (resAttrib->attrName && resAttrib->attrValue)
+ {
+ if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, resAttrib->attrName))
+ {
+ char *dmv = OCCreateString((OCStringLL *)resAttrib->attrValue);
+ if (dmv)
+ {
+ OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, dmv);
+ OICFree(dmv);
+ }
+ }
+ else
+ {
+ OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, (char *)resAttrib->attrValue);
+ }
+ }
+ }
+
if (devAddr)
{
OCResourceProperty p = OCGetResourceProperties((OCResourceHandle *)resourcePtr);
OCRepPayloadSetPropObjectAsOwner(tempPayload, OC_RSRVD_POLICY, policy);
}
- if(!*payload)
+ if (!*payload)
{
*payload = tempPayload;
}
return OC_STACK_OK;
}
-uint8_t IsCollectionResource (OCResource *resource)
-{
- if(!resource)
- {
- return 0;
- }
-
- if(resource->rsrcChildResourcesHead != NULL)
- {
- return 1;
- }
-
- return 0;
-}
-
OCResource *FindResourceByUri(const char* resourceUri)
{
if(!resourceUri)
return NULL;
}
-
OCStackResult DetermineResourceHandling (const OCServerRequest *request,
ResourceHandling *handling,
OCResource **resource)
return OC_STACK_NO_RESOURCE;
}
- if (IsCollectionResource (resourcePtr))
+ if (resourcePtr && resourcePtr->rsrcChildResourcesHead != NULL)
{
// Collection resource
if (resourcePtr->entityHandler != defaultResourceEHandler)
return true;
}
- OCResourceType *resourceTypePtr = resource->rsrcType;
-
- while (resourceTypePtr)
+ for (OCResourceType *rtPtr = resource->rsrcType; rtPtr; rtPtr = rtPtr->next)
{
- if (strcmp (resourceTypePtr->resourcetypename, resourceTypeFilter) == 0)
+ if (0 == strcmp(rtPtr->resourcetypename, resourceTypeFilter))
{
return true;
}
- resourceTypePtr = resourceTypePtr->next;
}
OIC_LOG_V(INFO, TAG, "%s does not contain rt=%s.", resource->uri, resourceTypeFilter);
return true;
}
- OCResourceInterface *interfacePtr = resource->rsrcInterface;
-
- while (interfacePtr)
+ for (OCResourceInterface *ifPtr = resource->rsrcInterface; ifPtr; ifPtr = ifPtr->next)
{
- if (strcmp (interfacePtr->name, interfaceFilter) == 0 ||
- strcmp (OC_RSRVD_INTERFACE_LL, interfaceFilter) == 0 ||
- strcmp (OC_RSRVD_INTERFACE_DEFAULT, interfaceFilter) == 0)
+ if (0 == strcmp(ifPtr->name, interfaceFilter) ||
+ 0 == strcmp(OC_RSRVD_INTERFACE_LL, interfaceFilter) ||
+ 0 == strcmp(OC_RSRVD_INTERFACE_DEFAULT, interfaceFilter))
{
return true;
}
- interfacePtr = interfacePtr->next;
}
OIC_LOG_V(INFO, TAG, "%s does not contain if=%s.", resource->uri, interfaceFilter);
*/
if (!(resourceTypeFilter && *resourceTypeFilter))
{
- OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE \
+ OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE\
resource", resource->uri);
return false;
}
}
- else if ( !(resource->resourceProperties & OC_ACTIVE) ||
+ else if (!(resource->resourceProperties & OC_ACTIVE) ||
!(resource->resourceProperties & OC_DISCOVERABLE))
{
OIC_LOG_V(INFO, TAG, "%s not ACTIVE or DISCOVERABLE", resource->uri);
return resourceMatchesIFFilter(resource, interfaceFilter) &&
resourceMatchesRTFilter(resource, resourceTypeFilter);
-
}
OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCResource *resource,
return OCDoResponse(&response);
}
+
+static OCStackResult EHRequest(OCEntityHandlerRequest *ehRequest, OCPayloadType type,
+ OCServerRequest *request, OCResource *resource)
+{
+ return FormOCEntityHandlerRequest(ehRequest,
+ (OCRequestHandle)request->requestId,
+ request->method,
+ &request->devAddr,
+ (OCResourceHandle)resource,
+ request->query,
+ type,
+ request->payload,
+ request->payloadSize,
+ request->numRcvdVendorSpecificHeaderOptions,
+ request->rcvdVendorSpecificHeaderOptions,
+ (OCObserveAction)request->observationOption,
+ (OCObservationId)0,
+ request->coapID);
+}
+
#ifdef RD_SERVER
/**
* Find resource at the resource directory server. This resource is not local resource but a
#endif
)
{
- discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
+ discoveryResult = getQueryParamsForFiltering(virtualUriInRequest, request->query,
&interfaceQuery, &resourceTypeQuery);
VERIFY_SUCCESS(discoveryResult);
if (!interfaceQuery && !resourceTypeQuery)
{
OCResource *resourcePtr = FindResourceByUri(OC_RSRVD_DEVICE_URI);
VERIFY_PARAM_NON_NULL(TAG, resourcePtr, "Device URI not found.");
- discoveryResult = BuildResponseRepresentation(resourcePtr, (OCRepPayload **)&payload, NULL, true);
-
+ discoveryResult = BuildDevicePlatformPayload(resourcePtr, (OCRepPayload **)&payload, true);
}
else if (virtualUriInRequest == OC_PLATFORM_URI)
{
OCResource *resourcePtr = FindResourceByUri(OC_RSRVD_PLATFORM_URI);
VERIFY_PARAM_NON_NULL(TAG, resourcePtr, "Platform URI not found.");
- discoveryResult = BuildResponseRepresentation(resourcePtr, (OCRepPayload **)&payload, NULL, false);
+ discoveryResult = BuildDevicePlatformPayload(resourcePtr, (OCRepPayload **)&payload, false);
}
#ifdef ROUTING_GATEWAY
else if (OC_GATEWAY_URI == virtualUriInRequest)
}
static OCStackResult
-HandleDefaultDeviceEntityHandler (OCServerRequest *request)
+HandleDefaultDeviceEntityHandler(OCServerRequest *request)
{
- if(!request)
+ if (!request)
{
return OC_STACK_INVALID_PARAM;
}
- OCStackResult result = OC_STACK_OK;
OCEntityHandlerResult ehResult = OC_EH_ERROR;
OCEntityHandlerRequest ehRequest = {0};
-
OIC_LOG(INFO, TAG, "Entering HandleResourceWithDefaultDeviceEntityHandler");
- result = FormOCEntityHandlerRequest(&ehRequest,
- (OCRequestHandle) request->requestId,
- request->method,
- &request->devAddr,
- (OCResourceHandle) NULL, request->query,
- PAYLOAD_TYPE_REPRESENTATION,
- request->payload,
- request->payloadSize,
- request->numRcvdVendorSpecificHeaderOptions,
- request->rcvdVendorSpecificHeaderOptions,
- (OCObserveAction)request->observationOption,
- (OCObservationId)0,
- request->coapID);
+ OCStackResult result = EHRequest(&ehRequest, PAYLOAD_TYPE_REPRESENTATION, request, NULL);
VERIFY_SUCCESS(result);
// At this point we know for sure that defaultDeviceHandler exists
}
static OCStackResult
-HandleResourceWithEntityHandler (OCServerRequest *request,
- OCResource *resource,
- uint8_t collectionResource)
+HandleResourceWithEntityHandler(OCServerRequest *request,
+ OCResource *resource)
{
- OC_UNUSED(collectionResource);
-
if(!request || ! resource)
{
return OC_STACK_INVALID_PARAM;
type = PAYLOAD_TYPE_SECURITY;
}
- result = FormOCEntityHandlerRequest(&ehRequest,
- (OCRequestHandle)request->requestId,
- request->method,
- &request->devAddr,
- (OCResourceHandle)resource,
- request->query,
- type,
- request->payload,
- request->payloadSize,
- request->numRcvdVendorSpecificHeaderOptions,
- request->rcvdVendorSpecificHeaderOptions,
- (OCObserveAction)request->observationOption,
- 0,
- request->coapID);
+ result = EHRequest(&ehRequest, type, request, resource);
VERIFY_SUCCESS(result);
if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
return result;
}
-static OCStackResult
-HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
- OCResource *resource)
+static OCStackResult HandleCollectionResourceDefaultEntityHandler(OCServerRequest *request,
+ OCResource *resource)
{
- if(!request || !resource)
+ if (!request || !resource)
{
return OC_STACK_INVALID_PARAM;
}
- OCStackResult result = OC_STACK_ERROR;
OCEntityHandlerRequest ehRequest = {0};
-
- result = FormOCEntityHandlerRequest(&ehRequest,
- (OCRequestHandle)request->requestId,
- request->method,
- &request->devAddr,
- (OCResourceHandle)resource,
- request->query,
- PAYLOAD_TYPE_REPRESENTATION,
- request->payload,
- request->payloadSize,
- request->numRcvdVendorSpecificHeaderOptions,
- request->rcvdVendorSpecificHeaderOptions,
- (OCObserveAction)request->observationOption,
- (OCObservationId)0,
- request->coapID);
+ OCStackResult result = EHRequest(&ehRequest, PAYLOAD_TYPE_REPRESENTATION, request, resource);
if(result == OC_STACK_OK)
{
result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest);
}
case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
{
- ret = HandleResourceWithEntityHandler (request, resource, 0);
+ ret = HandleResourceWithEntityHandler (request, resource);
break;
}
case OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER:
{
- ret = HandleResourceWithEntityHandler (request, resource, 1);
+ ret = HandleResourceWithEntityHandler (request, resource);
break;
}
case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER:
{
dataModelVersion = OCCreateOCStringLL(OC_DATA_MODEL_VERSION);
VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION, dataModelVersion));
+ OCFreeOCStringLL(dataModelVersion);
}
OIC_LOG(INFO, TAG, "Device parameter initialized successfully.");
return OC_STACK_OK;
OCStackResult OCSetAttribute(OCResource* resource, const char* attribute, const void* value)
{
- OCAttribute *resAttrib = (OCAttribute *)OICCalloc(1, sizeof(OCAttribute));
- VERIFY_PARAM_NON_NULL(TAG, resAttrib, "Failed allocation OCAttribute");
- resAttrib->attrName = OICStrdup(attribute);
- VERIFY_PARAM_NON_NULL(TAG, resAttrib->attrName, "Failed allocating attribute name");
- // A special case when value is of type OCStringLL
- if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, attribute))
+ // See if the attribute already exists in the list.
+ OCAttribute *resAttrib = NULL;
+ for (resAttrib = resource->rsrcAttributes; resAttrib; resAttrib = resAttrib->next)
{
- resAttrib->attrValue = CloneOCStringLL((OCStringLL *)value);
+ if (0 == strcmp(attribute, resAttrib->attrName))
+ {
+ // Found, free the old value.
+ if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, resAttrib->attrName))
+ {
+ OCFreeOCStringLL((OCStringLL *)resAttrib->attrValue);
+ }
+ else
+ {
+ OICFree((char *)resAttrib->attrValue);
+ }
+ break;
+ }
}
- else
+
+ // If not already in the list, add it.
+ if (NULL == resAttrib)
{
- resAttrib->attrValue = OICStrdup((char *)value);
+ resAttrib = (OCAttribute *)OICCalloc(1, sizeof(OCAttribute));
+ VERIFY_PARAM_NON_NULL(TAG, resAttrib, "Failed allocating OCAttribute");
+ resAttrib->attrName = OICStrdup(attribute);
+ VERIFY_PARAM_NON_NULL(TAG, resAttrib->attrName, "Failed allocating attribute name");
+ resAttrib->next = resource->rsrcAttributes;
+ resource->rsrcAttributes = resAttrib;
}
- VERIFY_PARAM_NON_NULL(TAG, resAttrib->attrValue, "Failed allocating attribute value");
- resAttrib->next = NULL;
- if (!resource->rsrcAttributes)
+ // Fill in the new value.
+ if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, attribute))
{
- resource->rsrcAttributes = resAttrib;
+ resAttrib->attrValue = CloneOCStringLL((OCStringLL *)value);
}
else
{
- OCAttribute *temp = resource->rsrcAttributes;
- for (; temp->next; temp = temp->next)
- {
- if (0 == strcmp(attribute, temp->attrName))
- {
- if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, temp->attrName))
- {
- OCFreeOCStringLL((OCStringLL *)temp->attrValue);
- }
- {
- OICFree((char *)temp->attrValue);
- }
- break;
- }
- }
- temp->next = resAttrib;
+ resAttrib->attrValue = OICStrdup((char *)value);
}
+ VERIFY_PARAM_NON_NULL(TAG, resAttrib->attrValue, "Failed allocating attribute value");
+
return OC_STACK_OK;
exit:
OCStackResult OCSetPropertyValue(OCPayloadType type, const char *prop, const void *value)
{
- if (!prop)
+ if (!prop || !value)
{
return OC_STACK_INVALID_PARAM;
}
{
OIC_LOG(ERROR, TAG, "Resource does not exist.");
}
- if (value)
+ else
{
res = OCSetAttribute(resource, prop, value);
}