IOT-1877 : start presence issue
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocstack.c
index c41f0e8..277cd6e 100644 (file)
@@ -544,11 +544,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 +557,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)
             {
                 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);
+            }
         }
 
-        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,8 +583,8 @@ 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;
@@ -595,12 +599,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 +613,19 @@ 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)
                 {
                     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");
                 }
@@ -1313,7 +1321,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;
                     }
@@ -1378,7 +1386,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;
@@ -1408,8 +1417,11 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
 
                 for (uint8_t i = start; i < responseInfo->info.numOptions; i++)
                 {
-                    memcpy (&(response.rcvdVendorSpecificHeaderOptions[i-start]),
-                            &(responseInfo->info.options[i]), sizeof(OCHeaderOption));
+                    if(&(responseInfo->info.options[i]))
+                    {
+                        memcpy (&(response.rcvdVendorSpecificHeaderOptions[i-start]),
+                                &(responseInfo->info.options[i]), sizeof(OCHeaderOption));
+                    }
                 }
             }
 
@@ -1953,7 +1965,7 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque
         return;
     }
     serverRequest.numRcvdVendorSpecificHeaderOptions = tempNum;
-    if (serverRequest.numRcvdVendorSpecificHeaderOptions)
+    if (serverRequest.numRcvdVendorSpecificHeaderOptions && requestInfo->info.options)
     {
         memcpy (&(serverRequest.rcvdVendorSpecificHeaderOptions), requestInfo->info.options,
             sizeof(CAHeaderOption_t)*tempNum);
@@ -2234,9 +2246,9 @@ exit:
     if(result != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "Stack initialization error");
+        TerminateScheduleResourceList();
         deleteAllResources();
         CATerminate();
-        TerminateScheduleResourceList();
         stackState = OC_STACK_UNINITIALIZED;
     }
     return result;
@@ -2259,10 +2271,14 @@ OCStackResult OCStop()
 
     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
@@ -2276,20 +2292,20 @@ OCStackResult OCStop()
     TerminateKeepAlive(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();
 
-
     stackState = OC_STACK_UNINITIALIZED;
     return OC_STACK_OK;
 }
@@ -4030,7 +4046,7 @@ 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.
@@ -5038,6 +5054,21 @@ void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isCon
     {
        g_connectionHandler(info, isConnected);
     }
+
+    /*
+     * 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);
+    }
 }
 
 void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler,