X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fstack%2Fsrc%2Focstack.c;h=f5575b1e18e642cc9676933332002c0fb41bb84d;hb=1e743d337b66bda0e44a5ca500d4d7178bb599b5;hp=c41f0e8aa81c7a446c07c2d9f0746ca30380e07e;hpb=338044812ecee35167a8b7a3f77d763a864f384f;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index c41f0e8..f5575b1 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); /** + * Unbind all child resources. + * + * @param resourceChild Specified binded resource head is deleted from parent. + */ +static void unbindChildResources(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 @@ -408,15 +431,6 @@ static void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bo */ static void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isConnected); -/** - * Register network monitoring callback. - * Network status changes are delivered these callback. - * @param adapterHandler Adapter state monitoring callback. - * @param connectionHandler Connection state monitoring callback. - */ -static void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler, - CAConnectionStateChangedCB connectionHandler); - //----------------------------------------------------------------------------- // Internal functions //----------------------------------------------------------------------------- @@ -484,6 +498,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 +523,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 +541,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; } //----------------------------------------------------------------------------- @@ -544,11 +564,11 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat { case OC_OBSERVER_NOT_INTERESTED: OIC_LOG(DEBUG, TAG, "observer not interested in our notifications"); - observer = GetObserverUsingToken (token, tokenLength); - if(observer) + observer = GetObserverUsingToken(token, tokenLength); + if (observer) { result = FormOCEntityHandlerRequest(&ehRequest, - (OCRequestHandle)NULL, + 0, OC_REST_NOMETHOD, &observer->devAddr, (OCResourceHandle)NULL, @@ -557,16 +577,23 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat OC_OBSERVE_DEREGISTER, observer->observeId, 0); - if(result != OC_STACK_OK) + if (result != OC_STACK_OK) { + FreeObserver(observer); return result; } - observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest, - observer->resource->entityHandlerCallbackParam); + + if (observer->resource && observer->resource->entityHandler) + { + observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest, + observer->resource->entityHandlerCallbackParam); + } + + FreeObserver(observer); } - result = DeleteObserverUsingToken (token, tokenLength); - if(result == OC_STACK_OK) + result = DeleteObserverUsingToken(token, tokenLength); + if (result == OC_STACK_OK) { OIC_LOG(DEBUG, TAG, "Removed observer successfully"); } @@ -579,12 +606,13 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat case OC_OBSERVER_STILL_INTERESTED: OIC_LOG(DEBUG, TAG, "observer still interested, reset the failedCount"); - observer = GetObserverUsingToken (token, tokenLength); - if(observer) + observer = GetObserverUsingToken(token, tokenLength); + if (observer) { observer->forceHighQos = 0; observer->failedCommCount = 0; result = OC_STACK_OK; + FreeObserver(observer); } else { @@ -595,12 +623,12 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat case OC_OBSERVER_FAILED_COMM: OIC_LOG(DEBUG, TAG, "observer is unreachable"); observer = GetObserverUsingToken (token, tokenLength); - if(observer) + if (observer) { - if(observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM) + if (observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM) { result = FormOCEntityHandlerRequest(&ehRequest, - (OCRequestHandle)NULL, + 0, OC_REST_NOMETHOD, &observer->devAddr, (OCResourceHandle)NULL, @@ -609,15 +637,20 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat OC_OBSERVE_DEREGISTER, observer->observeId, 0); - if(result != OC_STACK_OK) + if (result != OC_STACK_OK) { + FreeObserver(observer); return OC_STACK_ERROR; } - observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest, - observer->resource->entityHandlerCallbackParam); - result = DeleteObserverUsingToken (token, tokenLength); - if(result == OC_STACK_OK) + if (observer->resource && observer->resource->entityHandler) + { + observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest, + observer->resource->entityHandlerCallbackParam); + } + + result = DeleteObserverUsingToken(token, tokenLength); + if (result == OC_STACK_OK) { OIC_LOG(DEBUG, TAG, "Removed observer successfully"); } @@ -635,6 +668,8 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat observer->failedCommCount); result = OC_STACK_CONTINUE; } + + FreeObserver(observer); } break; default: @@ -675,18 +710,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; } @@ -742,6 +795,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; @@ -751,6 +810,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; } @@ -778,6 +852,7 @@ OCTransportFlags CAToOCTransportFlags(CATransportFlags_t caFlags) return (OCTransportFlags)caFlags; } +#ifdef WITH_PRESENCE static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds) { uint32_t lowerBound = 0; @@ -867,6 +942,7 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr) return OC_PRESENCE_TRIGGER_DELETE; } } +#endif // WITH_PRESENCE OCStackResult OCEncodeAddressForRFC6874(char *outputAddress, size_t outputSize, @@ -931,8 +1007,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; } @@ -972,6 +1048,7 @@ OCStackResult OCDecodeAddressForRFC6874(char *outputAddress, return OC_STACK_OK; } +#ifdef WITH_PRESENCE /** * The cononical presence allows constructed URIs to be string compared. * @@ -1093,7 +1170,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) { @@ -1102,7 +1179,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) { @@ -1112,7 +1189,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; } @@ -1189,9 +1267,9 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint, } } - OIC_LOG(INFO, TAG, "Callback for presence"); - + OIC_LOG(INFO, TAG, "Before calling into application address space for presence"); cbResult = cbNode->callBack(cbNode->context, cbNode->handle, &response); + OIC_LOG(INFO, TAG, "After calling into application address space for presence"); if (cbResult == OC_STACK_DELETE_TRANSACTION) { @@ -1202,27 +1280,80 @@ 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); - ResourceObserver * observer = GetObserverUsingToken (responseInfo->info.token, - responseInfo->info.tokenLength); - 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"); @@ -1238,33 +1369,60 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp else if(responseInfo->result == CA_RETRANSMIT_TIMEOUT) { OIC_LOG(INFO, TAG, "Receiving A Timeout for this token"); - OIC_LOG(INFO, TAG, "Calling into application address space"); OCClientResponse response = {.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; response.result = CAResponseToOCStackResult(responseInfo->result); + OIC_LOG(INFO, TAG, "Before calling into application address space for reTrans timeout"); cbNode->callBack(cbNode->context, cbNode->handle, &response); + OIC_LOG(INFO, TAG, "After calling into application address space for reTrans timeout"); + FindAndDeleteClientCB(cbNode); + OICFree((void *)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; + + OIC_LOG(INFO, TAG, "Before calling into application address space for observe resp"); + cbNode->callBack(cbNode->context, + cbNode->handle, + &response); + OIC_LOG(INFO, TAG, "After calling into application address space for observe resp"); + 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; @@ -1313,7 +1471,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp type = PAYLOAD_TYPE_REPRESENTATION; } #ifdef TCP_ADAPTER - else if (strcmp(cbNode->requestUri, KEEPALIVE_RESOURCE_URI) == 0) + else if (strcmp(cbNode->requestUri, OC_RSRVD_KEEPALIVE_URI) == 0) { type = PAYLOAD_TYPE_REPRESENTATION; } @@ -1322,6 +1480,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((void *)response.resourceUri); return; } } @@ -1359,17 +1518,28 @@ 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((void *)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((void *)response.resourceUri); + return; + } + } + else { - OIC_LOG(ERROR, TAG, "Error converting payload"); - OCPayloadDestroy(response.payload); - return; + OICFree((void *)response.resourceUri); + response.resourceUri = OICStrdup(cbNode->requestUri); } } @@ -1378,7 +1548,8 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp { int start = 0; //First option always with option ID is COAP_OPTION_OBSERVE if it is available. - if(responseInfo->info.options[0].optionID == COAP_OPTION_OBSERVE) + if(responseInfo->info.options + && responseInfo->info.options[0].optionID == COAP_OPTION_OBSERVE) { size_t i; uint32_t observationOption; @@ -1403,13 +1574,24 @@ 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((void *)response.resourceUri); return; } - for (uint8_t i = start; i < responseInfo->info.numOptions; i++) + if (response.numRcvdVendorSpecificHeaderOptions > 0) { - memcpy (&(response.rcvdVendorSpecificHeaderOptions[i-start]), - &(responseInfo->info.options[i]), sizeof(OCHeaderOption)); + response.rcvdVendorSpecificHeaderOptions = + (OCHeaderOption *) OICCalloc(response.numRcvdVendorSpecificHeaderOptions, sizeof(OCHeaderOption)); + if (NULL == response.rcvdVendorSpecificHeaderOptions) + { + OIC_LOG(ERROR, TAG, "Failed to allocate memory for vendor header options"); + OCPayloadDestroy(response.payload); + OICFree((void *)response.resourceUri); + return; + } + + memcpy(response.rcvdVendorSpecificHeaderOptions, responseInfo->info.options + start, + response.numRcvdVendorSpecificHeaderOptions*sizeof(OCHeaderOption)); } } @@ -1424,16 +1606,58 @@ 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) + { + 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) { - OCUpdateResourceInsWithResponse(cbNode->requestUri, &response); + 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); + } + + OIC_LOG(INFO, TAG, "Before calling into application address space for handleResponse"); OCStackApplicationResult appFeedback = cbNode->callBack(cbNode->context, cbNode->handle, &response); + OIC_LOG(INFO, TAG, "After calling into application address space for handleResponse"); + cbNode->sequenceNumber = response.sequenceNumber; if (appFeedback == OC_STACK_DELETE_TRANSACTION) @@ -1451,15 +1675,24 @@ 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((void *)response.resourceUri); OCPayloadDestroy(response.payload); + OICFree(response.rcvdVendorSpecificHeaderOptions); } return; } + ResourceObserver * observer = GetObserverUsingToken (responseInfo->info.token, + responseInfo->info.tokenLength); + if(observer) { OIC_LOG(INFO, TAG, "There is an observer associated with the response token"); @@ -1485,6 +1718,8 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp OCStackFeedBack(responseInfo->info.token, responseInfo->info.tokenLength, OC_OBSERVER_FAILED_COMM); } + + FreeObserver(observer); return; } @@ -1500,9 +1735,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); + } } } @@ -1532,6 +1771,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 @@ -1547,6 +1787,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 @@ -1562,7 +1803,7 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res #endif OCHandleResponse(endPoint, responseInfo); - + OIC_TRACE_END(); OIC_LOG(INFO, TAG, "Exit HandleCAResponses"); } @@ -1576,6 +1817,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); @@ -1590,7 +1832,9 @@ void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *er response.identity.id_length = errorInfo->info.identity.id_length; response.result = CAResultToOCResult(errorInfo->result); + OIC_LOG(INFO, TAG, "Before calling into application address space for error response"); cbNode->callBack(cbNode->context, cbNode->handle, &response); + OIC_LOG(INFO, TAG, "After calling into application address space for error response"); } ResourceObserver *observer = GetObserverUsingToken(errorInfo->info.token, @@ -1607,6 +1851,7 @@ void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *er } OIC_LOG(INFO, TAG, "Exit HandleCAErrorResponse"); + OIC_TRACE_END(); } /* @@ -1621,9 +1866,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; @@ -1783,6 +2033,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; @@ -1952,10 +2203,20 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque OICFree(serverRequest.requestToken); return; } + serverRequest.numRcvdVendorSpecificHeaderOptions = tempNum; - if (serverRequest.numRcvdVendorSpecificHeaderOptions) + if (serverRequest.numRcvdVendorSpecificHeaderOptions && requestInfo->info.options) { - memcpy (&(serverRequest.rcvdVendorSpecificHeaderOptions), requestInfo->info.options, + serverRequest.rcvdVendorSpecificHeaderOptions = (OCHeaderOption*) OICCalloc(tempNum, sizeof(OCHeaderOption)); + if (NULL == serverRequest.rcvdVendorSpecificHeaderOptions) + { + OIC_LOG(ERROR, TAG, "Failed to allocated memory to vnd header options!"); + OICFree(serverRequest.payload); + OICFree(serverRequest.requestToken); + return; + } + + memcpy (serverRequest.rcvdVendorSpecificHeaderOptions, requestInfo->info.options, sizeof(CAHeaderOption_t)*tempNum); } @@ -1971,15 +2232,35 @@ 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); + // Delete observer node if it is OBSERVE failure from app + if (serverRequest.observationOption == OC_OBSERVE_REGISTER) + { + DeleteObserverUsingToken(requestInfo->info.token, requestInfo->info.tokenLength); + } + CAResponseResult_t stackResponse = OCToCAStackResult(requestResult, serverRequest.method); @@ -1993,6 +2274,7 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque // The token is copied in there, and is thus still owned by this function. OICFree(serverRequest.payload); OICFree(serverRequest.requestToken); + OICFree(serverRequest.rcvdVendorSpecificHeaderOptions); OIC_LOG(INFO, TAG, "Exit OCHandleRequests"); } @@ -2000,15 +2282,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; } @@ -2028,6 +2313,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 @@ -2063,6 +2349,7 @@ void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque OCHandleRequests(endPoint, requestInfo); } OIC_LOG(INFO, TAG, "Exit HandleCARequests"); + OIC_TRACE_END(); } //----------------------------------------------------------------------------- @@ -2095,6 +2382,16 @@ OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode) OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags) { + OC_UNUSED(serverFlags); + OC_UNUSED(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 \ @@ -2156,10 +2453,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( @@ -2191,7 +2488,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 @@ -2226,17 +2523,19 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag #ifdef TCP_ADAPTER if (result == OC_STACK_OK) { - result = InitializeKeepAlive(myStackMode); + result = OCInitializeKeepAlive(myStackMode); } #endif + InitializeObserverList(); + exit: if(result != OC_STACK_OK) { OIC_LOG(ERROR, TAG, "Stack initialization error"); + TerminateScheduleResourceList(); deleteAllResources(); CATerminate(); - TerminateScheduleResourceList(); stackState = OC_STACK_UNINITIALIZED; } return result; @@ -2253,16 +2552,24 @@ 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, + OCDefaultConnectionStateChangedHandler); + #ifdef WITH_PRESENCE // Ensure that the TTL associated with ANY and ALL presence notifications originating from // here send with the code "OC_STACK_PRESENCE_STOPPED" result. presenceResource.presenceTTL = 0; + presenceState = OC_PRESENCE_UNINITIALIZED; #endif // WITH_PRESENCE #ifdef ROUTING_GATEWAY @@ -2273,22 +2580,25 @@ OCStackResult OCStop() #endif #ifdef TCP_ADAPTER - TerminateKeepAlive(myStackMode); + OCTerminateKeepAlive(myStackMode); #endif - // Free memory dynamically allocated for resources - deleteAllResources(); - CATerminate(); TerminateScheduleResourceList(); // Remove all observers DeleteObserverList(); + // Free memory dynamically allocated for resources + deleteAllResources(); // Remove all the client callbacks DeleteClientCBList(); + // Terminate connectivity-abstraction layer. + CATerminate(); // De-init the SRM Policy Engine // TODO after BeachHead delivery: consolidate into single SRMDeInit() SRMDeInitPolicyEngine(); + // Destroy Observer List Mutex + TerminateObserverList(); stackState = OC_STACK_UNINITIALIZED; return OC_STACK_OK; @@ -2335,28 +2645,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); @@ -2531,7 +2825,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) @@ -2566,6 +2860,7 @@ error: return result; } +#ifdef WITH_PRESENCE static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint, char **requestUri, bool isMulticast) @@ -2582,6 +2877,7 @@ static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint, return OC_STACK_OK; } +#endif // WITH_PRESENCE /** * Discover or Perform requests on a specified resource @@ -2597,7 +2893,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); @@ -2659,7 +2978,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 @@ -2673,6 +2991,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. @@ -2700,9 +3019,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) { @@ -2796,6 +3126,7 @@ OCStackResult OCDoResource(OCDoHandle *handle, goto exit; } + token = NULL; // Client CB list entry now owns it devAddr = NULL; // Client CB list entry now owns it resourceUri = NULL; // Client CB list entry now owns it resourceType = NULL; // Client CB list entry now owns it @@ -2839,13 +3170,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; } @@ -2939,6 +3269,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; @@ -3029,7 +3367,10 @@ OCStackResult OCProcessPresence() OIC_LOG_V(DEBUG, TAG, "moving to TTL level %d", cbNode->presence->TTLlevel); + OIC_LOG(INFO, TAG, "Before calling into application address space for presence timeout"); cbResult = cbNode->callBack(cbNode->context, cbNode->handle, &clientResponse); + OIC_LOG(INFO, TAG, "After calling into application address space for presence timeout"); + if (cbResult == OC_STACK_DELETE_TRANSACTION) { FindAndDeleteClientCB(cbNode); @@ -3077,6 +3418,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 @@ -3087,7 +3433,7 @@ OCStackResult OCProcess() #endif #ifdef TCP_ADAPTER - ProcessKeepAlive(); + OCProcessKeepAlive(); #endif return OC_STACK_OK; } @@ -3115,7 +3461,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) { @@ -3451,8 +3799,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"); @@ -4019,6 +4370,7 @@ OCNotifyListOfObservers (OCResourceHandle handle, OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse) { + OIC_TRACE_BEGIN(%s:OCDoResponse, TAG); OCStackResult result = OC_STACK_ERROR; OCServerRequest *serverRequest = NULL; @@ -4030,13 +4382,14 @@ OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse) // Normal response // Get pointer to request info - serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle); + serverRequest = GetServerRequestUsingHandle(ehResponse->requestHandle); if(serverRequest) { // response handler in ocserverrequest.c. Usually HandleSingleResponse. result = serverRequest->ehResponseHandler(ehResponse); } + OIC_TRACE_END(); return result; } @@ -4294,12 +4647,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; } @@ -4325,37 +4678,72 @@ 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) + { + unbindChildResources(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; - - while (pointer) + for (OCResourceInterface *pointer = resourceInterface; pointer; pointer = next) { - next = pointer->next; - OICFree(pointer->name); + next = pointer->next ? pointer->next : NULL; + if (pointer->name) + { + OICFree(pointer->name); + pointer->name = NULL; + } OICFree(pointer); - pointer = next; + } +} + +void unbindChildResources(OCChildResource *head) +{ + OCChildResource *next = NULL; + for (OCChildResource *current = head; current; current = next) + { + next = current->next; + OICFree(current); } } @@ -4364,16 +4752,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); } } @@ -4633,47 +5027,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; @@ -4697,11 +5072,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]); + } } } @@ -4774,7 +5157,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); @@ -4840,8 +5223,19 @@ OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri, { OCBindResourceInsToResource(handle, ins); } + + OICFree(uri); + uri = NULL; } } + + // Free links + size_t count = calcDimTotal(dimensions); + for (size_t k = 0; k < count; k++) + { + OCRepPayloadDestroy(links[k]); + } + OICFree(links); } } } @@ -4878,13 +5272,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) { @@ -4925,7 +5319,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; @@ -4943,7 +5337,7 @@ OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins) #endif OCStackResult OCSetHeaderOption(OCHeaderOption* ocHdrOpt, size_t* numOptions, uint16_t optionID, - void* optionData, size_t optionDataLength) + const void* optionData, size_t optionDataLength) { if (!ocHdrOpt) { @@ -5038,14 +5432,21 @@ void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isCon { g_connectionHandler(info, isConnected); } -} -void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler, - CAConnectionStateChangedCB connectionHandler) -{ - OIC_LOG(DEBUG, TAG, "OCSetNetworkMonitorHandler"); - g_adapterHandler = adapterHandler; - g_connectionHandler = connectionHandler; + /* + * If the client observes one or more resources over a reliable connection, + * then the CoAP server (or intermediary in the role of the CoAP server) + * MUST remove all entries associated with the client endpoint from the lists + * of observers when the connection is either closed or times out. + */ + if (!isConnected) + { + OCDevAddr devAddr = { OC_DEFAULT_ADAPTER }; + CopyEndpointToDevAddr(info, &devAddr); + + // remove observer list with remote device address. + DeleteObserverUsingDevAddr(&devAddr); + } } OCStackResult OCGetDeviceId(OCUUIdentity *deviceId) @@ -5078,3 +5479,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; +}