X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fstack%2Fsrc%2Focobserve.c;h=9cc6557dd7dec7a7badd5aa16b4115eb4c759027;hb=c315c87e07c4080ecd0ef488e7a1047bc3c509b2;hp=636572adb109f1b49e839256fbc7e650399ec5ed;hpb=084ac4fa5ac4792acb4d5123e13bcbadab803001;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/src/ocobserve.c b/resource/csdk/stack/src/ocobserve.c index 636572a..9cc6557 100644 --- a/resource/csdk/stack/src/ocobserve.c +++ b/resource/csdk/stack/src/ocobserve.c @@ -31,9 +31,9 @@ #include "ocserverrequest.h" #include "logger.h" -#include "utlist.h" -#include "pdu.h" - +#include +#include +#include // Module Name #define MOD_NAME "ocobserve" @@ -96,6 +96,67 @@ static OCQualityOfService DetermineObserverQoS(OCMethod method, return decidedQoS; } +/** + * Create a get request and pass to entityhandler to notify specific observer. + * + * @param observer Observer that need to be notified. + * @param qos Quality of service of resource. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +static OCStackResult SendObserveNotification(ResourceObserver *observer, + OCQualityOfService qos) +{ + OCStackResult result = OC_STACK_ERROR; + OCServerRequest * request = NULL; + OCEntityHandlerRequest ehRequest = {0}; + OCEntityHandlerResult ehResult = OC_EH_ERROR; + + result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET, + 0, observer->resource->sequenceNum, qos, + observer->query, NULL, NULL, + observer->token, observer->tokenLength, + observer->resUri, 0, observer->acceptFormat, + &observer->devAddr); + + if (request) + { + request->observeResult = OC_STACK_OK; + if (result == OC_STACK_OK) + { + result = FormOCEntityHandlerRequest( + &ehRequest, + (OCRequestHandle) request->requestId, + request->method, + &request->devAddr, + (OCResourceHandle) observer->resource, + request->query, + PAYLOAD_TYPE_REPRESENTATION, + request->payload, + request->payloadSize, + request->numRcvdVendorSpecificHeaderOptions, + request->rcvdVendorSpecificHeaderOptions, + OC_OBSERVE_NO_OPTION, + 0, + request->coapID); + if (result == OC_STACK_OK) + { + ehResult = observer->resource->entityHandler(OC_REQUEST_FLAG, &ehRequest, + observer->resource->entityHandlerCallbackParam); + if (ehResult == OC_EH_ERROR) + { + FindAndDeleteServerRequest(request); + } + // Reset Observer TTL. + observer->TTL = GetTicks(MAX_OBSERVER_TTL_SECONDS * MILLISECONDS_PER_SECOND); + } + OCPayloadDestroy(ehRequest.payload); + } + } + + return result; +} + #ifdef WITH_PRESENCE OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge, OCPresenceTrigger trigger, OCResourceType *resourceType, OCQualityOfService qos) @@ -129,45 +190,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, { #endif qos = DetermineObserverQoS(method, resourceObserver, qos); - - result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET, - 0, resPtr->sequenceNum, qos, resourceObserver->query, - NULL, NULL, - resourceObserver->token, resourceObserver->tokenLength, - resourceObserver->resUri, 0, resourceObserver->acceptFormat, - &resourceObserver->devAddr); - - if (request) - { - request->observeResult = OC_STACK_OK; - if (result == OC_STACK_OK) - { - result = FormOCEntityHandlerRequest( - &ehRequest, - (OCRequestHandle) request, - request->method, - &request->devAddr, - (OCResourceHandle) resPtr, - request->query, - PAYLOAD_TYPE_REPRESENTATION, - request->payload, - request->payloadSize, - request->numRcvdVendorSpecificHeaderOptions, - request->rcvdVendorSpecificHeaderOptions, - OC_OBSERVE_NO_OPTION, - 0); - if (result == OC_STACK_OK) - { - ehResult = resPtr->entityHandler(OC_REQUEST_FLAG, &ehRequest, - resPtr->entityHandlerCallbackParam); - if (ehResult == OC_EH_ERROR) - { - FindAndDeleteServerRequest(request); - } - } - OCPayloadDestroy(ehRequest.payload); - } - } + result = SendObserveNotification(resourceObserver, qos); #ifdef WITH_PRESENCE } else @@ -199,7 +222,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, ehResponse.ehResult = OC_EH_OK; ehResponse.payload = (OCPayload*)presenceResBuf; ehResponse.persistentBufferFlag = 0; - ehResponse.requestHandle = (OCRequestHandle) request; + ehResponse.requestHandle = (OCRequestHandle) request->requestId; ehResponse.resourceHandle = (OCResourceHandle) resPtr; OICStrcpy(ehResponse.resourceUri, sizeof(ehResponse.resourceUri), resourceObserver->resUri); @@ -285,7 +308,7 @@ OCStackResult SendListObserverNotification (OCResource * resource, } memcpy(ehResponse.payload, payload, sizeof(*payload)); ehResponse.persistentBufferFlag = 0; - ehResponse.requestHandle = (OCRequestHandle) request; + ehResponse.requestHandle = (OCRequestHandle) request->requestId; ehResponse.resourceHandle = (OCResourceHandle) resource; result = OCDoResponse(&ehResponse); if (result == OC_STACK_OK) @@ -302,6 +325,9 @@ OCStackResult SendListObserverNotification (OCResource * resource, { OIC_LOG_V(INFO, TAG, "Error notifying observer id %d.", *obsIdList); } + // Reset Observer TTL. + observer->TTL = + GetTicks(MAX_OBSERVER_TTL_SECONDS * MILLISECONDS_PER_SECOND); } else { @@ -344,7 +370,10 @@ OCStackResult GenerateObserverId (OCObservationId *observationId) do { - *observationId = OCGetRandomByte(); + do + { + *observationId = OCGetRandomByte(); + } while (0 == *observationId); //Make sure *observationId is not 0 // Check if observation Id already exists resObs = GetObserverUsingId (*observationId); } while (NULL != resObs); @@ -376,7 +405,7 @@ OCStackResult AddObserver (const char *resUri, return OC_STACK_RESOURCE_ERROR; } - if (!resUri || !token || !*token) + if (!resUri || !token) { return OC_STACK_INVALID_PARAM; } @@ -409,6 +438,17 @@ OCStackResult AddObserver (const char *resUri, obsNode->devAddr = *devAddr; obsNode->resource = resHandle; +#ifdef WITH_PRESENCE + if ((strcmp(resUri, OC_RSRVD_PRESENCE_URI) == 0)) + { + obsNode->TTL = 0; + } + else +#endif + { + obsNode->TTL = GetTicks(MAX_OBSERVER_TTL_SECONDS * MILLISECONDS_PER_SECOND); + } + LL_APPEND (g_serverObsList, obsNode); return OC_STACK_OK; @@ -424,6 +464,31 @@ exit: return OC_STACK_NO_MEMORY; } +/* + * This function checks if the node is past its time to live and + * deletes it if timed-out. Calling this function with a presence callback + * with ttl set to 0 will not delete anything as presence nodes have + * their own mechanisms for timeouts. A null argument will cause the function to + * silently return. + */ +static void CheckTimedOutObserver(ResourceObserver* observer) +{ + if (!observer || observer->TTL == 0) + { + return; + } + + coap_tick_t now; + coap_ticks(&now); + + if (observer->TTL < now) + { + // Send confirmable notification message to observer. + OIC_LOG(INFO, TAG, "Sending High-QoS notification to observer"); + SendObserveNotification(observer, OC_HIGH_QOS); + } +} + ResourceObserver* GetObserverUsingId (const OCObservationId observeId) { ResourceObserver *out = NULL; @@ -436,6 +501,7 @@ ResourceObserver* GetObserverUsingId (const OCObservationId observeId) { return out; } + CheckTimedOutObserver(out); } } OIC_LOG(INFO, TAG, "Observer node not found!!"); @@ -444,21 +510,22 @@ ResourceObserver* GetObserverUsingId (const OCObservationId observeId) ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLength) { - ResourceObserver *out = NULL; - - if (token && *token) + if (token) { OIC_LOG(INFO, TAG, "Looking for token"); OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength); - OIC_LOG(INFO, TAG, "\tFound token:"); + ResourceObserver *out = NULL; LL_FOREACH (g_serverObsList, out) { - OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength); + /* de-annotate below line if want to see all token in cbList */ + //OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength); if ((memcmp(out->token, token, tokenLength) == 0)) { + OIC_LOG(INFO, TAG, "Found in observer list"); return out; } + CheckTimedOutObserver(out); } } else @@ -472,7 +539,7 @@ ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLen OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength) { - if (!token || !*token) + if (!token) { return OC_STACK_INVALID_PARAM; } @@ -492,6 +559,32 @@ OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength) return OC_STACK_OK; } +OCStackResult DeleteObserverUsingDevAddr(const OCDevAddr *devAddr) +{ + if (!devAddr) + { + return OC_STACK_INVALID_PARAM; + } + + ResourceObserver *out = NULL; + ResourceObserver *tmp = NULL; + LL_FOREACH_SAFE(g_serverObsList, out, tmp) + { + if (out) + { + if ((strcmp(out->devAddr.addr, devAddr->addr) == 0) + && out->devAddr.port == devAddr->port) + { + OIC_LOG_V(INFO, TAG, "deleting observer id %u with %s:%u", + out->observeId, out->devAddr.addr, out->devAddr.port); + OCStackFeedBack(out->token, out->tokenLength, OC_OBSERVER_NOT_INTERESTED); + } + } + } + + return OC_STACK_OK; +} + void DeleteObserverList() { ResourceObserver *out = NULL;