// For POSIX.1-2001 base specification,
// Refer http://pubs.opengroup.org/onlinepubs/009695399/
#define _POSIX_C_SOURCE 200112L
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
-#ifdef WITH_STRING_H
+#include "iotivity_config.h"
+#ifdef HAVE_STRING_H
#include <string.h>
#endif
-#ifdef WITH_STRINGS_H
+#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include "secureresourcemanager.h"
#include "cacommon.h"
#include "cainterface.h"
-#include "rdpayload.h"
#include "ocpayload.h"
-#ifdef WITH_RD
-#include "rd_server.h"
-#endif
-
#ifdef ROUTING_GATEWAY
#include "routingmanager.h"
#endif
+#ifdef RD_SERVER
+#include "rd_database.h"
+#endif
+
/// Module Name
#define TAG "OIC_RI_RESOURCE"
*/
static OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
OCDiscoveryPayload* payload,
- OCDevAddr *endpoint,
- bool rdResponse);
+ OCDevAddr *endpoint);
//-----------------------------------------------------------------------------
// Default resource entity handler function
OIC_LOG_V(INFO, TAG, "Extracting params from %s", query);
+ if (strnlen(query, MAX_QUERY_LENGTH) >= MAX_QUERY_LENGTH)
+ {
+ OIC_LOG(ERROR, TAG, "Query exceeds maximum length.");
+ return OC_STACK_INVALID_QUERY;
+ }
+
char *keyValuePair = strtok_r (query, OC_QUERY_SEPARATOR, &restOfQuery);
while(keyValuePair)
return OC_PRESENCE;
}
#endif //WITH_PRESENCE
+
+#ifdef MQ_BROKER
+ else if (0 == strcmp(uriInRequest, OC_RSRVD_WELL_KNOWN_MQ_URI))
+ {
+ return OC_MQ_BROKER_URI;
+ }
+#endif //MQ_BROKER
return OC_UNKNOWN_URI;
}
}
OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
- OCDiscoveryPayload *payload, OCDevAddr *devAddr, bool rdResponse)
+ OCDiscoveryPayload *payload, OCDevAddr *devAddr)
{
if (!resourcePtr || !payload)
{
}
}
- if (rdResponse)
- {
- securePort = devAddr->port;
- }
-
- uint16_t tcpPort = 0;
#ifdef TCP_ADAPTER
+ uint16_t tcpPort = 0;
if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK)
{
tcpPort = 0;
switch (ehResult)
{
case OC_EH_OK:
+ case OC_EH_CONTENT:
+ case OC_EH_VALID:
result = OC_STACK_OK;
break;
case OC_EH_SLOW:
return OCDoResponse(&response);
}
-#ifdef WITH_RD
-static OCStackResult checkResourceExistsAtRD(const char *interfaceType, const char *resourceType,
- OCResource **payload, OCDevAddr *devAddr)
-{
- 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
- {
- OIC_LOG_V(ERROR, TAG, "The resource type or interface type doe not exist \
- on the resource directory");
- }
- return OC_STACK_ERROR;
-}
-#endif
-
static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
{
if (!request || !resource)
OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
// Step 1: Generate the response to discovery request
- if (virtualUriInRequest == OC_WELL_KNOWN_URI)
+ if (virtualUriInRequest == OC_WELL_KNOWN_URI
+#ifdef MQ_BROKER
+ || virtualUriInRequest == OC_MQ_BROKER_URI
+#endif
+ )
{
if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
{
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);
- }
+ bool foundResourceAtRD = false;
if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
{
+ OCResourceProperty prop = OC_DISCOVERABLE;
+#ifdef MQ_BROKER
+ if (OC_MQ_BROKER_URI == virtualUriInRequest)
+ {
+ prop = OC_MQ_BROKER;
+ }
+#endif
+
for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
{
- bool result = false;
- if (resource->resourceProperties & OC_DISCOVERABLE)
+ foundResourceAtRD = false;
+#ifdef RD_SERVER
+ if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
{
- result = true;
+ if (OC_STACK_OK == OCRDDatabaseCheckResources(interfaceQuery, resourceTypeQuery, discPayload))
+ {
+ foundResourceAtRD = true;
+ discoveryResult = OC_STACK_OK;
+ }
}
-
- if (result)
+#endif
+ if (!foundResourceAtRD && (resource->resourceProperties & prop))
{
- discoveryResult = BuildVirtualResourceResponse(resource,
- discPayload, &request->devAddr, false);
+ discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
}
}
}
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)
{
-#ifdef WITH_RD
+#ifdef RD_SERVER
if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
{
- OCResource *resource1 = NULL;
- OCDevAddr devAddr;
- discoveryResult = checkResourceExistsAtRD(interfaceQuery,
- resourceTypeQuery, &resource1, &devAddr);
- if (discoveryResult != OC_STACK_OK)
+ if (OC_STACK_OK == OCRDDatabaseCheckResources(interfaceQuery, resourceTypeQuery, discPayload))
{
- break;
+ foundResourceAtRD = true;
+ discoveryResult = OC_STACK_OK;
}
- discoveryResult = BuildVirtualResourceResponse(resource1,
- discPayload, &devAddr, true);
- if (payload)
- {
- discPayload->baseURI = OICStrdup(devAddr.addr);
- }
- OICFree(resource1->uri);
- for (OCResourceType *rsrcRt = resource1->rsrcType, *rsrcRtNext = NULL; rsrcRt; )
- {
- rsrcRtNext = rsrcRt->next;
- OICFree(rsrcRt->resourcetypename);
- OICFree(rsrcRt);
- rsrcRt = rsrcRtNext;
- }
-
- for (OCResourceInterface *rsrcPtr = resource1->rsrcInterface, *rsrcNext = NULL; rsrcPtr; )
- {
- rsrcNext = rsrcPtr->next;
- OICFree(rsrcPtr->name);
- OICFree(rsrcPtr);
- rsrcPtr = rsrcNext;
- }
- foundResourceAtRD = true;
}
#endif
if (!foundResourceAtRD && includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
{
- discoveryResult = BuildVirtualResourceResponse(resource,
- discPayload, &request->devAddr, false);
+ discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
}
}
// Set discoveryResult appropriately if no 'valid' resources are available
discoveryResult = OC_STACK_NO_RESOURCE;
}
}
+ if (discoveryResult == OC_STACK_OK && foundResourceAtRD == false)
+ {
+ 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);
+ }
+ }
}
else
{
discoveryResult = OC_STACK_NO_MEMORY;
}
+
}
else
{
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);
}
{
// 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);
}
}
}
- if (request && strcmp(request->resourceUrl, OC_RSRVD_RD_URI) == 0)
- {
- type = PAYLOAD_TYPE_RD;
- }
-
result = FormOCEntityHandlerRequest(&ehRequest,
(OCRequestHandle)request,
request->method,
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
{
OIC_LOG(INFO, TAG, "Removed observer successfully");
request->observeResult = OC_STACK_OK;
+ // There should be no observe option header for de-registration response.
+ // Set as an invalid value here so we can detect it later and remove the field in response.
+ request->observationOption = MAX_SEQUENCE_NUMBER + 1;
}
else
{