// For POSIX.1-2001 base specification,
// Refer http://pubs.opengroup.org/onlinepubs/009695399/
#define _POSIX_C_SOURCE 200112L
-#include "ocresource.h"
+
+#ifdef WITH_ARDUINO
#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include "ocresource.h"
#include "ocresourcehandler.h"
#include "ocobserve.h"
#include "occollection.h"
#include "logger.h"
#include "cJSON.h"
#include "ocpayload.h"
-
+#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
/// Module Name
-#define TAG PCF("ocresource")
+#define TAG "OIC_RI_RESOURCE"
+
#define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
- {OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
+ {OIC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
-#define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
- TAG, PCF(#arg " is NULL")); return (retVal); } }
+#define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \
+ TAG, #arg " is NULL"); return (retVal); } }
extern OCResource *headResource;
-static OCPlatformInfo savedPlatformInfo = {};
-static OCDeviceInfo savedDeviceInfo = {};
+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
return OC_STACK_OK;
}
+#ifdef TCP_ADAPTER
+/* This method will retrieve the tcp port */
+static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port)
+{
+ uint16_t p = 0;
+
+ if (endpoint->adapter == OC_ADAPTER_IP)
+ {
+ if (endpoint->flags & OC_IP_USE_V4)
+ {
+ p = caglobals.tcp.ipv4.port;
+ }
+ else if (endpoint->flags & OC_IP_USE_V6)
+ {
+ p = caglobals.tcp.ipv6.port;
+ }
+ }
+
+ *port = p;
+ return OC_STACK_OK;
+}
+#endif
+
/*
* Function will extract 0, 1 or 2 filters from query.
* More than 2 filters or unsupported filters will result in error.
*filterOne = NULL;
*filterTwo = NULL;
- OC_LOG_V(INFO, TAG, "Extracting params from %s", query);
+ 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);
{
if (numKeyValuePairsParsed >= 2)
{
- OC_LOG(ERROR, TAG, PCF("More than 2 queries params in URI."));
+ OIC_LOG(ERROR, TAG, "More than 2 queries params in URI.");
return OC_STACK_INVALID_QUERY;
}
{
return OC_STACK_INVALID_QUERY;
}
- else if (strcmp (key, OC_RSRVD_INTERFACE) == 0)
+ else if (strncasecmp(key, OC_RSRVD_INTERFACE, sizeof(OC_RSRVD_INTERFACE) - 1) == 0)
{
*filterOne = value; // if
}
- else if (strcmp (key, OC_RSRVD_RESOURCE_TYPE) == 0)
+ else if (strncasecmp(key, OC_RSRVD_RESOURCE_TYPE, sizeof(OC_RSRVD_INTERFACE) - 1) == 0)
{
*filterTwo = value; // rt
}
else
{
- OC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
+ OIC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
return OC_STACK_INVALID_QUERY;
}
++numKeyValuePairsParsed;
keyValuePair = strtok_r(NULL, OC_QUERY_SEPARATOR, &restOfQuery);
}
- OC_LOG_V(INFO, TAG, "Extracted params %s and %s.", *filterOne, *filterTwo);
+ OIC_LOG_V(INFO, TAG, "Extracted params if: %s and rt: %s.", *filterOne, *filterTwo);
return OC_STACK_OK;
}
{
return OC_RESOURCE_TYPES_URI;
}
+#ifdef ROUTING_GATEWAY
+ else if (0 == strcmp(uriInRequest, OC_RSRVD_GATEWAY_URI))
+ {
+ return OC_GATEWAY_URI;
+ }
+#endif
#ifdef WITH_PRESENCE
else if (strcmp(uriInRequest, OC_RSRVD_PRESENCE_URI) == 0)
{
if (uri == OC_PRESENCE)
{
//Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
- OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request for virtual resource."));
+ OIC_LOG(INFO, TAG, "OC_PRESENCE Request for virtual resource.");
return OC_STACK_OK;
}
#endif
}
OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
- OCDiscoveryPayload *payload, OCDevAddr *devAddr)
+ OCDiscoveryPayload *payload, OCDevAddr *devAddr, bool rdResponse)
{
if (!resourcePtr || !payload)
{
return OC_STACK_INVALID_PARAM;
}
- uint16_t port = 0;
+ uint16_t securePort = 0;
if (resourcePtr->resourceProperties & OC_SECURE)
{
- if (GetSecurePortInfo(devAddr, &port) != OC_STACK_OK)
+ if (GetSecurePortInfo(devAddr, &securePort) != OC_STACK_OK)
{
- port = 0;
+ securePort = 0;
}
}
- OCDiscoveryPayloadAddResource(payload, resourcePtr, port);
+ if (rdResponse)
+ {
+ securePort = devAddr->port;
+ }
+
+ uint16_t tcpPort = 0;
+#ifdef TCP_ADAPTER
+ if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK)
+ {
+ tcpPort = 0;
+ }
+#endif
+
+ OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort);
return OC_STACK_OK;
}
-
uint8_t IsCollectionResource (OCResource *resource)
{
if(!resource)
return 0;
}
- for (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
+ if(resource->rsrcChildResourcesHead != NULL)
{
- if (resource->rsrcResources[i])
- {
- return 1;
- }
+ return 1;
}
+
return 0;
}
}
pointer = pointer->next;
}
- OC_LOG_V(INFO, TAG, "Resource %s not found", resourceUri);
+ OIC_LOG_V(INFO, TAG, "Resource %s not found", resourceUri);
return NULL;
}
return OC_STACK_INVALID_PARAM;
}
- OC_LOG_V(INFO, TAG, "DetermineResourceHandling for %s", request->resourceUrl);
+ OIC_LOG_V(INFO, TAG, "DetermineResourceHandling for %s", request->resourceUrl);
// Check if virtual resource
if (GetTypeOfVirtualURI(request->resourceUrl) != OC_UNKNOWN_URI)
{
- OC_LOG_V (INFO, TAG, "%s is virtual", request->resourceUrl);
+ OIC_LOG_V (INFO, TAG, "%s is virtual", request->resourceUrl);
*handling = OC_RESOURCE_VIRTUAL;
*resource = headResource;
return OC_STACK_OK;
}
else
{
- OCResource *resourcePtr = NULL;
- resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
+ OCResource *resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
*resource = resourcePtr;
if (!resourcePtr)
{
case OC_EH_RESOURCE_DELETED:
result = OC_STACK_RESOURCE_DELETED;
break;
+ case OC_EH_CHANGED:
+ result = OC_STACK_RESOURCE_CHANGED;
+ break;
case OC_EH_RESOURCE_NOT_FOUND:
result = OC_STACK_NO_RESOURCE;
break;
resourceTypePtr = resourceTypePtr->next;
}
- OC_LOG_V(INFO, TAG, PCF("%s does not contain rt=%s."), resource->uri, resourceTypeFilter);
+ OIC_LOG_V(INFO, TAG, "%s does not contain rt=%s.", resource->uri, resourceTypeFilter);
return false;
}
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;
}
interfacePtr = interfacePtr->next;
}
- OC_LOG_V(INFO, TAG, PCF("%s does not contain if=%s."), resource->uri, interfaceFilter);
+ OIC_LOG_V(INFO, TAG, "%s does not contain if=%s.", resource->uri, interfaceFilter);
return false;
}
* 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)
{
- OC_LOG(ERROR, TAG, PCF("Invalid resource"));
+ OIC_LOG(ERROR, TAG, "Invalid 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))
{
- OC_LOG_V(INFO, TAG, PCF("%s no query string for EXPLICIT_DISCOVERABLE \
- resource"), resource->uri);
+ OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE \
+ resource", resource->uri);
return false;
}
}
else if ( !(resource->resourceProperties & OC_ACTIVE) ||
!(resource->resourceProperties & OC_DISCOVERABLE))
{
- OC_LOG_V(INFO, TAG, PCF("%s not ACTIVE or DISCOVERABLE"), resource->uri);
+ OIC_LOG_V(INFO, TAG, "%s not ACTIVE or DISCOVERABLE", resource->uri);
return false;
}
OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCResource *resource,
OCPayload *discoveryPayload, OCEntityHandlerResult ehResult)
{
- OCEntityHandlerResponse response = {};
+ OCEntityHandlerResponse response = {0};
response.ehResult = ehResult;
response.payload = discoveryPayload;
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)
}
OCStackResult discoveryResult = OC_STACK_ERROR;
-
- bool bMulticast = false; // Was the discovery request a multicast request?
OCPayload* payload = NULL;
- OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
+ OIC_LOG(INFO, TAG, "Entering HandleVirtualResource");
OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
// Step 1: Generate the response to discovery request
if (virtualUriInRequest == OC_WELL_KNOWN_URI)
{
- char *filterOne = NULL;
- char *filterTwo = NULL;
+ 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,
- &filterOne, &filterTwo);
+ &interfaceQuery, &resourceTypeQuery);
+ bool interfaceQueryAllocated = false;
+ if (!interfaceQuery && !resourceTypeQuery)
+ {
+ interfaceQueryAllocated = true;
+ interfaceQuery = OICStrdup(OC_RSRVD_INTERFACE_LL);
+ }
if (discoveryResult == OC_STACK_OK)
{
- payload = (OCPayload*)OCDiscoveryPayloadCreate();
+ payload = (OCPayload *)OCDiscoveryPayloadCreate();
- if(payload)
+ if (payload)
{
- for(;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
+ 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);
+ }
+
+ if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
{
- if(includeThisResourceInResponse(resource, filterOne, filterTwo))
+ for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
{
- discoveryResult = BuildVirtualResourceResponse(resource,
- (OCDiscoveryPayload*)payload,
- &request->devAddr);
+ bool result = false;
+ if (resource->resourceProperties & OC_DISCOVERABLE)
+ {
+ result = true;
+ }
+
+ if (result)
+ {
+ discoveryResult = BuildVirtualResourceResponse(resource,
+ discPayload, &request->devAddr, false);
+ }
}
}
- // Set discoveryResult appropriately if no 'valid' resources are available.
- if (((OCDiscoveryPayload*)payload)->resources == NULL)
+ else
{
- discoveryResult = OC_STACK_NO_RESOURCE;
+ 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->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)
+ {
+#ifdef WITH_RD
+ 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)
+ {
+ break;
+ }
+ 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);
+ }
+ }
+ // Set discoveryResult appropriately if no 'valid' resources are available
+ if (discPayload->resources == NULL && !foundResourceAtRD)
+ {
+ discoveryResult = OC_STACK_NO_RESOURCE;
+ }
}
}
else
}
else
{
- OC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
+ OIC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
+ }
+ if (interfaceQueryAllocated)
+ {
+ OICFree(interfaceQuery);
}
}
else if (virtualUriInRequest == OC_DEVICE_URI)
{
- payload = (OCPayload*)OCDevicePayloadCreate(OC_RSRVD_DEVICE_URI,
- OCGetServerInstanceID(), savedDeviceInfo.deviceName,
- OC_SPEC_VERSION, OC_DATA_MODEL_VERSION);
- if (!payload)
+ if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
{
- discoveryResult = OC_STACK_NO_MEMORY;
+ 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
{
- discoveryResult = OC_STACK_OK;
+ 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);
+ }
}
}
else if (virtualUriInRequest == OC_PLATFORM_URI)
{
- payload = (OCPayload*)OCPlatformPayloadCreate(
- OC_RSRVD_PLATFORM_URI,
- &savedPlatformInfo);
+ 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;
discoveryResult = OC_STACK_OK;
}
}
+#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
/**
* Step 2: Send the discovery response
* request is unicast, it should send an error(RESOURCE_NOT_FOUND - 404) response.
*/
- #ifdef WITH_PRESENCE
+#ifdef WITH_PRESENCE
if ((virtualUriInRequest == OC_PRESENCE) &&
(resource->resourceProperties & OC_ACTIVE))
{
}
else
#endif
+#ifdef ROUTING_GATEWAY
+ // Gateway uses the RMHandleGatewayRequest to respond to the request.
+ if (OC_GATEWAY_URI != virtualUriInRequest)
+#endif
{
if(discoveryResult == OC_STACK_OK)
{
SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK);
}
- else if(bMulticast == false)
+ else if(((request->devAddr.flags & OC_MULTICAST) == false) &&
+ (request->devAddr.adapter != OC_ADAPTER_RFCOMM_BTEDR) &&
+ (request->devAddr.adapter != OC_ADAPTER_GATT_BTLE))
{
- OC_LOG_V(ERROR, TAG, "Sending a (%d) error to (%d) \
- discovery request", discoveryResult, virtualUriInRequest);
+ 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
{
// Ignoring the discovery request as per RFC 7252, Section #8.2
- OC_LOG_V(INFO, TAG, "Silently ignoring the request since device does not have \
- any useful data to send");
+ OIC_LOG(INFO, TAG, "Silently ignoring the request since no useful data to send. ");
}
}
OCStackResult result = OC_STACK_OK;
OCEntityHandlerResult ehResult = OC_EH_ERROR;
- OCEntityHandlerRequest ehRequest = {};
+ OCEntityHandlerRequest ehRequest = {0};
- OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
+ 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);
+ (OCObservationId)0,
+ request->coapID);
VERIFY_SUCCESS(result, OC_STACK_OK);
// At this point we know for sure that defaultDeviceHandler exists
(char*) request->resourceUrl, defaultDeviceHandlerCallbackParameter);
if(ehResult == OC_EH_SLOW)
{
- OC_LOG(INFO, TAG, PCF("This is a slow resource"));
+ OIC_LOG(INFO, TAG, "This is a slow resource");
request->slowFlag = 1;
}
else if(ehResult == OC_EH_ERROR)
}
result = EntityHandlerCodeToOCStackCode(ehResult);
exit:
+ OCPayloadDestroy(ehRequest.payload);
return result;
}
OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
ResourceObserver *resObs = NULL;
- OCEntityHandlerRequest ehRequest = {};
+ OCEntityHandlerRequest ehRequest = {0};
- OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
+ OIC_LOG(INFO, TAG, "Entering HandleResourceWithEntityHandler");
+ OCPayloadType type = PAYLOAD_TYPE_REPRESENTATION;
+ // check the security 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->devAddr,
(OCResourceHandle)resource,
request->query,
+ type,
request->payload,
request->payloadSize,
request->numRcvdVendorSpecificHeaderOptions,
request->rcvdVendorSpecificHeaderOptions,
(OCObserveAction)request->observationOption,
- 0);
+ 0,
+ request->coapID);
VERIFY_SUCCESS(result, OC_STACK_OK);
if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
{
- OC_LOG(INFO, TAG, PCF("No observation requested"));
+ OIC_LOG(INFO, TAG, "No observation requested");
ehFlag = OC_REQUEST_FLAG;
}
else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER && !collectionResource)
{
- OC_LOG(INFO, TAG, PCF("Observation registration requested"));
+ OIC_LOG(INFO, TAG, "Observation registration requested");
+
+ ResourceObserver *obs = GetObserverUsingToken (request->requestToken,
+ request->tokenLength);
+
+ if (obs)
+ {
+ OIC_LOG (INFO, TAG, "Observer with this token already present");
+ OIC_LOG (INFO, TAG, "Possibly re-transmitted CON OBS request");
+ OIC_LOG (INFO, TAG, "Not adding observer. Not responding to client");
+ OIC_LOG (INFO, TAG, "The first request for this token is already ACKED.");
+
+ // server requests are usually free'd when the response is sent out
+ // for the request in ocserverrequest.c : HandleSingleResponse()
+ // Since we are making an early return and not responding, the server request
+ // needs to be deleted.
+ FindAndDeleteServerRequest (request);
+ return OC_STACK_OK;
+ }
result = GenerateObserverId(&ehRequest.obsInfo.obsId);
VERIFY_SUCCESS(result, OC_STACK_OK);
result = AddObserver ((const char*)(request->resourceUrl),
(const char *)(request->query),
ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
- resource, request->qos,
+ resource, request->qos, request->acceptFormat,
&request->devAddr);
if(result == OC_STACK_OK)
{
- OC_LOG(INFO, TAG, PCF("Added observer successfully"));
+ OIC_LOG(INFO, TAG, "Added observer successfully");
request->observeResult = OC_STACK_OK;
ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
}
// The error in observeResult for the request will be used when responding to this
// request by omitting the observation option/sequence number.
request->observeResult = OC_STACK_ERROR;
- OC_LOG(ERROR, TAG, PCF("Observer Addition failed"));
+ OIC_LOG(ERROR, TAG, "Observer Addition failed");
ehFlag = OC_REQUEST_FLAG;
}
else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
!collectionResource)
{
- OC_LOG(INFO, TAG, PCF("Deregistering observation requested"));
+ OIC_LOG(INFO, TAG, "Deregistering observation requested");
resObs = GetObserverUsingToken (request->requestToken, request->tokenLength);
if(result == OC_STACK_OK)
{
- OC_LOG(INFO, TAG, PCF("Removed observer successfully"));
+ 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
{
result = OC_STACK_OK;
request->observeResult = OC_STACK_ERROR;
- OC_LOG(ERROR, TAG, PCF("Observer Removal failed"));
+ OIC_LOG(ERROR, TAG, "Observer Removal failed");
}
}
else
ehResult = resource->entityHandler(ehFlag, &ehRequest, resource->entityHandlerCallbackParam);
if(ehResult == OC_EH_SLOW)
{
- OC_LOG(INFO, TAG, PCF("This is a slow resource"));
+ OIC_LOG(INFO, TAG, "This is a slow resource");
request->slowFlag = 1;
}
else if(ehResult == OC_EH_ERROR)
}
result = EntityHandlerCodeToOCStackCode(ehResult);
exit:
+ OCPayloadDestroy(ehRequest.payload);
return result;
}
}
OCStackResult result = OC_STACK_ERROR;
- OCEntityHandlerRequest ehRequest = {};
+ OCEntityHandlerRequest ehRequest = {0};
result = FormOCEntityHandlerRequest(&ehRequest,
(OCRequestHandle)request,
&request->devAddr,
(OCResourceHandle)resource,
request->query,
+ PAYLOAD_TYPE_REPRESENTATION,
request->payload,
request->payloadSize,
request->numRcvdVendorSpecificHeaderOptions,
request->rcvdVendorSpecificHeaderOptions,
(OCObserveAction)request->observationOption,
- (OCObservationId)0);
- if(result != OC_STACK_OK)
+ (OCObservationId)0,
+ request->coapID);
+ if(result == OC_STACK_OK)
{
- return result;
+ result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest);
}
- return (DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest));
+ OCPayloadDestroy(ehRequest.payload);
+ return result;
}
OCStackResult
}
case OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER:
{
- OC_LOG(INFO, TAG, PCF("OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER"));
+ OIC_LOG(INFO, TAG, "OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER");
return OC_STACK_ERROR;
}
case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
}
default:
{
- OC_LOG(INFO, TAG, PCF("Invalid Resource Determination"));
+ OIC_LOG(INFO, TAG, "Invalid Resource Determination");
return OC_STACK_ERROR;
}
}
void DeletePlatformInfo()
{
- OC_LOG(INFO, TAG, PCF("Deleting platform info."));
+ OIC_LOG(INFO, TAG, "Deleting platform info.");
OICFree(savedPlatformInfo.platformID);
savedPlatformInfo.platformID = NULL;
if (res != OC_STACK_OK)
{
- OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
+ OIC_LOG_V(ERROR, TAG, "Failed to save platform info. errno(%d)", res);
}
else
{
- OC_LOG(ERROR, TAG, PCF("Platform info saved."));
+ OIC_LOG(INFO, TAG, "Platform info saved.");
}
return res;
void DeleteDeviceInfo()
{
- OC_LOG(INFO, TAG, PCF("Deleting device info."));
+ 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;
}
static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
return OC_STACK_NO_MEMORY;
}
+ if (info.types)
+ {
+ 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)
+ {
+ // Append the oic.wk.d at the start of rt link parameter value.
+ OCStringLL *dest = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
+ if (!dest)
+ {
+ DeleteDeviceInfo();
+ return OC_STACK_NO_MEMORY;
+ }
+ dest->value = OICStrdup (OC_RSRVD_RESOURCE_TYPE_DEVICE);
+ if (!dest->value)
+ {
+ DeleteDeviceInfo();
+ return OC_STACK_NO_MEMORY;
+ }
+ dest->next = savedDeviceInfo.types;
+ savedDeviceInfo.types = dest;
+ }
+ if(!savedDeviceInfo.types && info.types)
+ {
+ DeleteDeviceInfo();
+ return OC_STACK_NO_MEMORY;
+ }
+ }
+
+ if (info.specVersion)
+ {
+ savedDeviceInfo.specVersion = OICStrdup(info.specVersion);
+ if(!savedDeviceInfo.specVersion && info.specVersion)
+ {
+ DeleteDeviceInfo();
+ return OC_STACK_NO_MEMORY;
+ }
+ }
+ else
+ {
+ savedDeviceInfo.specVersion = OICStrdup(OC_SPEC_VERSION);
+ if(!savedDeviceInfo.specVersion && OC_SPEC_VERSION)
+ {
+ DeleteDeviceInfo();
+ return OC_STACK_NO_MEMORY;
+ }
+ }
+
+ if (info.dataModelVersions)
+ {
+ savedDeviceInfo.dataModelVersions = CloneOCStringLL(info.dataModelVersions);
+ if(!savedDeviceInfo.dataModelVersions && info.dataModelVersions)
+ {
+ DeleteDeviceInfo();
+ return OC_STACK_NO_MEMORY;
+ }
+ }
+ 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;
+ }
+ }
+
return OC_STACK_OK;
}
VERIFY_SUCCESS(res, OC_STACK_OK);
- if(OCGetServerInstanceID() == NULL)
+ if (OCGetServerInstanceIDString() == NULL)
{
- OC_LOG(INFO, TAG, PCF("Device ID generation failed"));
+ OIC_LOG(INFO, TAG, "Device ID generation failed");
res = OC_STACK_ERROR;
goto exit;
}
- OC_LOG(INFO, TAG, PCF("Device initialized successfully."));
+ OIC_LOG(INFO, TAG, "Device initialized successfully.");
return OC_STACK_OK;
- exit:
- DeleteDeviceInfo();
- return res;
-
+exit:
+ DeleteDeviceInfo();
+ return res;
}