#define _GNU_SOURCE
#endif
+#include "iotivity_config.h"
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#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 "oickeepaliveinternal.h"
+#include "platform_features.h"
+#include "payload_logging.h"
#ifdef ROUTING_GATEWAY
#include "routingmanager.h"
#endif
/// Module Name
#define TAG "OIC_RI_RESOURCE"
-#define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
+#define VERIFY_SUCCESS(op) { if (op != (OC_STACK_OK)) \
{OIC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
-#define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \
- TAG, #arg " is NULL"); return (retVal); } }
-
-#include "platform_features.h"
-
extern OCResource *headResource;
-static OCPlatformInfo savedPlatformInfo = {0};
-static OCDeviceInfo savedDeviceInfo = {0};
/**
* Prepares a Payload for response.
*/
static OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
OCDiscoveryPayload* payload,
- OCDevAddr *endpoint,
- bool rdResponse);
+ OCDevAddr *endpoint);
//-----------------------------------------------------------------------------
// Default resource entity handler function
#ifdef TCP_ADAPTER
/* This method will retrieve the tcp port */
-static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port)
+static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port, bool secured)
{
uint16_t p = 0;
{
if (endpoint->flags & OC_IP_USE_V4)
{
- p = caglobals.tcp.ipv4.port;
+ p = secured ? caglobals.tcp.ipv4s.port : caglobals.tcp.ipv4.port;
}
else if (endpoint->flags & OC_IP_USE_V6)
{
- p = caglobals.tcp.ipv6.port;
+ p = secured ? caglobals.tcp.ipv6s.port : caglobals.tcp.ipv6.port;
}
}
* 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;
char *restOfQuery = NULL;
+ char *keyValuePair = NULL;
int numKeyValuePairsParsed = 0;
*filterOne = NULL;
*filterTwo = NULL;
- OIC_LOG_V(INFO, TAG, "Extracting params from %s", query);
+ queryDup = OICStrdup(query);
+ if (NULL == queryDup)
+ {
+ OIC_LOG_V(ERROR, TAG, "Creating duplicate string failed!");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ OIC_LOG_V(INFO, TAG, "Extracting params from %s", queryDup);
- if (strnlen(query, MAX_QUERY_LENGTH) >= MAX_QUERY_LENGTH)
+ OCStackResult eCode = OC_STACK_INVALID_QUERY;
+ if (strnlen(queryDup, MAX_QUERY_LENGTH) >= MAX_QUERY_LENGTH)
{
OIC_LOG(ERROR, TAG, "Query exceeds maximum length.");
- return OC_STACK_INVALID_QUERY;
+ goto exit;
}
- char *keyValuePair = strtok_r (query, OC_QUERY_SEPARATOR, &restOfQuery);
+ keyValuePair = strtok_r (queryDup, OC_QUERY_SEPARATOR, &restOfQuery);
while(keyValuePair)
{
if (numKeyValuePairsParsed >= 2)
{
OIC_LOG(ERROR, TAG, "More than 2 queries params in URI.");
- return OC_STACK_INVALID_QUERY;
+ goto exit;
}
key = strtok_r(keyValuePair, OC_KEY_VALUE_DELIMITER, &value);
if (!key || !value)
{
- return OC_STACK_INVALID_QUERY;
+ goto exit;
}
else if (strncasecmp(key, OC_RSRVD_INTERFACE, sizeof(OC_RSRVD_INTERFACE) - 1) == 0)
{
else
{
OIC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
- return OC_STACK_INVALID_QUERY;
+ goto exit;
}
++numKeyValuePairsParsed;
keyValuePair = strtok_r(NULL, OC_QUERY_SEPARATOR, &restOfQuery);
}
+ if (*filterOne)
+ {
+ *filterOne = OICStrdup(*filterOne);
+ if (NULL == *filterOne)
+ {
+ OIC_LOG_V(ERROR, TAG, "Creating duplicate string failed!");
+ eCode = OC_STACK_NO_MEMORY;
+ goto exit;
+ }
+ }
+
+ if (*filterTwo)
+ {
+ *filterTwo = OICStrdup(*filterTwo);
+ if (NULL == *filterTwo)
+ {
+ OIC_LOG_V(ERROR, TAG, "Creating duplicate string failed!");
+ OICFree(*filterOne);
+ eCode = OC_STACK_NO_MEMORY;
+ goto exit;
+ }
+ }
+
+ OICFree(queryDup);
OIC_LOG_V(INFO, TAG, "Extracted params if: %s and rt: %s.", *filterOne, *filterTwo);
return OC_STACK_OK;
+
+exit:
+ *filterOne = NULL;
+ *filterTwo = NULL;
+ OICFree(queryDup);
+ return eCode;
}
static OCVirtualResources GetTypeOfVirtualURI(const char *uriInRequest)
return OC_MQ_BROKER_URI;
}
#endif //MQ_BROKER
+
+#ifdef TCP_ADAPTER
+ else if (strcmp(uriInRequest, OC_RSRVD_KEEPALIVE_URI) == 0)
+ {
+ return OC_KEEPALIVE_RESOURCE_URI;
+ }
+#endif
+
return OC_UNKNOWN_URI;
}
*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 result;
}
-OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
- OCRepPayload** payload)
+bool appendOCStringLL(OCRepPayload *device, OCStringLL *dmv)
{
- OCRepPayload *tempPayload = OCRepPayloadCreate();
+ int size = 0;
+ for (OCStringLL *ll = dmv; ll; ll = ll->next, size++);
+ size_t dim[MAX_REP_ARRAY_DEPTH] = {size, 0, 0};
+ char **dt = (char **)OICMalloc(sizeof(char *) * size);
+ int i = 0;
+ VERIFY_PARAM_NON_NULL(TAG, dt, "Data Model Version allocation failed.");
+ for (OCStringLL *ll = dmv; ll; ll = ll->next, i++)
+ {
+ dt[i] = OICStrdup(ll->value);
+ VERIFY_PARAM_NON_NULL(TAG, dt[i], "Data Model Version adding failed.");
+ }
+ if (!OCRepPayloadSetStringArrayAsOwner(device, OC_RSRVD_DATA_MODEL_VERSION, dt, dim))
+ {
+ goto exit;
+ }
+ return true;
+exit:
+ for (int i = 0; i < size; i++)
+ {
+ OICFree(dt[i]);
+ }
+ OICFree(dt);
+ return false;
+}
+
+static OCStackResult BuildDevicePlatformPayload(const OCResource *resourcePtr, OCRepPayload** payload, bool addDeviceId)
+{
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();
+ if (!deviceId)
+ {
+ OIC_LOG(ERROR, TAG, "Failed retrieving device id.");
+ return OC_STACK_ERROR;
+ }
+ OCRepPayloadSetPropString(tempPayload, OC_RSRVD_DEVICE_ID, deviceId);
+ }
OCResourceType *resType = resourcePtr->rsrcType;
while(resType)
OCAttribute *resAttrib = resourcePtr->rsrcAttributes;
while(resAttrib)
{
- OCRepPayloadSetPropString(tempPayload, resAttrib->attrName,
- resAttrib->attrValue);
+ 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);
+ }
+ }
resAttrib = resAttrib->next;
}
return OC_STACK_OK;
}
-OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
- OCDiscoveryPayload *payload, OCDevAddr *devAddr, bool rdResponse)
+OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
+ OCRepPayload** payload, OCDevAddr *devAddr)
{
- if (!resourcePtr || !payload)
+ if (!resourcePtr)
{
return OC_STACK_INVALID_PARAM;
}
- uint16_t securePort = 0;
- if (resourcePtr->resourceProperties & OC_SECURE)
+
+ OCRepPayload *tempPayload = OCRepPayloadCreate();
+ if(!tempPayload)
{
- if (GetSecurePortInfo(devAddr, &securePort) != OC_STACK_OK)
- {
- securePort = 0;
- }
+ return OC_STACK_NO_MEMORY;
}
- if (rdResponse)
+ OCRepPayloadSetPropString(tempPayload, OC_RSRVD_HREF, resourcePtr->uri);
+
+ uint8_t numElement = 0;
+ if (OC_STACK_OK == OCGetNumberOfResourceTypes((OCResource *)resourcePtr, &numElement))
{
- securePort = devAddr->port;
+ size_t rtDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
+ char **rt = (char **)OICMalloc(sizeof(char *) * numElement);
+ if (!rt)
+ {
+ OIC_LOG(ERROR, TAG, "Resource type allocation failed.");
+ OCRepPayloadDestroy(tempPayload);
+ return OC_STACK_NO_MEMORY;
+ }
+ 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);
}
- uint16_t tcpPort = 0;
-#ifdef TCP_ADAPTER
- if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK)
+ numElement = 0;
+ if (OC_STACK_OK == OCGetNumberOfResourceInterfaces((OCResource *)resourcePtr, &numElement))
{
- tcpPort = 0;
+ size_t ifDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
+ char **itf = (char **)OICMalloc(sizeof(char *) * numElement);
+ if (!itf)
+ {
+ OIC_LOG(ERROR, TAG, "Resource interface allocation failed.");
+ OCRepPayloadDestroy(tempPayload);
+ return OC_STACK_NO_MEMORY;
+ }
+ 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);
+ OCRepPayload *policy = OCRepPayloadCreate();
+ if (!policy)
+ {
+ OCPayloadDestroy((OCPayload *)tempPayload);
+ return OC_STACK_NO_MEMORY;
+ }
+ OCRepPayloadSetPropInt(policy, OC_RSRVD_BITMAP, ((p & OC_DISCOVERABLE) | (p & OC_OBSERVABLE)));
+ if (p & OC_SECURE)
+ {
+ OCRepPayloadSetPropBool(policy, OC_RSRVD_SECURE, p & OC_SECURE);
+ uint16_t securePort = 0;
+ if (GetSecurePortInfo(devAddr, &securePort) != OC_STACK_OK)
+ {
+ securePort = 0;
+ }
+ OCRepPayloadSetPropInt(policy, OC_RSRVD_HOSTING_PORT, securePort);
+ }
+ OCRepPayloadSetPropObjectAsOwner(tempPayload, OC_RSRVD_POLICY, policy);
+ }
+
+ if (!*payload)
+ {
+ *payload = tempPayload;
+ }
+ else
+ {
+ OCRepPayloadAppend(*payload, tempPayload);
}
- OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort);
-#else
- OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort);
-#endif
return OC_STACK_OK;
}
-uint8_t IsCollectionResource (OCResource *resource)
+OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
+ OCDiscoveryPayload *payload, OCDevAddr *devAddr)
{
- if(!resource)
+ if (!resourcePtr || !payload)
{
- return 0;
+ return OC_STACK_INVALID_PARAM;
}
-
- if(resource->rsrcChildResourcesHead != NULL)
+ uint16_t securePort = 0;
+ if (resourcePtr->resourceProperties & OC_SECURE)
{
- return 1;
+ if (GetSecurePortInfo(devAddr, &securePort) != OC_STACK_OK)
+ {
+ securePort = 0;
+ }
}
- return 0;
+#ifdef TCP_ADAPTER
+ uint16_t tcpPort = 0;
+ GetTCPPortInfo(devAddr, &tcpPort, (resourcePtr->resourceProperties & OC_SECURE));
+
+ OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort);
+#else
+ OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort);
+#endif
+
+ return OC_STACK_OK;
}
OCResource *FindResourceByUri(const char* 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)
switch (ehResult)
{
case OC_EH_OK:
+ case OC_EH_CONTENT:
+ case OC_EH_VALID:
result = OC_STACK_OK;
break;
case OC_EH_SLOW:
result = OC_STACK_ERROR;
break;
case OC_EH_FORBIDDEN:
- result = OC_STACK_RESOURCE_ERROR;
+ result = OC_STACK_FORBIDDEN_REQ;
break;
case OC_EH_RESOURCE_CREATED:
result = OC_STACK_RESOURCE_CREATED;
case OC_EH_RESOURCE_NOT_FOUND:
result = OC_STACK_NO_RESOURCE;
break;
+ case OC_EH_INTERNAL_SERVER_ERROR:
+ result = OC_STACK_INTERNAL_SERVER_ERROR;
+ break;
+ case OC_EH_NOT_IMPLEMENTED:
+ result = OC_STACK_NOT_IMPLEMENTED;
+ break;
+ case OC_EH_BAD_GATEWAY:
+ result = OC_STACK_BAD_GATEWAY;
+ break;
+ case OC_EH_SERVICE_UNAVAILABLE:
+ result = OC_STACK_SERVICE_UNAVAILABLE;
+ break;
+ case OC_EH_RETRANSMIT_TIMEOUT:
+ result = OC_STACK_GATEWAY_TIMEOUT;
+ break;
+ case OC_EH_PROXY_NOT_SUPPORTED:
+ result = OC_STACK_PROXY_NOT_SUPPORTED;
+ break;
default:
result = OC_STACK_ERROR;
}
return false;
}
- // Null or empty is analogous to no filter.
- if (resourceTypeFilter == NULL || *resourceTypeFilter == 0)
+ // Null is analogous to no filter.
+ if (NULL == resourceTypeFilter)
{
return true;
}
- OCResourceType *resourceTypePtr = resource->rsrcType;
+ // Empty resourceType filter is analogous to error query
+ if (0 == strlen(resourceTypeFilter))
+ {
+ return false;
+ }
- 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 false;
}
- // Null or empty is analogous to no filter.
- if (interfaceFilter == NULL || *interfaceFilter == 0)
+ // Null is analogous to no filter.
+ if (NULL == interfaceFilter)
{
return true;
}
- OCResourceInterface *interfacePtr = resource->rsrcInterface;
+ // Empty interface filter is analogous to error query
+ if (0 == strlen(interfaceFilter))
+ {
+ return false;
+ }
- 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,
response.ehResult = ehResult;
response.payload = discoveryPayload;
response.persistentBufferFlag = 0;
- response.requestHandle = (OCRequestHandle) request;
+ response.requestHandle = (OCRequestHandle) request->requestId;
response.resourceHandle = (OCResourceHandle) 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
+ * remote resource.
+ *
+ * @param resource The resource to check the matching resource URI.
+ * @param interfaceQuery The interface query parameter.
+ * @param resourceTypeQuery The resourceType query parameter.
+ * @param discPayload The payload that will be added with the resource information if found at RD.
+ *
+ * @return ::OC_STACK_OK if the resource is found else ::OC_STACK_NO_RESOURCE.
+ * In case if build is not with flag RD_SERVER, it returns ::OC_STACK_NO_RESOURCE.
+ */
+static OCStackResult findResourceAtRD(const OCResource* resource, const char *interfaceQuery,
+ const char *resourceTypeQuery, OCDiscoveryPayload *discPayload)
+{
+ if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
+ {
+ if (OC_STACK_OK == OCRDDatabaseCheckResources(interfaceQuery, resourceTypeQuery, discPayload))
+ {
+ return OC_STACK_OK;
+ }
+ }
+
+ return OC_STACK_NO_RESOURCE;
+}
+#endif
+
+/**
+ * Creates a discovery payload and add device id information. This information is included in all
+ * /oic/res response.
+ *
+ * @param payload payload that will have memory alllocated and device id information added.
+ *
+ * @return ::OC_STACK_OK if successful in allocating memory and adding ID information.
+ * ::OC_STACK_NO_MEMORY if failed allocating the memory.
+ */
+static OCStackResult discoveryPayloadCreateAndAddDeviceId(OCPayload **payload)
+{
+ if (*payload)
+ {
+ OIC_LOG(DEBUG, TAG, "Payload is already allocated");
+ return OC_STACK_OK;
+ }
+
+ *payload = (OCPayload *) OCDiscoveryPayloadCreate();
+ VERIFY_PARAM_NON_NULL(TAG, *payload, "Failed adding device id to discovery payload.");
+
+ {
+ OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)*payload;
+ discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
+ VERIFY_PARAM_NON_NULL(TAG, discPayload->sid, "Failed adding device id to discovery payload.");
+
+ const char* uid = OCGetServerInstanceIDString();
+ if (uid)
+ {
+ memcpy(discPayload->sid, uid, UUID_STRING_SIZE);
+ }
+
+ }
+ return OC_STACK_OK;
+exit:
+ OCPayloadDestroy(*payload);
+ return OC_STACK_NO_MEMORY;
+}
+
+/**
+ * Add the common properties to the payload, they are only included in case of oic.if.baseline response.
+ *
+ * @param discPayload payload that will have the baseline information included.
+ *
+ * @return ::OC_STACK_OK if successful in adding all the information. ::OC_STACK_NO_MEMORY if failed
+ * allocating the memory for the baseline information.
+ */
+static OCStackResult addDiscoveryBaselineCommonProperties(OCDiscoveryPayload *discPayload)
+{
+ if (!discPayload)
+ {
+ OIC_LOG(ERROR, TAG, "Payload is not allocated");
+ return OC_STACK_ERROR;
+ }
+
+ OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, (void **)&discPayload->name);
+
+ discPayload->type = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+ VERIFY_PARAM_NON_NULL(TAG, discPayload->type, "Failed adding rt to discovery payload.");
+ discPayload->type->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
+ VERIFY_PARAM_NON_NULL(TAG, discPayload->type, "Failed adding rt value to discovery payload.");
+
+ OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_LL);
+ OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_DEFAULT);
+ VERIFY_PARAM_NON_NULL(TAG, discPayload->iface, "Failed adding if to discovery payload.");
+
+ return OC_STACK_OK;
+
+exit:
+ return OC_STACK_NO_MEMORY;
+}
+
+static bool isUnicast(OCServerRequest *request)
+{
+ bool isMulticast = request->devAddr.flags & OC_MULTICAST;
+ return (isMulticast == false &&
+ (request->devAddr.adapter != OC_ADAPTER_RFCOMM_BTEDR) &&
+ (request->devAddr.adapter != OC_ADAPTER_GATT_BTLE));
+}
+
static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
{
if (!request || !resource)
return OC_STACK_INVALID_PARAM;
}
- OCStackResult discoveryResult = OC_STACK_ERROR;
OCPayload* payload = NULL;
+ char *interfaceQuery = NULL;
+ char *resourceTypeQuery = NULL;
OIC_LOG(INFO, TAG, "Entering HandleVirtualResource");
OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
+#ifdef TCP_ADAPTER
+ if (OC_KEEPALIVE_RESOURCE_URI == virtualUriInRequest)
+ {
+ // Received request for a keepalive
+ OIC_LOG(INFO, TAG, "Request is for KeepAlive Request");
+ return OCHandleKeepAliveRequest(request, resource);
+ }
+#endif
+
+ OCStackResult discoveryResult = OC_STACK_ERROR;
+ if (request->method == OC_REST_PUT || request->method == OC_REST_POST ||
+ request->method == OC_REST_DELETE)
+ {
+ OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d",
+ request->resourceUrl, request->method);
+ return OC_STACK_UNAUTHORIZED_REQ;
+ }
+
// Step 1: Generate the response to discovery request
if (virtualUriInRequest == OC_WELL_KNOWN_URI
#ifdef MQ_BROKER
#endif
)
{
- if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
- {
- OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d", request->resourceUrl, request->method);
- return OC_STACK_UNAUTHORIZED_REQ;
- }
-
- char *interfaceQuery = NULL;
- char *resourceTypeQuery = NULL;
-
- discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
+ discoveryResult = getQueryParamsForFiltering(virtualUriInRequest, request->query,
&interfaceQuery, &resourceTypeQuery);
- bool interfaceQueryAllocated = false;
+ VERIFY_SUCCESS(discoveryResult);
+
if (!interfaceQuery && !resourceTypeQuery)
{
- interfaceQueryAllocated = true;
+ // If no query is sent, default interface is used i.e. oic.if.ll.
interfaceQuery = OICStrdup(OC_RSRVD_INTERFACE_LL);
}
- if (discoveryResult == OC_STACK_OK)
- {
- payload = (OCPayload *)OCDiscoveryPayloadCreate();
-
- if (payload)
- {
- OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload;
- discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
- VERIFY_NON_NULL(discPayload->sid, ERROR, OC_STACK_NO_MEMORY);
-
- const char* uid = OCGetServerInstanceIDString();
- if (uid)
- {
- memcpy(discPayload->sid, uid, UUID_STRING_SIZE);
- }
+ discoveryResult = discoveryPayloadCreateAndAddDeviceId(&payload);
+ VERIFY_PARAM_NON_NULL(TAG, payload, "Failed creating Discovery Payload.");
+ VERIFY_SUCCESS(discoveryResult);
- if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
- {
- OCResourceProperty prop = OC_DISCOVERABLE;
+ OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload;
+ if (interfaceQuery && 0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_DEFAULT))
+ {
+ discoveryResult = addDiscoveryBaselineCommonProperties(discPayload);
+ VERIFY_SUCCESS(discoveryResult);
+ }
+ OCResourceProperty prop = OC_DISCOVERABLE;
#ifdef MQ_BROKER
- if (OC_MQ_BROKER_URI == virtualUriInRequest)
- {
- prop = OC_MQ_BROKER;
- }
+ prop = (OC_MQ_BROKER_URI == virtualUriInRequest) ? OC_MQ_BROKER : prop;
#endif
-
- for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
- {
- bool result = false;
-
- if (resource->resourceProperties & prop)
- {
- result = true;
- }
-
- if (result)
- {
- discoveryResult = BuildVirtualResourceResponse(resource,
- discPayload, &request->devAddr, false);
- }
- }
- }
- else
+ for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
+ {
+ // This case will handle when no resource type and it is oic.if.ll.
+ // Do not assume check if the query is ll
+ if (!resourceTypeQuery &&
+ (interfaceQuery && 0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
+ {
+ // Only include discoverable type
+ if (resource->resourceProperties & prop)
{
- if (interfaceQuery && (0 != strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
- {
- discPayload->uri = OICStrdup(OC_RSRVD_WELL_KNOWN_URI);
- VERIFY_NON_NULL(discPayload->uri, ERROR, OC_STACK_NO_MEMORY);
- if (savedDeviceInfo.deviceName)
- {
- discPayload->name = OICStrdup(savedDeviceInfo.deviceName);
- VERIFY_NON_NULL(discPayload->name, ERROR, OC_STACK_NO_MEMORY);
- }
- discPayload->type = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
- VERIFY_NON_NULL(discPayload->type, ERROR, OC_STACK_NO_MEMORY);
- discPayload->type->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
- VERIFY_NON_NULL(discPayload->type->value, ERROR, OC_STACK_NO_MEMORY);
- OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_LL);
- OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_DEFAULT);
- VERIFY_NON_NULL(discPayload->iface, ERROR, OC_STACK_NO_MEMORY);
- }
- bool foundResourceAtRD = false;
- for (;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
- {
- if (!foundResourceAtRD && includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
- {
- discoveryResult = BuildVirtualResourceResponse(resource,
- discPayload, &request->devAddr, false);
- }
- }
- // Set discoveryResult appropriately if no 'valid' resources are available
- if (discPayload->resources == NULL && !foundResourceAtRD)
- {
- discoveryResult = OC_STACK_NO_RESOURCE;
- }
+ discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
}
}
+ else if (includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
+ {
+ discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
+ }
else
{
- discoveryResult = OC_STACK_NO_MEMORY;
+ discoveryResult = OC_STACK_OK;
}
}
- else
- {
- OIC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
- }
- if (interfaceQueryAllocated)
+ if (discPayload->resources == NULL)
{
- OICFree(interfaceQuery);
+ discoveryResult = OC_STACK_NO_RESOURCE;
}
}
else if (virtualUriInRequest == OC_DEVICE_URI)
{
- if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
- {
- OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d", request->resourceUrl, request->method);
- return OC_STACK_UNAUTHORIZED_REQ;
- }
-
- const char* deviceId = OCGetServerInstanceIDString();
- if (!deviceId)
- {
- discoveryResult = OC_STACK_ERROR;
- }
- else
- {
- char *dataModelVersions = OCCreateString(savedDeviceInfo.dataModelVersions);
- if (!dataModelVersions)
- {
- discoveryResult = OC_STACK_NO_MEMORY;
- }
- else
- {
- payload = (OCPayload*) OCDevicePayloadCreate(deviceId, savedDeviceInfo.deviceName,
- savedDeviceInfo.types, savedDeviceInfo.specVersion, dataModelVersions);
- if (!payload)
- {
- discoveryResult = OC_STACK_NO_MEMORY;
- }
- else
- {
- discoveryResult = OC_STACK_OK;
- }
- OICFree(dataModelVersions);
- }
- }
+ OCResource *resourcePtr = FindResourceByUri(OC_RSRVD_DEVICE_URI);
+ VERIFY_PARAM_NON_NULL(TAG, resourcePtr, "Device URI not found.");
+ discoveryResult = BuildDevicePlatformPayload(resourcePtr, (OCRepPayload **)&payload, true);
}
else if (virtualUriInRequest == OC_PLATFORM_URI)
{
- if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
- {
- OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d", request->resourceUrl, request->method);
- return OC_STACK_UNAUTHORIZED_REQ;
- }
-
- payload = (OCPayload*)OCPlatformPayloadCreate(&savedPlatformInfo);
- if (!payload)
- {
- discoveryResult = OC_STACK_NO_MEMORY;
- }
- else
- {
- discoveryResult = OC_STACK_OK;
- }
+ OCResource *resourcePtr = FindResourceByUri(OC_RSRVD_PLATFORM_URI);
+ VERIFY_PARAM_NON_NULL(TAG, resourcePtr, "Platform URI not found.");
+ discoveryResult = BuildDevicePlatformPayload(resourcePtr, (OCRepPayload **)&payload, false);
}
#ifdef ROUTING_GATEWAY
else if (OC_GATEWAY_URI == virtualUriInRequest)
// Received request for a gateway
OIC_LOG(INFO, TAG, "Request is for Gateway Virtual Request");
discoveryResult = RMHandleGatewayRequest(request, resource);
-
}
#endif
if ((virtualUriInRequest == OC_PRESENCE) &&
(resource->resourceProperties & OC_ACTIVE))
{
+ // Need to send ACK when the request is CON.
+ if (request->qos == OC_HIGH_QOS)
+ {
+ CAEndpoint_t endpoint = { .adapter = CA_DEFAULT_ADAPTER };
+ CopyDevAddrToEndpoint(&request->devAddr, &endpoint);
+ SendDirectStackResponse(&endpoint, request->coapID, CA_EMPTY, CA_MSG_ACKNOWLEDGE,
+ 0, NULL, NULL, 0, NULL, CA_RESPONSE_FOR_RES);
+ }
+ FindAndDeleteServerRequest(request);
+
// Presence uses observer notification api to respond via SendPresenceNotification.
SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
}
else
- #endif
-#ifdef ROUTING_GATEWAY
+#endif
+#if ROUTING_GATEWAY
// Gateway uses the RMHandleGatewayRequest to respond to the request.
if (OC_GATEWAY_URI != virtualUriInRequest)
#endif
{
+ OIC_LOG_PAYLOAD(DEBUG, payload);
if(discoveryResult == OC_STACK_OK)
{
+
SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK);
}
- else if(((request->devAddr.flags & OC_MULTICAST) == false) &&
- (request->devAddr.adapter != OC_ADAPTER_RFCOMM_BTEDR) &&
- (request->devAddr.adapter != OC_ADAPTER_GATT_BTLE))
- {
- OIC_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);
- }
- else
+ else // Error handling
{
- // Ignoring the discovery request as per RFC 7252, Section #8.2
- OIC_LOG(INFO, TAG, "Silently ignoring the request since no useful data to send. ");
+ if (isUnicast(request))
+ {
+ OIC_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);
+ }
+ else // Multicast
+ {
+ // Ignoring the discovery request as per RFC 7252, Section #8.2
+ OIC_LOG(INFO, TAG, "Silently ignoring the request since no useful data to send.");
+ // the request should be removed.
+ // since it never remove and causes a big memory waste.
+ FindAndDeleteServerRequest(request);
+ }
+ discoveryResult = OC_STACK_CONTINUE;
}
}
+exit:
+ if (interfaceQuery)
+ {
+ OICFree(interfaceQuery);
+ }
+
+ if (resourceTypeQuery)
+ {
+ OICFree(resourceTypeQuery);
+ }
OCPayloadDestroy(payload);
- return OC_STACK_OK;
+ // To ignore the message, OC_STACK_CONTINUE is sent
+ return discoveryResult;
}
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,
- 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);
- VERIFY_SUCCESS(result, OC_STACK_OK);
+ OCStackResult result = EHRequest(&ehRequest, PAYLOAD_TYPE_REPRESENTATION, request, NULL);
+ VERIFY_SUCCESS(result);
// At this point we know for sure that defaultDeviceHandler exists
ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
}
static OCStackResult
-HandleResourceWithEntityHandler (OCServerRequest *request,
- OCResource *resource,
- uint8_t collectionResource)
+HandleResourceWithEntityHandler(OCServerRequest *request,
+ OCResource *resource)
{
if(!request || ! resource)
{
if (request && request->resourceUrl && SRMIsSecurityResourceURI(request->resourceUrl))
{
type = PAYLOAD_TYPE_SECURITY;
-
}
- if (request && strcmp(request->resourceUrl, OC_RSRVD_RD_URI) == 0)
- {
- type = PAYLOAD_TYPE_RD;
- }
-
- 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,
- request->coapID);
- VERIFY_SUCCESS(result, OC_STACK_OK);
+ result = EHRequest(&ehRequest, type, request, resource);
+ VERIFY_SUCCESS(result);
if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
{
OIC_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)
{
OIC_LOG(INFO, TAG, "Observation registration requested");
}
result = GenerateObserverId(&ehRequest.obsInfo.obsId);
- VERIFY_SUCCESS(result, OC_STACK_OK);
+ VERIFY_SUCCESS(result);
result = AddObserver ((const char*)(request->resourceUrl),
(const char *)(request->query),
request->observeResult = OC_STACK_OK;
ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
}
+ else if (result == OC_STACK_RESOURCE_ERROR)
+ {
+ OIC_LOG(INFO, TAG, "The Resource is not active, discoverable or observable");
+ request->observeResult = OC_STACK_ERROR;
+ ehFlag = OC_REQUEST_FLAG;
+ }
else
{
// The error in observeResult for the request will be used when responding to this
}
}
- else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
- !collectionResource)
+ else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER)
{
OIC_LOG(INFO, TAG, "Deregistering observation requested");
{
// Stack does not contain this observation request
// Either token is incorrect or observation list is corrupted
- result = OC_STACK_ERROR;
+ result = OC_STACK_NO_RESOURCE;
goto exit;
}
ehRequest.obsInfo.obsId = resObs->observeId;
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,
- 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:
return ret;
}
-void DeletePlatformInfo()
+OCStackResult OCSetPlatformInfo(OCPlatformInfo info)
{
- OIC_LOG(INFO, TAG, "Deleting platform info.");
-
- OICFree(savedPlatformInfo.platformID);
- savedPlatformInfo.platformID = NULL;
-
- OICFree(savedPlatformInfo.manufacturerName);
- savedPlatformInfo.manufacturerName = NULL;
-
- OICFree(savedPlatformInfo.manufacturerUrl);
- savedPlatformInfo.manufacturerUrl = NULL;
-
- OICFree(savedPlatformInfo.modelNumber);
- savedPlatformInfo.modelNumber = NULL;
-
- OICFree(savedPlatformInfo.dateOfManufacture);
- savedPlatformInfo.dateOfManufacture = NULL;
-
- OICFree(savedPlatformInfo.platformVersion);
- savedPlatformInfo.platformVersion = NULL;
-
- OICFree(savedPlatformInfo.operatingSystemVersion);
- savedPlatformInfo.operatingSystemVersion = NULL;
-
- OICFree(savedPlatformInfo.hardwareVersion);
- savedPlatformInfo.hardwareVersion = NULL;
-
- OICFree(savedPlatformInfo.firmwareVersion);
- savedPlatformInfo.firmwareVersion = NULL;
-
- OICFree(savedPlatformInfo.supportUrl);
- savedPlatformInfo.supportUrl = NULL;
-
- 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))
- {
- DeletePlatformInfo();
- return OC_STACK_INVALID_PARAM;
+ OCResource *resource = NULL;
+ if (!info.platformID || !info.manufacturerName)
+ {
+ OIC_LOG(ERROR, TAG, "No value specified.");
+ goto exit;
+ }
+ if (0 == strlen(info.platformID) || 0 == strlen(info.manufacturerName))
+ {
+ OIC_LOG(ERROR, TAG, "The passed value cannot be empty");
+ goto exit;
+ }
+ if ((info.manufacturerName && strlen(info.manufacturerName) > MAX_PLATFORM_NAME_LENGTH) ||
+ (info.manufacturerUrl && strlen(info.manufacturerUrl) > MAX_PLATFORM_URL_LENGTH) ||
+ (info.modelNumber && strlen(info.modelNumber) > MAX_PLATFORM_NAME_LENGTH) ||
+ (info.platformVersion && strlen(info.platformVersion) > MAX_PLATFORM_NAME_LENGTH) ||
+ (info.operatingSystemVersion && strlen(info.operatingSystemVersion) > MAX_PLATFORM_NAME_LENGTH) ||
+ (info.hardwareVersion && strlen(info.hardwareVersion) > MAX_PLATFORM_NAME_LENGTH) ||
+ (info.firmwareVersion && strlen(info.firmwareVersion) > MAX_PLATFORM_NAME_LENGTH) ||
+ (info.supportUrl && strlen(info.supportUrl) > MAX_PLATFORM_URL_LENGTH))
+ {
+ OIC_LOG(ERROR, TAG, "The passed value is bigger than permitted.");
+ goto exit;
}
+ resource = FindResourceByUri(OC_RSRVD_PLATFORM_URI);
+ if (!resource)
+ {
+ OIC_LOG(ERROR, TAG, "Platform Resource does not exist.");
+ goto exit;
+ }
+ OIC_LOG(INFO, TAG, "Entering OCSetPlatformInfo");
+ VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_PLATFORM_ID, info.platformID));
+ VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_NAME, info.manufacturerName));
+ OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_URL, info.manufacturerUrl);
+ OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MODEL_NUM, info.modelNumber);
+ OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_DATE, info.dateOfManufacture);
+ OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_PLATFORM_VERSION, info.platformVersion);
+ OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_OS_VERSION, info.operatingSystemVersion);
+ OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_HARDWARE_VERSION, info.hardwareVersion);
+ OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_FIRMWARE_VERSION, info.firmwareVersion);
+ OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_SUPPORT_URL, info.supportUrl);
+ OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_SYSTEM_TIME, info.systemTime);
+ OIC_LOG(INFO, TAG, "Platform parameter initialized successfully.");
return OC_STACK_OK;
+exit:
+ return OC_STACK_INVALID_PARAM;
}
-OCStackResult SavePlatformInfo(OCPlatformInfo info)
+OCStackResult OCSetDeviceInfo(OCDeviceInfo info)
{
- DeletePlatformInfo();
+ OCStringLL *dataModelVersion = NULL;
+ OCResource *resource = FindResourceByUri(OC_RSRVD_DEVICE_URI);
+ if (!resource)
+ {
+ OIC_LOG(ERROR, TAG, "Device Resource does not exist.");
+ goto exit;
+ }
+ if (!info.deviceName || info.deviceName[0] == '\0')
+ {
+ OIC_LOG(ERROR, TAG, "Null or empty device name.");
+ return OC_STACK_INVALID_PARAM;
+ }
- OCStackResult res = DeepCopyPlatFormInfo(info);
+ if (OCGetServerInstanceIDString() == NULL)
+ {
+ OIC_LOG(INFO, TAG, "Device ID generation failed");
+ goto exit;
+ }
- if (res != OC_STACK_OK)
+ VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, info.deviceName));
+ for (OCStringLL *temp = info.types; temp; temp = temp->next)
+ {
+ if (temp->value)
+ {
+ VERIFY_SUCCESS(OCBindResourceTypeToResource(resource, temp->value));
+ }
+ }
+ VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_SPEC_VERSION, info.specVersion ?
+ info.specVersion: OC_SPEC_VERSION));
+ if (info.dataModelVersions)
{
- OIC_LOG_V(ERROR, TAG, "Failed to save platform info. errno(%d)", res);
+ VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION, info.dataModelVersions));
}
else
{
- OIC_LOG(INFO, TAG, "Platform info saved.");
+ dataModelVersion = OCCreateOCStringLL(OC_DATA_MODEL_VERSION);
+ VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION, dataModelVersion));
+#ifdef __TIZENRT__
+ OCFreeOCStringLL(dataModelVersion);
+#endif
}
+ OIC_LOG(INFO, TAG, "Device parameter initialized successfully.");
+ return OC_STACK_OK;
- return res;
-}
-
-void DeleteDeviceInfo()
-{
- OIC_LOG(INFO, TAG, "Deleting device info.");
-
- OICFree(savedDeviceInfo.deviceName);
- OCFreeOCStringLL(savedDeviceInfo.types);
- OICFree(savedDeviceInfo.specVersion);
- OCFreeOCStringLL(savedDeviceInfo.dataModelVersions);
- savedDeviceInfo.deviceName = NULL;
- savedDeviceInfo.specVersion = NULL;
- savedDeviceInfo.dataModelVersions = NULL;
+exit:
+ if (dataModelVersion)
+ {
+ OCFreeOCStringLL(dataModelVersion);
+ }
+ return OC_STACK_ERROR;
}
-static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
+OCStackResult OCGetAttribute(const OCResource *resource, const char *attribute, void **value)
{
- savedDeviceInfo.deviceName = OICStrdup(info.deviceName);
-
- if(!savedDeviceInfo.deviceName && info.deviceName)
+ if (!resource || !attribute)
{
- DeleteDeviceInfo();
- return OC_STACK_NO_MEMORY;
+ return OC_STACK_INVALID_PARAM;
}
-
- if (info.types)
+ if (0 == strlen(attribute))
{
- savedDeviceInfo.types = CloneOCStringLL(info.types);
- OCStringLL *type = info.types;
- bool found = false;
- while (type)
- {
- if (type && type->value && 0 == strcmp(type->value, OC_RSRVD_RESOURCE_TYPE_DEVICE))
- {
- found = true;
- }
- type = type->next;
- }
- if (!found)
+ return OC_STACK_INVALID_PARAM;
+ }
+ for (OCAttribute *temp = resource->rsrcAttributes; temp; temp = temp->next)
+ {
+ if (0 == strcmp(attribute, temp->attrName))
{
- // Append the oic.wk.d at the start of rt link parameter value.
- OCStringLL *dest = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
- if (!dest)
+ // A special case as this type return OCStringLL
+ if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, attribute))
{
- DeleteDeviceInfo();
- return OC_STACK_NO_MEMORY;
+ *value = CloneOCStringLL((OCStringLL *)temp->attrValue);
+ return OC_STACK_OK;
}
- dest->value = OICStrdup (OC_RSRVD_RESOURCE_TYPE_DEVICE);
- if (!dest->value)
+ else
{
- DeleteDeviceInfo();
- return OC_STACK_NO_MEMORY;
+ *value = OICStrdup((char *)temp->attrValue);
+ return OC_STACK_OK;
}
- dest->next = savedDeviceInfo.types;
- savedDeviceInfo.types = dest;
- }
- if(!savedDeviceInfo.types && info.types)
- {
- DeleteDeviceInfo();
- return OC_STACK_NO_MEMORY;
}
}
+ return OC_STACK_NO_RESOURCE;
+}
- if (info.specVersion)
+OCStackResult OCGetPropertyValue(OCPayloadType type, const char *prop, void **value)
+{
+ if (!prop || *value)
{
- savedDeviceInfo.specVersion = OICStrdup(info.specVersion);
- if(!savedDeviceInfo.specVersion && info.specVersion)
- {
- DeleteDeviceInfo();
- return OC_STACK_NO_MEMORY;
- }
+ return OC_STACK_INVALID_PARAM;
}
- else
+ if (strlen(prop) == 0)
{
- savedDeviceInfo.specVersion = OICStrdup(OC_SPEC_VERSION);
- if(!savedDeviceInfo.specVersion && OC_SPEC_VERSION)
+ return OC_STACK_INVALID_PARAM;
+ }
+ OCStackResult res = OC_STACK_NO_RESOURCE;
+ if (PAYLOAD_TYPE_DEVICE == type || PAYLOAD_TYPE_PLATFORM == type)
+ {
+ const char *pathType = (type == PAYLOAD_TYPE_DEVICE) ? OC_RSRVD_DEVICE_URI : OC_RSRVD_PLATFORM_URI;
+ OCResource *resource = FindResourceByUri(pathType);
+ if (!resource)
{
- DeleteDeviceInfo();
- return OC_STACK_NO_MEMORY;
+ return OC_STACK_NO_RESOURCE;
}
+
+ res = OCGetAttribute(resource, prop, value);
}
+ return res;
+}
- if (info.dataModelVersions)
+OCStackResult OCSetAttribute(OCResource* resource, const char* attribute, const void* value)
+{
+ // See if the attribute already exists in the list.
+ OCAttribute *resAttrib;
+ for (resAttrib = resource->rsrcAttributes; resAttrib; resAttrib = resAttrib->next)
{
- savedDeviceInfo.dataModelVersions = CloneOCStringLL(info.dataModelVersions);
- if(!savedDeviceInfo.dataModelVersions && info.dataModelVersions)
+ if (0 == strcmp(attribute, resAttrib->attrName))
{
- DeleteDeviceInfo();
- return OC_STACK_NO_MEMORY;
+ // 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;
}
}
+
+ // If not already in the list, add it.
+ if (NULL == resAttrib)
+ {
+ 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;
+ }
+
+ // Fill in the new value.
+ if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, attribute))
+ {
+ resAttrib->attrValue = CloneOCStringLL((OCStringLL *)value);
+ }
else
{
- savedDeviceInfo.dataModelVersions = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
- if (!savedDeviceInfo.dataModelVersions)
- {
- return OC_STACK_NO_MEMORY;
- }
- savedDeviceInfo.dataModelVersions->value = OICStrdup(OC_DATA_MODEL_VERSION);
- if(!savedDeviceInfo.dataModelVersions->value && OC_DATA_MODEL_VERSION)
- {
- DeleteDeviceInfo();
- return OC_STACK_NO_MEMORY;
- }
+ resAttrib->attrValue = OICStrdup((char *)value);
}
+ VERIFY_PARAM_NON_NULL(TAG, resAttrib->attrValue, "Failed allocating attribute value");
return OC_STACK_OK;
-}
-
-OCStackResult SaveDeviceInfo(OCDeviceInfo info)
-{
- OCStackResult res = OC_STACK_OK;
- DeleteDeviceInfo();
-
- res = DeepCopyDeviceInfo(info);
+exit:
+ OCDeleteResourceAttributes(resAttrib);
+ return OC_STACK_NO_MEMORY;
- VERIFY_SUCCESS(res, OC_STACK_OK);
+}
- if (OCGetServerInstanceIDString() == NULL)
+OCStackResult OCSetPropertyValue(OCPayloadType type, const char *prop, const void *value)
+{
+ if (!prop || !value)
{
- OIC_LOG(INFO, TAG, "Device ID generation failed");
- res = OC_STACK_ERROR;
- goto exit;
+ return OC_STACK_INVALID_PARAM;
+ }
+ if (strlen(prop) == 0)
+ {
+ return OC_STACK_INVALID_PARAM;
}
- OIC_LOG(INFO, TAG, "Device initialized successfully.");
- return OC_STACK_OK;
+ OCStackResult res = OC_STACK_ERROR;
+ if (PAYLOAD_TYPE_DEVICE == type || PAYLOAD_TYPE_PLATFORM == type)
+ {
+ const char *pathType = (type == PAYLOAD_TYPE_DEVICE) ? OC_RSRVD_DEVICE_URI : OC_RSRVD_PLATFORM_URI;
+ OCResource *resource = FindResourceByUri(pathType);
+ if (!resource)
+ {
+ OIC_LOG(ERROR, TAG, "Resource does not exist.");
+ }
+ else
+ {
+ res = OCSetAttribute(resource, prop, value);
+ }
+ }
-exit:
- DeleteDeviceInfo();
return res;
}