Index: pjproject/trunk/pjsip/include/pjsip/sip_transport.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 5096)
+++ pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 5097)
@@ -1514,4 +1514,65 @@
 
 /**
+ * Structure of dropped received data.
+ */
+typedef struct pjsip_tp_dropped_data
+{
+    /**
+     * The transport receiving the data.
+     */
+    pjsip_transport *tp;
+
+    /**
+     * The data.
+     */
+    void	    *data;
+
+    /**
+     * The data length.
+     * If the status field below indicates an invalid SIP message
+     * (PJSIP_EINVALIDMSG) and application detects a SIP message
+     * at position p, it can pass the data back to PJSIP to be processed
+     * by setting the len to p. This can be useful for apps which
+     * wishes to use the same transport for SIP signalling and non-SIP
+     * purposes (such as SIP outbound using STUN message).
+     */
+    pj_size_t	     len;
+
+    /**
+     * The status or reason of drop. For example, a leading newlines (common
+     * keep-alive packet) will be dropped with status PJ_EIGNORED, an invalid
+     * SIP message will have status PJSIP_EINVALIDMSG, a SIP message overflow
+     * will have status PJSIP_ERXOVERFLOW.
+     */
+    pj_status_t	     status;
+
+} pjsip_tp_dropped_data;
+
+
+/**
+ * Type of callback to data dropping notifications.
+ *
+ * @param data		The dropped data.
+ */
+typedef void (*pjsip_tp_on_rx_dropped_cb)(pjsip_tp_dropped_data *data);
+
+
+/**
+ * Set callback of data dropping. The caller will be notified whenever any
+ * received data is dropped (due to leading newlines or keep-alive packet or
+ * invalid SIP message). This callback can be useful for application,
+ * for example, to implement custom keep-alive mechanism or connection
+ * availability detection.
+ *
+ * @param mgr	    Transport manager.
+ * @param cb	    The callback function, set to NULL to reset the callback.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tpmgr_set_drop_data_cb(pjsip_tpmgr *mgr,
+						  pjsip_tp_on_rx_dropped_cb cb);
+
+
+/**
  * @}
  */
Index: pjproject/trunk/pjsip/src/pjsip/sip_transport.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 5096)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 5097)
@@ -100,4 +100,5 @@
     pj_status_t	   (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*);
     pjsip_tp_state_callback tp_state_cb;
+    pjsip_tp_on_rx_dropped_cb tp_drop_data_cb;
 
     /* Transmit data list, for transmit data cleanup when transport manager
@@ -1694,4 +1695,16 @@
 	    remaining_len -= (p - current_pkt);
 	    total_processed += (p - current_pkt);
+
+	    /* Notify application about the dropped newlines */
+	    if (mgr->tp_drop_data_cb) {
+		pjsip_tp_dropped_data dd;
+		pj_bzero(&dd, sizeof(dd));
+		dd.tp = tr;
+		dd.data = current_pkt;
+		dd.len = p - current_pkt;
+		dd.status = PJ_EIGNORED;
+		(*mgr->tp_drop_data_cb)(&dd);
+	    }
+
 	    current_pkt = p;
 	    if (remaining_len == 0) {
@@ -1720,4 +1733,16 @@
 		if (remaining_len == PJSIP_MAX_PKT_LEN) {
 		    mgr->on_rx_msg(mgr->endpt, PJSIP_ERXOVERFLOW, rdata);
+		    
+		    /* Notify application about the message overflow */
+	    	    if (mgr->tp_drop_data_cb) {
+			pjsip_tp_dropped_data dd;
+			pj_bzero(&dd, sizeof(dd));
+			dd.tp = tr;
+			dd.data = current_pkt;
+			dd.len = msg_fragment_size;
+			dd.status = PJSIP_ERXOVERFLOW;
+			(*mgr->tp_drop_data_cb)(&dd);
+	    	    }
+		    
 		    /* Exhaust all data. */
 		    return rdata->pkt_info.len;
@@ -1784,4 +1809,18 @@
 	    }
 
+	    /* Notify application about the dropped data (syntax error) */
+	    if (tmp.slen && mgr->tp_drop_data_cb) {
+		pjsip_tp_dropped_data dd;
+		pj_bzero(&dd, sizeof(dd));
+		dd.tp = tr;
+		dd.data = current_pkt;
+		dd.len = msg_fragment_size;
+		dd.status = PJSIP_EINVALIDMSG;
+		(*mgr->tp_drop_data_cb)(&dd);
+		
+		if (dd.len > 0 && dd.len < msg_fragment_size)
+		    msg_fragment_size = dd.len;
+	    }
+
 	    goto finish_process_fragment;
 	}
@@ -2266,2 +2305,15 @@
     return PJ_SUCCESS;
 }
+
+/*
+ * Set callback of data dropping.
+ */
+PJ_DEF(pj_status_t) pjsip_tpmgr_set_drop_data_cb(pjsip_tpmgr *mgr,
+						 pjsip_tp_on_rx_dropped_cb cb)
+{
+    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+    mgr->tp_drop_data_cb = cb;
+
+    return PJ_SUCCESS;
+}
