Earlier collection payload was added in discovery payload to handle RD response in
a separate way in form of tags and links. But with recent changes and discussion
baseURI is mvoed to discovery payload.
With this change there is one response for /oic/res with an additional field for RD.
Change-Id: Ia29cc64ffb48062d72ee4b9a9b59013480f13ff1
Signed-off-by: Habib Virji <habib.virji@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/4611
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jonc@osg.samsung.com>
OCRepPayload** payload);
/**
- * Prepares a Payload for response.
- */
-OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
- OCDiscoveryPayload* payload,
- OCDevAddr *endpoint);
-
-/**
* A helper function that Maps an @ref OCEntityHandlerResult type to an
* @ref OCStackResult type.
*/
uint8_t* sid;
+ /** A special case for handling RD address. */
+ char* baseURI;
+
/** This structure holds the old /oic/res response. */
OCResourcePayload *resources;
- /** This structure holds the collection response for the /oic/res. */
- OCResourceCollectionPayload *collectionResources;
+
} OCDiscoveryPayload;
/**
// Arbitrarily chosen size that seems to contain the majority of packages
#define INIT_SIZE (255)
-// CBOR Array Length
-#define DISCOVERY_CBOR_ARRAY_LEN 1
-// CBOR Res Map Length
-#define DISCOVERY_CBOR_RES_MAP_LEN 2
// CBOR Links Map Length
#define DISCOVERY_CBOR_LINKS_MAP_LEN 4
cbor_encoder_init(&encoder, outPayload, *size, 0);
- if (payload->collectionResources)
- {
- CborError cborEncoderResult;
- cborEncoderResult = cbor_encoder_create_array(&encoder, &rootArray, DISCOVERY_CBOR_ARRAY_LEN);
- if (CborNoError != cborEncoderResult)
- {
- OC_LOG(ERROR, TAG, "Failed creating root array.");
- goto cbor_error;
- }
-
- CborEncoder colArray;
- cborEncoderResult = cbor_encoder_create_array(&rootArray, &colArray, CborIndefiniteLength);
- if (CborNoError != cborEncoderResult)
- {
- OC_LOG(ERROR, TAG, "Failed creating collection array.");
- goto cbor_error;
- }
- OCResourceCollectionPayload *colResources = payload->collectionResources;
- while (colResources)
- {
- if (OC_STACK_OK != OCTagsPayloadToCbor(colResources->tags, &colArray))
- {
- goto cbor_error;
- }
- if (OC_STACK_OK != OCLinksPayloadToCbor(colResources->setLinks, &colArray))
- {
- goto cbor_error;
- }
- colResources = colResources->next;
- }
- cborEncoderResult = cbor_encoder_close_container(&rootArray, &colArray);
- if (CborNoError != cborEncoderResult)
- {
- OC_LOG(ERROR, TAG, "Failed closing collection array.");
- goto cbor_error;
- }
- cborEncoderResult = cbor_encoder_close_container(&encoder, &rootArray);
- if (CborNoError != cborEncoderResult)
- {
- OC_LOG(ERROR, TAG, "Failed closing root array.");
- goto cbor_error;
- }
- }
- else if (payload->resources)
+ if (payload->resources)
{
/*
The format for the payload is "modelled" as JSON.
}
]
*/
- CborEncoder rootMap = {};
+ CborEncoder rootMap = {0};
size_t resourceCount = OCDiscoveryPayloadGetResourceCount(payload);
// Open the main root array
err = err | cbor_encoder_create_array(&encoder, &rootArray, 1);
// Open the root map in the root array
- err = err | cbor_encoder_create_map(&rootArray, &rootMap, DISCOVERY_CBOR_RES_MAP_LEN);
+ err = err | cbor_encoder_create_map(&rootArray, &rootMap, CborIndefiniteLength);
// Insert Device ID into the root map
err = err | cbor_encode_text_string(&rootMap, OC_RSRVD_DEVICE_ID,
sizeof(OC_RSRVD_DEVICE_ID) - 1);
err = err | cbor_encode_byte_string(&rootMap, payload->sid, UUID_SIZE);
+ // Insert baseURI if present
+ err = err | ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_BASE_URI,
+ sizeof(OC_RSRVD_BASE_URI) - 1,
+ payload->baseURI);
// Insert Links into the root map.
- CborEncoder linkArray = {};
+ CborEncoder linkArray = {0};
err = err | cbor_encode_text_string(&rootMap, OC_RSRVD_LINKS,
sizeof(OC_RSRVD_LINKS) - 1);
err = err | cbor_encoder_create_array(&rootMap, &linkArray, resourceCount);
for(size_t i = 0; i < resourceCount; ++i)
{
- CborEncoder resourceMapElement = {};
+ CborEncoder resourceMapElement = {0};
OCResourcePayload* resource = OCDiscoveryPayloadGetResource(payload, i);
if(!resource)
{
}
// Policy
- CborEncoder policyMap;
+ CborEncoder policyMap = {0};
err = err | cbor_encode_text_string(&resourceMapElement, OC_RSRVD_POLICY,
sizeof(OC_RSRVD_POLICY) - 1);
err = err | cbor_encoder_create_map(&resourceMapElement, &policyMap, CborIndefiniteLength);
err = err | cbor_encode_uint(&policyMap, resource->port);
}
}
+ if (payload->baseURI)
+ {
+ err = err | cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
+ sizeof(OC_RSRVD_HOSTING_PORT) - 1);
+ err = err | cbor_encode_uint(&policyMap, resource->port);
+ }
err = err | cbor_encoder_close_container(&resourceMapElement, &policyMap);
}
return checkError(err, &encoder, outPayload, size);
-cbor_error:
- OICFree(outPayload);
- return OC_STACK_ERROR;
}
static int64_t OCConvertDevicePayload(OCDevicePayload* payload, uint8_t* outPayload,
bool err = false;
OCResourcePayload* resource = NULL;
uint16_t resourceCount = 0;
- CborValue resourceMap = {};
+ CborValue resourceMap = { 0 };
OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
if(!out)
}
// Root value is already inside the main root array
- CborValue rootMap = {};
+ CborValue rootMap = { 0 };
// Enter the main root map
err = err || cbor_value_enter_container(rootValue, &rootMap);
// Look for DI
- CborValue curVal = {};
+ CborValue curVal = { 0 };
err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
if (CborNoError != err)
{
size_t len;
err = cbor_value_dup_byte_string(&curVal, &(out->sid), &len, NULL);
+ // BaseURI - Not a mandatory field
+ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
+ if (CborNoError == err && cbor_value_is_valid(&curVal))
+ {
+ err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
+ if (CborNoError != err)
+ {
+ OC_LOG(ERROR, TAG, "baseURI failed.");
+ goto malformed_cbor;
+ }
+ }
+
// Look for Links which will have an array as the value
err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &curVal);
if (CborNoError != err)
}
// Uri
- CborValue uriVal = {};
+ CborValue uriVal = { 0 };
err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &uriVal);
if (CborNoError != err)
{
goto malformed_cbor;
}
// ResourceTypes
- CborValue rtVal = {};
+ CborValue rtVal = { 0 };
err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &rtVal);
if (CborNoError != err)
{
}
// Interface Types
- CborValue ifVal = {};
+ CborValue ifVal = { 0 };
err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_INTERFACE, &ifVal);
if (CborNoError != err)
{
}
// Policy
- CborValue policyMap = {};
+ CborValue policyMap = { 0 };
err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
if (CborNoError != err)
{
goto malformed_cbor;
}
// Bitmap
- CborValue val = {};
+ CborValue val = { 0 };
err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
if (CborNoError != err)
{
goto malformed_cbor;
}
// Port
- CborValue port;
+ CborValue port = { 0 };
err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
&port);
if (CborNoError != err)
OC_LOG(ERROR, TAG, "Cbor finding port type failed.");
goto malformed_cbor;
}
+ if (cbor_value_is_valid(&port))
+ {
+ err = cbor_value_get_uint64(&port, &temp);
+ if (CborNoError != err)
+ {
+ OC_LOG(ERROR, TAG, "Cbor finding port value failed.");
+ goto malformed_cbor;
+ }
+ resource->port = (uint16_t)temp;
+ }
+ }
+ else if (out->baseURI)
+ {
+ // Port
+ CborValue port = { 0 };
+ err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &port);
+ if (CborNoError != err)
+ {
+ OC_LOG(ERROR, TAG, "Cbor finding port type failed.");
+ goto malformed_cbor;
+ }
if(cbor_value_is_valid(&port))
{
err = cbor_value_get_uint64(&port, &temp);
OICFree(resource);
OCDiscoveryPayloadDestroy(out);
return OC_STACK_MALFORMED_RESPONSE;
-
-cbor_error:
- OCDiscoveryCollectionPayloadDestroy(out);
- return OC_STACK_MALFORMED_RESPONSE;
}
static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* rootValue)
#include "cacommon.h"
#include "cainterface.h"
#include "rdpayload.h"
+#include "ocpayload.h"
#ifdef WITH_RD
#include "rd_server.h"
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);
+
//-----------------------------------------------------------------------------
// Default resource entity handler function
//-----------------------------------------------------------------------------
}
OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
- OCDiscoveryPayload *payload, OCDevAddr *devAddr)
+ OCDiscoveryPayload *payload, OCDevAddr *devAddr, bool rdResponse)
{
if (!resourcePtr || !payload)
{
}
}
- OCDiscoveryPayloadAddResource(payload, resourcePtr, port);
- return OC_STACK_OK;
-}
-
-OCStackResult BuildVirtualCollectionResourceResponse(const OCResourceCollectionPayload *resourcePtr,
- OCDiscoveryPayload *payload, OCDevAddr *devAddr)
-{
- if (!resourcePtr || !payload)
- {
- return OC_STACK_INVALID_PARAM;
- }
- if (resourcePtr->tags && (resourcePtr->tags->bitmap & OC_SECURE))
- {
- if (GetSecurePortInfo(devAddr, &resourcePtr->tags->port) != OC_STACK_OK)
- {
- OC_LOG(ERROR, TAG, "Failed setting secure port.");
- }
- }
- if (resourcePtr->tags && !resourcePtr->tags->baseURI)
+ if (rdResponse)
{
- resourcePtr->tags->baseURI = OICStrdup(devAddr->addr);
- if (resourcePtr->tags->port == 0 && devAddr->port != 0)
- {
- resourcePtr->tags->port = devAddr->port;
- }
+ port = devAddr->port;
}
- OCDiscoveryCollectionPayloadAddResource(payload, resourcePtr->tags, resourcePtr->setLinks);
+
+ OCDiscoveryPayloadAddResource(payload, resourcePtr, port);
return OC_STACK_OK;
}
#ifdef WITH_RD
static OCStackResult checkResourceExistsAtRD(const char *interfaceType, const char *resourceType,
- OCResourceCollectionPayload **repPayload, OCDevAddr *devAddr)
+ OCResource **payload, OCDevAddr *devAddr)
{
- if (OCRDCheckPublishedResource(interfaceType, resourceType, repPayload, devAddr) == OC_STACK_OK)
+ OCResourceCollectionPayload *repPayload;
+ if (!payload)
+ {
+ return OC_STACK_ERROR;
+ }
+ if (OCRDCheckPublishedResource(interfaceType, resourceType, &repPayload, devAddr) == OC_STACK_OK)
{
+ if (!repPayload)
+ {
+ return OC_STACK_ERROR;
+ }
+ OCResource *ptr = ((OCResource *) OICCalloc(1, sizeof(OCResource)));
+ if (!ptr)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+
+ ptr->uri = OICStrdup(repPayload->setLinks->href);
+ if (!ptr->uri)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+ OCStringLL *rt = repPayload->setLinks->rt;
+ while (rt)
+ {
+ OCResourceType *temp = (OCResourceType *) OICCalloc(1, sizeof(OCResourceType));
+ if(!temp)
+ {
+ OICFree(ptr->uri);
+ return OC_STACK_NO_MEMORY;
+ }
+ temp->next = NULL;
+ temp->resourcetypename = OICStrdup(rt->value);
+ if (!ptr->rsrcType)
+ {
+ ptr->rsrcType = temp;
+ }
+ else
+ {
+ OCResourceType *type = ptr->rsrcType;
+ while (type->next)
+ {
+ type = type->next;
+ }
+ type->next = temp;
+ }
+ rt = rt->next;
+ }
+
+ OCStringLL *itf = repPayload->setLinks->itf;
+ while (itf)
+ {
+ OCResourceInterface *temp = (OCResourceInterface *) OICCalloc(1, sizeof(OCResourceInterface));
+ if (!temp)
+ {
+ OICFree(ptr->uri);
+
+ return OC_STACK_NO_MEMORY;
+ }
+ temp->next = NULL;
+ temp->name = OICStrdup(itf->value);
+ if (!ptr->rsrcInterface)
+ {
+ ptr->rsrcInterface = temp;
+ }
+ else
+ {
+ OCResourceInterface *type = ptr->rsrcInterface;
+ while (type->next)
+ {
+ type = type->next;
+ }
+ type->next = temp;
+ }
+ itf = itf->next;
+ }
+
+ ptr->resourceProperties = (OCResourceProperty) repPayload->tags->bitmap;
+
+ OCFreeCollectionResource(repPayload);
+ *payload = ptr;
return OC_STACK_OK;
}
else
if(payload)
{
((OCDiscoveryPayload*)payload)->sid = (uint8_t*)OICCalloc(1, UUID_SIZE);
- memcpy(((OCDiscoveryPayload*)payload)->sid,
- OCGetServerInstanceID(), UUID_SIZE);
+ memcpy(((OCDiscoveryPayload*)payload)->sid, OCGetServerInstanceID(), UUID_SIZE);
bool foundResourceAtRD = false;
for(;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
#ifdef WITH_RD
if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
{
- OCResourceCollectionPayload *repPayload;
+ OCResource *resource = NULL;
OCDevAddr devAddr;
- discoveryResult = checkResourceExistsAtRD(filterOne, filterTwo, &repPayload, &devAddr);
+ discoveryResult = checkResourceExistsAtRD(filterOne, filterTwo,
+ &resource, &devAddr);
if (discoveryResult != OC_STACK_OK)
{
break;
}
- discoveryResult = BuildVirtualCollectionResourceResponse(repPayload,
+ discoveryResult = BuildVirtualResourceResponse(resource,
(OCDiscoveryPayload*)payload,
- &devAddr);
+ &devAddr, true);
+ if (payload)
+ {
+ ((OCDiscoveryPayload*)payload)->baseURI = OICStrdup(devAddr.addr);
+ }
foundResourceAtRD = true;
}
#endif
{
discoveryResult = BuildVirtualResourceResponse(resource,
(OCDiscoveryPayload*)payload,
- &request->devAddr);
+ &request->devAddr, false);
}
}
// Set discoveryResult appropriately if no 'valid' resources are available
return NULL;
}
-void OCLinksAddResource(OCDiscoveryPayload *payload, const char *href, OCStringLL *rt,
- OCStringLL *itf, const char *rel, bool obs, const char *title, const char *uri,
- uint8_t ins, OCStringLL *mt)
-{
- if(!payload->collectionResources->setLinks)
- {
- payload->collectionResources->setLinks =
- OCCopyLinksResources(href, rt, itf, rel, obs, title, uri, ins, mt);
- }
- else
- {
- OCLinksPayload *p = payload->collectionResources->setLinks;
- while (p->next)
- {
- p = p->next;
- }
- p->next = OCCopyLinksResources(href, rt, itf, rel, obs, title, uri, ins, mt);
- }
-}
-
OCResourceCollectionPayload* OCCopyCollectionResource(OCTagsPayload *tags, OCLinksPayload *links)
{
if (!tags || !links)
return pl;
}
-OCStackResult OCDiscoveryCollectionPayloadAddResource(OCDiscoveryPayload *payload, OCTagsPayload *tags, OCLinksPayload *links)
-{
- OCResourceCollectionPayload* res = OCCopyCollectionResource(tags, links);
- if (res == NULL)
- {
- return OC_STACK_NO_MEMORY;
- }
- if(!payload->collectionResources)
- {
- payload->collectionResources = res;
- }
- else
- {
- OCResourceCollectionPayload *p = payload->collectionResources;
- while(p->next)
- {
- p = p->next;
- }
- p->next = res;
- }
- return OC_STACK_OK;
-}
-
void OCFreeLinksResource(OCLinksPayload *payload)
{
if (!payload)
OICFree(payload);
}
-void OCDiscoveryCollectionPayloadDestroy(OCDiscoveryPayload* payload)
-{
- if(!payload)
- {
- return;
- }
-
- OCFreeCollectionResource(payload->collectionResources);
- OICFree(payload);
-}
-
-
void OCTagsLog(const LogLevel level, const OCTagsPayload *tags)
{
if (tags)
: m_clientWrapper(cw), m_devAddr(devAddr)
{
OCResourcePayload* res = payload->resources;
- OCResourceCollectionPayload* colRes = payload->collectionResources;
if (res)
{
while(res)
{
m_devAddr.port = res->port;
}
-
- m_resources.push_back(std::shared_ptr<OC::OCResource>(
+ if (payload->baseURI)
+ {
+ OCDevAddr rdPubAddr = m_devAddr;
+ OICStrcpy(rdPubAddr.addr, sizeof(rdPubAddr.addr), payload->baseURI);
+ rdPubAddr.port = res->port;
+ m_resources.push_back(std::shared_ptr<OC::OCResource>(
+ new OC::OCResource(m_clientWrapper, rdPubAddr,
+ std::string(res->uri),
+ std::string((char*)uuidString),
+ (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+ StringLLToVector(res->types),
+ StringLLToVector(res->interfaces)
+ )));
+ }
+ else
+ {
+ m_resources.push_back(std::shared_ptr<OC::OCResource>(
new OC::OCResource(m_clientWrapper, m_devAddr,
std::string(res->uri),
std::string(uuidString),
StringLLToVector(res->types),
StringLLToVector(res->interfaces)
)));
- res = res->next;
- }
- }
- else if (colRes)
- {
- while(colRes)
- {
- OCDevAddr colAddr;
- OICStrcpy(colAddr.addr, sizeof(colAddr.addr), colRes->tags->baseURI);
- if (colRes->tags->bitmap & OC_SECURE)
- {
- colAddr.flags =
- (OCTransportFlags)(OC_FLAG_SECURE | colRes->tags->bitmap);
- if (colRes->tags->port != 0)
- {
- colAddr.port = colRes->tags->port;
- }
- }
- else
- {
- colAddr.port = colRes->tags->port;
}
-
- m_resources.push_back(std::shared_ptr<OC::OCResource>(
- new OC::OCResource(m_clientWrapper, colAddr,
- std::string(colRes->setLinks->href),
- std::string((char*)colRes->tags->di.id),
- (colRes->tags->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
- StringLLToVector(colRes->setLinks->rt),
- StringLLToVector(colRes->setLinks->itf)
- )));
- colRes = colRes->next;
+ res = res->next;
}
}
}
*
* @param interfaceType a interface type that is being queried.
* @param resourceType a resource type that is being queried.
- * @param payload A payload of the maching resource type or interface type or NULL.
+ * @param payload A payload of the matching resource type or interface type or NULL.
* @param addr A device address.
*
* @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR is returned except
// not null it will continue execution.
if (!resourceType && !interfaceType)
{
- OC_LOG(DEBUG, TAG, "Missing resource type and interace type.");
+ OC_LOG(DEBUG, TAG, "Missing resource type or interace type.");
return OC_STACK_INVALID_PARAM;
}
// If either rt or itf are NULL, it should skip remaining code execution.
if (!tLinks->rt || !tLinks->itf)
{
- OC_LOG(DEBUG, TAG, "Either resource type and interface type are missing.");
+ OC_LOG(DEBUG, TAG, "Either resource type or interface type is missing.");
continue;
}
if (resourceType)