X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fstack%2Fsrc%2Focresource.c;h=00ee331862c573a53d9a473005049afa9dd86a83;hb=41e04322a0b5684ed05e3b7968f44fc172a664a6;hp=d33849931f8755d4f0f702fde80569e6313bae24;hpb=c96e932067b534b2b294b092d4f87bb495aa6807;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/src/ocresource.c b/resource/csdk/stack/src/ocresource.c index d338499..00ee331 100755 --- a/resource/csdk/stack/src/ocresource.c +++ b/resource/csdk/stack/src/ocresource.c @@ -25,7 +25,18 @@ // 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 + +#include "iotivity_config.h" +#ifdef HAVE_STRING_H #include +#endif +#ifdef HAVE_STRINGS_H +#include +#endif + #include "ocresource.h" #include "ocresourcehandler.h" #include "ocobserve.h" @@ -38,17 +49,16 @@ #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" @@ -58,6 +68,8 @@ #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}; @@ -67,8 +79,7 @@ static OCDeviceInfo savedDeviceInfo = {0}; */ static OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, OCDiscoveryPayload* payload, - OCDevAddr *endpoint, - bool rdResponse); + OCDevAddr *endpoint); //----------------------------------------------------------------------------- // Default resource entity handler function @@ -105,6 +116,29 @@ static OCStackResult GetSecurePortInfo(OCDevAddr *endpoint, uint16_t *port) 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. @@ -125,6 +159,12 @@ static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char 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) @@ -141,11 +181,11 @@ static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char { 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 } @@ -159,7 +199,7 @@ static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char keyValuePair = strtok_r(NULL, OC_QUERY_SEPARATOR, &restOfQuery); } - OIC_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; } @@ -193,6 +233,21 @@ static OCVirtualResources GetTypeOfVirtualURI(const char *uriInRequest) 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 + +#ifdef TCP_ADAPTER + else if (strcmp(uriInRequest, OC_RSRVD_KEEPALIVE_URI) == 0) + { + return OC_KEEPALIVE_RESOURCE_URI; + } +#endif + return OC_UNKNOWN_URI; } @@ -279,27 +334,32 @@ OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr, } OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, - OCDiscoveryPayload *payload, OCDevAddr *devAddr, bool rdResponse) + OCDiscoveryPayload *payload, OCDevAddr *devAddr) { 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; } } - if (rdResponse) +#ifdef TCP_ADAPTER + uint16_t tcpPort = 0; + if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK) { - port = devAddr->port; + tcpPort = 0; } + OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort); +#else + OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort); +#endif - OCDiscoveryPayloadAddResource(payload, resourcePtr, port); return OC_STACK_OK; } @@ -420,6 +480,8 @@ OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult) switch (ehResult) { case OC_EH_OK: + case OC_EH_CONTENT: + case OC_EH_VALID: result = OC_STACK_OK; break; case OC_EH_SLOW: @@ -437,6 +499,9 @@ OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult) 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; @@ -492,7 +557,9 @@ static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter) 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; } @@ -509,8 +576,8 @@ static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter) * 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) { @@ -518,14 +585,13 @@ static bool includeThisResourceInResponse(OCResource *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); @@ -558,102 +624,6 @@ OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCRes 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) @@ -662,8 +632,6 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource } OCStackResult discoveryResult = OC_STACK_ERROR; - - bool bMulticast = false; // Was the discovery request a multicast request? OCPayload* payload = NULL; OIC_LOG(INFO, TAG, "Entering HandleVirtualResource"); @@ -671,13 +639,29 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource 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) + { + 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, &interfaceQuery, &resourceTypeQuery); + bool interfaceQueryAllocated = false; + if (!interfaceQuery && !resourceTypeQuery) + { + interfaceQueryAllocated = true; + interfaceQuery = OICStrdup(OC_RSRVD_INTERFACE_LL); + } if (discoveryResult == OC_STACK_OK) { @@ -685,69 +669,115 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource 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); + OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload; + bool foundResourceAtRD = false; - if (interfaceQuery && 0 == strcmp(OC_RSRVD_INTERFACE_LL, interfaceQuery)) + 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) { - discoveryResult = BuildVirtualResourceResponse(resource, - (OCDiscoveryPayload *)payload, &request->devAddr, false); + foundResourceAtRD = false; +#ifdef RD_SERVER + if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0) + { + if (OC_STACK_OK == OCRDDatabaseCheckResources(interfaceQuery, resourceTypeQuery, discPayload)) + { + foundResourceAtRD = true; + discoveryResult = OC_STACK_OK; + } + } +#endif + if (!foundResourceAtRD && (resource->resourceProperties & prop)) + { + discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr); + } } } else { - bool foundResourceAtRD = false; + 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); + } 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, - (OCDiscoveryPayload*)payload, &devAddr, true); - if (payload) - { - ((OCDiscoveryPayload*)payload)->baseURI = OICStrdup(devAddr.addr); - } - OCDiscoveryResourceDestroy(resource1); - foundResourceAtRD = true; } #endif if (!foundResourceAtRD && includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery)) { - discoveryResult = BuildVirtualResourceResponse(resource, - (OCDiscoveryPayload*)payload, &request->devAddr, false); + discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr); } } // 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; } } + 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 { OIC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult); } + if (interfaceQueryAllocated) + { + OICFree(interfaceQuery); + } } 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) { @@ -755,20 +785,35 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource } else { - payload = (OCPayload*) OCDevicePayloadCreate(deviceId, savedDeviceInfo.deviceName, - OC_SPEC_VERSION, OC_DATA_MODEL_VERSION); - if (!payload) + char *dataModelVersions = OCCreateString(savedDeviceInfo.dataModelVersions); + if (!dataModelVersions) { discoveryResult = OC_STACK_NO_MEMORY; } else { - discoveryResult = OC_STACK_OK; + 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) { + 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) { @@ -788,7 +833,14 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource } #endif - +#ifdef TCP_ADAPTER + else if (OC_KEEPALIVE_RESOURCE_URI == virtualUriInRequest) + { + // Received request for a keepalive + OIC_LOG(INFO, TAG, "Request is for KeepAlive Request"); + discoveryResult = HandleKeepAliveRequest(request, resource); + } +#endif /** * Step 2: Send the discovery response * @@ -807,33 +859,53 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource 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 { - if(discoveryResult == OC_STACK_OK) - { - SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK); - } - else if(bMulticast == 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 +#if TCP_ADAPTER + // KeepAlive uses the HandleKeepAliveRequest to respond to the request. + if (OC_KEEPALIVE_RESOURCE_URI != virtualUriInRequest) +#endif { - // Ignoring the discovery request as per RFC 7252, Section #8.2 - OIC_LOG(INFO, TAG, "Silently ignoring the request since device does not have \ - any useful data to send"); + 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 + { + // 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); + } } } @@ -866,7 +938,8 @@ HandleDefaultDeviceEntityHandler (OCServerRequest *request) 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 @@ -913,11 +986,6 @@ HandleResourceWithEntityHandler (OCServerRequest *request, } - if (request && strcmp(request->resourceUrl, OC_RSRVD_RD_URI) == 0) - { - type = PAYLOAD_TYPE_RD; - } - result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle)request, request->method, @@ -930,7 +998,8 @@ HandleResourceWithEntityHandler (OCServerRequest *request, 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) @@ -975,15 +1044,21 @@ HandleResourceWithEntityHandler (OCServerRequest *request, 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 { - result = OC_STACK_OK; - // 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; OIC_LOG(ERROR, TAG, "Observer Addition failed"); ehFlag = OC_REQUEST_FLAG; + FindAndDeleteServerRequest(request); + goto exit; } } @@ -1010,12 +1085,16 @@ HandleResourceWithEntityHandler (OCServerRequest *request, { 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; OIC_LOG(ERROR, TAG, "Observer Removal failed"); + FindAndDeleteServerRequest(request); + goto exit; } } else @@ -1064,7 +1143,8 @@ HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request, request->numRcvdVendorSpecificHeaderOptions, request->rcvdVendorSpecificHeaderOptions, (OCObserveAction)request->observationOption, - (OCObservationId)0); + (OCObservationId)0, + request->coapID); if(result == OC_STACK_OK) { result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest); @@ -1220,7 +1300,12 @@ 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; } static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info) @@ -1233,6 +1318,87 @@ 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; }