Index: pjproject/branches/projects/sipit24/pjnath/include/pjnath/config.h
===================================================================
--- pjproject/branches/projects/sipit24/pjnath/include/pjnath/config.h	(revision 2716)
+++ pjproject/branches/projects/sipit24/pjnath/include/pjnath/config.h	(revision 2717)
@@ -370,20 +370,24 @@
 /**
  * Minimum interval value to be used for sending STUN keep-alive on the ICE
- * stream transport, in seconds. This minimum interval, plus a random value
- * which maximum is PJ_ICE_ST_KEEP_ALIVE_MAX_RAND, specify the actual interval
+ * session, in seconds. This minimum interval, plus a random value
+ * which maximum is PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND, specify the actual interval
  * of the STUN keep-alive.
  *
- * Default: 20 seconds
- *
- * @see PJ_ICE_ST_KEEP_ALIVE_MAX_RAND
- */
-#ifndef PJ_ICE_ST_KEEP_ALIVE_MIN
-#   define PJ_ICE_ST_KEEP_ALIVE_MIN		    20
-#endif
-
+ * Default: 15 seconds
+ *
+ * @see PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND
+ */
+#ifndef PJ_ICE_SESS_KEEP_ALIVE_MIN
+#   define PJ_ICE_SESS_KEEP_ALIVE_MIN		    20
+#endif
+
+/* Warn about deprecated macro */
+#ifdef PJ_ICE_ST_KEEP_ALIVE_MIN
+#   error PJ_ICE_ST_KEEP_ALIVE_MIN is deprecated
+#endif
 
 /**
  * To prevent STUN keep-alives to be sent simultaneously, application should
- * add random interval to minimum interval (PJ_ICE_ST_KEEP_ALIVE_MIN). This
+ * add random interval to minimum interval (PJ_ICE_SESS_KEEP_ALIVE_MIN). This
  * setting specifies the maximum random value to be added to the minimum
  * interval, in seconds.
@@ -391,8 +395,13 @@
  * Default: 5 seconds
  *
- * @see PJ_ICE_ST_KEEP_ALIVE_MIN
- */
-#ifndef PJ_ICE_ST_KEEP_ALIVE_MAX_RAND
-#   define PJ_ICE_ST_KEEP_ALIVE_MAX_RAND	    5
+ * @see PJ_ICE_SESS_KEEP_ALIVE_MIN
+ */
+#ifndef PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND
+#   define PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND	    5
+#endif
+
+/* Warn about deprecated macro */
+#ifdef PJ_ICE_ST_KEEP_ALIVE_MAX_RAND
+#   error PJ_ICE_ST_KEEP_ALIVE_MAX_RAND is deprecated
 #endif
 
Index: pjproject/branches/projects/sipit24/pjnath/include/pjnath/ice_session.h
===================================================================
--- pjproject/branches/projects/sipit24/pjnath/include/pjnath/ice_session.h	(revision 2716)
+++ pjproject/branches/projects/sipit24/pjnath/include/pjnath/ice_session.h	(revision 2717)
@@ -637,4 +637,5 @@
     unsigned		 comp_cnt;		    /**< # of components.   */
     pj_ice_sess_comp	 comp[PJ_ICE_MAX_COMP];	    /**< Component array    */
+    unsigned		 comp_ka;		    /**< Next comp for KA   */
 
     /* Local candidates */
Index: pjproject/branches/projects/sipit24/pjnath/include/pjnath/stun_msg.h
===================================================================
--- pjproject/branches/projects/sipit24/pjnath/include/pjnath/stun_msg.h	(revision 2716)
+++ pjproject/branches/projects/sipit24/pjnath/include/pjnath/stun_msg.h	(revision 2717)
@@ -198,4 +198,8 @@
     PJ_STUN_BINDING_ERROR_RESPONSE	    = 0x0111,
 
+    /**
+     * Binding Indication (ICE)
+     */
+    PJ_STUN_BINDING_INDICATION		    = 0x0011,
 
     /**
Index: pjproject/branches/projects/sipit24/pjnath/include/pjnath/stun_session.h
===================================================================
--- pjproject/branches/projects/sipit24/pjnath/include/pjnath/stun_session.h	(revision 2716)
+++ pjproject/branches/projects/sipit24/pjnath/include/pjnath/stun_session.h	(revision 2717)
@@ -486,4 +486,16 @@
 PJ_DECL(void) pj_stun_session_set_log(pj_stun_session *sess,
 				      unsigned flags);
+/**
+ * Configure whether the STUN session should utilize FINGERPRINT in
+ * outgoing messages.
+ *
+ * @param sess	    The STUN session instance.
+ * @param use	    Boolean for the setting.
+ *
+ * @return	    The previous configured value of FINGERPRINT
+ *		    utilization of the sessoin.
+ */
+PJ_DECL(pj_bool_t) pj_stun_session_use_fingerprint(pj_stun_session *sess,
+						   pj_bool_t use);
 
 /**
Index: pjproject/branches/projects/sipit24/pjnath/src/pjnath/ice_session.c
===================================================================
--- pjproject/branches/projects/sipit24/pjnath/src/pjnath/ice_session.c	(revision 2716)
+++ pjproject/branches/projects/sipit24/pjnath/src/pjnath/ice_session.c	(revision 2717)
@@ -76,5 +76,5 @@
     TIMER_START_NOMINATED_CHECK,/**< Controlling agent start connectivity
 				     checks with USE-CANDIDATE flag.	*/
-					
+    TIMER_KEEP_ALIVE		/**< ICE keep-alive timer.		*/
 
 };
@@ -134,4 +134,5 @@
 static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te);
 static void on_ice_complete(pj_ice_sess *ice, pj_status_t status);
+static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now);
 static void destroy_ice(pj_ice_sess *ice,
 			pj_status_t reason);
@@ -1112,4 +1113,12 @@
 	break;
     case TIMER_COMPLETION_CALLBACK:
+	/* Start keep-alive timer but don't send any packets yet.
+	 * Need to do it here just in case app destroy the session
+	 * in the callback.
+	 */
+	if (ice->ice_status == PJ_SUCCESS)
+	    ice_keep_alive(ice, PJ_FALSE);
+
+	/* Notify app about ICE completion*/
 	if (ice->cb.on_ice_complete)
 	    (*ice->cb.on_ice_complete)(ice, ice->ice_status);
@@ -1118,4 +1127,70 @@
 	start_nominated_check(ice);
 	break;
+    case TIMER_KEEP_ALIVE:
+	ice_keep_alive(ice, PJ_TRUE);
+	break;
+    }
+}
+
+/* Send keep-alive */
+static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now)
+{
+    if (send_now) {
+	/* Send Binding Indication for the component */
+	pj_ice_sess_comp *comp = &ice->comp[ice->comp_ka];
+	pj_stun_tx_data *tdata;
+	pj_ice_sess_check *the_check;
+	pj_ice_msg_data *msg_data;
+	int addr_len;
+	pj_bool_t saved;
+	pj_status_t status;
+
+	/* Must have nominated check by now */
+	pj_assert(comp->nominated_check != NULL);
+	the_check = comp->nominated_check;
+
+	/* Create the Binding Indication */
+	status = pj_stun_session_create_ind(comp->stun_sess, 
+					    PJ_STUN_BINDING_INDICATION,
+					    &tdata);
+	if (status != PJ_SUCCESS)
+	    goto done;
+
+	/* Need the transport_id */
+	msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data);
+	msg_data->transport_id = the_check->lcand->transport_id;
+
+	/* Temporarily disable FINGERPRINT. The Binding Indication 
+	 * SHOULD NOT contain any attributes.
+	 */
+	saved = pj_stun_session_use_fingerprint(comp->stun_sess, PJ_FALSE);
+
+	/* Send to session */
+	addr_len = pj_sockaddr_get_len(&the_check->rcand->addr);
+	status = pj_stun_session_send_msg(comp->stun_sess, msg_data,
+					  PJ_FALSE, PJ_FALSE, 
+					  &the_check->rcand->addr, 
+					  addr_len, tdata);
+
+	/* Restore FINGERPRINT usage */
+	pj_stun_session_use_fingerprint(comp->stun_sess, saved);
+
+done:
+	ice->comp_ka = (ice->comp_ka + 1) % ice->comp_cnt;
+    }
+
+    if (ice->timer.id == TIMER_NONE) {
+	pj_time_val delay = { 0, 0 };
+
+	delay.msec = (PJ_ICE_SESS_KEEP_ALIVE_MIN + 
+		      (pj_rand() % PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND)) * 1000 / 
+		     ice->comp_cnt;
+	pj_time_val_normalize(&delay);
+
+	ice->timer.id = TIMER_KEEP_ALIVE;
+	pj_timer_heap_schedule(ice->stun_cfg.timer_heap, &ice->timer, &delay);
+
+    } else {
+	pj_assert(!"Not expected any timer active");
     }
 }
@@ -2614,4 +2689,6 @@
 					 unsigned src_addr_len)
 {
+    struct stun_data *sd;
+
     PJ_UNUSED_ARG(sess);
     PJ_UNUSED_ARG(pkt);
@@ -2622,7 +2699,16 @@
     PJ_UNUSED_ARG(src_addr_len);
 
-    PJ_TODO(SUPPORT_RX_BIND_REQUEST_AS_INDICATION);
-
-    return PJ_ENOTSUP;
+    sd = (struct stun_data*) pj_stun_session_get_user_data(sess);
+
+    if (msg->hdr.type == PJ_STUN_BINDING_INDICATION) {
+	LOG5((sd->ice->obj_name, "Received Binding Indication keep-alive "
+	      "for component %d", sd->comp_id));
+    } else {
+	LOG4((sd->ice->obj_name, "Received unexpected %s indication "
+	      "for component %d", pj_stun_get_method_name(msg->hdr.type), 
+	      sd->comp_id));
+    }
+
+    return PJ_SUCCESS;
 }
 
Index: pjproject/branches/projects/sipit24/pjnath/src/pjnath/stun_session.c
===================================================================
--- pjproject/branches/projects/sipit24/pjnath/src/pjnath/stun_session.c	(revision 2716)
+++ pjproject/branches/projects/sipit24/pjnath/src/pjnath/stun_session.c	(revision 2717)
@@ -636,4 +636,16 @@
 }
 
+PJ_DEF(pj_bool_t) pj_stun_session_use_fingerprint(pj_stun_session *sess,
+						  pj_bool_t use)
+{
+    pj_bool_t old_use;
+
+    PJ_ASSERT_RETURN(sess, PJ_FALSE);
+
+    old_use = sess->use_fingerprint;
+    sess->use_fingerprint = use;
+    return old_use;
+}
+
 static pj_status_t get_auth(pj_stun_session *sess,
 			    pj_stun_tx_data *tdata)
