IOT-2228: Stop observe once.
authorSoemin Tjong <stjong@microsoft.com>
Wed, 10 May 2017 01:09:10 +0000 (18:09 -0700)
committerDan Mihai <Daniel.Mihai@microsoft.com>
Tue, 16 May 2017 23:41:22 +0000 (23:41 +0000)
https://jira.iotivity.org/browse/IOT-2228

Prevent raised exception in OC library.

Change-Id: I8774cac155b446a166f574a2e5c357c6a53ba1f2
Signed-off-by: Soemin Tjong <stjong@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/19761
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Dan Mihai <Daniel.Mihai@microsoft.com>
resource/IPCA/src/app.cpp
resource/IPCA/src/callback.cpp
resource/IPCA/src/inc/callback.h
resource/IPCA/unittests/IPCAElevatorClient.cpp

index cd0600e..03e723a 100644 (file)
@@ -185,6 +185,7 @@ void App::AppWorkerThread(App* app)
         // Do callbacks for expired outstanding requests.
         std::vector<CallbackInfo::Ptr> expiredCallbacks;
         app->m_callback->CompleteAndRemoveExpiredCallbackInfo(expiredCallbacks);
+        expiredCallbacks.clear();   // no use of the expired callbacks.
 
         // Get oustanding Observe requests and ping the device every PingPeriodMS.
         std::vector<CallbackInfo::Ptr> observeCallbacks;
@@ -578,6 +579,11 @@ IPCAStatus App::ObserveResource(
 
     status = device->ObserveResource(cbInfo);
 
+    if (status == IPCA_OK)
+    {
+        cbInfo->inObserve = true;
+    }
+
     if ((status != IPCA_OK) && (cbInfo != nullptr))
     {
         if (handle != nullptr)
@@ -697,9 +703,10 @@ IPCAStatus App::CloseIPCAHandle(IPCAHandle handle,
             m_discoveryList.erase(cbInfo->mapKey);
         }
         else
-        if (cbInfo->type == CallbackType_ResourceChange)
+        if ((cbInfo->type == CallbackType_ResourceChange) && cbInfo->inObserve)
         {
             cbInfo->device->StopObserve(cbInfo);
+            cbInfo->inObserve = false;
         }
     }
 
index 3d42d62..06a5ebb 100644 (file)
@@ -112,6 +112,7 @@ void Callback::CommonInitializeCallbackInfo(CallbackInfo::Ptr cbInfo)
     cbInfo->markedToBeRemoved = false;
     cbInfo->requestSentTimestamp = 0;
     cbInfo->closeHandleCompleteCallback = nullptr;
+    cbInfo->inObserve = false;
 }
 
 CallbackInfo::Ptr Callback::CreatePasswordCallbackInfo(
@@ -459,6 +460,9 @@ void Callback::CompleteAndRemoveExpiredCallbackInfo(std::vector<CallbackInfo::Pt
 {
     const int RequestTimeoutMs = 247000;    // This is EXCHANGE_LIFETIME defined in RFC7252.
 
+    // Separate list for callbacks that are already completed.
+    std::vector<CallbackInfo::Ptr> completedCallbacks;
+
     uint64_t currentTime = OICGetCurrentTime(TIME_IN_MS);
 
     {
@@ -477,8 +481,7 @@ void Callback::CompleteAndRemoveExpiredCallbackInfo(std::vector<CallbackInfo::Pt
             if ((entry.second->markedToBeRemoved == true) &&
                 (entry.second->callbackInProgressCount == 0))
             {
-                m_expiredCallbacksInProgress++;
-                cbInfoList.push_back(entry.second);
+                completedCallbacks.push_back(entry.second);
                 continue;
             }
 
@@ -500,6 +503,11 @@ void Callback::CompleteAndRemoveExpiredCallbackInfo(std::vector<CallbackInfo::Pt
         }
 
         // Remove them from the list.
+        for (auto const& entry : completedCallbacks)
+        {
+            m_callbackInfoList.erase(entry->mapKey);
+        }
+
         for (auto const& entry : cbInfoList)
         {
             m_callbackInfoList.erase(entry->mapKey);
index 904b68a..d8ec2b6 100644 (file)
@@ -85,6 +85,8 @@ struct CallbackInfo
     std::shared_ptr<OC::OCResource> ocResource; // The OCResource this callback works with.
 
     uint64_t requestSentTimestamp; // when the request was sent to the server.
+
+    bool inObserve; // set to true when observe request is sent for this callback.
 };
 
 // Represent IPCAResourceChangeCallback, IPCAGetPropertiesComplete, IPCASetPropertiesComplete.
index de40ec1..ebdf0dd 100644 (file)
@@ -280,6 +280,7 @@ void IPCAElevatorClient::StopObserve()
     if (m_observeHandle)
     {
         IPCACloseHandle(m_observeHandle, nullptr, 0);
+        m_observeHandle = nullptr;
     }
 }
 
@@ -360,6 +361,7 @@ void IPCAElevatorClient::SetUp()
     m_ipcaAppHandle = nullptr;
     m_deviceDiscoveryHandle = nullptr;
     m_deviceHandle = nullptr;
+    m_observeHandle = nullptr;
     m_newResourcePath = "";
 
     IPCAAppInfo ipcaAppInfo = { IPCATestAppUuid, IPCATestAppName, "1.0.0", "Microsoft" };
@@ -729,7 +731,7 @@ void IPCA_CALL C_ControlledRequestCompleteCallback(
     ContextForCloseHandleTest* testContext = reinterpret_cast<ContextForCloseHandleTest*>(context);
     testContext->isInCallback = true;
 
-    if (result != IPCA_OK)
+    if ((result != IPCA_OK) && (result != IPCA_RESOURCE_CREATED) && (result != IPCA_RESOURCE_DELETED))
     {
         std::cout << "C_ControlledRequestCompleteCallback(): unsuccessful. result = " << result;
         std::cout << std::endl;