/** To represent resource type with platform.*/
#define OC_RSRVD_RESOURCE_TYPE_PLATFORM "oic.wk.p"
+/** To represent resource type with RES.*/
+#define OC_RSRVD_RESOURCE_TYPE_RES "oic.wk.res"
+
/** To represent interface.*/
#define OC_RSRVD_INTERFACE "if"
{
OCPayload base;
+ /** Device Id */
char *sid;
/** A special case for handling RD address. */
char* baseURI;
+ /** Name */
+ char *name;
+
+ /** HREF */
+ char *uri;
+
+ /** Resource Type */
+ char *type;
+
+ /** Interface */
+ OCStringLL *interface;
+
/** This structure holds the old /oic/res response. */
OCResourcePayload *resources;
{
OIC_LOG_V(level, PL_TAG, "\tBase URI:%s", payload->baseURI);
}
+ if (payload->name)
+ {
+ OIC_LOG_V(level, PL_TAG, "\tNAME: %s", payload->name);
+ }
+ if (payload->uri)
+ {
+ OIC_LOG_V(level, PL_TAG, "\tURI: %s", payload->uri);
+ }
+ if (payload->type)
+ {
+ OIC_LOG_V(level, PL_TAG, "\tResource Type: %s", payload->type);
+ }
+ OIC_LOG(level, PL_TAG, "\tInterface:");
+ for (OCStringLL *itf = payload->interface; itf; itf = itf->next)
+ {
+ OIC_LOG_V(level, PL_TAG, "\t\t%s", itf->value);
+ }
+
OCResourcePayload* res = payload->resources;
while(res)
return;
}
OICFree(payload->sid);
+ OICFree(payload->baseURI);
+ OICFree(payload->uri);
+ OICFree(payload->type);
+ OICFree(payload->name);
+ OCFreeOCStringLL(payload->interface);
OCDiscoveryResourceDestroy(payload->resources);
OICFree(payload);
}
[ // rootArray
{ // rootMap
"di" : UUID, // device ID
+ "href": "/oic/res"
+ "rt": "oic.wk.res"
+ "n":"MyDevice"
+ "if":"oic.if.ll oic.if.baseline"
+ "di": "0685B960-736F-46F7-BEC0-9E6CBD61ADC1",
links :[ // linksArray contains maps of resources
{
href, rt, if, policy // Resource 1
err |= cbor_encoder_create_map(&rootArray, &rootMap, CborIndefiniteLength);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery map");
+ // Insert Name
+ err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_NAME,
+ sizeof(OC_RSRVD_DEVICE_NAME) - 1, payload->name);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting name");
+
+ // Insert URI
+ err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
+ payload->uri);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting href");
+
// Insert Device ID into the root map
- err |= AddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_ID, sizeof(OC_RSRVD_DEVICE_ID) - 1, payload->sid);
+ err |= AddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_ID, sizeof(OC_RSRVD_DEVICE_ID) - 1,
+ payload->sid);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting device id");
+ // Insert Resource Type
+ err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_RESOURCE_TYPE,
+ sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->type);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting RT");
+
+ // Insert interfaces
+ if (payload->interface)
+ {
+ err |= cbor_encode_text_string(&rootMap, OC_RSRVD_INTERFACE,
+ sizeof(OC_RSRVD_INTERFACE) - 1);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface types tag");
+ char *joinedTypes = OCStringLLJoin(payload->interface);
+ VERIFY_PARAM_NON_NULL(TAG, joinedTypes, "Failed creating joined string");
+ err |= cbor_encode_text_string(&rootMap, joinedTypes, strlen(joinedTypes));
+ OICFree(joinedTypes);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface types value");
+ }
+
// Insert baseURI if present
err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_BASE_URI,
sizeof(OC_RSRVD_BASE_URI) - 1,
VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
}
+ // HREF - Not a mandatory field
+ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
+ if (cbor_value_is_valid(&curVal))
+ {
+ err = cbor_value_dup_text_string(&curVal, &(out->uri), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find uri value");
+ }
+
+ // RT - Not a mandatory field
+ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
+ if (cbor_value_is_valid(&curVal))
+ {
+ err = cbor_value_dup_text_string(&curVal, &(out->type), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
+ }
+
+ // IF - Not a mandatory field
+ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal);
+ if (cbor_value_is_valid(&curVal))
+ {
+ err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &out->interface);
+ }
+ if (!out->interface)
+ {
+ if (!OCResourcePayloadAddStringLL(&out->interface, OC_RSRVD_INTERFACE_LL))
+ {
+ err = CborErrorOutOfMemory;
+ }
+ }
+
+ // Name - Not a mandatory field
+ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_NAME, &curVal);
+ if (cbor_value_is_valid(&curVal))
+ {
+ err = cbor_value_dup_text_string(&curVal, &out->name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find device name");
+ }
+
// Look for Links which will have an array as the value
CborValue linkMap;
err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
*outPayload = (OCPayload *)out;
+ OIC_LOG_PAYLOAD(DEBUG, *outPayload);
+
return OC_STACK_OK;
exit:
while (interfacePtr)
{
- if (strcmp (interfacePtr->name, interfaceFilter) == 0)
+ if ((strcmp (interfacePtr->name, interfaceFilter) == 0) &&
+ (strcmp (OC_RSRVD_INTERFACE_LL, interfaceFilter) == 0 ||
+ strcmp (OC_RSRVD_INTERFACE_DEFAULT, interfaceFilter) == 0))
{
return true;
}
* 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)
+ char *interfaceFilter,
+ char *resourceTypeFilter)
{
if (!resource)
{
return false;
}
- if ( resource->resourceProperties & OC_EXPLICIT_DISCOVERABLE)
+ 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)))
+ if (!(resourceTypeFilter && *resourceTypeFilter))
{
OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE \
resource", resource->uri);
discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
&interfaceQuery, &resourceTypeQuery);
+ bool interfaceQueryAllocated = false;
+ if (!interfaceQuery && !resourceTypeQuery)
+ {
+ interfaceQueryAllocated = true;
+ interfaceQuery = OICStrdup(OC_RSRVD_INTERFACE_LL);
+ }
if (discoveryResult == OC_STACK_OK)
{
if (payload)
{
- ((OCDiscoveryPayload*)payload)->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
- VERIFY_NON_NULL(((OCDiscoveryPayload*)payload)->sid, ERROR, OC_STACK_NO_MEMORY);
- memcpy(((OCDiscoveryPayload*)payload)->sid, OCGetServerInstanceIDString(), UUID_STRING_SIZE);
-
- if (interfaceQuery && 0 == strcmp(OC_RSRVD_INTERFACE_LL, interfaceQuery))
+ OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload;
+ discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
+ VERIFY_NON_NULL(discPayload->sid, ERROR, OC_STACK_NO_MEMORY);
+ memcpy(discPayload->sid, OCGetServerInstanceIDString(), UUID_STRING_SIZE);
+ if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
{
for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
{
- discoveryResult = BuildVirtualResourceResponse(resource,
- (OCDiscoveryPayload *)payload, &request->devAddr, false);
+ bool result = false;
+ if (resource->resourceProperties & OC_EXPLICIT_DISCOVERABLE)
+ {
+ if (resourceTypeQuery && resourceMatchesRTFilter(resource, resourceTypeQuery))
+ {
+ result = true;
+ }
+ }
+ if (resource->resourceProperties & OC_DISCOVERABLE)
+ {
+ result = true;
+ }
+
+ if (result)
+ {
+ discoveryResult = BuildVirtualResourceResponse(resource,
+ discPayload, &request->devAddr, false);
+ }
}
}
else
{
+ if ((interfaceQuery && (0 != strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL))) ||
+ !interfaceQuery)
+ {
+ 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 = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
+ VERIFY_NON_NULL(discPayload->type, ERROR, OC_STACK_NO_MEMORY);
+ OCResourcePayloadAddStringLL(&discPayload->interface, OC_RSRVD_INTERFACE_LL);
+ OCResourcePayloadAddStringLL(&discPayload->interface, OC_RSRVD_INTERFACE_DEFAULT);
+ VERIFY_NON_NULL(discPayload->interface, ERROR, OC_STACK_NO_MEMORY);
+ }
bool foundResourceAtRD = false;
for (;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
{
break;
}
discoveryResult = BuildVirtualResourceResponse(resource1,
- (OCDiscoveryPayload*)payload, &devAddr, true);
+ discPayload, &devAddr, true);
if (payload)
{
- ((OCDiscoveryPayload*)payload)->baseURI = OICStrdup(devAddr.addr);
+ discPayload->baseURI = OICStrdup(devAddr.addr);
}
OICFree(resource1->uri);
for (OCResourceType *rsrcRt = resource1->rsrcType, *rsrcRtNext = NULL; rsrcRt; )
if (!foundResourceAtRD && includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
{
discoveryResult = BuildVirtualResourceResponse(resource,
- (OCDiscoveryPayload*)payload, &request->devAddr, false);
+ discPayload, &request->devAddr, false);
}
}
// Set discoveryResult appropriately if no 'valid' resources are available
- if (((OCDiscoveryPayload*)payload)->resources == NULL && !foundResourceAtRD)
+ if (discPayload->resources == NULL && !foundResourceAtRD)
{
discoveryResult = OC_STACK_NO_RESOURCE;
}
{
OIC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
}
+ if (interfaceQueryAllocated)
+ {
+ OICFree(interfaceQuery);
+ }
}
else if (virtualUriInRequest == OC_DEVICE_URI)
{
insertResourceType(resource, pointer);
result = OC_STACK_OK;
- exit:
+exit:
if (result != OC_STACK_OK)
{
OICFree(pointer);
if (!*firstInterface)
{
- *firstInterface = newInterface;
+ // If first interface is not oic.if.baseline, by default add it as first interface type.
+ if (0 == strcmp(newInterface->name, OC_RSRVD_INTERFACE_DEFAULT))
+ {
+ *firstInterface = newInterface;
+ }
+ else
+ {
+ OCStackResult result = BindResourceInterfaceToResource(resource, OC_RSRVD_INTERFACE_DEFAULT);
+ if (result != OC_STACK_OK)
+ {
+ OICFree(newInterface->name);
+ OICFree(newInterface);
+ return;
+ }
+ if (*firstInterface)
+ {
+ (*firstInterface)->next = newInterface;
+ }
+ }
}
+ // If once add oic.if.baseline, later too below code take care of freeing memory.
else if (strcmp(newInterface->name, OC_RSRVD_INTERFACE_DEFAULT) == 0)
{
if (strcmp((*firstInterface)->name, OC_RSRVD_INTERFACE_DEFAULT) == 0)
OICFree(newInterface);
return;
}
+ // This code will not hit anymore, keeping
else
{
newInterface->next = *firstInterface;
uint8_t numResourceInterfaces;
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
- EXPECT_EQ(1, numResourceInterfaces);
- const char *resourceInterfaceName = OCGetResourceInterfaceName(handle, 0);
+ EXPECT_EQ(2, numResourceInterfaces);
+ const char *resourceInterfaceName1 = OCGetResourceInterfaceName(handle, 0);
+ EXPECT_STREQ(OC_RSRVD_INTERFACE_DEFAULT, resourceInterfaceName1);
+ const char *resourceInterfaceName = OCGetResourceInterfaceName(handle, 1);
EXPECT_STREQ("core.rw", resourceInterfaceName);
// try getting resource interface names with an invalid index
- resourceInterfaceName = OCGetResourceInterfaceName(handle, 1);
+ resourceInterfaceName = OCGetResourceInterfaceName(handle, 2);
EXPECT_STREQ(NULL, resourceInterfaceName);
// try getting resource interface names with an invalid index
resourceInterfaceName = OCGetResourceInterfaceName(handle, 10);
uint8_t numResourceInterfaces;
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
- EXPECT_EQ(1, numResourceInterfaces);
+ EXPECT_EQ(2, numResourceInterfaces);
EXPECT_EQ(OC_STACK_OK, OCStop());
}
uint8_t numResourceInterfaces;
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
- EXPECT_EQ(1, numResourceInterfaces);
+ EXPECT_EQ(2, numResourceInterfaces);
EXPECT_EQ(OC_STACK_OK, OCStop());
}
uint8_t numResourceInterfaces;
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
- EXPECT_EQ(1, numResourceInterfaces);
- const char *resourceInterfaceName = OCGetResourceInterfaceName(handle, 0);
+ EXPECT_EQ(2, numResourceInterfaces);
+ const char *resourceInterfaceName = OCGetResourceInterfaceName(handle, 1);
EXPECT_STREQ("core.rw", resourceInterfaceName);
EXPECT_EQ(OC_STACK_INVALID_PARAM, OCBindResourceInterfaceToResource(handle, NULL));
uint8_t numResourceInterfaces;
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
- EXPECT_EQ(1, numResourceInterfaces);
- const char *resourceInterfaceName = OCGetResourceInterfaceName(handle, 0);
+ EXPECT_EQ(2, numResourceInterfaces);
+ const char *resourceInterfaceName = OCGetResourceInterfaceName(handle, 1);
EXPECT_STREQ("core.rw", resourceInterfaceName);
EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle, "core.r"));
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
- EXPECT_EQ(2, numResourceInterfaces);
- resourceInterfaceName = OCGetResourceInterfaceName(handle, 1);
+ EXPECT_EQ(3, numResourceInterfaces);
+ resourceInterfaceName = OCGetResourceInterfaceName(handle, 2);
EXPECT_STREQ("core.r", resourceInterfaceName);
EXPECT_EQ(OC_STACK_OK, OCStop());
uint8_t numResourceInterfaces;
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
- EXPECT_EQ(1, numResourceInterfaces);
+ EXPECT_EQ(2, numResourceInterfaces);
EXPECT_EQ(OC_STACK_INVALID_PARAM, OCBindResourceInterfaceToResource(handle, 0));
uint8_t numResourceInterfaces;
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
- EXPECT_EQ(1, numResourceInterfaces);
+ EXPECT_EQ(2, numResourceInterfaces);
EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle, "core.r"));
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
- EXPECT_EQ(2, numResourceInterfaces);
+ EXPECT_EQ(3, numResourceInterfaces);
EXPECT_EQ(OC_STACK_OK, OCStop());
}
// Make sure the resource elements are still correct
uint8_t numResourceInterfaces;
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle2, &numResourceInterfaces));
- EXPECT_EQ(1, numResourceInterfaces);
- const char *resourceInterfaceName = OCGetResourceInterfaceName(handle2, 0);
+ EXPECT_EQ(2, numResourceInterfaces);
+ const char *resourceInterfaceName = OCGetResourceInterfaceName(handle2, 1);
EXPECT_STREQ("core.rw", resourceInterfaceName);
EXPECT_EQ(OC_STACK_OK, OCStop());