X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fstack%2Fsrc%2Focserverrequest.c;h=a15fcc15f37543916ad507786d576d812acad746;hb=17c68b2fd1e74586f85e552eeab4e32dc121f8a0;hp=9f8b0dc82525f6b7c43da19dcd6db0afdf695b62;hpb=8c01dff2c5bc5496f7dc1632c498943ec6ecb015;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/src/ocserverrequest.c b/resource/csdk/stack/src/ocserverrequest.c index 9f8b0dc..a15fcc1 100644 --- a/resource/csdk/stack/src/ocserverrequest.c +++ b/resource/csdk/stack/src/ocserverrequest.c @@ -26,6 +26,11 @@ #include "oic_string.h" #include "ocpayload.h" #include "ocpayloadcbor.h" +#include "logger.h" + +#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) +#include "routingutility.h" +#endif #include "cacommon.h" #include "cainterface.h" @@ -36,7 +41,7 @@ // Module Name #define VERIFY_NON_NULL(arg) { if (!arg) {OC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} } -#define TAG PCF("ocserverrequest") +#define TAG "ocserverrequest" static struct OCServerRequest * serverRequestList = NULL; static struct OCServerResponse * serverResponseList = NULL; @@ -56,6 +61,11 @@ static struct OCServerResponse * serverResponseList = NULL; */ static OCStackResult AddServerResponse (OCServerResponse ** response, OCRequestHandle requestHandle) { + if (!response) + { + return OC_STACK_INVALID_PARAM; + } + OCServerResponse * serverResponse = NULL; serverResponse = (OCServerResponse *) OICCalloc(1, sizeof(OCServerResponse)); @@ -66,7 +76,7 @@ static OCStackResult AddServerResponse (OCServerResponse ** response, OCRequestH serverResponse->requestHandle = requestHandle; *response = serverResponse; - OC_LOG(INFO, TAG, PCF("Server Response Added!!")); + OC_LOG(INFO, TAG, "Server Response Added!!"); LL_APPEND (serverResponseList, serverResponse); return OC_STACK_OK; @@ -93,7 +103,7 @@ static void DeleteServerRequest(OCServerRequest * serverRequest) OICFree(serverRequest->requestToken); OICFree(serverRequest); serverRequest = NULL; - OC_LOG(INFO, TAG, PCF("Server Request Removed!!")); + OC_LOG(INFO, TAG, "Server Request Removed!!"); } } @@ -109,7 +119,7 @@ static void DeleteServerResponse(OCServerResponse * serverResponse) LL_DELETE(serverResponseList, serverResponse); OICFree(serverResponse->payload); OICFree(serverResponse); - OC_LOG(INFO, TAG, PCF("Server Response Removed!!")); + OC_LOG(INFO, TAG, "Server Response Removed!!"); } } @@ -134,6 +144,39 @@ static void FindAndDeleteServerResponse(OCServerResponse * serverResponse) } } +/** + * Ensure no accept header option is included when sending responses and add routing info to + * outgoing response. + * + * @param object CA remote endpoint. + * @param requestInfo CA request info. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +static OCStackResult OCSendResponse(const CAEndpoint_t *object, CAResponseInfo_t *responseInfo) +{ +#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) + // Add route info in RM option. + OCStackResult rmResult = RMAddInfo(object->routeData, &(responseInfo->info.options), + &(responseInfo->info.numOptions)); + if(OC_STACK_OK != rmResult) + { + OC_LOG(ERROR, TAG, "Add option failed"); + return rmResult; + } +#endif + + // Do not include the accept header option + responseInfo->info.acceptFormat = CA_FORMAT_UNDEFINED; + CAResult_t result = CASendResponse(object, responseInfo); + if(CA_STATUS_OK != result) + { + OC_LOG_V(ERROR, TAG, "CASendResponse failed with CA error %u", result); + return CAResultToOCResult(result); + } + return OC_STACK_OK; +} + //------------------------------------------------------------------------------------------------- // Internal APIs //------------------------------------------------------------------------------------------------- @@ -151,15 +194,15 @@ OCServerRequest * GetServerRequestUsingToken (const CAToken_t token, uint8_t tok { if(!token) { - OC_LOG(ERROR, TAG, PCF("Invalid Parameter Token")); + OC_LOG(ERROR, TAG, "Invalid Parameter Token"); return NULL; } OCServerRequest * out = NULL; - OC_LOG(INFO, TAG,PCF("Get server request with token")); + OC_LOG(INFO, TAG,"Get server request with token"); OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength); - OC_LOG(INFO, TAG,PCF("Found token")); + OC_LOG(INFO, TAG,"Found token"); LL_FOREACH (serverRequestList, out) { OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->requestToken, tokenLength); @@ -168,7 +211,7 @@ OCServerRequest * GetServerRequestUsingToken (const CAToken_t token, uint8_t tok return out; } } - OC_LOG(ERROR, TAG, PCF("Server Request not found!!")); + OC_LOG(ERROR, TAG, "Server Request not found!!"); return NULL; } @@ -189,7 +232,7 @@ OCServerRequest * GetServerRequestUsingHandle (const OCServerRequest * handle) return out; } } - OC_LOG(ERROR, TAG, PCF("Server Request not found!!")); + OC_LOG(ERROR, TAG, "Server Request not found!!"); return NULL; } @@ -211,7 +254,7 @@ OCServerResponse * GetServerResponseUsingHandle (const OCServerRequest * handle) return out; } } - OC_LOG(ERROR, TAG, PCF("Server Response not found!!")); + OC_LOG(ERROR, TAG, "Server Response not found!!"); return NULL; } @@ -221,10 +264,18 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID, OCQualityOfService qos, char * query, OCHeaderOption * rcvdVendorSpecificHeaderOptions, uint8_t * payload, CAToken_t requestToken, uint8_t tokenLength, - char * resourceUrl, size_t reqTotalSize, const OCDevAddr *devAddr) + char * resourceUrl, size_t reqTotalSize, OCPayloadFormat acceptFormat, + const OCDevAddr *devAddr) { + if (!request) + { + return OC_STACK_INVALID_PARAM; + } + OCServerRequest * serverRequest = NULL; + OC_LOG_V(INFO, TAG, "addserverrequest entry!! [%s:%u]", devAddr->addr, devAddr->port); + serverRequest = (OCServerRequest *) OICCalloc(1, sizeof(OCServerRequest) + (reqTotalSize ? reqTotalSize : 1) - 1); VERIFY_NON_NULL(devAddr); @@ -239,6 +290,7 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID, serverRequest->observationOption = observationOption; serverRequest->observeResult = OC_STACK_ERROR; serverRequest->qos = qos; + serverRequest->acceptFormat = acceptFormat; serverRequest->ehResponseHandler = HandleSingleResponse; serverRequest->numResponses = 1; @@ -284,7 +336,7 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID, serverRequest->devAddr = *devAddr; *request = serverRequest; - OC_LOG(INFO, TAG, PCF("Server Request Added!!")); + OC_LOG(INFO, TAG, "Server Request Added!!"); LL_APPEND (serverRequestList, serverRequest); return OC_STACK_OK; @@ -305,6 +357,7 @@ OCStackResult FormOCEntityHandlerRequest( OCDevAddr *endpoint, OCResourceHandle resource, char * queryBuf, + OCPayloadType payloadType, uint8_t * payload, size_t payloadSize, uint8_t numVendorOptions, @@ -324,7 +377,8 @@ OCStackResult FormOCEntityHandlerRequest( if(payload && payloadSize) { - if(OCParsePayload(&entityHandlerRequest->payload, payload, payloadSize) != OC_STACK_OK) + if(OCParsePayload(&entityHandlerRequest->payload, payloadType, + payload, payloadSize) != OC_STACK_OK) { return OC_STACK_ERROR; } @@ -364,14 +418,32 @@ void FindAndDeleteServerRequest(OCServerRequest * serverRequest) } } -CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result) +CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result, OCMethod method) { - CAResponseResult_t caResult = CA_BAD_REQ; + CAResponseResult_t caResult; switch (result) { case OC_EH_OK: - caResult = CA_SUCCESS; + switch (method) + { + case OC_REST_PUT: + case OC_REST_POST: + // This Response Code is like HTTP 204 "No Content" but only used in + // response to POST and PUT requests. + caResult = CA_CHANGED; + break; + case OC_REST_GET: + // This Response Code is like HTTP 200 "OK" but only used in response to + // GET requests. + caResult = CA_CONTENT; + break; + default: + // This should not happen but, + // give it a value just in case but output an error + caResult = CA_CONTENT; + OC_LOG_V(ERROR, TAG, "Unexpected OC_EH_OK return code for method [d].", method); + } break; case OC_EH_ERROR: caResult = CA_BAD_REQ; @@ -383,7 +455,7 @@ CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result) caResult = CA_DELETED; break; case OC_EH_SLOW: - caResult = CA_SUCCESS; + caResult = CA_CONTENT; break; case OC_EH_FORBIDDEN: caResult = CA_UNAUTHORIZED_REQ; @@ -407,12 +479,11 @@ CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result) * @return * OCStackResult */ - OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) { OCStackResult result = OC_STACK_ERROR; - CAEndpoint_t responseEndpoint = {}; - CAResponseInfo_t responseInfo = {}; + CAEndpoint_t responseEndpoint = {.adapter = CA_DEFAULT_ADAPTER}; + CAResponseInfo_t responseInfo = {.result = CA_EMPTY}; CAHeaderOption_t* optionsPointer = NULL; if(!ehResponse || !ehResponse->requestHandle) @@ -425,7 +496,7 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) CopyDevAddrToEndpoint(&serverRequest->devAddr, &responseEndpoint); responseInfo.info.resourceUri = serverRequest->resourceUrl; - responseInfo.result = ConvertEHResultToCAResult(ehResponse->ehResult); + responseInfo.result = ConvertEHResultToCAResult(ehResponse->ehResult, serverRequest->method); if(serverRequest->notificationFlag && serverRequest->qos == OC_HIGH_QOS) { @@ -449,6 +520,11 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) { responseInfo.info.type = CA_MSG_NONCONFIRM; } + else + { + OC_LOG(ERROR, TAG, "default responseInfo type is NON"); + responseInfo.info.type = CA_MSG_NONCONFIRM; + } char rspToken[CA_MAX_TOKEN_LEN + 1] = {}; responseInfo.info.messageId = serverRequest->coapID; @@ -474,7 +550,7 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) if(!responseInfo.info.options) { - OC_LOG(FATAL, TAG, PCF("Memory alloc for options failed")); + OC_LOG(FATAL, TAG, "Memory alloc for options failed"); return OC_STACK_NO_MEMORY; } @@ -487,8 +563,14 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) responseInfo.info.options[0].protocolID = CA_COAP_ID; responseInfo.info.options[0].optionID = COAP_OPTION_OBSERVE; responseInfo.info.options[0].optionLength = sizeof(uint32_t); - memcpy(responseInfo.info.options[0].optionData, - &(serverRequest->observationOption), sizeof(uint32_t)); + uint8_t* observationData = (uint8_t*)responseInfo.info.options[0].optionData; + uint32_t observationOption= serverRequest->observationOption; + + for (size_t i=sizeof(uint32_t); i; --i) + { + observationData[i-1] = observationOption & 0xFF; + observationOption >>=8; + } // Point to the next header option before copying vender specific header options optionsPointer += 1; @@ -506,52 +588,61 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) responseInfo.info.options = NULL; } + responseInfo.isMulticast = false; + responseInfo.info.payload = NULL; + responseInfo.info.payloadSize = 0; + responseInfo.info.payloadFormat = CA_FORMAT_UNDEFINED; + // Put the JSON prefix and suffix around the payload if(ehResponse->payload) { - OCStackResult result; - if((result = OCConvertPayload(ehResponse->payload, &responseInfo.info.payload, - &responseInfo.info.payloadSize)) - != OC_STACK_OK) + if (ehResponse->payload->type == PAYLOAD_TYPE_PRESENCE) + { + responseInfo.isMulticast = true; + } + else { - OC_LOG(ERROR, TAG, "Error converting payload"); - return result; + responseInfo.isMulticast = false; } - if(responseInfo.info.payloadSize > MAX_RESPONSE_LENGTH) + switch(serverRequest->acceptFormat) { - OICFree(responseInfo.info.payload); - OC_LOG(ERROR, TAG, "Payload too long!"); - return OC_STACK_INVALID_PARAM; + case OC_FORMAT_UNDEFINED: + // No preference set by the client, so default to CBOR then + case OC_FORMAT_CBOR: + if((result = OCConvertPayload(ehResponse->payload, &responseInfo.info.payload, + &responseInfo.info.payloadSize)) + != OC_STACK_OK) + { + OC_LOG(ERROR, TAG, "Error converting payload"); + OICFree(responseInfo.info.options); + return result; + } + responseInfo.info.payloadFormat = CA_FORMAT_APPLICATION_CBOR; + break; + default: + responseInfo.result = CA_NOT_ACCEPTABLE; } } - else - { - responseInfo.info.payload = NULL; - responseInfo.info.payloadSize = 0; - } - #ifdef WITH_PRESENCE +#ifdef WITH_PRESENCE CATransportAdapter_t CAConnTypes[] = { CA_ADAPTER_IP, CA_ADAPTER_GATT_BTLE, CA_ADAPTER_RFCOMM_BTEDR - #ifdef RA_ADAPTER +#ifdef RA_ADAPTER , CA_ADAPTER_REMOTE_ACCESS - #endif +#endif + +#ifdef TCP_ADAPTER + , CA_ADAPTER_TCP +#endif }; - const char * connTypes[] = {"ip" , "ble", "edr" - #ifdef RA_ADAPTER - , "ra" - #endif - }; - int size = sizeof(CAConnTypes)/ sizeof(CATransportAdapter_t); - CATransportAdapter_t adapter = responseEndpoint.adapter; - CAResult_t caResult = CA_STATUS_FAILED; - result = OC_STACK_OK; + size_t size = sizeof(CAConnTypes)/ sizeof(CATransportAdapter_t); + CATransportAdapter_t adapter = responseEndpoint.adapter; // Default adapter, try to send response out on all adapters. if (adapter == CA_DEFAULT_ADAPTER) { @@ -561,46 +652,43 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) CA_ADAPTER_GATT_BTLE | CA_ADAPTER_RFCOMM_BTEDR - #ifdef RA_ADAP +#ifdef RA_ADAP | CA_ADAPTER_REMOTE_ACCESS - #endif +#endif + +#ifdef TCP_ADAPTER + | CA_ADAPTER_TCP +#endif ); } - for(int i = 0; i < size; i++ ) + result = OC_STACK_OK; + OCStackResult tempResult = OC_STACK_OK; + + for(size_t i = 0; i < size; i++ ) { responseEndpoint.adapter = (CATransportAdapter_t)(adapter & CAConnTypes[i]); if(responseEndpoint.adapter) { - //The result is set to OC_STACK_OK only if CASendResponse succeeds in sending the + //The result is set to OC_STACK_OK only if OCSendResponse succeeds in sending the //response on all the n/w interfaces else it is set to OC_STACK_ERROR - caResult = CASendResponse(&responseEndpoint, &responseInfo); - if(caResult != CA_STATUS_OK) - { - OC_LOG_V(ERROR, TAG, "CASendResponse failed with CA error %u", caResult); - result = CAResultToOCResult(caResult); - } + tempResult = OCSendResponse(&responseEndpoint, &responseInfo); + } + if(OC_STACK_OK != tempResult) + { + result = tempResult; } } - #else +#else - OC_LOG(INFO, TAG, PCF("Calling CASendResponse with:")); + OC_LOG(INFO, TAG, "Calling OCSendResponse with:"); OC_LOG_V(INFO, TAG, "\tEndpoint address: %s", responseEndpoint.addr); OC_LOG_V(INFO, TAG, "\tEndpoint adapter: %s", responseEndpoint.adapter); OC_LOG_V(INFO, TAG, "\tResponse result : %s", responseInfo.result); OC_LOG_V(INFO, TAG, "\tResponse for uri: %s", responseInfo.info.resourceUri); - CAResult_t caResult = CASendResponse(&responseEndpoint, &responseInfo); - if(caResult != CA_STATUS_OK) - { - OC_LOG(ERROR, TAG, PCF("CASendResponse failed")); - result = CAResultToOCResult(caResult); - } - else - { - result = OC_STACK_OK; - } - #endif + result = OCSendResponse(&responseEndpoint, &responseInfo); +#endif OICFree(responseInfo.info.payload); OICFree(responseInfo.info.options); @@ -623,30 +711,29 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) */ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse) { - OCStackResult stackRet = OC_STACK_ERROR; - OCServerRequest * serverRequest = NULL; - OCServerResponse * serverResponse = NULL; - if(!ehResponse || !ehResponse->payload) { - OC_LOG(ERROR, TAG, PCF("HandleAggregateResponse invalid parameters")); + OC_LOG(ERROR, TAG, "HandleAggregateResponse invalid parameters"); return OC_STACK_INVALID_PARAM; } OC_LOG(INFO, TAG, "Inside HandleAggregateResponse"); - serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle); - serverResponse = GetServerResponseUsingHandle((OCServerRequest *)ehResponse->requestHandle); + OCServerRequest *serverRequest = GetServerRequestUsingHandle((OCServerRequest *) + ehResponse->requestHandle); + OCServerResponse *serverResponse = GetServerResponseUsingHandle((OCServerRequest *) + ehResponse->requestHandle); + OCStackResult stackRet = OC_STACK_ERROR; if(serverRequest) { if(!serverResponse) { - OC_LOG(INFO, TAG, PCF("This is the first response fragment")); + OC_LOG(INFO, TAG, "This is the first response fragment"); stackRet = AddServerResponse(&serverResponse, ehResponse->requestHandle); if (OC_STACK_OK != stackRet) { - OC_LOG(ERROR, TAG, PCF("Error adding server response")); + OC_LOG(ERROR, TAG, "Error adding server response"); return stackRet; } VERIFY_NON_NULL(serverResponse); @@ -655,13 +742,12 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse) if(ehResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION) { stackRet = OC_STACK_ERROR; - OC_LOG(ERROR, TAG, PCF("Error adding payload, as it was the incorrect type")); + OC_LOG(ERROR, TAG, "Error adding payload, as it was the incorrect type"); goto exit; } if(!serverResponse->payload) { - serverResponse->payload = (OCPayload*)OCRepPayloadCreate(); serverResponse->payload = ehResponse->payload; } else @@ -675,7 +761,7 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse) if(serverRequest->numResponses == 0) { - OC_LOG(INFO, TAG, PCF("This is the last response fragment")); + OC_LOG(INFO, TAG, "This is the last response fragment"); ehResponse->payload = serverResponse->payload; stackRet = HandleSingleResponse(ehResponse); //Delete the request and response @@ -684,7 +770,7 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse) } else { - OC_LOG(INFO, TAG, PCF("More response fragments to come")); + OC_LOG(INFO, TAG, "More response fragments to come"); stackRet = OC_STACK_OK; } }