X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=resource%2Fcsdk%2Fstack%2Fsrc%2Focresource.c;h=16579f8ffb922bcd27fbb166ea19db45638a86c9;hb=7f00f942c39b7bc27c7eeecf213a239c3fe4173c;hp=6b8c542934996ae7a1fe8335b656e07793ccc16f;hpb=92a3e77a05c814567bdf26a04535c3f8aec37135;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/src/ocresource.c b/resource/csdk/stack/src/ocresource.c index 6b8c542..16579f8 100755 --- a/resource/csdk/stack/src/ocresource.c +++ b/resource/csdk/stack/src/ocresource.c @@ -44,35 +44,25 @@ #include "oic_malloc.h" #include "oic_string.h" #include "logger.h" -#include "cJSON.h" #include "ocpayload.h" #include "secureresourcemanager.h" #include "cacommon.h" #include "cainterface.h" #include "ocpayload.h" - +#include "oickeepaliveinternal.h" +#include "platform_features.h" +#include "payload_logging.h" #ifdef ROUTING_GATEWAY #include "routingmanager.h" #endif -#ifdef RD_SERVER -#include "rd_database.h" -#endif - /// Module Name #define TAG "OIC_RI_RESOURCE" -#define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \ +#define VERIFY_SUCCESS(op) { if (op != (OC_STACK_OK)) \ {OIC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} } -#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}; /** * Prepares a Payload for response. @@ -118,7 +108,7 @@ static OCStackResult GetSecurePortInfo(OCDevAddr *endpoint, uint16_t *port) #ifdef TCP_ADAPTER /* This method will retrieve the tcp port */ -static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port) +static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port, bool secured) { uint16_t p = 0; @@ -126,11 +116,11 @@ static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port) { if (endpoint->flags & OC_IP_USE_V4) { - p = caglobals.tcp.ipv4.port; + p = secured ? caglobals.tcp.ipv4s.port : caglobals.tcp.ipv4.port; } else if (endpoint->flags & OC_IP_USE_V6) { - p = caglobals.tcp.ipv6.port; + p = secured ? caglobals.tcp.ipv6s.port : caglobals.tcp.ipv6.port; } } @@ -146,8 +136,13 @@ static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port) * Resource and device filters in the SAME query are NOT validated * and resources will likely not clear filters. */ -static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char **filterTwo) +OCStackResult ExtractFiltersFromQuery(const char *query, char **filterOne, char **filterTwo) { + if (!query) + { + OIC_LOG_V(ERROR, TAG, "Query is empty!"); + return OC_STACK_INVALID_QUERY; + } char *key = NULL; char *value = NULL; char *queryDup = NULL; @@ -301,14 +296,14 @@ static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *q *filterOne = NULL; *filterTwo = NULL; - #ifdef WITH_PRESENCE +#ifdef WITH_PRESENCE if (uri == OC_PRESENCE) { //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK. OIC_LOG(INFO, TAG, "OC_PRESENCE Request for virtual resource."); return OC_STACK_OK; } - #endif +#endif OCStackResult result = OC_STACK_OK; @@ -320,23 +315,57 @@ static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *q return result; } -OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr, - OCRepPayload** payload) +bool appendOCStringLL(OCRepPayload *device, OCStringLL *dmv) { - OCRepPayload *tempPayload = OCRepPayloadCreate(); + int size = 0; + for (OCStringLL *ll = dmv; ll; ll = ll->next, size++); + size_t dim[MAX_REP_ARRAY_DEPTH] = {size, 0, 0}; + char **dt = (char **)OICMalloc(sizeof(char *) * size); + int i = 0; + VERIFY_PARAM_NON_NULL(TAG, dt, "Data Model Version allocation failed."); + for (OCStringLL *ll = dmv; ll; ll = ll->next, i++) + { + dt[i] = OICStrdup(ll->value); + VERIFY_PARAM_NON_NULL(TAG, dt[i], "Data Model Version adding failed."); + } + if (!OCRepPayloadSetStringArrayAsOwner(device, OC_RSRVD_DATA_MODEL_VERSION, dt, dim)) + { + goto exit; + } + return true; +exit: + for (int i = 0; i < size; i++) + { + OICFree(dt[i]); + } + OICFree(dt); + return false; +} + +static OCStackResult BuildDevicePlatformPayload(const OCResource *resourcePtr, OCRepPayload** payload, bool addDeviceId) +{ if (!resourcePtr) { - OCRepPayloadDestroy(tempPayload); return OC_STACK_INVALID_PARAM; } - if(!tempPayload) + OCRepPayload *tempPayload = OCRepPayloadCreate(); + if (!tempPayload) { return OC_STACK_NO_MEMORY; } - OCRepPayloadSetUri(tempPayload, resourcePtr->uri); + if (addDeviceId) + { + const char *deviceId = OCGetServerInstanceIDString(); + if (!deviceId) + { + OIC_LOG(ERROR, TAG, "Failed retrieving device id."); + return OC_STACK_ERROR; + } + OCRepPayloadSetPropString(tempPayload, OC_RSRVD_DEVICE_ID, deviceId); + } OCResourceType *resType = resourcePtr->rsrcType; while(resType) @@ -355,8 +384,22 @@ OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr, OCAttribute *resAttrib = resourcePtr->rsrcAttributes; while(resAttrib) { - OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, - resAttrib->attrValue); + if (resAttrib->attrName && resAttrib->attrValue) + { + if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, resAttrib->attrName)) + { + char *dmv = OCCreateString((OCStringLL *)resAttrib->attrValue); + if (dmv) + { + OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, dmv); + OICFree(dmv); + } + } + else + { + OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, (char *)resAttrib->attrValue); + } + } resAttrib = resAttrib->next; } @@ -372,6 +415,117 @@ OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr, return OC_STACK_OK; } +OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr, + OCRepPayload** payload, OCDevAddr *devAddr) +{ + if (!resourcePtr) + { + return OC_STACK_INVALID_PARAM; + } + + OCRepPayload *tempPayload = OCRepPayloadCreate(); + if(!tempPayload) + { + return OC_STACK_NO_MEMORY; + } + + OCRepPayloadSetPropString(tempPayload, OC_RSRVD_HREF, resourcePtr->uri); + + uint8_t numElement = 0; + if (OC_STACK_OK == OCGetNumberOfResourceTypes((OCResource *)resourcePtr, &numElement)) + { + size_t rtDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0}; + char **rt = (char **)OICMalloc(sizeof(char *) * numElement); + if (!rt) + { + OIC_LOG(ERROR, TAG, "Resource type allocation failed."); + OCRepPayloadDestroy(tempPayload); + return OC_STACK_NO_MEMORY; + } + for (uint8_t i = 0; i < numElement; ++i) + { + const char *value = OCGetResourceTypeName((OCResource *)resourcePtr, i); + OIC_LOG_V(DEBUG, TAG, "value: %s", value); + rt[i] = OICStrdup(value); + } + OCRepPayloadSetStringArrayAsOwner(tempPayload, OC_RSRVD_RESOURCE_TYPE, rt, rtDim); + } + + numElement = 0; + if (OC_STACK_OK == OCGetNumberOfResourceInterfaces((OCResource *)resourcePtr, &numElement)) + { + size_t ifDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0}; + char **itf = (char **)OICMalloc(sizeof(char *) * numElement); + if (!itf) + { + OIC_LOG(ERROR, TAG, "Resource interface allocation failed."); + OCRepPayloadDestroy(tempPayload); + return OC_STACK_NO_MEMORY; + } + for (uint8_t i = 0; i < numElement; ++i) + { + const char *value = OCGetResourceInterfaceName((OCResource *)resourcePtr, i); + OIC_LOG_V(DEBUG, TAG, "value: %s", value); + itf[i] = OICStrdup(value); + } + OCRepPayloadSetStringArrayAsOwner(tempPayload, OC_RSRVD_INTERFACE, itf, ifDim); + } + + for (OCAttribute *resAttrib = resourcePtr->rsrcAttributes; resAttrib; resAttrib = resAttrib->next) + { + if (resAttrib->attrName && resAttrib->attrValue) + { + if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, resAttrib->attrName)) + { + char *dmv = OCCreateString((OCStringLL *)resAttrib->attrValue); + if (dmv) + { + OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, dmv); + OICFree(dmv); + } + } + else + { + OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, (char *)resAttrib->attrValue); + } + } + } + + if (devAddr) + { + OCResourceProperty p = OCGetResourceProperties((OCResourceHandle *)resourcePtr); + OCRepPayload *policy = OCRepPayloadCreate(); + if (!policy) + { + OCPayloadDestroy((OCPayload *)tempPayload); + return OC_STACK_NO_MEMORY; + } + OCRepPayloadSetPropInt(policy, OC_RSRVD_BITMAP, ((p & OC_DISCOVERABLE) | (p & OC_OBSERVABLE))); + if (p & OC_SECURE) + { + OCRepPayloadSetPropBool(policy, OC_RSRVD_SECURE, p & OC_SECURE); + uint16_t securePort = 0; + if (GetSecurePortInfo(devAddr, &securePort) != OC_STACK_OK) + { + securePort = 0; + } + OCRepPayloadSetPropInt(policy, OC_RSRVD_HOSTING_PORT, securePort); + } + OCRepPayloadSetPropObjectAsOwner(tempPayload, OC_RSRVD_POLICY, policy); + } + + if (!*payload) + { + *payload = tempPayload; + } + else + { + OCRepPayloadAppend(*payload, tempPayload); + } + + return OC_STACK_OK; +} + OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, OCDiscoveryPayload *payload, OCDevAddr *devAddr) { @@ -390,10 +544,8 @@ OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, #ifdef TCP_ADAPTER uint16_t tcpPort = 0; - if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK) - { - tcpPort = 0; - } + GetTCPPortInfo(devAddr, &tcpPort, (resourcePtr->resourceProperties & OC_SECURE)); + OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort); #else OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort); @@ -402,21 +554,6 @@ OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, return OC_STACK_OK; } -uint8_t IsCollectionResource (OCResource *resource) -{ - if(!resource) - { - return 0; - } - - if(resource->rsrcChildResourcesHead != NULL) - { - return 1; - } - - return 0; -} - OCResource *FindResourceByUri(const char* resourceUri) { if(!resourceUri) @@ -437,7 +574,6 @@ OCResource *FindResourceByUri(const char* resourceUri) return NULL; } - OCStackResult DetermineResourceHandling (const OCServerRequest *request, ResourceHandling *handling, OCResource **resource) @@ -481,7 +617,7 @@ OCStackResult DetermineResourceHandling (const OCServerRequest *request, return OC_STACK_NO_RESOURCE; } - if (IsCollectionResource (resourcePtr)) + if (resourcePtr && resourcePtr->rsrcChildResourcesHead != NULL) { // Collection resource if (resourcePtr->entityHandler != defaultResourceEHandler) @@ -532,9 +668,6 @@ OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult) case OC_EH_FORBIDDEN: result = OC_STACK_FORBIDDEN_REQ; break; - case OC_EH_INTERNAL_SERVER_ERROR: - result = OC_STACK_INTERNAL_SERVER_ERROR; - break; case OC_EH_RESOURCE_CREATED: result = OC_STACK_RESOURCE_CREATED; break; @@ -547,6 +680,24 @@ OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult) case OC_EH_RESOURCE_NOT_FOUND: result = OC_STACK_NO_RESOURCE; break; + case OC_EH_INTERNAL_SERVER_ERROR: + result = OC_STACK_INTERNAL_SERVER_ERROR; + break; + case OC_EH_NOT_IMPLEMENTED: + result = OC_STACK_NOT_IMPLEMENTED; + break; + case OC_EH_BAD_GATEWAY: + result = OC_STACK_BAD_GATEWAY; + break; + case OC_EH_SERVICE_UNAVAILABLE: + result = OC_STACK_SERVICE_UNAVAILABLE; + break; + case OC_EH_RETRANSMIT_TIMEOUT: + result = OC_STACK_GATEWAY_TIMEOUT; + break; + case OC_EH_PROXY_NOT_SUPPORTED: + result = OC_STACK_PROXY_NOT_SUPPORTED; + break; default: result = OC_STACK_ERROR; } @@ -561,21 +712,24 @@ static bool resourceMatchesRTFilter(OCResource *resource, char *resourceTypeFilt return false; } - // Null or empty is analogous to no filter. - if (resourceTypeFilter == NULL || *resourceTypeFilter == 0) + // Null is analogous to no filter. + if (NULL == resourceTypeFilter) { return true; } - OCResourceType *resourceTypePtr = resource->rsrcType; + // Empty resourceType filter is analogous to error query + if (0 == strlen(resourceTypeFilter)) + { + return false; + } - while (resourceTypePtr) + for (OCResourceType *rtPtr = resource->rsrcType; rtPtr; rtPtr = rtPtr->next) { - if (strcmp (resourceTypePtr->resourcetypename, resourceTypeFilter) == 0) + if (0 == strcmp(rtPtr->resourcetypename, resourceTypeFilter)) { return true; } - resourceTypePtr = resourceTypePtr->next; } OIC_LOG_V(INFO, TAG, "%s does not contain rt=%s.", resource->uri, resourceTypeFilter); @@ -589,23 +743,26 @@ static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter) return false; } - // Null or empty is analogous to no filter. - if (interfaceFilter == NULL || *interfaceFilter == 0) + // Null is analogous to no filter. + if (NULL == interfaceFilter) { return true; } - OCResourceInterface *interfacePtr = resource->rsrcInterface; + // Empty interface filter is analogous to error query + if (0 == strlen(interfaceFilter)) + { + return false; + } - while (interfacePtr) + for (OCResourceInterface *ifPtr = resource->rsrcInterface; ifPtr; ifPtr = ifPtr->next) { - if ((strcmp (interfacePtr->name, interfaceFilter) == 0) && - (strcmp (OC_RSRVD_INTERFACE_LL, interfaceFilter) == 0 || - strcmp (OC_RSRVD_INTERFACE_DEFAULT, interfaceFilter) == 0)) + if (0 == strcmp(ifPtr->name, interfaceFilter) || + 0 == strcmp(OC_RSRVD_INTERFACE_LL, interfaceFilter) || + 0 == strcmp(OC_RSRVD_INTERFACE_DEFAULT, interfaceFilter)) { return true; } - interfacePtr = interfacePtr->next; } OIC_LOG_V(INFO, TAG, "%s does not contain if=%s.", resource->uri, interfaceFilter); @@ -635,12 +792,12 @@ static bool includeThisResourceInResponse(OCResource *resource, */ if (!(resourceTypeFilter && *resourceTypeFilter)) { - OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE \ + OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE\ resource", resource->uri); return false; } } - else if ( !(resource->resourceProperties & OC_ACTIVE) || + else if (!(resource->resourceProperties & OC_ACTIVE) || !(resource->resourceProperties & OC_DISCOVERABLE)) { OIC_LOG_V(INFO, TAG, "%s not ACTIVE or DISCOVERABLE", resource->uri); @@ -649,7 +806,6 @@ static bool includeThisResourceInResponse(OCResource *resource, return resourceMatchesIFFilter(resource, interfaceFilter) && resourceMatchesRTFilter(resource, resourceTypeFilter); - } OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCResource *resource, @@ -660,12 +816,138 @@ OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCRes response.ehResult = ehResult; response.payload = discoveryPayload; response.persistentBufferFlag = 0; - response.requestHandle = (OCRequestHandle) request; + response.requestHandle = (OCRequestHandle) request->requestId; response.resourceHandle = (OCResourceHandle) resource; return OCDoResponse(&response); } +static OCStackResult EHRequest(OCEntityHandlerRequest *ehRequest, OCPayloadType type, + OCServerRequest *request, OCResource *resource) +{ + return FormOCEntityHandlerRequest(ehRequest, + (OCRequestHandle)request->requestId, + request->method, + &request->devAddr, + (OCResourceHandle)resource, + request->query, + type, + request->payload, + request->payloadSize, + request->numRcvdVendorSpecificHeaderOptions, + request->rcvdVendorSpecificHeaderOptions, + (OCObserveAction)request->observationOption, + (OCObservationId)0, + request->coapID); +} + +#ifdef RD_SERVER +/** + * Find resource at the resource directory server. This resource is not local resource but a + * remote resource. + * + * @param resource The resource to check the matching resource URI. + * @param interfaceQuery The interface query parameter. + * @param resourceTypeQuery The resourceType query parameter. + * @param discPayload The payload that will be added with the resource information if found at RD. + * + * @return ::OC_STACK_OK if the resource is found else ::OC_STACK_NO_RESOURCE. + * In case if build is not with flag RD_SERVER, it returns ::OC_STACK_NO_RESOURCE. + */ +static OCStackResult findResourceAtRD(const OCResource* resource, const char *interfaceQuery, + const char *resourceTypeQuery, OCDiscoveryPayload *discPayload) +{ + if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0) + { + if (OC_STACK_OK == OCRDDatabaseCheckResources(interfaceQuery, resourceTypeQuery, discPayload)) + { + return OC_STACK_OK; + } + } + + return OC_STACK_NO_RESOURCE; +} +#endif + +/** + * Creates a discovery payload and add device id information. This information is included in all + * /oic/res response. + * + * @param payload payload that will have memory alllocated and device id information added. + * + * @return ::OC_STACK_OK if successful in allocating memory and adding ID information. + * ::OC_STACK_NO_MEMORY if failed allocating the memory. + */ +static OCStackResult discoveryPayloadCreateAndAddDeviceId(OCPayload **payload) +{ + if (*payload) + { + OIC_LOG(DEBUG, TAG, "Payload is already allocated"); + return OC_STACK_OK; + } + + *payload = (OCPayload *) OCDiscoveryPayloadCreate(); + VERIFY_PARAM_NON_NULL(TAG, *payload, "Failed adding device id to discovery payload."); + + { + OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)*payload; + discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE); + VERIFY_PARAM_NON_NULL(TAG, discPayload->sid, "Failed adding device id to discovery payload."); + + const char* uid = OCGetServerInstanceIDString(); + if (uid) + { + memcpy(discPayload->sid, uid, UUID_STRING_SIZE); + } + + } + return OC_STACK_OK; +exit: + OCPayloadDestroy(*payload); + return OC_STACK_NO_MEMORY; +} + +/** + * Add the common properties to the payload, they are only included in case of oic.if.baseline response. + * + * @param discPayload payload that will have the baseline information included. + * + * @return ::OC_STACK_OK if successful in adding all the information. ::OC_STACK_NO_MEMORY if failed + * allocating the memory for the baseline information. + */ +static OCStackResult addDiscoveryBaselineCommonProperties(OCDiscoveryPayload *discPayload) +{ + if (!discPayload) + { + OIC_LOG(ERROR, TAG, "Payload is not allocated"); + return OC_STACK_ERROR; + } + + OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, (void **)&discPayload->name); + + discPayload->type = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL)); + VERIFY_PARAM_NON_NULL(TAG, discPayload->type, "Failed adding rt to discovery payload."); + discPayload->type->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES); + VERIFY_PARAM_NON_NULL(TAG, discPayload->type, "Failed adding rt value to discovery payload."); + + OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_LL); + OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_DEFAULT); + VERIFY_PARAM_NON_NULL(TAG, discPayload->iface, "Failed adding if to discovery payload."); + + return OC_STACK_OK; + +exit: + return OC_STACK_NO_MEMORY; +} + +static bool isUnicast(OCServerRequest *request) +{ + bool isMulticast = request->devAddr.flags & OC_MULTICAST; + return (isMulticast == false && + (request->devAddr.adapter != OC_ADAPTER_RFCOMM_BTEDR) && + (request->devAddr.adapter != OC_ADAPTER_GATT_BTLE)); +} + static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource) { if (!request || !resource) @@ -673,13 +955,32 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource return OC_STACK_INVALID_PARAM; } - OCStackResult discoveryResult = OC_STACK_ERROR; OCPayload* payload = NULL; + char *interfaceQuery = NULL; + char *resourceTypeQuery = NULL; OIC_LOG(INFO, TAG, "Entering HandleVirtualResource"); OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl); +#ifdef TCP_ADAPTER + if (OC_KEEPALIVE_RESOURCE_URI == virtualUriInRequest) + { + // Received request for a keepalive + OIC_LOG(INFO, TAG, "Request is for KeepAlive Request"); + return OCHandleKeepAliveRequest(request, resource); + } +#endif + + OCStackResult discoveryResult = OC_STACK_ERROR; + 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; + } + // Step 1: Generate the response to discovery request if (virtualUriInRequest == OC_WELL_KNOWN_URI #ifdef MQ_BROKER @@ -687,190 +988,68 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource #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, + discoveryResult = getQueryParamsForFiltering(virtualUriInRequest, request->query, &interfaceQuery, &resourceTypeQuery); - bool interfaceQueryAllocated = false; + VERIFY_SUCCESS(discoveryResult); + if (!interfaceQuery && !resourceTypeQuery) { - interfaceQueryAllocated = true; + // If no query is sent, default interface is used i.e. oic.if.ll. interfaceQuery = OICStrdup(OC_RSRVD_INTERFACE_LL); } - if (discoveryResult == OC_STACK_OK) - { - payload = (OCPayload *)OCDiscoveryPayloadCreate(); - - if (payload) - { - OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload; - bool foundResourceAtRD = false; + discoveryResult = discoveryPayloadCreateAndAddDeviceId(&payload); + VERIFY_PARAM_NON_NULL(TAG, payload, "Failed creating Discovery Payload."); + VERIFY_SUCCESS(discoveryResult); - if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL))) - { - OCResourceProperty prop = OC_DISCOVERABLE; + OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload; + if (interfaceQuery && 0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_DEFAULT)) + { + discoveryResult = addDiscoveryBaselineCommonProperties(discPayload); + VERIFY_SUCCESS(discoveryResult); + } + OCResourceProperty prop = OC_DISCOVERABLE; #ifdef MQ_BROKER - if (OC_MQ_BROKER_URI == virtualUriInRequest) - { - prop = OC_MQ_BROKER; - } + prop = (OC_MQ_BROKER_URI == virtualUriInRequest) ? OC_MQ_BROKER : prop; #endif - - for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next) - { - 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 - { - 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 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 && includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery)) - { - discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr); - } - } - // Set discoveryResult appropriately if no 'valid' resources are available - if (discPayload->resources == NULL && !foundResourceAtRD) - { - discoveryResult = OC_STACK_NO_RESOURCE; - } - } - if (discoveryResult == OC_STACK_OK && foundResourceAtRD == false) + for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next) + { + // This case will handle when no resource type and it is oic.if.ll. + // Do not assume check if the query is ll + if (!resourceTypeQuery && + (interfaceQuery && 0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL))) + { + // Only include discoverable type + if (resource->resourceProperties & prop) { - 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); - } + discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr); } } + else if (includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery)) + { + discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr); + } else { - discoveryResult = OC_STACK_NO_MEMORY; + discoveryResult = OC_STACK_OK; } - } - else + if (discPayload->resources == NULL) { - OIC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult); - } - - if (interfaceQuery) - { - OICFree(interfaceQuery); - } - - if (resourceTypeQuery) - { - OICFree(resourceTypeQuery); + discoveryResult = OC_STACK_NO_RESOURCE; } } 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) - { - discoveryResult = OC_STACK_ERROR; - } - else - { - 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); - } - } + OCResource *resourcePtr = FindResourceByUri(OC_RSRVD_DEVICE_URI); + VERIFY_PARAM_NON_NULL(TAG, resourcePtr, "Device URI not found."); + discoveryResult = BuildDevicePlatformPayload(resourcePtr, (OCRepPayload **)&payload, true); } 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) - { - discoveryResult = OC_STACK_NO_MEMORY; - } - else - { - discoveryResult = OC_STACK_OK; - } + OCResource *resourcePtr = FindResourceByUri(OC_RSRVD_PLATFORM_URI); + VERIFY_PARAM_NON_NULL(TAG, resourcePtr, "Platform URI not found."); + discoveryResult = BuildDevicePlatformPayload(resourcePtr, (OCRepPayload **)&payload, false); } #ifdef ROUTING_GATEWAY else if (OC_GATEWAY_URI == virtualUriInRequest) @@ -878,17 +1057,9 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource // Received request for a gateway OIC_LOG(INFO, TAG, "Request is for Gateway Virtual Request"); discoveryResult = RMHandleGatewayRequest(request, resource); - - } -#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 * @@ -927,26 +1098,23 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource if (OC_GATEWAY_URI != virtualUriInRequest) #endif { -#if TCP_ADAPTER - // KeepAlive uses the HandleKeepAliveRequest to respond to the request. - if (OC_KEEPALIVE_RESOURCE_URI != virtualUriInRequest) -#endif + OIC_LOG_PAYLOAD(DEBUG, payload); + if(discoveryResult == OC_STACK_OK) { - 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)) + + SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK); + } + else // Error handling + { + if (isUnicast(request)) { 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); + OC_EH_RESOURCE_NOT_FOUND : OC_EH_ERROR); } - else + else // Multicast { // 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."); @@ -954,41 +1122,39 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource // since it never remove and causes a big memory waste. FindAndDeleteServerRequest(request); } + discoveryResult = OC_STACK_CONTINUE; } } +exit: + if (interfaceQuery) + { + OICFree(interfaceQuery); + } + + if (resourceTypeQuery) + { + OICFree(resourceTypeQuery); + } OCPayloadDestroy(payload); - return OC_STACK_OK; + // To ignore the message, OC_STACK_CONTINUE is sent + return discoveryResult; } static OCStackResult -HandleDefaultDeviceEntityHandler (OCServerRequest *request) +HandleDefaultDeviceEntityHandler(OCServerRequest *request) { - if(!request) + if (!request) { return OC_STACK_INVALID_PARAM; } - OCStackResult result = OC_STACK_OK; OCEntityHandlerResult ehResult = OC_EH_ERROR; OCEntityHandlerRequest ehRequest = {0}; - 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, - request->coapID); - VERIFY_SUCCESS(result, OC_STACK_OK); + OCStackResult result = EHRequest(&ehRequest, PAYLOAD_TYPE_REPRESENTATION, request, NULL); + VERIFY_SUCCESS(result); // At this point we know for sure that defaultDeviceHandler exists ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest, @@ -1009,9 +1175,8 @@ exit: } static OCStackResult -HandleResourceWithEntityHandler (OCServerRequest *request, - OCResource *resource, - uint8_t collectionResource) +HandleResourceWithEntityHandler(OCServerRequest *request, + OCResource *resource) { if(!request || ! resource) { @@ -1031,24 +1196,10 @@ HandleResourceWithEntityHandler (OCServerRequest *request, if (request && request->resourceUrl && SRMIsSecurityResourceURI(request->resourceUrl)) { type = PAYLOAD_TYPE_SECURITY; - } - result = FormOCEntityHandlerRequest(&ehRequest, - (OCRequestHandle)request, - request->method, - &request->devAddr, - (OCResourceHandle)resource, - request->query, - type, - request->payload, - request->payloadSize, - request->numRcvdVendorSpecificHeaderOptions, - request->rcvdVendorSpecificHeaderOptions, - (OCObserveAction)request->observationOption, - 0, - request->coapID); - VERIFY_SUCCESS(result, OC_STACK_OK); + result = EHRequest(&ehRequest, type, request, resource); + VERIFY_SUCCESS(result); if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION) { @@ -1078,7 +1229,7 @@ HandleResourceWithEntityHandler (OCServerRequest *request, } result = GenerateObserverId(&ehRequest.obsInfo.obsId); - VERIFY_SUCCESS(result, OC_STACK_OK); + VERIFY_SUCCESS(result); result = AddObserver ((const char*)(request->resourceUrl), (const char *)(request->query), @@ -1120,7 +1271,7 @@ HandleResourceWithEntityHandler (OCServerRequest *request, { // Stack does not contain this observation request // Either token is incorrect or observation list is corrupted - result = OC_STACK_ERROR; + result = OC_STACK_NO_RESOURCE; goto exit; } ehRequest.obsInfo.obsId = resObs->observeId; @@ -1166,32 +1317,16 @@ exit: return result; } -static OCStackResult -HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request, - OCResource *resource) +static OCStackResult HandleCollectionResourceDefaultEntityHandler(OCServerRequest *request, + OCResource *resource) { - if(!request || !resource) + if (!request || !resource) { return OC_STACK_INVALID_PARAM; } - OCStackResult result = OC_STACK_ERROR; OCEntityHandlerRequest ehRequest = {0}; - - result = FormOCEntityHandlerRequest(&ehRequest, - (OCRequestHandle)request, - request->method, - &request->devAddr, - (OCResourceHandle)resource, - request->query, - PAYLOAD_TYPE_REPRESENTATION, - request->payload, - request->payloadSize, - request->numRcvdVendorSpecificHeaderOptions, - request->rcvdVendorSpecificHeaderOptions, - (OCObserveAction)request->observationOption, - (OCObservationId)0, - request->coapID); + OCStackResult result = EHRequest(&ehRequest, PAYLOAD_TYPE_REPRESENTATION, request, resource); if(result == OC_STACK_OK) { result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest); @@ -1225,12 +1360,12 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque } case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER: { - ret = HandleResourceWithEntityHandler (request, resource, 0); + ret = HandleResourceWithEntityHandler (request, resource); break; } case OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER: { - ret = HandleResourceWithEntityHandler (request, resource, 1); + ret = HandleResourceWithEntityHandler (request, resource); break; } case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER: @@ -1252,224 +1387,242 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque return ret; } -void DeletePlatformInfo() -{ - OIC_LOG(INFO, TAG, "Deleting platform info."); - - OICFree(savedPlatformInfo.platformID); - savedPlatformInfo.platformID = NULL; - - OICFree(savedPlatformInfo.manufacturerName); - savedPlatformInfo.manufacturerName = NULL; - - OICFree(savedPlatformInfo.manufacturerUrl); - savedPlatformInfo.manufacturerUrl = NULL; - - OICFree(savedPlatformInfo.modelNumber); - savedPlatformInfo.modelNumber = NULL; - - OICFree(savedPlatformInfo.dateOfManufacture); - savedPlatformInfo.dateOfManufacture = NULL; - - OICFree(savedPlatformInfo.platformVersion); - savedPlatformInfo.platformVersion = NULL; - - OICFree(savedPlatformInfo.operatingSystemVersion); - savedPlatformInfo.operatingSystemVersion = NULL; - - OICFree(savedPlatformInfo.hardwareVersion); - savedPlatformInfo.hardwareVersion = NULL; - - OICFree(savedPlatformInfo.firmwareVersion); - savedPlatformInfo.firmwareVersion = NULL; - - OICFree(savedPlatformInfo.supportUrl); - savedPlatformInfo.supportUrl = NULL; - - OICFree(savedPlatformInfo.systemTime); - savedPlatformInfo.systemTime = NULL; -} - -static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info) +OCStackResult OCSetPlatformInfo(OCPlatformInfo info) { - savedPlatformInfo.platformID = OICStrdup(info.platformID); - savedPlatformInfo.manufacturerName = OICStrdup(info.manufacturerName); - savedPlatformInfo.manufacturerUrl = OICStrdup(info.manufacturerUrl); - savedPlatformInfo.modelNumber = OICStrdup(info.modelNumber); - savedPlatformInfo.dateOfManufacture = OICStrdup(info.dateOfManufacture); - savedPlatformInfo.platformVersion = OICStrdup(info.platformVersion); - savedPlatformInfo.operatingSystemVersion = OICStrdup(info.operatingSystemVersion); - savedPlatformInfo.hardwareVersion = OICStrdup(info.hardwareVersion); - savedPlatformInfo.firmwareVersion = OICStrdup(info.firmwareVersion); - savedPlatformInfo.supportUrl = OICStrdup(info.supportUrl); - savedPlatformInfo.systemTime = OICStrdup(info.systemTime); - - if ((!savedPlatformInfo.platformID && info.platformID)|| - (!savedPlatformInfo.manufacturerName && info.manufacturerName)|| - (!savedPlatformInfo.manufacturerUrl && info.manufacturerUrl)|| - (!savedPlatformInfo.modelNumber && info.modelNumber)|| - (!savedPlatformInfo.dateOfManufacture && info.dateOfManufacture)|| - (!savedPlatformInfo.platformVersion && info.platformVersion)|| - (!savedPlatformInfo.operatingSystemVersion && info.operatingSystemVersion)|| - (!savedPlatformInfo.hardwareVersion && info.hardwareVersion)|| - (!savedPlatformInfo.firmwareVersion && info.firmwareVersion)|| - (!savedPlatformInfo.supportUrl && info.supportUrl)|| - (!savedPlatformInfo.systemTime && info.systemTime)) - { - DeletePlatformInfo(); - return OC_STACK_INVALID_PARAM; + OCResource *resource = NULL; + if (!info.platformID || !info.manufacturerName) + { + OIC_LOG(ERROR, TAG, "No value specified."); + goto exit; + } + if (0 == strlen(info.platformID) || 0 == strlen(info.manufacturerName)) + { + OIC_LOG(ERROR, TAG, "The passed value cannot be empty"); + goto exit; + } + if ((info.manufacturerName && strlen(info.manufacturerName) > MAX_PLATFORM_NAME_LENGTH) || + (info.manufacturerUrl && strlen(info.manufacturerUrl) > MAX_PLATFORM_URL_LENGTH) || + (info.modelNumber && strlen(info.modelNumber) > MAX_PLATFORM_NAME_LENGTH) || + (info.platformVersion && strlen(info.platformVersion) > MAX_PLATFORM_NAME_LENGTH) || + (info.operatingSystemVersion && strlen(info.operatingSystemVersion) > MAX_PLATFORM_NAME_LENGTH) || + (info.hardwareVersion && strlen(info.hardwareVersion) > MAX_PLATFORM_NAME_LENGTH) || + (info.firmwareVersion && strlen(info.firmwareVersion) > MAX_PLATFORM_NAME_LENGTH) || + (info.supportUrl && strlen(info.supportUrl) > MAX_PLATFORM_URL_LENGTH)) + { + OIC_LOG(ERROR, TAG, "The passed value is bigger than permitted."); + goto exit; } + resource = FindResourceByUri(OC_RSRVD_PLATFORM_URI); + if (!resource) + { + OIC_LOG(ERROR, TAG, "Platform Resource does not exist."); + goto exit; + } + OIC_LOG(INFO, TAG, "Entering OCSetPlatformInfo"); + VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_PLATFORM_ID, info.platformID)); + VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_NAME, info.manufacturerName)); + OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_URL, info.manufacturerUrl); + OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MODEL_NUM, info.modelNumber); + OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_DATE, info.dateOfManufacture); + OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_PLATFORM_VERSION, info.platformVersion); + OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_OS_VERSION, info.operatingSystemVersion); + OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_HARDWARE_VERSION, info.hardwareVersion); + OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_FIRMWARE_VERSION, info.firmwareVersion); + OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_SUPPORT_URL, info.supportUrl); + OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_SYSTEM_TIME, info.systemTime); + OIC_LOG(INFO, TAG, "Platform parameter initialized successfully."); return OC_STACK_OK; +exit: + return OC_STACK_INVALID_PARAM; } -OCStackResult SavePlatformInfo(OCPlatformInfo info) +OCStackResult OCSetDeviceInfo(OCDeviceInfo info) { - DeletePlatformInfo(); + OCStringLL *dataModelVersion = NULL; + OCResource *resource = FindResourceByUri(OC_RSRVD_DEVICE_URI); + if (!resource) + { + OIC_LOG(ERROR, TAG, "Device Resource does not exist."); + goto exit; + } + if (!info.deviceName || info.deviceName[0] == '\0') + { + OIC_LOG(ERROR, TAG, "Null or empty device name."); + return OC_STACK_INVALID_PARAM; + } - OCStackResult res = DeepCopyPlatFormInfo(info); + if (OCGetServerInstanceIDString() == NULL) + { + OIC_LOG(INFO, TAG, "Device ID generation failed"); + goto exit; + } - if (res != OC_STACK_OK) + VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, info.deviceName)); + for (OCStringLL *temp = info.types; temp; temp = temp->next) { - OIC_LOG_V(ERROR, TAG, "Failed to save platform info. errno(%d)", res); + if (temp->value) + { + VERIFY_SUCCESS(OCBindResourceTypeToResource(resource, temp->value)); + } + } + VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_SPEC_VERSION, info.specVersion ? + info.specVersion: OC_SPEC_VERSION)); + if (info.dataModelVersions) + { + VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION, info.dataModelVersions)); } else { - OIC_LOG(INFO, TAG, "Platform info saved."); + dataModelVersion = OCCreateOCStringLL(OC_DATA_MODEL_VERSION); + VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION, dataModelVersion)); +#ifdef __TIZENRT__ + OCFreeOCStringLL(dataModelVersion); +#endif } + OIC_LOG(INFO, TAG, "Device parameter initialized successfully."); + return OC_STACK_OK; - return res; -} - -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; +exit: + if (dataModelVersion) + { + OCFreeOCStringLL(dataModelVersion); + } + return OC_STACK_ERROR; } -static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info) +OCStackResult OCGetAttribute(const OCResource *resource, const char *attribute, void **value) { - savedDeviceInfo.deviceName = OICStrdup(info.deviceName); - - if(!savedDeviceInfo.deviceName && info.deviceName) + if (!resource || !attribute) { - DeleteDeviceInfo(); - return OC_STACK_NO_MEMORY; + return OC_STACK_INVALID_PARAM; } - - if (info.types) + if (0 == strlen(attribute)) { - 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) + return OC_STACK_INVALID_PARAM; + } + for (OCAttribute *temp = resource->rsrcAttributes; temp; temp = temp->next) + { + if (0 == strcmp(attribute, temp->attrName)) { - // Append the oic.wk.d at the start of rt link parameter value. - OCStringLL *dest = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL)); - if (!dest) + // A special case as this type return OCStringLL + if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, attribute)) { - DeleteDeviceInfo(); - return OC_STACK_NO_MEMORY; + *value = CloneOCStringLL((OCStringLL *)temp->attrValue); + return OC_STACK_OK; } - dest->value = OICStrdup (OC_RSRVD_RESOURCE_TYPE_DEVICE); - if (!dest->value) + else { - DeleteDeviceInfo(); - return OC_STACK_NO_MEMORY; + *value = OICStrdup((char *)temp->attrValue); + return OC_STACK_OK; } - dest->next = savedDeviceInfo.types; - savedDeviceInfo.types = dest; - } - if(!savedDeviceInfo.types && info.types) - { - DeleteDeviceInfo(); - return OC_STACK_NO_MEMORY; } } + return OC_STACK_NO_RESOURCE; +} - if (info.specVersion) +OCStackResult OCGetPropertyValue(OCPayloadType type, const char *prop, void **value) +{ + if (!prop || *value) { - savedDeviceInfo.specVersion = OICStrdup(info.specVersion); - if(!savedDeviceInfo.specVersion && info.specVersion) - { - DeleteDeviceInfo(); - return OC_STACK_NO_MEMORY; - } + return OC_STACK_INVALID_PARAM; } - else + if (strlen(prop) == 0) { - savedDeviceInfo.specVersion = OICStrdup(OC_SPEC_VERSION); - if(!savedDeviceInfo.specVersion && OC_SPEC_VERSION) + return OC_STACK_INVALID_PARAM; + } + OCStackResult res = OC_STACK_NO_RESOURCE; + if (PAYLOAD_TYPE_DEVICE == type || PAYLOAD_TYPE_PLATFORM == type) + { + const char *pathType = (type == PAYLOAD_TYPE_DEVICE) ? OC_RSRVD_DEVICE_URI : OC_RSRVD_PLATFORM_URI; + OCResource *resource = FindResourceByUri(pathType); + if (!resource) { - DeleteDeviceInfo(); - return OC_STACK_NO_MEMORY; + return OC_STACK_NO_RESOURCE; } + + res = OCGetAttribute(resource, prop, value); } + return res; +} - if (info.dataModelVersions) +OCStackResult OCSetAttribute(OCResource* resource, const char* attribute, const void* value) +{ + // See if the attribute already exists in the list. + OCAttribute *resAttrib; + for (resAttrib = resource->rsrcAttributes; resAttrib; resAttrib = resAttrib->next) { - savedDeviceInfo.dataModelVersions = CloneOCStringLL(info.dataModelVersions); - if(!savedDeviceInfo.dataModelVersions && info.dataModelVersions) + if (0 == strcmp(attribute, resAttrib->attrName)) { - DeleteDeviceInfo(); - return OC_STACK_NO_MEMORY; + // Found, free the old value. + if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, resAttrib->attrName)) + { + OCFreeOCStringLL((OCStringLL *)resAttrib->attrValue); + } + else + { + OICFree((char *)resAttrib->attrValue); + } + break; } } + + // If not already in the list, add it. + if (NULL == resAttrib) + { + resAttrib = (OCAttribute *)OICCalloc(1, sizeof(OCAttribute)); + VERIFY_PARAM_NON_NULL(TAG, resAttrib, "Failed allocating OCAttribute"); + resAttrib->attrName = OICStrdup(attribute); + VERIFY_PARAM_NON_NULL(TAG, resAttrib->attrName, "Failed allocating attribute name"); + resAttrib->next = resource->rsrcAttributes; + resource->rsrcAttributes = resAttrib; + } + + // Fill in the new value. + if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, attribute)) + { + resAttrib->attrValue = CloneOCStringLL((OCStringLL *)value); + } 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; - } + resAttrib->attrValue = OICStrdup((char *)value); } + VERIFY_PARAM_NON_NULL(TAG, resAttrib->attrValue, "Failed allocating attribute value"); return OC_STACK_OK; -} - -OCStackResult SaveDeviceInfo(OCDeviceInfo info) -{ - OCStackResult res = OC_STACK_OK; - - DeleteDeviceInfo(); - res = DeepCopyDeviceInfo(info); +exit: + OCDeleteResourceAttributes(resAttrib); + return OC_STACK_NO_MEMORY; - VERIFY_SUCCESS(res, OC_STACK_OK); +} - if (OCGetServerInstanceIDString() == NULL) +OCStackResult OCSetPropertyValue(OCPayloadType type, const char *prop, const void *value) +{ + if (!prop || !value) { - OIC_LOG(INFO, TAG, "Device ID generation failed"); - res = OC_STACK_ERROR; - goto exit; + return OC_STACK_INVALID_PARAM; + } + if (strlen(prop) == 0) + { + return OC_STACK_INVALID_PARAM; } - OIC_LOG(INFO, TAG, "Device initialized successfully."); - return OC_STACK_OK; + OCStackResult res = OC_STACK_ERROR; + if (PAYLOAD_TYPE_DEVICE == type || PAYLOAD_TYPE_PLATFORM == type) + { + const char *pathType = (type == PAYLOAD_TYPE_DEVICE) ? OC_RSRVD_DEVICE_URI : OC_RSRVD_PLATFORM_URI; + OCResource *resource = FindResourceByUri(pathType); + if (!resource) + { + OIC_LOG(ERROR, TAG, "Resource does not exist."); + } + else + { + res = OCSetAttribute(resource, prop, value); + } + } -exit: - DeleteDeviceInfo(); return res; }