diff --git a/src/ringdht/sips_transport_ice.cpp b/src/ringdht/sips_transport_ice.cpp
index a571aaef4c72c07ae17c47e0a57e1f72105ec928..c30f553d788cba43e2c093a9c7292820e21be740 100644
--- a/src/ringdht/sips_transport_ice.cpp
+++ b/src/ringdht/sips_transport_ice.cpp
@@ -279,6 +279,10 @@ void
 SipsIceTransport::handleEvents()
 {
     // Notify transport manager about state changes first
+    // Note: stop when disconnected event is encountered
+    // and differ its notification AFTER pending rx msg to let
+    // them a chance to be delivered to application before closing
+    // the transport.
     decltype(stateChangeEvents_) eventDataQueue;
     {
         std::lock_guard<std::mutex> lk{stateChangeEventsMutex_};
@@ -286,11 +290,20 @@ SipsIceTransport::handleEvents()
         stateChangeEvents_.clear();
     }
 
-    if (auto state_cb = pjsip_tpmgr_get_state_cb(trData_.base.tpmgr)) {
+    ChangeStateEventData disconnectedEvent;
+    bool disconnected = false;
+    auto state_cb = pjsip_tpmgr_get_state_cb(trData_.base.tpmgr);
+    if (state_cb) {
         for (auto& evdata : eventDataQueue) {
             evdata.tls_info.ssl_sock_info = &evdata.ssl_info;
             evdata.state_info.ext_info = &evdata.tls_info;
-            (*state_cb)(&trData_.base, evdata.state, &evdata.state_info);
+            if (evdata.state != PJSIP_TP_STATE_DISCONNECTED) {
+                (*state_cb)(&trData_.base, evdata.state, &evdata.state_info);
+            } else {
+                disconnectedEvent = std::move(evdata);
+                disconnected = true;
+                break;
+            }
         }
     }
 
@@ -328,6 +341,10 @@ SipsIceTransport::handleEvents()
             }
         }
     }
+
+    // Time to deliver disconnected event if exists
+    if (disconnected and state_cb)
+        (*state_cb)(&trData_.base, disconnectedEvent.state, &disconnectedEvent.state_info);
 }
 
 void