Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 397)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 398)
@@ -93,4 +93,8 @@
     unsigned		 index;	    /**< Index in pjsua array.		    */
     pjsip_inv_session	*inv;	    /**< The invite session.		    */
+    pj_time_val		 start_time;/**< First INVITE sent/received.	    */
+    pj_time_val		 res_time;  /**< First response sent/received.	    */
+    pj_time_val		 conn_time; /**< Connected/confirmed time.	    */
+    pj_time_val		 dis_time;  /**< Disconnect time.		    */
     int			 acc_index; /**< Account index being used.	    */
     pjmedia_session	*session;   /**< The media session.		    */
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 397)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 398)
@@ -193,6 +193,11 @@
     }
 
+    /* Mark call start time. */
+    pj_gettimeofday(&pjsua.calls[call_index].start_time);
+
+    /* Reset first response time */
+    pjsua.calls[call_index].res_time.sec = 0;
+
     /* Create outgoing dialog: */
-
     status = pjsip_dlg_create_uac( pjsip_ua_instance(), 
 				   &pjsua.acc[acc_index].local_uri,
@@ -359,4 +364,9 @@
     }
 
+    /* Mark call start time. */
+    pj_gettimeofday(&pjsua.calls[call_index].start_time);
+
+    /* Reset first response time */
+    pjsua.calls[call_index].res_time.sec = 0;
 
     /* Get media capability from media endpoint: */
@@ -498,8 +508,26 @@
     pjsua_call *call = inv->dlg->mod_data[pjsua.mod.id];
 
+    if (!call)
+	return;
+
+    /* Get call times */
+    switch (inv->state) {
+	case PJSIP_INV_STATE_EARLY:
+	case PJSIP_INV_STATE_CONNECTING:
+	    if (call->res_time.sec == 0)
+		pj_gettimeofday(&call->res_time);
+	    break;
+	case PJSIP_INV_STATE_CONFIRMED:
+	    pj_gettimeofday(&call->conn_time);
+	    break;
+	case PJSIP_INV_STATE_DISCONNECTED:
+	    pj_gettimeofday(&call->dis_time);
+	    break;
+    }
+
     /* If this is an outgoing INVITE that was created because of
      * REFER/transfer, send NOTIFY to transferer.
      */
-    if (call && call->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE)  {
+    if (call->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE)  {
 	int st_code = -1;
 	pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE;
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c	(revision 397)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c	(revision 398)
@@ -694,5 +694,5 @@
 	PJ_LOG(3,(THIS_FILE, 
 	       "                  RX pt=%d, stat last update: %s\n"
-	       "                     total %s packets %sB received (%sB +IP hdr)%s\n"
+	       "                     total %spkt %sB (%sB +IP hdr)%s\n"
 	       "                     pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
 	       "                           (msec)    min     avg     max     last\n"
@@ -739,5 +739,5 @@
 	PJ_LOG(3,(THIS_FILE,
 	       "                  TX pt=%d, stat last update: %s\n"
-	       "                     total %s packets %sB received (%sB +IP hdr)%s\n"
+	       "                     total %spkt %sB (%sB +IP hdr)%s\n"
 	       "                     pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
 	       "                           (msec)    min     avg     max     last\n"
@@ -816,5 +816,8 @@
 	for (i=0; i<pjsua.max_calls; ++i) {
 
-	    if (pjsua.calls[i].inv == NULL)
+	    pjsua_call *call = &pjsua.calls[i];
+	    pj_time_val duration, res_delay, con_delay;
+
+	    if (call->inv == NULL)
 		continue;
 
@@ -822,6 +825,36 @@
 	    PJ_LOG(3,(THIS_FILE, "%s", buf));
 
-	    if (pjsua.calls[i].session)
-		dump_media_session(pjsua.calls[i].session);
+	    /* Calculate call duration */
+	    if (call->inv->state >= PJSIP_INV_STATE_CONFIRMED) {
+		pj_gettimeofday(&duration);
+		PJ_TIME_VAL_SUB(duration, call->conn_time);
+		con_delay = call->conn_time;
+		PJ_TIME_VAL_SUB(con_delay, call->start_time);
+	    } else {
+		duration.sec = duration.msec = 0;
+		con_delay.sec = con_delay.msec = 0;
+	    }
+
+	    /* Calculate first response delay */
+	    if (call->inv->state >= PJSIP_INV_STATE_EARLY) {
+		res_delay = call->res_time;
+		PJ_TIME_VAL_SUB(res_delay, call->start_time);
+	    } else {
+		res_delay.sec = res_delay.msec = 0;
+	    }
+
+	    /* Print duration */
+	    PJ_LOG(3,(THIS_FILE, 
+		      "               Call time: %02dh:%02dm:%02ds, "
+		      "1st res in %d ms, conn in %dms",
+		      (duration.sec / 3600),
+		      ((duration.sec % 3600)/60),
+		      (duration.sec % 60),
+		      PJ_TIME_VAL_MSEC(res_delay), 
+		      PJ_TIME_VAL_MSEC(con_delay)));
+
+	    /* Dump session statistics */
+	    if (call->session)
+		dump_media_session(call->session);
 	}
     }
