Fix duplicate observer registrations due to slow server or network.
authorMandeep Shetty <mandeep.shetty@intel.com>
Fri, 25 Sep 2015 20:52:54 +0000 (13:52 -0700)
committerPatrick Lankswert <patrick.lankswert@intel.com>
Wed, 30 Sep 2015 18:31:33 +0000 (18:31 +0000)
This fixes IOT-720 and IOT-612.

The client retransmits a confirmable request before the 1st timeout for
un-acknowledged confirmable request. The server is occasionally too slow
to respond or the network is slow sometimes.
In case of OBSERVE registrations, a retransmit means two or more  observers will
be added for one observe request the client sent.
This leads to lot's of extra notifications being sent out and only one
of observers from the multiple clones are deleted if the client
de-registers.

Fix is to check with the token if observer was already added and ignore
the request if it was as the client was likely already ACKED for the
first request the server fully processed.

This should be cherrypicked to 1.0.0-dev.

Change-Id: I7ecfe1a6e8009606a9430515cbcedef2516507d7
Signed-off-by: Mandeep Shetty <mandeep.shetty@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/3155
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Patrick Lankswert <patrick.lankswert@intel.com>
resource/csdk/stack/src/ocresource.c

index 95265bb..afffce3 100644 (file)
@@ -788,6 +788,24 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
     {
         OC_LOG(INFO, TAG, "Observation registration requested");
 
+        ResourceObserver *obs = GetObserverUsingToken (request->requestToken,
+                                    request->tokenLength);
+
+        if (obs)
+        {
+            OC_LOG (INFO, TAG, "Observer with this token already present");
+            OC_LOG (INFO, TAG, "Possibly re-transmitted CON OBS request");
+            OC_LOG (INFO, TAG, "Not adding observer. Not responding to client");
+            OC_LOG (INFO, TAG, "The first request for this token is already ACKED.");
+
+            // server requests are usually free'd when the response is sent out
+            // for the request in ocserverrequest.c : HandleSingleResponse()
+            // Since we are making an early return and not responding, the server request
+            // needs to be deleted.
+            FindAndDeleteServerRequest (request);
+            return OC_STACK_OK;
+        }
+
         result = GenerateObserverId(&ehRequest.obsInfo.obsId);
         VERIFY_SUCCESS(result, OC_STACK_OK);