X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fstack%2Fsrc%2Focstack.c;h=c8c0da583ea58baacde021a3383a9b720bdb0df4;hb=41e04322a0b5684ed05e3b7968f44fc172a664a6;hp=d3e892240e9264bf7e364264050b0807877a646c;hpb=7b017138673175a8a5891b242efca8ed44227349;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index d3e8922..c8c0da5 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -36,6 +36,7 @@ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS #endif +#include "iotivity_config.h" #include #include #include @@ -57,7 +58,8 @@ #include "cainterface.h" #include "ocpayload.h" #include "ocpayloadcbor.h" -#include "platform_features.h" +#include "cautilinterface.h" +#include "oicgroup.h" #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) #include "routingutility.h" @@ -80,9 +82,7 @@ #ifdef HAVE_SYS_TIME_H #include #endif -#include "coap_time.h" -#include "utlist.h" -#include "pdu.h" +#include #ifdef HAVE_ARPA_INET_H #include @@ -137,9 +137,13 @@ static bool gRASetInfo = false; #endif OCDeviceEntityHandler defaultDeviceHandler; void* defaultDeviceHandlerCallbackParameter = NULL; -static const char COAP_TCP[] = "coap+tcp:"; +static const char COAP_TCP_SCHEME[] = "coap+tcp:"; +static const char COAPS_TCP_SCHEME[] = "coaps+tcp:"; static const char CORESPEC[] = "core"; +CAAdapterStateChangedCB g_adapterHandler = NULL; +CAConnectionStateChangedCB g_connectionHandler = NULL; + //----------------------------------------------------------------------------- // Macros //----------------------------------------------------------------------------- @@ -318,15 +322,6 @@ static OCStackResult CAResultToOCStackResult(CAResult_t caResult); static OCStackResult CAResponseToOCStackResult(CAResponseResult_t caCode); /** - * Convert OCStackResult to CAResponseResult_t. - * - * @param caCode OCStackResult code. - * @param method OCMethod method the return code replies to. - * @return ::CA_CONTENT on OK, some other value upon failure. - */ -static CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method); - -/** * Convert OCTransportFlags_t to CATransportModifiers_t. * * @param ocConType OCTransportFlags_t input. @@ -414,10 +409,54 @@ static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds); */ static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t *requestInfo); +/** + * default adapter state change callback method + * + * @param adapter CA network adapter type. + * @param enabled current adapter state. + */ +static void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled); + +/** + * default connection state change callback method + * + * @param info CAEndpoint which has address, port and etc. + * @param isConnected current connection state. + */ +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 //----------------------------------------------------------------------------- +bool checkProxyUri(OCHeaderOption *options, uint8_t numOptions) +{ + if (!options || 0 == numOptions) + { + OIC_LOG (INFO, TAG, "No options present"); + return false; + } + + for (uint8_t i = 0; i < numOptions; i++) + { + if (options[i].protocolID == OC_COAP_ID && options[i].optionID == OC_RSRVD_PROXY_OPTION_ID) + { + OIC_LOG(DEBUG, TAG, "Proxy URI is present"); + return true; + } + } + return false; +} + uint32_t GetTicks(uint32_t afterMilliSeconds) { coap_tick_t now; @@ -446,7 +485,11 @@ void CopyEndpointToDevAddr(const CAEndpoint_t *in, OCDevAddr *out) out->port = in->port; out->ifindex = in->ifindex; #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) - memcpy(out->routeData, in->routeData, sizeof(out->routeData)); + /* This assert is to prevent accidental mismatch between address size macros defined in + * RI and CA and cause crash here. */ + OC_STATIC_ASSERT(MAX_ADDR_STR_SIZE_CA == MAX_ADDR_STR_SIZE, + "Address size mismatch between RI and CA"); + memcpy(out->routeData, in->routeData, sizeof(in->routeData)); #endif } @@ -459,7 +502,11 @@ void CopyDevAddrToEndpoint(const OCDevAddr *in, CAEndpoint_t *out) out->flags = OCToCATransportFlags(in->flags); OICStrcpy(out->addr, sizeof(out->addr), in->addr); #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) - memcpy(out->routeData, in->routeData, sizeof(out->routeData)); + /* This assert is to prevent accidental mismatch between address size macros defined in + * RI and CA and cause crash here. */ + OC_STATIC_ASSERT(MAX_ADDR_STR_SIZE_CA == MAX_ADDR_STR_SIZE, + "Address size mismatch between RI and CA"); + memcpy(out->routeData, in->routeData, sizeof(in->routeData)); #endif out->port = in->port; out->ifindex = in->ifindex; @@ -848,7 +895,7 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr) } /** - * Encode an address string to match RFC6874. + * Encode an address string to match RFC 6874. * * @param outputAddress a char array to be written with the encoded string. * @@ -867,17 +914,7 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr) VERIFY_NON_NULL(inputAddress, FATAL, OC_STACK_INVALID_PARAM); VERIFY_NON_NULL(outputAddress, FATAL, OC_STACK_INVALID_PARAM); - /** @todo Use a max IPv6 string length instead of CA_MAX_URI_LENGTH. */ -#define ENCODE_MAX_INPUT_LENGTH CA_MAX_URI_LENGTH - - size_t inputLength = strnlen(inputAddress, ENCODE_MAX_INPUT_LENGTH); - - if (inputLength >= ENCODE_MAX_INPUT_LENGTH) - { - OIC_LOG(ERROR, TAG, - "encodeAddressForRFC6874 failed: Invalid input string: too long/unterminated!"); - return OC_STACK_INVALID_PARAM; - } + size_t inputLength = strnlen(inputAddress, outputSize); // inputSize includes the null terminator size_t inputSize = inputLength + 1; @@ -886,7 +923,7 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr) { OIC_LOG_V(ERROR, TAG, "encodeAddressForRFC6874 failed: " - "outputSize (%d) < inputSize (%d)", + "outputSize (%zu) < inputSize (%zu)", outputSize, inputSize); return OC_STACK_ERROR; @@ -927,11 +964,11 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr) // Fail if we don't have room for encoded string's two additional chars if (outputSize < (inputSize + 2)) { - OIC_LOG(ERROR, TAG, "encodeAddressForRFC6874 failed: Input string is already encoded"); + OIC_LOG(ERROR, TAG, "encodeAddressForRFC6874 failed: encoded output will not fit!"); return OC_STACK_ERROR; } - // Restore the null terminator with an escaped '%' character, per RFC6874 + // Restore the null terminator with an escaped '%' character, per RFC 6874 OICStrcpy(outputAddress, scopeIdPart - addressPart, addressPart); strcat(outputAddress, "%25"); strcat(outputAddress, scopeIdPart); @@ -944,15 +981,19 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr) * * requestUri must be a char array of size CA_MAX_URI_LENGTH */ -static int FormCanonicalPresenceUri(const CAEndpoint_t *endpoint, char *resourceUri, - char *presenceUri) +static int FormCanonicalPresenceUri(const CAEndpoint_t *endpoint, + char *presenceUri, bool isMulticast) { VERIFY_NON_NULL(endpoint , FATAL, OC_STACK_INVALID_PARAM); - VERIFY_NON_NULL(resourceUri, FATAL, OC_STACK_INVALID_PARAM); VERIFY_NON_NULL(presenceUri, FATAL, OC_STACK_INVALID_PARAM); - CAEndpoint_t *ep = (CAEndpoint_t *)endpoint; + if (isMulticast) + { + OIC_LOG(DEBUG, TAG, "Make Multicast Presence URI"); + return snprintf(presenceUri, CA_MAX_URI_LENGTH, "%s", OC_RSRVD_PRESENCE_URI); + } + CAEndpoint_t *ep = (CAEndpoint_t *)endpoint; if (ep->adapter == CA_ADAPTER_IP) { if ((ep->flags & CA_IPV6) && !(ep->flags & CA_IPV4)) @@ -1020,39 +1061,6 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint, return OC_STACK_ERROR; } - // check for unicast presence - uriLen = FormCanonicalPresenceUri(endpoint, OC_RSRVD_PRESENCE_URI, presenceUri); - if (uriLen < 0 || (size_t)uriLen >= sizeof (presenceUri)) - { - return OC_STACK_INVALID_URI; - } - - cbNode = GetClientCB(NULL, 0, NULL, presenceUri); - if (cbNode) - { - presenceSubscribe = 1; - } - else - { - // check for multiicast presence - CAEndpoint_t ep = { .adapter = endpoint->adapter, - .flags = endpoint->flags }; - - uriLen = FormCanonicalPresenceUri(&ep, OC_RSRVD_PRESENCE_URI, presenceUri); - - cbNode = GetClientCB(NULL, 0, NULL, presenceUri); - if (cbNode) - { - multicastPresenceSubscribe = 1; - } - } - - if (!presenceSubscribe && !multicastPresenceSubscribe) - { - OIC_LOG(ERROR, TAG, "Received a presence notification, but no callback, ignoring"); - goto exit; - } - response.payload = NULL; response.result = OC_STACK_OK; @@ -1082,6 +1090,36 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint, maxAge = ((OCPresencePayload*)response.payload)->maxAge; } + // check for unicast presence + uriLen = FormCanonicalPresenceUri(endpoint, presenceUri, + responseInfo->isMulticast); + if (uriLen < 0 || (size_t)uriLen >= sizeof (presenceUri)) + { + return OC_STACK_INVALID_URI; + } + OIC_LOG(ERROR, TAG, "check for unicast presence"); + cbNode = GetClientCB(NULL, 0, NULL, presenceUri); + if (cbNode) + { + presenceSubscribe = 1; + } + else + { + // check for multicast presence + OIC_LOG(ERROR, TAG, "check for multicast presence"); + cbNode = GetClientCB(NULL, 0, NULL, OC_RSRVD_PRESENCE_URI); + if (cbNode) + { + multicastPresenceSubscribe = 1; + } + } + + if (!presenceSubscribe && !multicastPresenceSubscribe) + { + OIC_LOG(ERROR, TAG, "Received a presence notification, but no callback, ignoring"); + goto exit; + } + if (presenceSubscribe) { if(cbNode->sequenceNumber == response.sequenceNumber) @@ -1132,70 +1170,31 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint, ResetPresenceTTL(cbNode, maxAge); cbNode->sequenceNumber = response.sequenceNumber; - - // Ensure that a filter is actually applied. - if( resourceTypeName && cbNode->filterResourceType) - { - if(!findResourceType(cbNode->filterResourceType, resourceTypeName)) - { - goto exit; - } - } } } else { // This is the multicast case - OCMulticastNode* mcNode = NULL; - mcNode = GetMCPresenceNode(presenceUri); - - if(mcNode != NULL) - { - if(mcNode->nonce == response.sequenceNumber) - { - OIC_LOG(INFO, TAG, "No presence change (Multicast)"); - goto exit; - } - mcNode->nonce = response.sequenceNumber; - - if(maxAge == 0) - { - OIC_LOG(INFO, TAG, "Stopping presence"); - response.result = OC_STACK_PRESENCE_STOPPED; - } - } - else + OIC_LOG(INFO, TAG, "this is the multicast presence"); + if (0 == maxAge) { - char* uri = OICStrdup(presenceUri); - if (!uri) - { - OIC_LOG(INFO, TAG, - "No Memory for URI to store in the presence node"); - result = OC_STACK_NO_MEMORY; - goto exit; - } - - result = AddMCPresenceNode(&mcNode, uri, response.sequenceNumber); - if(result == OC_STACK_NO_MEMORY) - { - OIC_LOG(INFO, TAG, - "No Memory for Multicast Presence Node"); - OICFree(uri); - goto exit; - } - // presence node now owns uri + OIC_LOG(INFO, TAG, "Stopping presence"); + response.result = OC_STACK_PRESENCE_STOPPED; } + } - // Ensure that a filter is actually applied. - if(resourceTypeName && cbNode->filterResourceType) + // Ensure that a filter is actually applied. + if (resourceTypeName && cbNode->filterResourceType) + { + OIC_LOG_V(INFO, TAG, "find resource type : %s", resourceTypeName); + if(!findResourceType(cbNode->filterResourceType, resourceTypeName)) { - if(!findResourceType(cbNode->filterResourceType, resourceTypeName)) - { - goto exit; - } + goto exit; } } + OIC_LOG(INFO, TAG, "Callback for presence"); + cbResult = cbNode->callBack(cbNode->context, cbNode->handle, &response); if (cbResult == OC_STACK_DELETE_TRANSACTION) @@ -1266,7 +1265,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp OCClientResponse response = {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}}; - response.sequenceNumber = -1; + response.sequenceNumber = MAX_SEQUENCE_NUMBER + 1; CopyEndpointToDevAddr(endPoint, &response.devAddr); FixUpClientResponse(&response); response.resourceUri = responseInfo->info.resourceUri; @@ -1314,10 +1313,10 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp #endif else if (strcmp(cbNode->requestUri, OC_RSRVD_RD_URI) == 0) { - type = PAYLOAD_TYPE_RD; + type = PAYLOAD_TYPE_REPRESENTATION ; } #ifdef TCP_ADAPTER - else if (strcmp(cbNode->requestUri, KEEPALIVE_RESOURCE_URI) == 0) + else if (strcmp(cbNode->requestUri, OC_KEEPALIVE_RESOURCE_URI) == 0) { type = PAYLOAD_TYPE_REPRESENTATION; } @@ -1336,25 +1335,26 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp cbNode->method == OC_REST_OBSERVE_ALL || cbNode->method == OC_REST_DELETE) { - char targetUri[MAX_URI_LENGTH]; - snprintf(targetUri, MAX_URI_LENGTH, "%s?rt=%s", OC_RSRVD_RD_URI, - OC_RSRVD_RESOURCE_TYPE_RDPUBLISH); - if (strcmp(targetUri, cbNode->requestUri) == 0) + if (cbNode->requestUri) { - type = PAYLOAD_TYPE_RD; + if (strcmp(OC_RSRVD_PLATFORM_URI, cbNode->requestUri) == 0) + { + type = PAYLOAD_TYPE_PLATFORM; + } + else if (strcmp(OC_RSRVD_DEVICE_URI, cbNode->requestUri) == 0) + { + type = PAYLOAD_TYPE_DEVICE; + } + if (type == PAYLOAD_TYPE_INVALID) + { + OIC_LOG_V(INFO, TAG, "Assuming PAYLOAD_TYPE_REPRESENTATION: %d %s", + cbNode->method, cbNode->requestUri); + type = PAYLOAD_TYPE_REPRESENTATION; + } } - else if (strcmp(OC_RSRVD_PLATFORM_URI, cbNode->requestUri) == 0) - { - type = PAYLOAD_TYPE_PLATFORM; - } - else if (strcmp(OC_RSRVD_DEVICE_URI, cbNode->requestUri) == 0) - { - type = PAYLOAD_TYPE_DEVICE; - } - if (type == PAYLOAD_TYPE_INVALID) + else { - OIC_LOG_V(INFO, TAG, "Assuming PAYLOAD_TYPE_REPRESENTATION: %d %s", - cbNode->method, cbNode->requestUri); + OIC_LOG(INFO, TAG, "No Request URI, PROXY URI"); type = PAYLOAD_TYPE_REPRESENTATION; } } @@ -1418,6 +1418,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp if (cbNode->method == OC_REST_OBSERVE && response.sequenceNumber > OC_OFFSET_SEQUENCE_NUMBER && + cbNode->sequenceNumber <= MAX_SEQUENCE_NUMBER && response.sequenceNumber <= cbNode->sequenceNumber) { OIC_LOG_V(INFO, TAG, "Received stale notification. Number :%d", @@ -1446,7 +1447,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp if(responseInfo->info.type == CA_MSG_CONFIRM) { SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY, - CA_MSG_ACKNOWLEDGE, 0, NULL, NULL, 0, NULL); + CA_MSG_ACKNOWLEDGE, 0, NULL, NULL, 0, NULL, CA_RESPONSE_FOR_RES); } OCPayloadDestroy(response.payload); @@ -1496,7 +1497,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp { 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_MSG_RESET, 0, NULL, NULL, 0, NULL, CA_RESPONSE_FOR_RES); } } @@ -1518,8 +1519,6 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp return; } - - OIC_LOG(INFO, TAG, "Exit OCHandleResponse"); } void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo) @@ -1596,7 +1595,6 @@ void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *er response.result = CAResultToOCStackResult(errorInfo->result); cbNode->callBack(cbNode->context, cbNode->handle, &response); - FindAndDeleteClientCB(cbNode); } OIC_LOG(INFO, TAG, "Exit HandleCAErrorResponse"); @@ -1610,7 +1608,8 @@ void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *er OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16_t coapID, const CAResponseResult_t responseResult, const CAMessageType_t type, const uint8_t numOptions, const CAHeaderOption_t *options, - CAToken_t token, uint8_t tokenLength, const char *resourceUri) + CAToken_t token, uint8_t tokenLength, const char *resourceUri, + CADataType_t dataType) { OIC_LOG(DEBUG, TAG, "Entering SendDirectStackResponse"); CAResponseInfo_t respInfo = { @@ -1634,6 +1633,7 @@ OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16 respInfo.info.type = type; respInfo.info.resourceUri = OICStrdup (resourceUri); respInfo.info.acceptFormat = CA_FORMAT_UNDEFINED; + respInfo.info.dataType = dataType; #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) // Add the destination to route option from the endpoint->routeData. @@ -1771,15 +1771,6 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque { OIC_LOG(DEBUG, TAG, "Enter OCHandleRequests"); -#ifdef TCP_ADAPTER - if (requestInfo->info.resourceUri && - strcmp(requestInfo->info.resourceUri, KEEPALIVE_RESOURCE_URI) == 0) - { - HandleKeepAliveRequest(endPoint, requestInfo); - return; - } -#endif - OCStackResult requestResult = OC_STACK_ERROR; if(myStackMode == OC_CLIENT) @@ -1869,7 +1860,8 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_BAD_REQ, requestInfo->info.type, requestInfo->info.numOptions, requestInfo->info.options, requestInfo->info.token, - requestInfo->info.tokenLength, requestInfo->info.resourceUri); + requestInfo->info.tokenLength, requestInfo->info.resourceUri, + CA_RESPONSE_DATA); OICFree(serverRequest.payload); return; } @@ -1888,7 +1880,8 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_INTERNAL_SERVER_ERROR, requestInfo->info.type, requestInfo->info.numOptions, requestInfo->info.options, requestInfo->info.token, - requestInfo->info.tokenLength, requestInfo->info.resourceUri); + requestInfo->info.tokenLength, requestInfo->info.resourceUri, + CA_RESPONSE_DATA); OICFree(serverRequest.payload); return; } @@ -1939,7 +1932,8 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_BAD_OPT, requestInfo->info.type, requestInfo->info.numOptions, requestInfo->info.options, requestInfo->info.token, - requestInfo->info.tokenLength, requestInfo->info.resourceUri); + requestInfo->info.tokenLength, requestInfo->info.resourceUri, + CA_RESPONSE_DATA); OICFree(serverRequest.payload); OICFree(serverRequest.requestToken); return; @@ -1959,9 +1953,15 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque if (requestInfo->info.type == CA_MSG_CONFIRM) { SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_EMPTY, - CA_MSG_ACKNOWLEDGE,0, NULL, NULL, 0, NULL); + CA_MSG_ACKNOWLEDGE,0, NULL, NULL, 0, NULL, + CA_RESPONSE_DATA); } } + 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(!OCResultToSuccess(requestResult)) { OIC_LOG_V(ERROR, TAG, "HandleStackRequests failed. error: %d", requestResult); @@ -1972,7 +1972,8 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque SendDirectStackResponse(endPoint, requestInfo->info.messageId, stackResponse, requestInfo->info.type, requestInfo->info.numOptions, requestInfo->info.options, requestInfo->info.token, - requestInfo->info.tokenLength, requestInfo->info.resourceUri); + requestInfo->info.tokenLength, requestInfo->info.resourceUri, + CA_RESPONSE_DATA); } // requestToken is fed to HandleStackRequests, which then goes to AddServerRequest. // The token is copied in there, and is thus still owned by this function. @@ -2174,12 +2175,19 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag defaultDeviceHandler = NULL; defaultDeviceHandlerCallbackParameter = NULL; + result = InitializeScheduleResourceList(); + VERIFY_SUCCESS(result, OC_STACK_OK); + result = CAResultToOCResult(CAInitialize()); VERIFY_SUCCESS(result, OC_STACK_OK); result = CAResultToOCResult(OCSelectNetwork()); VERIFY_SUCCESS(result, OC_STACK_OK); + result = CAResultToOCResult(CARegisterNetworkMonitorHandler( + OCDefaultAdapterStateChangedHandler, OCDefaultConnectionStateChangedHandler)); + VERIFY_SUCCESS(result, OC_STACK_OK); + switch (myStackMode) { case OC_CLIENT: @@ -2250,6 +2258,7 @@ exit: OIC_LOG(ERROR, TAG, "Stack initialization error"); deleteAllResources(); CATerminate(); + TerminateScheduleResourceList(); stackState = OC_STACK_UNINITIALIZED; } return result; @@ -2294,6 +2303,7 @@ OCStackResult OCStop() DeleteDeviceInfo(); DeletePlatformInfo(); CATerminate(); + TerminateScheduleResourceList(); // Remove all observers DeleteObserverList(); // Remove all the client callbacks @@ -2355,6 +2365,8 @@ CAMessageType_t qualityOfServiceToMessageType(OCQualityOfService qos) * 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" @@ -2409,7 +2421,8 @@ static OCStackResult ParseRequestUri(const char *fullUri, bool istcp = false; if (prefixLen) { - if ((prefixLen == sizeof(COAP_TCP) - 1) && (!strncmp(fullUri, COAP_TCP, prefixLen))) + if (((prefixLen == sizeof(COAP_TCP_SCHEME) - 1) && (!strncmp(fullUri, COAP_TCP_SCHEME, prefixLen))) + || ((prefixLen == sizeof(COAPS_TCP_SCHEME) - 1) && (!strncmp(fullUri, COAPS_TCP_SCHEME, prefixLen)))) { istcp = true; } @@ -2504,7 +2517,7 @@ static OCStackResult ParseRequestUri(const char *fullUri, da->port = port; da->adapter = adapter; da->flags = flags; - if (!strncmp(fullUri, "coaps:", 6)) + if (!strncmp(fullUri, "coaps", 5)) { da->flags = (OCTransportFlags)(da->flags|CA_SECURE); } @@ -2570,11 +2583,12 @@ error: } static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint, - char *resourceUri, char **requestUri) + char **requestUri, + bool isMulticast) { char uri[CA_MAX_URI_LENGTH]; - FormCanonicalPresenceUri(endpoint, resourceUri, uri); + FormCanonicalPresenceUri(endpoint, uri, isMulticast); *requestUri = OICStrdup(uri); if (!*requestUri) @@ -2604,7 +2618,6 @@ OCStackResult OCDoResource(OCDoHandle *handle, // Validate input parameters VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK); VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK); - VERIFY_NON_NULL(requestUri , FATAL, OC_STACK_INVALID_URI); OCStackResult result = OC_STACK_ERROR; CAResult_t caResult; @@ -2630,11 +2643,18 @@ OCStackResult OCDoResource(OCDoHandle *handle, adapter = (OCTransportAdapter)(connectivityType >> CT_ADAPTER_SHIFT); flags = (OCTransportFlags)(connectivityType & CT_MASK_FLAGS); - result = ParseRequestUri(requestUri, adapter, flags, &devAddr, &resourceUri, &resourceType); - - if (result != OC_STACK_OK) + if (requestUri) { - OIC_LOG_V(DEBUG, TAG, "Unable to parse uri: %s", requestUri); + result = ParseRequestUri(requestUri, adapter, flags, &devAddr, &resourceUri, &resourceType); + if (result != OC_STACK_OK) + { + OIC_LOG_V(DEBUG, TAG, "Unable to parse uri: %s", requestUri); + goto exit; + } + } + else if (!checkProxyUri(options, numOptions)) + { + OIC_LOG(ERROR, TAG, "Request doesn't contain RequestURI/Proxy URI"); goto exit; } @@ -2643,7 +2663,6 @@ OCStackResult OCDoResource(OCDoHandle *handle, case OC_REST_GET: case OC_REST_OBSERVE: case OC_REST_OBSERVE_ALL: - case OC_REST_CANCEL_OBSERVE: requestInfo.method = CA_GET; break; case OC_REST_PUT: @@ -2657,6 +2676,9 @@ OCStackResult OCDoResource(OCDoHandle *handle, break; case OC_REST_DISCOVER: qos = OC_LOW_QOS; +#ifdef WITH_PRESENCE + case OC_REST_PRESENCE: +#endif if (destination || devAddr) { requestInfo.isMulticast = false; @@ -2668,16 +2690,11 @@ OCStackResult OCDoResource(OCDoHandle *handle, destination = &tmpDevAddr; requestInfo.isMulticast = true; } - // CA_DISCOVER will become GET and isMulticast - requestInfo.method = CA_GET; - break; -#ifdef WITH_PRESENCE - case OC_REST_PRESENCE: - // Replacing method type with GET because "presence" - // is a stack layer only implementation. + // OC_REST_DISCOVER: CA_DISCOVER will become GET and isMulticast. + // OC_REST_PRESENCE: Since "presence" is a stack layer only implementation. + // replacing method type with GET. requestInfo.method = CA_GET; break; -#endif default: result = OC_STACK_INVALID_METHOD; goto exit; @@ -2721,7 +2738,6 @@ OCStackResult OCDoResource(OCDoHandle *handle, requestInfo.info.type = qualityOfServiceToMessageType(qos); requestInfo.info.token = token; requestInfo.info.tokenLength = tokenLength; - requestInfo.info.resourceUri = resourceUri; if ((method == OC_REST_OBSERVE) || (method == OC_REST_OBSERVE_ALL)) { @@ -2767,7 +2783,8 @@ OCStackResult OCDoResource(OCDoHandle *handle, if (method == OC_REST_PRESENCE) { char *presenceUri = NULL; - result = OCPreparePresence(&endpoint, resourceUri, &presenceUri); + result = OCPreparePresence(&endpoint, &presenceUri, + requestInfo.isMulticast); if (OC_STACK_OK != result) { goto exit; @@ -2776,10 +2793,17 @@ OCStackResult OCDoResource(OCDoHandle *handle, // Assign full presence uri as coap://ip:port/oic/ad to add to callback list. // Presence notification will form a canonical uri to // look for callbacks into the application. + if (resourceUri) + { + OICFree(resourceUri); + } resourceUri = presenceUri; } #endif + // update resourceUri onto requestInfo after check presence uri + requestInfo.info.resourceUri = resourceUri; + ttl = GetTicks(MAX_CB_TIMEOUT_SECONDS * MILLISECONDS_PER_SECOND); result = AddClientCB(&clientCB, cbData, token, tokenLength, &resHandle, method, devAddr, resourceUri, resourceType, ttl); @@ -2792,6 +2816,21 @@ OCStackResult OCDoResource(OCDoHandle *handle, resourceUri = NULL; // Client CB list entry now owns it resourceType = NULL; // Client CB list entry now owns it +#ifdef WITH_PRESENCE + if (method == OC_REST_PRESENCE) + { + if (requestInfo.isMulticast) + { + OIC_LOG(ERROR, TAG, "AddClientCB for presence done."); + goto exit; + } + else + { + OIC_LOG(ERROR, TAG, "this subscribe presence is unicast."); + } + } +#endif + // send request result = OCSendRequest(&endpoint, &requestInfo); if (OC_STACK_OK != result) @@ -3073,6 +3112,7 @@ OCStackResult OCProcess() #ifdef WITH_PRESENCE OCStackResult OCStartPresence(const uint32_t ttl) { + OIC_LOG(INFO, TAG, "Entering OCStartPresence"); uint8_t tokenLength = CA_MAX_TOKEN_LEN; OCChangeResourceProperty( &(((OCResource *)presenceResource.handle)->resourceProperties), @@ -3124,6 +3164,7 @@ OCStackResult OCStartPresence(const uint32_t ttl) OCStackResult OCStopPresence() { + OIC_LOG(INFO, TAG, "Entering OCStopPresence"); OCStackResult result = OC_STACK_ERROR; if(presenceResource.handle) @@ -3932,6 +3973,7 @@ void incrementSequenceNumber(OCResource * resPtr) OCStackResult SendPresenceNotification(OCResourceType *resourceType, OCPresenceTrigger trigger) { + OIC_LOG(INFO, TAG, "SendPresenceNotification"); OCResource *resPtr = NULL; OCStackResult result = OC_STACK_ERROR; OCMethod method = OC_REST_PRESENCE; @@ -3955,6 +3997,7 @@ OCStackResult SendPresenceNotification(OCResourceType *resourceType, OCStackResult SendStopNotification() { + OIC_LOG(INFO, TAG, "SendStopNotification"); OCResource *resPtr = NULL; OCStackResult result = OC_STACK_ERROR; OCMethod method = OC_REST_PRESENCE; @@ -4455,6 +4498,7 @@ OCResourceType *findResourceType(OCResourceType * resourceTypeList, const char * OCResourceType * rtPointer = resourceTypeList; while(resourceTypeName && rtPointer) { + OIC_LOG_V(DEBUG, TAG, "current resourceType : %s", rtPointer->resourcetypename); if(rtPointer->resourcetypename && strcmp(resourceTypeName, (const char *) (rtPointer->resourcetypename)) == 0) @@ -4694,20 +4738,20 @@ CAResult_t OCSelectNetwork() }; int numConnTypes = sizeof(connTypes)/sizeof(connTypes[0]); - for(int i = 0; iins = ins; + + return OC_STACK_OK; +} + +OCResourceHandle OCGetResourceHandleAtUri(const char *uri) +{ + if (!uri) + { + OIC_LOG(ERROR, TAG, "Resource uri is NULL"); + return NULL; + } + + OCResource *pointer = headResource; + + while (pointer) + { + if (strncmp(uri, pointer->uri, MAX_URI_LENGTH) == 0) + { + OIC_LOG_V(DEBUG, TAG, "Found Resource %s", uri); + return pointer; + } + pointer = pointer->next; + } + return NULL; +} + +OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins) +{ + OCResource *resource = NULL; + + VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM); + VERIFY_NON_NULL(ins, ERROR, OC_STACK_INVALID_PARAM); + + resource = findResource((OCResource *) handle); + if (resource) + { + *ins = resource->ins; + return OC_STACK_OK; + } + return OC_STACK_ERROR; +} + +OCStackResult OCSetHeaderOption(OCHeaderOption* ocHdrOpt, size_t* numOptions, uint16_t optionID, + void* optionData, size_t optionDataLength) +{ + if (!ocHdrOpt) + { + OIC_LOG (INFO, TAG, "Header options are NULL"); + return OC_STACK_INVALID_PARAM; + } + + if (!optionData) + { + OIC_LOG (INFO, TAG, "optionData are NULL"); + return OC_STACK_INVALID_PARAM; + } + + if (!numOptions) + { + OIC_LOG (INFO, TAG, "numOptions is NULL"); + return OC_STACK_INVALID_PARAM; + } + + if (*numOptions >= MAX_HEADER_OPTIONS) + { + OIC_LOG (INFO, TAG, "Exceeding MAX_HEADER_OPTIONS"); + return OC_STACK_NO_MEMORY; + } + + ocHdrOpt += *numOptions; + ocHdrOpt->protocolID = OC_COAP_ID; + ocHdrOpt->optionID = optionID; + ocHdrOpt->optionLength = + optionDataLength < MAX_HEADER_OPTION_DATA_LENGTH ? + optionDataLength : MAX_HEADER_OPTION_DATA_LENGTH; + memcpy(ocHdrOpt->optionData, (const void*) optionData, ocHdrOpt->optionLength); + *numOptions += 1; + + return OC_STACK_OK; +} +OCStackResult OCGetHeaderOption(OCHeaderOption* ocHdrOpt, size_t numOptions, uint16_t optionID, + void* optionData, size_t optionDataLength, uint16_t* receivedDataLength) +{ + if (!ocHdrOpt || !numOptions) + { + OIC_LOG (INFO, TAG, "No options present"); + return OC_STACK_OK; + } + + if (!optionData) + { + OIC_LOG (INFO, TAG, "optionData are NULL"); + return OC_STACK_INVALID_PARAM; + } + + if (!receivedDataLength) + { + OIC_LOG (INFO, TAG, "receivedDataLength is NULL"); + return OC_STACK_INVALID_PARAM; + } + + for (uint8_t i = 0; i < numOptions; i++) + { + if (ocHdrOpt[i].optionID == optionID) + { + if (optionDataLength >= ocHdrOpt->optionLength) + { + memcpy(optionData, ocHdrOpt->optionData, ocHdrOpt->optionLength); + *receivedDataLength = ocHdrOpt->optionLength; + return OC_STACK_OK; + } + else + { + OIC_LOG (ERROR, TAG, "optionDataLength is less than the length of received data"); + return OC_STACK_ERROR; + } + } + } + return OC_STACK_OK; +} +#endif + +void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled) +{ + OIC_LOG(DEBUG, TAG, "OCDefaultAdapterStateChangedHandler"); + if (g_adapterHandler) + { + g_adapterHandler(adapter, enabled); + } +} + +void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isConnected) +{ + OIC_LOG(DEBUG, TAG, "OCDefaultConnectionStateChangedHandler"); + if (g_connectionHandler) + { + g_connectionHandler(info, isConnected); + } +} + +void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler, + CAConnectionStateChangedCB connectionHandler) +{ + OIC_LOG(DEBUG, TAG, "OCSetNetworkMonitorHandler"); + g_adapterHandler = adapterHandler; + g_connectionHandler = connectionHandler; +} + +OCStackResult OCGetDeviceId(OCUUIdentity *deviceId) +{ + OicUuid_t oicUuid; + OCStackResult ret; + + ret = GetDoxmDeviceID(&oicUuid); + if (OC_STACK_OK == ret) + { + memcpy(deviceId, &oicUuid, UUID_IDENTITY_SIZE); + } + else + { + OIC_LOG(ERROR, TAG, "Device ID Get error"); + } + return ret; +} + +OCStackResult OCSetDeviceId(const OCUUIdentity *deviceId) +{ + OicUuid_t oicUuid; + OCStackResult ret; + OIC_LOG(ERROR, TAG, "Set deviceId DOXM"); + + memcpy(&oicUuid, deviceId, UUID_LENGTH); + for(int i=0;i < UUID_LENGTH; i++) + { + OIC_LOG_V(INFO, TAG, "Set Device Id %x", oicUuid.id[i]); + } + ret = SetDoxmDeviceID(&oicUuid); + return ret; +}