X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fstack%2Fsrc%2Focstack.c;h=c603445c13368ac95df929c6c3a963fb81696680;hb=3c093548382bb2542c87a67e6e5fa32552c29cb3;hp=277cd6e9dfabad0790ea25b359acdd0f00b90ee8;hpb=edcfc3d2329da7b914771c0dcff5f42c9b74fd93;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index 277cd6e..c603445 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -50,9 +50,11 @@ #include "oic_malloc.h" #include "oic_string.h" #include "logger.h" +#include "trace.h" #include "ocserverrequest.h" #include "secureresourcemanager.h" #include "psinterface.h" +#include "psiutils.h" #include "doxmresource.h" #include "cacommon.h" #include "cainterface.h" @@ -69,7 +71,7 @@ #endif #ifdef TCP_ADAPTER -#include "oickeepalive.h" +#include "oickeepaliveinternal.h" #endif //#ifdef DIRECT_PAIRING @@ -110,6 +112,14 @@ typedef enum } OCPresenceState; #endif +#if defined(__WITH_DTLS__) || defined (__WITH_TLS__) +typedef struct +{ + OCOtmEventHandler cb; + void *ctx; +} OCOtmEventHandler_t; +#endif + //----------------------------------------------------------------------------- // Private variables //----------------------------------------------------------------------------- @@ -144,6 +154,10 @@ static const char CORESPEC[] = "core"; CAAdapterStateChangedCB g_adapterHandler = NULL; CAConnectionStateChangedCB g_connectionHandler = NULL; +#if defined(__WITH_DTLS__) || defined (__WITH_TLS__) +static OCOtmEventHandler_t g_otmEventHandler = {NULL, NULL}; +#endif + //----------------------------------------------------------------------------- // Macros //----------------------------------------------------------------------------- @@ -258,6 +272,13 @@ static void deleteResourceType(OCResourceType *resourceType); static void deleteResourceInterface(OCResourceInterface *resourceInterface); /** + * Delete all child resources. + * + * @param resourceChild Specified binded resource is deleted from parent. + */ +static void deleteResourceChild(OCChildResource *resourceChild); + +/** * Delete all of the dynamically allocated elements that were created for the resource. * * @param resource Specified resource. @@ -291,10 +312,10 @@ static void incrementSequenceNumber(OCResource * resPtr); * * Note: At least one interface must succeed to initialize. If all calls to @ref CASelectNetwork * return something other than @ref CA_STATUS_OK, then this function fails. - * + * @param transportType OCTransportAdapter value to select. * @return ::CA_STATUS_OK on success, some other value upon failure. */ -static CAResult_t OCSelectNetwork(); +static CAResult_t OCSelectNetwork(OCTransportAdapter transportType); /** * Convert CAResponseResult_t to OCStackResult. @@ -370,6 +391,7 @@ static OCStackResult getQueryFromUri(const char * uri, char** resourceType, char static OCResourceType *findResourceType(OCResourceType * resourceTypeList, const char * resourceTypeName); +#ifdef WITH_PRESENCE /** * Reset presence TTL for a ClientCB struct. ttlLevel will be set to 0. * TTL will be set to maxAge. @@ -380,6 +402,7 @@ static OCResourceType *findResourceType(OCResourceType * resourceTypeList, * @return ::OC_STACK_OK on success, some other value upon failure. */ static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds); +#endif /** * Ensure the accept header option is set appropriatly before sending the requests and routing @@ -484,6 +507,7 @@ void CopyDevAddrToEndpoint(const OCDevAddr *in, CAEndpoint_t *out) out->adapter = (CATransportAdapter_t)in->adapter; out->flags = OCToCATransportFlags(in->flags); OICStrcpy(out->addr, sizeof(out->addr), in->addr); + OICStrcpy(out->remoteId, sizeof(out->remoteId), in->remoteId); #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) /* This assert is to prevent accidental mismatch between address size macros defined in * RI and CA and cause crash here. */ @@ -508,12 +532,14 @@ static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t * { VERIFY_NON_NULL(object, FATAL, OC_STACK_INVALID_PARAM); VERIFY_NON_NULL(requestInfo, FATAL, OC_STACK_INVALID_PARAM); + OIC_TRACE_BEGIN(%s:OCSendRequest, TAG); #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) OCStackResult rmResult = RMAddInfo(object->routeData, requestInfo, true, NULL); if (OC_STACK_OK != rmResult) { OIC_LOG(ERROR, TAG, "Add destination option failed"); + OIC_TRACE_END(); return rmResult; } #endif @@ -524,8 +550,11 @@ static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t * if(CA_STATUS_OK != result) { OIC_LOG_V(ERROR, TAG, "CASendRequest failed with CA error %u", result); + OIC_TRACE_END(); return CAResultToOCResult(result); } + + OIC_TRACE_END(); return OC_STACK_OK; } //----------------------------------------------------------------------------- @@ -683,18 +712,36 @@ OCStackResult CAResponseToOCStackResult(CAResponseResult_t caCode) case CA_NOT_FOUND: ret = OC_STACK_NO_RESOURCE; break; - case CA_RETRANSMIT_TIMEOUT: - ret = OC_STACK_COMM_ERROR; - break; case CA_REQUEST_ENTITY_TOO_LARGE: ret = OC_STACK_TOO_LARGE_REQ; break; + case CA_METHOD_NOT_ALLOWED: + ret = OC_STACK_METHOD_NOT_ALLOWED; + break; + case CA_NOT_ACCEPTABLE: + ret = OC_STACK_NOT_ACCEPTABLE; + break; case CA_FORBIDDEN_REQ: ret = OC_STACK_FORBIDDEN_REQ; break; case CA_INTERNAL_SERVER_ERROR: ret = OC_STACK_INTERNAL_SERVER_ERROR; break; + case CA_NOT_IMPLEMENTED: + ret = OC_STACK_NOT_IMPLEMENTED; + break; + case CA_BAD_GATEWAY: + ret = OC_STACK_BAD_GATEWAY; + break; + case CA_SERVICE_UNAVAILABLE: + ret = OC_STACK_SERVICE_UNAVAILABLE; + break; + case CA_RETRANSMIT_TIMEOUT: + ret = OC_STACK_GATEWAY_TIMEOUT; + break; + case CA_PROXY_NOT_SUPPORTED: + ret = OC_STACK_PROXY_NOT_SUPPORTED; + break; default: break; } @@ -750,6 +797,12 @@ CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method) case OC_STACK_COMM_ERROR: ret = CA_RETRANSMIT_TIMEOUT; break; + case OC_STACK_METHOD_NOT_ALLOWED: + ret = CA_METHOD_NOT_ALLOWED; + break; + case OC_STACK_NOT_ACCEPTABLE: + ret = CA_NOT_ACCEPTABLE; + break; case OC_STACK_UNAUTHORIZED_REQ: ret = CA_UNAUTHORIZED_REQ; break; @@ -759,6 +812,21 @@ CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method) case OC_STACK_INTERNAL_SERVER_ERROR: ret = CA_INTERNAL_SERVER_ERROR; break; + case OC_STACK_NOT_IMPLEMENTED: + ret = CA_NOT_IMPLEMENTED; + break; + case OC_STACK_BAD_GATEWAY: + ret = CA_BAD_GATEWAY; + break; + case OC_STACK_SERVICE_UNAVAILABLE: + ret = CA_SERVICE_UNAVAILABLE; + break; + case OC_STACK_GATEWAY_TIMEOUT: + ret = CA_RETRANSMIT_TIMEOUT; + break; + case OC_STACK_PROXY_NOT_SUPPORTED: + ret = CA_PROXY_NOT_SUPPORTED; + break; default: break; } @@ -786,6 +854,7 @@ OCTransportFlags CAToOCTransportFlags(CATransportFlags_t caFlags) return (OCTransportFlags)caFlags; } +#ifdef WITH_PRESENCE static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds) { uint32_t lowerBound = 0; @@ -875,6 +944,7 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr) return OC_PRESENCE_TRIGGER_DELETE; } } +#endif // WITH_PRESENCE OCStackResult OCEncodeAddressForRFC6874(char *outputAddress, size_t outputSize, @@ -939,8 +1009,8 @@ OCStackResult OCEncodeAddressForRFC6874(char *outputAddress, // Restore the null terminator with an escaped '%' character, per RFC 6874 OICStrcpy(outputAddress, scopeIdPart - addressPart, addressPart); - strcat(outputAddress, "%25"); - strcat(outputAddress, scopeIdPart); + OICStrcat(outputAddress, outputSize, "%25"); + OICStrcat(outputAddress, outputSize, scopeIdPart); return OC_STACK_OK; } @@ -980,6 +1050,7 @@ OCStackResult OCDecodeAddressForRFC6874(char *outputAddress, return OC_STACK_OK; } +#ifdef WITH_PRESENCE /** * The cononical presence allows constructed URIs to be string compared. * @@ -1101,7 +1172,7 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint, { return OC_STACK_INVALID_URI; } - OIC_LOG(ERROR, TAG, "check for unicast presence"); + OIC_LOG(INFO, TAG, "check for unicast presence"); cbNode = GetClientCB(NULL, 0, NULL, presenceUri); if (cbNode) { @@ -1110,7 +1181,7 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint, else { // check for multicast presence - OIC_LOG(ERROR, TAG, "check for multicast presence"); + OIC_LOG(INFO, TAG, "check for multicast presence"); cbNode = GetClientCB(NULL, 0, NULL, OC_RSRVD_PRESENCE_URI); if (cbNode) { @@ -1120,7 +1191,8 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint, if (!presenceSubscribe && !multicastPresenceSubscribe) { - OIC_LOG(ERROR, TAG, "Received a presence notification, but no callback, ignoring"); + OIC_LOG(INFO, TAG, "Received a presence notification, " + "but need to register presence callback, ignoring"); goto exit; } @@ -1210,17 +1282,59 @@ exit: OCPayloadDestroy(response.payload); return result; } +#endif // WITH_PRESENCE + +OCStackResult HandleBatchResponse(char *requestUri, OCRepPayload **payload) +{ + if (requestUri && *payload) + { + char *interfaceName = NULL; + char *rtTypeName = NULL; + char *uriQuery = NULL; + char *uriWithoutQuery = NULL; + if (OC_STACK_OK == getQueryFromUri(requestUri, &uriQuery, &uriWithoutQuery)) + { + if (OC_STACK_OK == ExtractFiltersFromQuery(uriQuery, &interfaceName, &rtTypeName)) + { + if (interfaceName && (0 == strcmp(OC_RSRVD_INTERFACE_BATCH, interfaceName))) + { + char *uri = (*payload)->uri; + if (uri && 0 != strcmp(uriWithoutQuery, uri)) + { + OCRepPayload *newPayload = OCRepPayloadCreate(); + if (newPayload) + { + OCRepPayloadSetUri(newPayload, uri); + newPayload->next = *payload; + *payload = newPayload; + } + } + } + } + } + + OICFree(interfaceName); + OICFree(rtTypeName); + OICFree(uriQuery); + OICFree(uriWithoutQuery); + return OC_STACK_OK; + } + return OC_STACK_INVALID_PARAM; +} void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo) { + OIC_TRACE_MARK(%s:OCHandleResponse:%s, TAG, responseInfo->info.resourceUri); OIC_LOG(DEBUG, TAG, "Enter OCHandleResponse"); +#ifdef WITH_PRESENCE if(responseInfo->info.resourceUri && strcmp(responseInfo->info.resourceUri, OC_RSRVD_PRESENCE_URI) == 0) { HandlePresenceResponse(endPoint, responseInfo); return; } +#endif ClientCB *cbNode = GetClientCB(responseInfo->info.token, responseInfo->info.tokenLength, NULL, NULL); @@ -1231,6 +1345,20 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp if(cbNode) { OIC_LOG(INFO, TAG, "There is a cbNode associated with the response token"); +#ifdef __TIZENRT__ + // check obs header option + bool obsHeaderOpt = false; + CAHeaderOption_t *options = responseInfo->info.options; + for (uint8_t i = 0; i< responseInfo->info.numOptions; i++) + { + if (options && options[i].protocolID == CA_COAP_ID && + options[i].optionID == COAP_OPTION_OBSERVE) + { + obsHeaderOpt = true; + break; + } + } +#endif if(responseInfo->result == CA_EMPTY) { OIC_LOG(INFO, TAG, "Receiving A ACK/RESET for this token"); @@ -1252,7 +1380,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}}; CopyEndpointToDevAddr(endPoint, &response.devAddr); FixUpClientResponse(&response); - response.resourceUri = responseInfo->info.resourceUri; + response.resourceUri = OICStrdup(responseInfo->info.resourceUri); memcpy(response.identity.id, responseInfo->info.identity.id, sizeof (response.identity.id)); response.identity.id_length = responseInfo->info.identity.id_length; @@ -1261,18 +1389,42 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp cbNode->callBack(cbNode->context, cbNode->handle, &response); FindAndDeleteClientCB(cbNode); + OICFree(response.resourceUri); + } +#ifdef __TIZENRT__ + else if ((cbNode->method == OC_REST_OBSERVE || cbNode->method == OC_REST_OBSERVE_ALL) + && (responseInfo->result == CA_CONTENT) && !obsHeaderOpt) + { + OCClientResponse response = + {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}}; + CopyEndpointToDevAddr(endPoint, &response.devAddr); + FixUpClientResponse(&response); + response.resourceUri = OICStrdup(responseInfo->info.resourceUri); + memcpy(response.identity.id, responseInfo->info.identity.id, + sizeof (response.identity.id)); + response.identity.id_length = responseInfo->info.identity.id_length; + response.result = OC_STACK_UNAUTHORIZED_REQ; + + cbNode->callBack(cbNode->context, + cbNode->handle, + &response); + FindAndDeleteClientCB(cbNode); + OICFree(response.resourceUri); } +#endif else { OIC_LOG(INFO, TAG, "This is a regular response, A client call back is found"); OIC_LOG(INFO, TAG, "Calling into application address space"); - OCClientResponse response = - {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}}; + OCClientResponse response; + memset(&response, 0, sizeof(OCClientResponse)); + response.devAddr.adapter = OC_DEFAULT_ADAPTER; + response.sequenceNumber = MAX_SEQUENCE_NUMBER + 1; CopyEndpointToDevAddr(endPoint, &response.devAddr); FixUpClientResponse(&response); - response.resourceUri = responseInfo->info.resourceUri; + response.resourceUri = OICStrdup(responseInfo->info.resourceUri); memcpy(response.identity.id, responseInfo->info.identity.id, sizeof (response.identity.id)); response.identity.id_length = responseInfo->info.identity.id_length; @@ -1330,6 +1482,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp { OIC_LOG_V(ERROR, TAG, "Unknown Payload type in Discovery: %d %s", cbNode->method, cbNode->requestUri); + OICFree(response.resourceUri); return; } } @@ -1367,17 +1520,27 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp { OIC_LOG_V(ERROR, TAG, "Unknown Payload type: %d %s", cbNode->method, cbNode->requestUri); + OICFree(response.resourceUri); return; } - if(OC_STACK_OK != OCParsePayload(&response.payload, + // In case of error, still want application to receive the error message. + if (OCResultToSuccess(response.result) || PAYLOAD_TYPE_REPRESENTATION == type) + { + if(OC_STACK_OK != OCParsePayload(&response.payload, type, responseInfo->info.payload, responseInfo->info.payloadSize)) + { + OIC_LOG(ERROR, TAG, "Error converting payload"); + OCPayloadDestroy(response.payload); + OICFree(response.resourceUri); + return; + } + } + else { - OIC_LOG(ERROR, TAG, "Error converting payload"); - OCPayloadDestroy(response.payload); - return; + response.resourceUri = OICStrdup(cbNode->requestUri); } } @@ -1412,6 +1575,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp { OIC_LOG(ERROR, TAG, "#header options are more than MAX_HEADER_OPTIONS"); OCPayloadDestroy(response.payload); + OICFree(response.resourceUri); return; } @@ -1436,13 +1600,52 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp else { #ifdef RD_CLIENT - // if request uri is '/oic/rd', update ins value of resource. - char *targetUri = strstr(cbNode->requestUri, OC_RSRVD_RD_URI); - if (targetUri) + if (cbNode->requestUri) + { + // if request uri is '/oic/rd', update ins value of resource. + char *targetUri = strstr(cbNode->requestUri, OC_RSRVD_RD_URI); + if (targetUri) + { + OCUpdateResourceInsWithResponse(cbNode->requestUri, &response); + } + } +#endif + // set remoteID(device ID) into OCClientResponse callback parameter + if (OC_REST_DISCOVER == cbNode->method) { - OCUpdateResourceInsWithResponse(cbNode->requestUri, &response); + OIC_LOG(INFO, TAG, "cbNode method is OC_REST_DISCOVER"); + OCDiscoveryPayload *payload = (OCDiscoveryPayload*) response.payload; + // Payload can be empty in case of error message. + if (payload && payload->sid) + { + OICStrcpy(response.devAddr.remoteId, sizeof(response.devAddr.remoteId), + payload->sid); + OIC_LOG_V(INFO_PRIVATE, TAG, "Device ID of response : %s", + response.devAddr.remoteId); + } + + if(NULL == response.resourceUri) + { + response.resourceUri = OICStrdup(cbNode->requestUri); + } + } +#ifdef TCP_ADAPTER + if (cbNode->requestUri) + { + OIC_LOG_V(INFO, TAG, "cbNode requestUri is %s", cbNode->requestUri); + if (cbNode->method == OC_REST_POST && + strcmp(cbNode->requestUri, OC_RSRVD_KEEPALIVE_URI) == 0) + { + OCHandleKeepAliveResponse(endPoint, response.payload); + } } #endif + if (response.payload && response.payload->type == PAYLOAD_TYPE_REPRESENTATION) + { + OIC_LOG(INFO, TAG, "Handle batch response"); + HandleBatchResponse(cbNode->requestUri, (OCRepPayload **)&response.payload); + } + OCStackApplicationResult appFeedback = cbNode->callBack(cbNode->context, cbNode->handle, &response); @@ -1463,10 +1666,15 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp //Need to send ACK when the response is CON if(responseInfo->info.type == CA_MSG_CONFIRM) { - SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY, + if (!(endPoint->adapter & CA_ADAPTER_TCP)) + { + OIC_LOG(INFO, TAG, "Received a confirmable message. Sending EMPTY"); + SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY, CA_MSG_ACKNOWLEDGE, 0, NULL, NULL, 0, NULL, CA_RESPONSE_FOR_RES); + } } + OICFree(response.resourceUri); OCPayloadDestroy(response.payload); } return; @@ -1512,9 +1720,13 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp } else { - OIC_LOG(INFO, TAG, "Received a message without callbacks. Sending RESET"); - SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY, - CA_MSG_RESET, 0, NULL, NULL, 0, NULL, CA_RESPONSE_FOR_RES); + if (!(endPoint->adapter & CA_ADAPTER_TCP)) + { + OIC_LOG(INFO, TAG, "Received a message without callbacks. Sending RESET"); + SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY, + CA_MSG_RESET, 0, NULL, NULL, 0, NULL, + CA_RESPONSE_FOR_RES); + } } } @@ -1544,6 +1756,7 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res VERIFY_NON_NULL_NR(responseInfo, FATAL); OIC_LOG(INFO, TAG, "Enter HandleCAResponses"); + OIC_TRACE_BEGIN(%s:HandleCAResponses, TAG); #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) #ifdef ROUTING_GATEWAY @@ -1559,6 +1772,7 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res if(ret != OC_STACK_OK || !needRIHandling) { OIC_LOG_V(INFO, TAG, "Routing status![%d]. Not forwarding to RI", ret); + OIC_TRACE_END(); return; } #endif @@ -1574,7 +1788,7 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res #endif OCHandleResponse(endPoint, responseInfo); - + OIC_TRACE_END(); OIC_LOG(INFO, TAG, "Exit HandleCAResponses"); } @@ -1588,6 +1802,7 @@ void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *er VERIFY_NON_NULL_NR(errorInfo, FATAL); OIC_LOG(INFO, TAG, "Enter HandleCAErrorResponse"); + OIC_TRACE_BEGIN(%s:HandleCAErrorResponse, TAG); ClientCB *cbNode = GetClientCB(errorInfo->info.token, errorInfo->info.tokenLength, NULL, NULL); @@ -1619,6 +1834,7 @@ void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *er } OIC_LOG(INFO, TAG, "Exit HandleCAErrorResponse"); + OIC_TRACE_END(); } /* @@ -1633,9 +1849,14 @@ OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16 CADataType_t dataType) { OIC_LOG(DEBUG, TAG, "Entering SendDirectStackResponse"); - CAResponseInfo_t respInfo = { - .result = responseResult - }; + + if (endPoint->flags & CA_MULTICAST) + { + OIC_LOG(ERROR, TAG, "It is unnecessary to respond to a multicast request"); + return OC_STACK_OK; + } + + CAResponseInfo_t respInfo = { .result = responseResult }; respInfo.info.messageId = coapID; respInfo.info.numOptions = numOptions; @@ -1795,6 +2016,7 @@ OCStackResult HandleStackRequests(OCServerProtocolRequest * protocolRequest) void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* requestInfo) { + OIC_TRACE_MARK(%s:OCHandleRequests:%s, TAG, requestInfo->info.resourceUri); OIC_LOG(DEBUG, TAG, "Enter OCHandleRequests"); OCStackResult requestResult = OC_STACK_ERROR; @@ -1983,11 +2205,25 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque CA_RESPONSE_DATA); } } +#ifndef __TIZENRT__ if (requestResult == OC_STACK_RESOURCE_ERROR && serverRequest.observationOption == OC_OBSERVE_REGISTER) { OIC_LOG_V(ERROR, TAG, "Observe Registration failed due to resource error"); } +#else + if (serverRequest.observationOption == OC_OBSERVE_REGISTER) + { + if (requestResult == OC_STACK_RESOURCE_ERROR) + { + OIC_LOG_V(ERROR, TAG, "Observe Registration failed due to resource error"); + } + else if (!OCResultToSuccess(requestResult)) + { + DeleteObserverUsingToken(requestInfo->info.token, requestInfo->info.tokenLength); + } + } +#endif else if(!OCResultToSuccess(requestResult)) { OIC_LOG_V(ERROR, TAG, "HandleStackRequests failed. error: %d", requestResult); @@ -2012,15 +2248,18 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* requestInfo) { OIC_LOG(INFO, TAG, "Enter HandleCARequests"); + OIC_TRACE_BEGIN(%s:HandleCARequests, TAG); if(!endPoint) { OIC_LOG(ERROR, TAG, "endPoint is NULL"); + OIC_TRACE_END(); return; } if(!requestInfo) { OIC_LOG(ERROR, TAG, "requestInfo is NULL"); + OIC_TRACE_END(); return; } @@ -2040,6 +2279,7 @@ void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque if(OC_STACK_OK != ret || !needRIHandling) { OIC_LOG_V(INFO, TAG, "Routing status![%d]. Not forwarding to RI", ret); + OIC_TRACE_END(); return; } #endif @@ -2075,6 +2315,7 @@ void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque OCHandleRequests(endPoint, requestInfo); } OIC_LOG(INFO, TAG, "Exit HandleCARequests"); + OIC_TRACE_END(); } //----------------------------------------------------------------------------- @@ -2107,6 +2348,13 @@ OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode) OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags) { + OIC_LOG(DEBUG, TAG, "call OCInit1"); + return OCInit2(mode, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS, OC_DEFAULT_ADAPTER); +} + +OCStackResult OCInit2(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags, + OCTransportAdapter transportType) +{ if(stackState == OC_STACK_INITIALIZED) { OIC_LOG(INFO, TAG, "Subsequent calls to OCInit() without calling \ @@ -2168,10 +2416,10 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag result = InitializeScheduleResourceList(); VERIFY_SUCCESS(result, OC_STACK_OK); - result = CAResultToOCResult(CAInitialize()); + result = CAResultToOCResult(CAInitialize((CATransportAdapter_t)transportType)); VERIFY_SUCCESS(result, OC_STACK_OK); - result = CAResultToOCResult(OCSelectNetwork()); + result = CAResultToOCResult(OCSelectNetwork(transportType)); VERIFY_SUCCESS(result, OC_STACK_OK); result = CAResultToOCResult(CARegisterNetworkMonitorHandler( @@ -2203,7 +2451,7 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag VERIFY_SUCCESS(result, OC_STACK_OK); #ifdef TCP_ADAPTER - CARegisterKeepAliveHandler(HandleKeepAliveConnCB); + CARegisterKeepAliveHandler(OCHandleKeepAliveConnCB); #endif #ifdef WITH_PRESENCE @@ -2238,7 +2486,7 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag #ifdef TCP_ADAPTER if (result == OC_STACK_OK) { - result = InitializeKeepAlive(myStackMode); + result = OCInitializeKeepAlive(myStackMode); } #endif @@ -2265,10 +2513,14 @@ OCStackResult OCStop() } else if (stackState != OC_STACK_INITIALIZED) { - OIC_LOG(ERROR, TAG, "Stack not initialized"); + OIC_LOG(INFO, TAG, "Stack not initialized"); return OC_STACK_ERROR; } + // unset cautil config + CAUtilConfig_t configs = {(CATransportBTFlags_t)CA_DEFAULT_BT_FLAGS}; + CAUtilSetBTConfigure(configs); + stackState = OC_STACK_UNINIT_IN_PROGRESS; CAUnregisterNetworkMonitorHandler(OCDefaultAdapterStateChangedHandler, @@ -2289,7 +2541,7 @@ OCStackResult OCStop() #endif #ifdef TCP_ADAPTER - TerminateKeepAlive(myStackMode); + OCTerminateKeepAlive(myStackMode); #endif TerminateScheduleResourceList(); @@ -2351,28 +2603,12 @@ CAMessageType_t qualityOfServiceToMessageType(OCQualityOfService qos) } } -/** - * A request uri consists of the following components in order: - * example - * optionally one of - * CoAP over UDP prefix "coap://" - * CoAP over TCP prefix "coap+tcp://" - * CoAP over DTLS prefix "coaps://" - * CoAP over TLS prefix "coaps+tcp://" - * optionally one of - * IPv6 address "[1234::5678]" - * IPv4 address "192.168.1.1" - * optional port ":5683" - * resource uri "/oc/core..." - * - * for PRESENCE requests, extract resource type. - */ -static OCStackResult ParseRequestUri(const char *fullUri, - OCTransportAdapter adapter, - OCTransportFlags flags, - OCDevAddr **devAddr, - char **resourceUri, - char **resourceType) +OCStackResult ParseRequestUri(const char *fullUri, + OCTransportAdapter adapter, + OCTransportFlags flags, + OCDevAddr **devAddr, + char **resourceUri, + char **resourceType) { VERIFY_NON_NULL(fullUri, FATAL, OC_STACK_INVALID_CALLBACK); @@ -2547,7 +2783,7 @@ static OCStackResult ParseRequestUri(const char *fullUri, result = OC_STACK_NO_MEMORY; goto error; } - strcpy(*resourceUri, slash); + OICStrcpy(*resourceUri, (ulen + 1), slash); } // resource type if (type && resourceType) @@ -2582,6 +2818,7 @@ error: return result; } +#ifdef WITH_PRESENCE static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint, char **requestUri, bool isMulticast) @@ -2598,6 +2835,7 @@ static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint, return OC_STACK_OK; } +#endif // WITH_PRESENCE /** * Discover or Perform requests on a specified resource @@ -2613,7 +2851,30 @@ OCStackResult OCDoResource(OCDoHandle *handle, OCHeaderOption *options, uint8_t numOptions) { + OCStackResult ret = OCDoRequest(handle, method, requestUri,destination, payload, + connectivityType, qos, cbData, options, numOptions); + + // This is the owner of the payload object, so we free it + OCPayloadDestroy(payload); + return ret; +} + +/** + * Discover or Perform requests on a specified resource + */ +OCStackResult OCDoRequest(OCDoHandle *handle, + OCMethod method, + const char *requestUri, + const OCDevAddr *destination, + OCPayload* payload, + OCConnectivityType connectivityType, + OCQualityOfService qos, + OCCallbackData *cbData, + OCHeaderOption *options, + uint8_t numOptions) +{ OIC_LOG(INFO, TAG, "Entering OCDoResource"); + OIC_TRACE_BEGIN(%s:OCDoRequest, TAG); // Validate input parameters VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK); @@ -2675,7 +2936,6 @@ OCStackResult OCDoResource(OCDoHandle *handle, requestInfo.method = CA_DELETE; break; case OC_REST_DISCOVER: - qos = OC_LOW_QOS; #ifdef WITH_PRESENCE case OC_REST_PRESENCE: #endif @@ -2689,6 +2949,7 @@ OCStackResult OCDoResource(OCDoHandle *handle, tmpDevAddr.flags = flags; destination = &tmpDevAddr; requestInfo.isMulticast = true; + qos = OC_LOW_QOS; } // OC_REST_DISCOVER: CA_DISCOVER will become GET and isMulticast. // OC_REST_PRESENCE: Since "presence" is a stack layer only implementation. @@ -2716,9 +2977,20 @@ OCStackResult OCDoResource(OCDoHandle *handle, result = OC_STACK_NO_MEMORY; goto exit; } + OIC_LOG(DEBUG, TAG, "devAddr is set as destination"); *devAddr = *destination; } + if (devAddr) + { + OIC_LOG_V(INFO_PRIVATE, TAG, "remoteId of devAddr : %s", devAddr->remoteId); + if (!requestInfo.isMulticast) + { + OIC_LOG_V(DEBUG, TAG, "remoteAddr of devAddr : [%s]:[%d]", + devAddr->addr, devAddr->port); + } + } + resHandle = GenerateInvocationHandle(); if (!resHandle) { @@ -2855,13 +3127,12 @@ exit: OICFree(resHandle); } - // This is the owner of the payload object, so we free it - OCPayloadDestroy(payload); OICFree(requestInfo.info.payload); OICFree(devAddr); OICFree(resourceUri); OICFree(resourceType); OICFree(requestInfo.info.options); + OIC_TRACE_END(); return result; } @@ -2955,6 +3226,14 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption FindAndDeleteClientCB(clientCB); break; #endif + case OC_REST_GET: + case OC_REST_PUT: + case OC_REST_POST: + case OC_REST_DELETE: + OIC_LOG_V(INFO, TAG, "Cancelling request callback for resource %s", + clientCB->requestUri); + FindAndDeleteClientCB(clientCB); + break; default: ret = OC_STACK_INVALID_METHOD; @@ -3093,6 +3372,11 @@ exit: OCStackResult OCProcess() { + if (stackState == OC_STACK_UNINITIALIZED) + { + OIC_LOG(ERROR, TAG, "OCProcess has failed. ocstack is not initialized"); + return OC_STACK_ERROR; + } #ifdef WITH_PRESENCE OCProcessPresence(); #endif @@ -3103,7 +3387,7 @@ OCStackResult OCProcess() #endif #ifdef TCP_ADAPTER - ProcessKeepAlive(); + OCProcessKeepAlive(); #endif return OC_STACK_OK; } @@ -3131,7 +3415,9 @@ OCStackResult OCStartPresence(const uint32_t ttl) { presenceResource.presenceTTL = ttl; } +#ifndef __TIZENRT__ OIC_LOG_V(DEBUG, TAG, "Presence TTL is %" PRIu32 " seconds", presenceResource.presenceTTL); +#endif if (OC_PRESENCE_UNINITIALIZED == presenceState) { @@ -3467,8 +3753,11 @@ OCStackResult OCUnBindResource( { OCChildResource *temp = tempChildResource->next; OICFree(tempChildResource); - tempLastChildResource->next = temp; - temp = NULL; + if (tempLastChildResource) + { + tempLastChildResource->next = temp; + temp = NULL; + } } OIC_LOG(INFO, TAG, "resource unbound"); @@ -4035,6 +4324,7 @@ OCNotifyListOfObservers (OCResourceHandle handle, OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse) { + OIC_TRACE_BEGIN(%s:OCDoResponse, TAG); OCStackResult result = OC_STACK_ERROR; OCServerRequest *serverRequest = NULL; @@ -4053,6 +4343,7 @@ OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse) result = serverRequest->ehResponseHandler(ehResponse); } + OIC_TRACE_END(); return result; } @@ -4310,12 +4601,12 @@ OCStackResult deleteResource(OCResource *resource) headResource = temp->next; } // Deleting tail. - else if (temp == tailResource) + else if (temp == tailResource && prev) { tailResource = prev; tailResource->next = NULL; } - else + else if (prev) { prev->next = temp->next; } @@ -4341,37 +4632,77 @@ void deleteResourceElements(OCResource *resource) return; } - OICFree(resource->uri); - deleteResourceType(resource->rsrcType); - deleteResourceInterface(resource->rsrcInterface); - OCDeleteResourceAttributes(resource->rsrcAttributes); + if (resource->uri) + { + OICFree(resource->uri); + resource->uri = NULL; + } + if (resource->rsrcType) + { + deleteResourceType(resource->rsrcType); + resource->rsrcType = NULL; + } + if (resource->rsrcInterface) + { + deleteResourceInterface(resource->rsrcInterface); + resource->rsrcInterface = NULL; + } + if (resource->rsrcChildResourcesHead) + { + deleteResourceChild(resource->rsrcChildResourcesHead); + resource->rsrcChildResourcesHead = NULL; + } + if (resource->rsrcAttributes) + { + OCDeleteResourceAttributes(resource->rsrcAttributes); + resource->rsrcAttributes = NULL; + } + resource = NULL; } void deleteResourceType(OCResourceType *resourceType) { - OCResourceType *pointer = resourceType; OCResourceType *next = NULL; - while (pointer) + for (OCResourceType *pointer = resourceType; pointer; pointer = next) { - next = pointer->next; - OICFree(pointer->resourcetypename); + next = pointer->next ? pointer->next : NULL; + if (pointer->resourcetypename) + { + OICFree(pointer->resourcetypename); + pointer->resourcetypename = NULL; + } OICFree(pointer); - pointer = next; } } void deleteResourceInterface(OCResourceInterface *resourceInterface) { - OCResourceInterface *pointer = resourceInterface; OCResourceInterface *next = NULL; + for (OCResourceInterface *pointer = resourceInterface; pointer; pointer = next) + { + next = pointer->next ? pointer->next : NULL; + if (pointer->name) + { + OICFree(pointer->name); + pointer->name = NULL; + } + OICFree(pointer); + } +} - while (pointer) +void deleteResourceChild(OCChildResource *resourceChild) +{ + OCChildResource *next = NULL; + for (OCChildResource *pointer = resourceChild; pointer; pointer = next) { - next = pointer->next; - OICFree(pointer->name); + next = pointer->next ? pointer->next : NULL; + if (pointer->rsrcResource) + { + deleteResourceElements(pointer->rsrcResource); + pointer->rsrcResource = NULL; + } OICFree(pointer); - pointer = next; } } @@ -4380,16 +4711,22 @@ void OCDeleteResourceAttributes(OCAttribute *rsrcAttributes) OCAttribute *next = NULL; for (OCAttribute *pointer = rsrcAttributes; pointer; pointer = next) { - next = pointer->next; + next = pointer->next ? pointer->next : NULL; if (pointer->attrName && 0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, pointer->attrName)) { OCFreeOCStringLL((OCStringLL *)pointer->attrValue); + pointer->attrValue = NULL; } - else + else if (pointer->attrValue) { OICFree(pointer->attrValue); + pointer->attrValue = NULL; + } + if (pointer->attrName) + { + OICFree(pointer->attrName); + pointer->attrName = NULL; } - OICFree(pointer->attrName); OICFree(pointer); } } @@ -4649,47 +4986,28 @@ OCStackResult getQueryFromUri(const char * uri, char** query, char ** uriWithout return OC_STACK_NO_MEMORY; } -static const OicUuid_t* OCGetServerInstanceID(void) -{ - static bool generated = false; - static OicUuid_t sid; - if (generated) - { - return &sid; - } - - if (OC_STACK_OK != GetDoxmDeviceID(&sid)) - { - OIC_LOG(FATAL, TAG, "Generate UUID for Server Instance failed!"); - return NULL; - } - generated = true; - return &sid; -} - const char* OCGetServerInstanceIDString(void) { - static bool generated = false; static char sidStr[UUID_STRING_SIZE]; - - if (generated) + OicUuid_t sid; + if (OC_STACK_OK != GetDoxmDeviceID(&sid)) { - return sidStr; + OIC_LOG(FATAL, TAG, "GetDoxmDeviceID failed!"); + return NULL; } - const OicUuid_t *sid = OCGetServerInstanceID(); - if (sid && OCConvertUuidToString(sid->id, sidStr) != RAND_UUID_OK) + if (OCConvertUuidToString(sid.id, sidStr) != RAND_UUID_OK) { OIC_LOG(FATAL, TAG, "Generate UUID String for Server Instance failed!"); return NULL; } - generated = true; return sidStr; } -CAResult_t OCSelectNetwork() +CAResult_t OCSelectNetwork(OCTransportAdapter transportType) { + OIC_LOG_V(DEBUG, TAG, "OCSelectNetwork [%d]", transportType); CAResult_t retResult = CA_STATUS_FAILED; CAResult_t caResult = CA_STATUS_OK; @@ -4713,11 +5031,19 @@ CAResult_t OCSelectNetwork() // If CA status is not initialized, CASelectNetwork() will not be called. if (caResult != CA_STATUS_NOT_INITIALIZED) { - caResult = CASelectNetwork(connTypes[i]); - if (caResult == CA_STATUS_OK) - { - retResult = CA_STATUS_OK; - } + if ((connTypes[i] & transportType) || (OC_DEFAULT_ADAPTER == transportType)) + { + OIC_LOG_V(DEBUG, TAG, "call CASelectNetwork [%d]", connTypes[i]); + caResult = CASelectNetwork(connTypes[i]); + if (caResult == CA_STATUS_OK) + { + retResult = CA_STATUS_OK; + } + } + else + { + OIC_LOG_V(DEBUG, TAG, "there is no transport type [%d]", connTypes[i]); + } } } @@ -4790,7 +5116,7 @@ OCStackResult OCSetProxyURI(const char *uri) #endif #if defined(RD_CLIENT) || defined(RD_SERVER) -OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, uint8_t ins) +OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, int64_t ins) { VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM); @@ -4894,13 +5220,13 @@ OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri, query = strstr(query, OC_RSRVD_INS); if (query) { - uint8_t queryIns = atoi(query + 4); + int64_t queryIns = atoi(query + 4); for (uint8_t i = 0; i < numResources; i++) { OCResourceHandle resHandle = OCGetResourceHandle(i); if (resHandle) { - uint8_t resIns = 0; + int64_t resIns = 0; OCGetResourceIns(resHandle, &resIns); if (queryIns && queryIns == resIns) { @@ -4941,7 +5267,7 @@ OCResourceHandle OCGetResourceHandleAtUri(const char *uri) return NULL; } -OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins) +OCStackResult OCGetResourceIns(OCResourceHandle handle, int64_t *ins) { OCResource *resource = NULL; @@ -5109,3 +5435,137 @@ OCStackResult OCSetDeviceId(const OCUUIdentity *deviceId) ret = SetDoxmDeviceID(&oicUuid); return ret; } + +OCStackResult OCGetDeviceOwnedState(bool *isOwned) +{ + bool isDeviceOwned = true; + OCStackResult ret = OC_STACK_ERROR; + + ret = GetDoxmIsOwned(&isDeviceOwned); + if (OC_STACK_OK == ret) + { + *isOwned = isDeviceOwned; + } + else + { + OIC_LOG(ERROR, TAG, "Device Owned State Get error"); + } + return ret; +} + +void OCClearCallBackList() +{ + DeleteClientCBList(); +} + +void OCClearObserverlist() +{ + DeleteObserverList(); +} + +int OCEncrypt(const unsigned char *pt, size_t pt_len, + unsigned char **ct, size_t *ct_len) +{ +#ifndef __SECURE_PSI__ + OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__); + return 0; +#else + OIC_LOG_V(DEBUG, TAG, "%s", __func__); + + return psiEncrypt(pt, pt_len, ct, ct_len); +#endif // __SECURE_PSI__ +} + +int OCDecrypt(const unsigned char *ct, size_t ct_len, + unsigned char **pt, size_t *pt_len) +{ +#ifndef __SECURE_PSI__ + OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__); + return 0; +#else + OIC_LOG_V(DEBUG, TAG, "%s", __func__); + + return psiDecrypt(ct, ct_len, pt, pt_len); +#endif // __SECURE_PSI__ +} + +OCStackResult OCSetKey(const unsigned char* key) +{ +#ifndef __SECURE_PSI__ + OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__); + return OC_STACK_OK; +#else + OIC_LOG_V(DEBUG, TAG, "%s", __func__); + + return psiSetKey(key); +#endif // __SECURE_PSI__ +} + +OCStackResult OCGetKey(unsigned char* key) +{ +#ifndef __SECURE_PSI__ + OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__); + return OC_STACK_OK; +#else + OIC_LOG_V(DEBUG, TAG, "%s", __func__); + + return psiGetKey(key); +#endif // __SECURE_PSI__ +} + +OCStackResult OCSetSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain, + const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue) +{ +#ifndef __SECURE_PSI__ + OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__); + return OC_STACK_OK; +#else + OIC_LOG_V(DEBUG, TAG, "%s", __func__); + + return setSecurePSI(key, psPlain, psEnc, psRescue); +#endif // __SECURE_PSI__ +} + +#if defined(__WITH_DTLS__) || defined (__WITH_TLS__) +static void OtmEventHandler(const char *addr, uint16_t port, const char *uuid, int event) +{ + if (g_otmEventHandler.cb) + { + g_otmEventHandler.cb(g_otmEventHandler.ctx, addr, port, uuid, event); + } +} + +/* TODO Work-around + * It is already declared in srmutility.h. + * We can't include the header file, because of "redefined VERIFY_NON_NULL" + */ +typedef void (*OicSecOtmEventHandler_t)(const char* addr, uint16_t port, + const char* uuid, int event); +void SetOtmEventHandler(OicSecOtmEventHandler_t otmEventHandler); +#endif + +OCStackResult OCSetOtmEventHandler(void *ctx, OCOtmEventHandler cb) +{ +#if defined(__WITH_DTLS__) || defined (__WITH_TLS__) + OIC_LOG_V(DEBUG, TAG, "%s", __func__); + + g_otmEventHandler.cb = cb; + g_otmEventHandler.ctx = ctx; + + if (g_otmEventHandler.cb) + { + OIC_LOG(DEBUG, TAG, "SET OCOtmEventHandler"); + SetOtmEventHandler(OtmEventHandler); + } + else + { + OIC_LOG(DEBUG, TAG, "UNSET OCOtmEventHandler"); + SetOtmEventHandler(NULL); + } +#else + OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__); + OC_UNUSED(ctx); + OC_UNUSED(cb); +#endif + return OC_STACK_OK; +}