diff -ruN pjproject-2.10/pjnath/include/pjnath/ice_strans.h pjsip/pjnath/include/pjnath/ice_strans.h
--- pjproject-2.10/pjnath/include/pjnath/ice_strans.h	2020-02-14 10:48:27.000000000 +0100
+++ pjsip/pjnath/include/pjnath/ice_strans.h	2021-02-06 17:37:27.238934521 +0100
@@ -144,6 +144,52 @@
 
 } pj_ice_strans_op;
 
+
+/**
+ * ICE stream transport's state.
+ */
+typedef enum pj_ice_strans_state
+{
+    /**
+     * ICE stream transport is not created.
+     */
+    PJ_ICE_STRANS_STATE_NULL,
+
+    /**
+     * ICE candidate gathering process is in progress.
+     */
+    PJ_ICE_STRANS_STATE_INIT,
+
+    /**
+     * ICE stream transport initialization/candidate gathering process is
+     * complete, ICE session may be created on this stream transport.
+     */
+    PJ_ICE_STRANS_STATE_READY,
+
+    /**
+     * New session has been created and the session is ready.
+     */
+    PJ_ICE_STRANS_STATE_SESS_READY,
+
+    /**
+     * ICE negotiation is in progress.
+     */
+    PJ_ICE_STRANS_STATE_NEGO,
+
+    /**
+     * ICE negotiation has completed successfully and media is ready
+     * to be used.
+     */
+    PJ_ICE_STRANS_STATE_RUNNING,
+
+    /**
+     * ICE negotiation has completed with failure.
+     */
+    PJ_ICE_STRANS_STATE_FAILED
+
+} pj_ice_strans_state;
+
+
 /** 
  * This structure contains callbacks that will be called by the 
  * ICE stream transport.
@@ -192,6 +238,18 @@
 			       pj_ice_strans_op op,
 			       pj_status_t status);
 
+    /**
+     * Callback to report ICE state changes.
+     *
+     * @param ice_st       The ICE stream transport.
+     * @param prev         Previous state.
+     * @param curr         Current state.
+     */
+    void    (*on_ice_state)(pj_ice_strans *ice_st,
+                           pj_ice_strans_state prev,
+                           pj_ice_strans_state curr);
+
+
 } pj_ice_strans_cb;
 
 
@@ -522,51 +580,6 @@
 } pj_ice_strans_cfg;
 
 
-/**
- * ICE stream transport's state.
- */
-typedef enum pj_ice_strans_state
-{
-    /**
-     * ICE stream transport is not created.
-     */
-    PJ_ICE_STRANS_STATE_NULL,
-
-    /**
-     * ICE candidate gathering process is in progress.
-     */
-    PJ_ICE_STRANS_STATE_INIT,
-
-    /**
-     * ICE stream transport initialization/candidate gathering process is
-     * complete, ICE session may be created on this stream transport.
-     */
-    PJ_ICE_STRANS_STATE_READY,
-
-    /**
-     * New session has been created and the session is ready.
-     */
-    PJ_ICE_STRANS_STATE_SESS_READY,
-
-    /**
-     * ICE negotiation is in progress.
-     */
-    PJ_ICE_STRANS_STATE_NEGO,
-
-    /**
-     * ICE negotiation has completed successfully and media is ready
-     * to be used.
-     */
-    PJ_ICE_STRANS_STATE_RUNNING,
-
-    /**
-     * ICE negotiation has completed with failure.
-     */
-    PJ_ICE_STRANS_STATE_FAILED
-
-} pj_ice_strans_state;
-
-
 /** 
  * Initialize ICE transport configuration with default values.
  *
@@ -921,6 +934,27 @@
 			     unsigned comp_id);
 
 /**
+ * Retrieve the ICE session associated with this transport
+ *
+ * @param ice_st       The ICE stream transport.
+ *
+ * @return             The ICE session associated with this transport
+ */
+PJ_DECL(pj_ice_sess*)
+pj_ice_strans_get_session(const pj_ice_strans *ice_st);
+
+/**
+ * Retrieve the ICE start time
+ *
+ * @param ice_st       The ICE stream transport.
+ *
+ * @return             The ICE start time
+ */
+PJ_DECL(pj_time_val)
+pj_ice_strans_get_start_time(const pj_ice_strans *ice_st);
+
+
+/**
  * Stop and destroy the ICE session inside this media transport. Application
  * needs to call this function once the media session is over (the call has
  * been disconnected).
diff -ruN pjproject-2.10/pjnath/src/pjnath/ice_strans.c pjsip/pjnath/src/pjnath/ice_strans.c
--- pjproject-2.10/pjnath/src/pjnath/ice_strans.c	2020-02-14 10:48:27.000000000 +0100
+++ pjsip/pjnath/src/pjnath/ice_strans.c	2021-02-06 17:27:03.341194358 +0100
@@ -240,6 +240,19 @@
 } sock_user_data;
 
 
+/* Set ICE state*/
+static void set_ice_state(pj_ice_strans *ice_st, pj_ice_strans_state state)
+{
+    pj_ice_strans_state prev = ice_st->state;
+
+    if (prev != state) {
+        ice_st->state = state;
+        if (ice_st->cb.on_ice_state)
+            (*ice_st->cb.on_ice_state)(ice_st, prev, state);
+    }
+}
+
+
 /* Validate configuration */
 static pj_status_t pj_ice_strans_cfg_check_valid(const pj_ice_strans_cfg *cfg)
 {
@@ -928,7 +941,7 @@
 		   pj_pool_calloc(pool, comp_cnt, sizeof(pj_ice_strans_comp*));
 
     /* Move state to candidate gathering */
-    ice_st->state = PJ_ICE_STRANS_STATE_INIT;
+    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_INIT);
 
     /* Acquire initialization mutex to prevent callback to be
      * called before we finish initialization.
@@ -1123,7 +1136,7 @@
      * candidate for a component.
      */
     ice_st->cb_called = PJ_TRUE;
-    ice_st->state = PJ_ICE_STRANS_STATE_READY;
+    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_READY);
     if (ice_st->cb.on_ice_complete)
 	(*ice_st->cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_INIT,
 				      status);
@@ -1289,7 +1302,7 @@
     }
 
     /* ICE session is ready for negotiation */
-    ice_st->state = PJ_ICE_STRANS_STATE_SESS_READY;
+    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_SESS_READY);
 
     return PJ_SUCCESS;
 
@@ -1518,7 +1531,7 @@
 	return status;
     }
 
-    ice_st->state = PJ_ICE_STRANS_STATE_NEGO;
+    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_NEGO);
     return status;
 }
 
@@ -1539,6 +1552,25 @@
 }
 
 /*
+ * Get ICE session.
+ */
+PJ_DEF(pj_ice_sess*)
+pj_ice_strans_get_session(const pj_ice_strans *ice_st)
+{
+    return ice_st->ice;
+}
+
+/*
+ * Get ICE start time.
+ */
+PJ_DEF(pj_time_val)
+pj_ice_strans_get_start_time(const pj_ice_strans *ice_st)
+{
+
+    return ice_st->start_time;
+}
+
+/*
  * Stop ICE!
  */
 PJ_DEF(pj_status_t) pj_ice_strans_stop_ice(pj_ice_strans *ice_st)
@@ -1556,7 +1588,7 @@
 	ice_st->ice = NULL;
     }
 
-    ice_st->state = PJ_ICE_STRANS_STATE_INIT;
+    set_ice_state(ice_st, PJ_ICE_STRANS_STATE_INIT);
 
     pj_grp_lock_release(ice_st->grp_lock);
 
@@ -1877,8 +1909,8 @@
 	    }
 	}
 
-	ice_st->state = (status==PJ_SUCCESS) ? PJ_ICE_STRANS_STATE_RUNNING :
-					       PJ_ICE_STRANS_STATE_FAILED;
+	set_ice_state(ice_st, (status==PJ_SUCCESS) ? PJ_ICE_STRANS_STATE_RUNNING :
+                                                     PJ_ICE_STRANS_STATE_FAILED);
 
 	pj_log_push_indent();
 	(*cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_NEGOTIATION, status);
