Index: pjproject/trunk/pjmedia/build/Makefile
===================================================================
--- pjproject/trunk/pjmedia/build/Makefile	(revision 636)
+++ pjproject/trunk/pjmedia/build/Makefile	(revision 637)
@@ -12,5 +12,5 @@
 #       "#define PJMEDIA_HAS_SPEEX_CODEC 0" in pj/config_site.h.
 #
-export CODEC_OBJS = $(GSM_OBJS) $(SPEEX_OBJS)
+export CODEC_OBJS = $(GSM_OBJS) $(SPEEX_OBJS) $(ILBC_OBJS)
 
 
@@ -107,9 +107,21 @@
 SPEEX_CFLAGS := -DHAVE_CONFIG_H=1 -I../src/pjmedia-codec
 
+ILBC_OBJS := 	ilbc.o \
+		ilbc/FrameClassify.o ilbc/LPCdecode.o ilbc/LPCencode.o \
+		ilbc/StateConstructW.o ilbc/StateSearchW.o ilbc/anaFilter.o \
+		ilbc/constants.o ilbc/createCB.o ilbc/doCPLC.o \
+		ilbc/enhancer.o ilbc/filter.o ilbc/gainquant.o \
+		ilbc/getCBvec.o ilbc/helpfun.o ilbc/hpInput.o \
+		ilbc/hpOutput.o ilbc/iCBConstruct.o ilbc/iCBSearch.o \
+		ilbc/iLBC_decode.o ilbc/iLBC_encode.o ilbc/lsf.o \
+		ilbc/packing.o ilbc/syntFilter.o
+ILBC_CFLAGS :=
+
 export PJMEDIA_CODEC_SRCDIR = ../src/pjmedia-codec
 export PJMEDIA_CODEC_OBJS += l16.o \
 			$(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
 			$(CODEC_OBJS)
-export PJMEDIA_CODEC_CFLAGS += $(_CFLAGS) $(GSM_CFLAGS) $(SPEEX_CFLAGS)
+export PJMEDIA_CODEC_CFLAGS += $(_CFLAGS) $(GSM_CFLAGS) $(SPEEX_CFLAGS) \
+			$(ILBC_CFLAGS)
 
 
Index: pjproject/trunk/pjmedia/build/pjmedia_codec.dsp
===================================================================
--- pjproject/trunk/pjmedia/build/pjmedia_codec.dsp	(revision 636)
+++ pjproject/trunk/pjmedia/build/pjmedia_codec.dsp	(revision 637)
@@ -101,4 +101,8 @@
 # Begin Source File
 
+SOURCE="..\src\pjmedia-codec\ilbc.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\src\pjmedia-codec\l16.c"
 
@@ -139,4 +143,8 @@
 # Begin Source File
 
+SOURCE="..\include\pjmedia-codec\ilbc.h"
+# End Source File
+# Begin Source File
+
 SOURCE="..\include\pjmedia-codec\l16.h"
 # End Source File
@@ -663,4 +671,201 @@
 # End Source File
 # End Group
+# End Group
+# Begin Group "iLBC Codec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\anaFilter.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\anaFilter.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\constants.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\constants.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\createCB.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\createCB.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\doCPLC.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\doCPLC.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\enhancer.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\enhancer.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\filter.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\filter.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\FrameClassify.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\FrameClassify.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\gainquant.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\gainquant.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\getCBvec.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\getCBvec.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\helpfun.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\helpfun.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\hpInput.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\hpInput.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\hpOutput.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\hpOutput.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iCBConstruct.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iCBConstruct.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iCBSearch.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iCBSearch.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iLBC_decode.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iLBC_decode.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iLBC_define.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iLBC_encode.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iLBC_encode.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\iLBC_test.c"
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\LPCdecode.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\LPCdecode.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\LPCencode.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\LPCencode.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\lsf.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\lsf.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\packing.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\packing.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\StateConstructW.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\StateConstructW.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\StateSearchW.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\StateSearchW.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\syntFilter.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\ilbc\syntFilter.h"
+# End Source File
 # End Group
 # End Target
Index: pjproject/trunk/pjmedia/include/pjmedia-codec.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia-codec.h	(revision 636)
+++ pjproject/trunk/pjmedia/include/pjmedia-codec.h	(revision 637)
@@ -28,4 +28,5 @@
 #include <pjmedia-codec/gsm.h>
 #include <pjmedia-codec/speex.h>
+#include <pjmedia-codec/ilbc.h>
 
 
Index: pjproject/trunk/pjmedia/include/pjmedia-codec/config.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia-codec/config.h	(revision 636)
+++ pjproject/trunk/pjmedia/include/pjmedia-codec/config.h	(revision 637)
@@ -47,4 +47,12 @@
 
 
+/**
+ * Unless specified otherwise, iLBC codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_ILBC_CODEC
+#   define PJMEDIA_HAS_ILBC_CODEC    1
+#endif
+
+
 
 #endif	/* __PJMEDIA_CODEC_CONFIG_H__ */
Index: pjproject/trunk/pjmedia/include/pjmedia-codec/types.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia-codec/types.h	(revision 636)
+++ pjproject/trunk/pjmedia/include/pjmedia-codec/types.h	(revision 637)
@@ -49,5 +49,6 @@
     PJMEDIA_RTP_PT_L16_32KHZ_STEREO,		/**< L16 @ 32KHz, stereo    */
     PJMEDIA_RTP_PT_L16_48KHZ_MONO,		/**< L16 @ 48KHz, mono	    */
-    PJMEDIA_RTP_PT_L16_48KHZ_STEREO		/**< L16 @ 48KHz, stereo    */
+    PJMEDIA_RTP_PT_L16_48KHZ_STEREO,		/**< L16 @ 48KHz, stereo    */
+    PJMEDIA_RTP_PT_ILBC				/**< iLBC (13.3/15.2Kbps)   */
 };
 
Index: pjproject/trunk/pjmedia/include/pjmedia/codec.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/codec.h	(revision 636)
+++ pjproject/trunk/pjmedia/include/pjmedia/codec.h	(revision 637)
@@ -272,9 +272,9 @@
 	unsigned    vad:1;	    /**< Voice Activity Detector.	*/
 	unsigned    cng:1;	    /**< Comfort Noise Generator.	*/
-	unsigned    lpf:1;	    /**< Low pass filter		*/
-	unsigned    hpf:1;	    /**< High pass filter		*/
 	unsigned    penh:1;	    /**< Perceptual Enhancement		*/
 	unsigned    plc:1;	    /**< Packet loss concealment	*/
 	unsigned    reserved:1;	    /**< Reserved, must be zero.	*/
+	pj_uint8_t  enc_fmtp_mode;  /**< Mode param in fmtp (def:0)	*/
+	pj_uint8_t  dec_fmtp_mode;  /**< Mode param in fmtp (def:0)	*/
     } setting;
 } pjmedia_codec_param;
Index: pjproject/trunk/pjmedia/include/pjmedia/errno.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/errno.h	(revision 636)
+++ pjproject/trunk/pjmedia/include/pjmedia/errno.h	(revision 637)
@@ -299,4 +299,14 @@
  */
 #define PJMEDIA_CODEC_EFRMINLEN	    (PJMEDIA_ERRNO_START+84)    /* 220084 */
+/**
+ * @hideinitializer
+ * Invalid PCM frame length.
+ */
+#define PJMEDIA_CODEC_EPCMFRMINLEN  (PJMEDIA_ERRNO_START+85)    /* 220085 */
+/**
+ * @hideinitializer
+ * Invalid mode.
+ */
+#define PJMEDIA_CODEC_EINMODE	    (PJMEDIA_ERRNO_START+86)    /* 220086 */
 
 
Index: pjproject/trunk/pjmedia/include/pjmedia/transport_udp.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/transport_udp.h	(revision 636)
+++ pjproject/trunk/pjmedia/include/pjmedia/transport_udp.h	(revision 637)
@@ -145,6 +145,28 @@
 
 /**
+ * Simulate packet lost in the specified direction (for testing purposes).
+ * When enabled, the transport will randomly drop packets to the specified
+ * direction.
+ *
+ * @param tp	    The UDP media transport.
+ * @param dir	    Media direction to which packets will be randomly dropped.
+ * @param pct_lost  Percent lost (0-100). Set to zero to disable packet
+ *		    lost simulation.
+ *
+ * @return	    PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_simulate_lost(pjmedia_transport *tp,
+							 pjmedia_dir dir,
+							 unsigned pct_lost);
+
+
+
+/**
  * Close UDP transport. Application can also use the "destroy" member of
  * media transport interface to close the UDP transport.
+ *
+ * @param tp	    The UDP media transport.
+ *
+ * @return	    PJ_SUCCESS on success.
  */
 PJ_DECL(pj_status_t) pjmedia_transport_udp_close(pjmedia_transport *tp);
Index: pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c	(revision 636)
+++ pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c	(revision 637)
@@ -409,6 +409,4 @@
     attr->setting.cng = 1;
     attr->setting.plc = 1;
-    attr->setting.hpf = 1;
-    attr->setting.lpf =1 ;
     attr->setting.penh =1 ;
     attr->setting.vad = 1;
Index: pjproject/trunk/pjmedia/src/pjmedia/dsound.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/dsound.c	(revision 636)
+++ pjproject/trunk/pjmedia/src/pjmedia/dsound.c	(revision 637)
@@ -45,5 +45,5 @@
 
 #define MAX_PACKET_BUFFER_COUNT	    32
-#define DEFAULT_BUFFER_COUNT	    16
+#define DEFAULT_BUFFER_COUNT	    32
 
 #define MAX_HARDWARE		    16
Index: pjproject/trunk/pjmedia/src/pjmedia/endpoint.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/endpoint.c	(revision 636)
+++ pjproject/trunk/pjmedia/src/pjmedia/endpoint.c	(revision 637)
@@ -347,5 +347,5 @@
 #endif
 
-    /* Add format and rtpmap for each codec */
+    /* Add format, rtpmap, and fmtp (when applicable) for each codec */
     for (i=0; i<endpt->codec_mgr.codec_cnt; ++i) {
 
@@ -354,4 +354,5 @@
 	char tmp_param[3];
 	pjmedia_sdp_attr *attr;
+	pjmedia_codec_param codec_param;
 	pj_str_t *fmt;
 
@@ -360,4 +361,6 @@
 
 	codec_info = &endpt->codec_mgr.codec_desc[i].info;
+	pjmedia_codec_mgr_get_default_param(&endpt->codec_mgr, codec_info,
+					    &codec_param);
 	fmt = &m->desc.fmt[m->desc.fmt_count++];
 
@@ -391,4 +394,18 @@
 	m->attr[m->attr_count++] = attr;
 
+	/* Add fmtp mode where applicable */
+	if (codec_param.setting.dec_fmtp_mode != 0) {
+	    const pj_str_t fmtp = { "fmtp", 4 };
+	    attr = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_attr));
+
+	    attr->name = fmtp;
+	    attr->value.ptr = pj_pool_alloc(pool, 32);
+	    attr->value.slen = 
+		pj_ansi_snprintf( attr->value.ptr, 32,
+				  ":%d mode=%d",
+				  codec_info->pt,
+				  codec_param.setting.dec_fmtp_mode);
+	    m->attr[m->attr_count++] = attr;
+	}
     }
 
Index: pjproject/trunk/pjmedia/src/pjmedia/errno.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/errno.c	(revision 636)
+++ pjproject/trunk/pjmedia/src/pjmedia/errno.c	(revision 637)
@@ -90,4 +90,6 @@
     PJ_BUILD_ERR( PJMEDIA_CODEC_EPCMTOOSHORT,   "PCM frame is too short" ),
     PJ_BUILD_ERR( PJMEDIA_CODEC_EFRMINLEN,      "Invalid codec frame length" ),
+    PJ_BUILD_ERR( PJMEDIA_CODEC_EPCMFRMINLEN,   "Invalid PCM frame length" ),
+    PJ_BUILD_ERR( PJMEDIA_CODEC_EINMODE,	"Invalid codec mode (no fmtp?)" ),
 
     /* Media errors. */
Index: pjproject/trunk/pjmedia/src/pjmedia/session.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/session.c	(revision 636)
+++ pjproject/trunk/pjmedia/src/pjmedia/session.c	(revision 637)
@@ -59,4 +59,53 @@
 
 /*
+ * Get fmtp mode parameter associated with the codec.
+ */
+static pj_status_t get_fmtp_mode(const pjmedia_sdp_media *m,
+				 const pj_str_t *fmt,
+				 int *p_mode)
+{
+    const pjmedia_sdp_attr *attr;
+    pjmedia_sdp_fmtp fmtp;
+    const pj_str_t str_mode = { "mode=", 5 };
+    char *pos;
+
+    /* Get "fmtp" attribute for the format */
+    attr = pjmedia_sdp_media_find_attr2(m, "fmtp", fmt);
+    if (attr == NULL)
+	return -1;
+
+    /* Parse "fmtp" attribute */
+    if (pjmedia_sdp_attr_get_fmtp(attr, &fmtp) != PJ_SUCCESS)
+	return -1;
+
+    /* Look for "mode=" string in the fmtp */
+    while (fmtp.fmt_param.slen >= str_mode.slen + 1) {
+	if (pj_strnicmp(&fmtp.fmt_param, &str_mode, str_mode.slen)==0) {
+	    /* Found "mode=" string */
+	    break;
+	}
+
+	fmtp.fmt_param.ptr++;
+	fmtp.fmt_param.slen--;
+    }
+
+    if (fmtp.fmt_param.slen < str_mode.slen + 1) {
+	/* "mode=" param not found */
+	return -1;
+    }
+
+    /* Get the mode */
+    pos = fmtp.fmt_param.ptr + str_mode.slen;
+    *p_mode = 0;
+    while (pj_isdigit(*pos)) {
+	*p_mode = *p_mode * 10 + (*pos - '0');
+	++pos;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
  * Create stream info from SDP media line.
  */
@@ -76,4 +125,5 @@
     const pjmedia_sdp_conn *rem_conn;
     pjmedia_sdp_rtpmap *rtpmap;
+    int local_fmtp_mode = 0, rem_fmtp_mode = 0;
     unsigned i, pt;
     pj_status_t status;
@@ -271,4 +321,5 @@
 
     } else {
+
 	attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP, 
 					   &local_m->desc.fmt[0]);
@@ -305,4 +356,7 @@
 	}
 
+	/* Get fmtp mode= param in local SDP, if any */
+	get_fmtp_mode(local_m, &local_m->desc.fmt[0], &local_fmtp_mode);
+
 	/* Determine payload type for outgoing channel, by finding
 	 * dynamic payload type in remote SDP that matches the answer.
@@ -331,4 +385,8 @@
 		/* Found matched codec. */
 		si->tx_pt = rpt;
+
+		/* Get fmtp mode param in remote SDP, if any */
+		get_fmtp_mode(rem_m, &rtpmap->pt, &rem_fmtp_mode);
+
 		break;
 	    }
@@ -345,4 +403,11 @@
     if (status != PJ_SUCCESS)
 	return status;
+
+    /* Set fmtp mode for both local and remote */
+    if (local_fmtp_mode != 0)
+	si->param->setting.dec_fmtp_mode = (pj_int8_t)local_fmtp_mode;
+    if (rem_fmtp_mode != 0)
+	si->param->setting.enc_fmtp_mode = (pj_int8_t)rem_fmtp_mode;
+
 
     /* Get incomming payload type for telephone-events */
Index: pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c	(revision 636)
+++ pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c	(revision 637)
@@ -22,4 +22,5 @@
 #include <pj/ioqueue.h>
 #include <pj/log.h>
+#include <pj/rand.h>
 #include <pj/string.h>
 
@@ -58,4 +59,7 @@
 			const void*,
 			pj_ssize_t);
+
+    unsigned		tx_drop_pct;	/**< Percent of tx pkts to drop.    */
+    unsigned		rx_drop_pct;	/**< Percent of rx pkts to drop.    */
 
     pj_sock_t	        rtp_sock;	/**< RTP socket			    */
@@ -372,4 +376,15 @@
 	user_data = udp->user_data;
 
+	/* Simulate packet lost on RX direction */
+	if (udp->rx_drop_pct) {
+	    if ((pj_rand() % 100) <= (int)udp->rx_drop_pct) {
+		PJ_LOG(5,(udp->base.name, 
+			  "RX RTP packet dropped because of pkt lost "
+			  "simulation"));
+		goto read_next_packet;
+	    }
+	}
+
+
 	if (udp->attached && cb)
 	    (*cb)(user_data, udp->rtp_pkt, bytes_read);
@@ -426,4 +441,5 @@
 	}
 
+read_next_packet:
 	bytes_read = sizeof(udp->rtp_pkt);
 	udp->rtp_addrlen = sizeof(pj_sockaddr_in);
@@ -582,4 +598,15 @@
     PJ_ASSERT_RETURN(size <= RTP_LEN, PJ_ETOOBIG);
 
+    /* Simulate packet lost on TX direction */
+    if (udp->tx_drop_pct) {
+	if ((pj_rand() % 100) <= (int)udp->tx_drop_pct) {
+	    PJ_LOG(5,(udp->base.name, 
+		      "TX RTP packet dropped because of pkt lost "
+		      "simulation"));
+	    return PJ_SUCCESS;
+	}
+    }
+
+
     id = udp->rtp_write_op_id;
     pw = &udp->rtp_pending_write[id];
@@ -629,2 +656,23 @@
 }
 
+
+PJ_DEF(pj_status_t) pjmedia_transport_udp_simulate_lost(pjmedia_transport *tp,
+							pjmedia_dir dir,
+							unsigned pct_lost)
+{
+    struct transport_udp *udp = (struct transport_udp*)tp;
+
+    PJ_ASSERT_RETURN(tp && 
+		     (dir==PJMEDIA_DIR_ENCODING||dir==PJMEDIA_DIR_DECODING) &&
+		     pct_lost <= 100, PJ_EINVAL);
+
+    if (dir == PJMEDIA_DIR_ENCODING)
+	udp->tx_drop_pct = pct_lost;
+    else if (dir == PJMEDIA_DIR_DECODING)
+	udp->rx_drop_pct = pct_lost;
+    else
+	return PJ_EINVAL;
+
+    return PJ_SUCCESS;
+}
+
Index: pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
===================================================================
--- pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c	(revision 636)
+++ pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c	(revision 637)
@@ -124,7 +124,11 @@
     puts  ("  --auto-loop         Automatically loop incoming RTP to outgoing RTP");
     puts  ("  --rtp-port=N        Base port to try for RTP (default=4000)");
-    puts  ("  --quality=N	  Specify media quality (0-10, default=10)");
+    puts  ("  --quality=N         Specify media quality (0-10, default=6)");
     puts  ("  --ptime=MSEC        Override codec ptime to MSEC (default=specific)");
     puts  ("  --no-vad            Disable VAD/silence detector (default=vad enabled)");
+    puts  ("  --ilbc-mode=MODE    Set iLBC codec mode (20 or 30, default is 20)");
+    puts  ("  --rx-drop-pct=PCT   Drop PCT percent of RX RTP (for pkt lost sim, default: 0)");
+    puts  ("  --tx-drop-pct=PCT   Drop PCT percent of TX RTP (for pkt lost sim, default: 0)");
+
 
     puts  ("");
@@ -256,6 +260,7 @@
 	   OPT_AUTO_ANSWER, OPT_AUTO_HANGUP, OPT_AUTO_PLAY, OPT_AUTO_LOOP,
 	   OPT_AUTO_CONF, OPT_CLOCK_RATE,
-	   OPT_PLAY_FILE, OPT_RTP_PORT, OPT_ADD_CODEC,
+	   OPT_PLAY_FILE, OPT_RTP_PORT, OPT_ADD_CODEC, OPT_ILBC_MODE,
 	   OPT_COMPLEXITY, OPT_QUALITY, OPT_PTIME, OPT_NO_VAD,
+	   OPT_RX_DROP_PCT, OPT_TX_DROP_PCT,
 	   OPT_NEXT_ACCOUNT, OPT_NEXT_CRED, OPT_MAX_CALLS, 
 	   OPT_DURATION, OPT_NO_TCP, OPT_NO_UDP,
@@ -299,4 +304,7 @@
 	{ "ptime",      1, 0, OPT_PTIME},
 	{ "no-vad",     0, 0, OPT_NO_VAD},
+	{ "ilbc-mode",	1, 0, OPT_ILBC_MODE},
+	{ "rx-drop-pct",1, 0, OPT_RX_DROP_PCT},
+	{ "tx-drop-pct",1, 0, OPT_TX_DROP_PCT},
 	{ "next-account",0,0, OPT_NEXT_ACCOUNT},
 	{ "next-cred",	0, 0, OPT_NEXT_CRED},
@@ -621,4 +629,31 @@
 		PJ_LOG(1,(THIS_FILE,
 			  "Error: invalid --quality (expecting 0-10"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_ILBC_MODE:
+	    cfg->media_cfg.ilbc_mode = my_atoi(pj_optarg);
+	    if (cfg->media_cfg.ilbc_mode!=20 && cfg->media_cfg.ilbc_mode!=30) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --ilbc-mode (expecting 20 or 30"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_RX_DROP_PCT:
+	    cfg->media_cfg.rx_drop_pct = my_atoi(pj_optarg);
+	    if (cfg->media_cfg.rx_drop_pct > 100) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --rx-drop-pct (expecting <= 100"));
+		return -1;
+	    }
+	    break;
+	    
+	case OPT_TX_DROP_PCT:
+	    cfg->media_cfg.tx_drop_pct = my_atoi(pj_optarg);
+	    if (cfg->media_cfg.tx_drop_pct > 100) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --tx-drop-pct (expecting <= 100"));
 		return -1;
 	    }
Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 636)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 637)
@@ -2088,5 +2088,5 @@
      * number.
      *
-     * Default: 5.
+     * Default: 6.
      */
     unsigned		quality;
@@ -2105,4 +2105,28 @@
      */
     pj_bool_t		no_vad;
+
+    /**
+     * iLBC mode (20 or 30).
+     *
+     * Default: 20
+     */
+    unsigned		ilbc_mode;
+
+    /**
+     * Percentage of RTP packet to drop in TX direction
+     * (to simulate packet lost).
+     *
+     * Default: 0
+     */
+    unsigned		tx_drop_pct;
+
+    /**
+     * Percentage of RTP packet to drop in RX direction
+     * (to simulate packet lost).
+     *
+     * Default: 0
+     */
+    unsigned		rx_drop_pct;
+
 };
 
@@ -2121,5 +2145,6 @@
     cfg->has_ioqueue = PJ_TRUE;
     cfg->thread_cnt = 1;
-    cfg->quality = 5;
+    cfg->quality = 6;
+    cfg->ilbc_mode = 20;
 }
 
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 636)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 637)
@@ -942,4 +942,5 @@
 
     /* Create SDP */
+    PJ_UNUSED_ARG(unhold);
     PJ_TODO(create_active_inactive_sdp_based_on_unhold_arg);
     status = pjmedia_endpt_create_sdp( pjsua_var.med_endpt, call->inv->pool, 
@@ -1854,6 +1855,6 @@
 	/* Override ptime, if this option is specified. */
 	if (pjsua_var.media_cfg.ptime != 0) {
-	    sess_info.stream_info[0].param->setting.frm_per_pkt = 
-		pjsua_var.media_cfg.ptime / sess_info.stream_info[0].param->info.frm_ptime;
+	    sess_info.stream_info[0].param->setting.frm_per_pkt = (pj_uint8_t)
+		(pjsua_var.media_cfg.ptime / sess_info.stream_info[0].param->info.frm_ptime);
 	    if (sess_info.stream_info[0].param->setting.frm_per_pkt == 0)
 		sess_info.stream_info[0].param->setting.frm_per_pkt = 1;
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 636)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 637)
@@ -1115,5 +1115,5 @@
 
     /* To be done!! */
-
+    PJ_UNUSED_ARG(force);
 
     PJ_TODO(pjsua_transport_close);
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c	(revision 636)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c	(revision 637)
@@ -86,4 +86,15 @@
 #endif /* PJMEDIA_HAS_SPEEX_CODEC */
 
+#if PJMEDIA_HAS_ILBC_CODEC
+    /* Register iLBC. */
+    status = pjmedia_codec_ilbc_init( pjsua_var.med_endpt, 
+				      pjsua_var.media_cfg.ilbc_mode);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Error initializing iLBC codec",
+		     status);
+	return status;
+    }
+#endif /* PJMEDIA_HAS_ILBC_CODEC */
+
 #if PJMEDIA_HAS_GSM_CODEC
     /* Register GSM */
@@ -485,4 +496,13 @@
 	    goto on_error;
 	}
+
+	pjmedia_transport_udp_simulate_lost(pjsua_var.calls[i].med_tp,
+					    PJMEDIA_DIR_ENCODING,
+					    pjsua_var.media_cfg.tx_drop_pct);
+
+	pjmedia_transport_udp_simulate_lost(pjsua_var.calls[i].med_tp,
+					    PJMEDIA_DIR_DECODING,
+					    pjsua_var.media_cfg.rx_drop_pct);
+
     }
 
@@ -661,5 +681,5 @@
 					    pjsua_var.mconf_cfg.samples_per_frame *
 					      1000 / pjsua_var.media_cfg.clock_rate, 
-					    0, 0, &port);
+					    options, 0, &port);
     if (status != PJ_SUCCESS) {
 	PJSUA_UNLOCK();
@@ -759,4 +779,13 @@
     pj_status_t status;
 
+    /* Don't support max_size at present */
+    PJ_ASSERT_RETURN(max_size == 0, PJ_EINVAL);
+
+    /* Don't support file format at present */
+    PJ_ASSERT_RETURN(file_format == 0, PJ_EINVAL);
+
+    /* Don't support encoding at present */
+    PJ_ASSERT_RETURN(encoding == NULL, PJ_EINVAL);
+
     if (pjsua_var.rec_cnt >= PJ_ARRAY_SIZE(pjsua_var.recorder))
 	return PJ_ETOOMANY;
@@ -783,5 +812,5 @@
 					    pjsua_var.mconf_cfg.samples_per_frame,
 					    pjsua_var.mconf_cfg.bits_per_sample, 
-					    0, 0, &port);
+					    options, 0, &port);
     if (status != PJ_SUCCESS) {
 	PJSUA_UNLOCK();
@@ -1093,7 +1122,7 @@
 					   const pjmedia_codec_param *param)
 {
+    PJ_UNUSED_ARG(id);
+    PJ_UNUSED_ARG(param);
     PJ_TODO(set_codec_param);
     return PJ_SUCCESS;
 }
-
-
