diff --git a/Freeswitch.2008.sln b/Freeswitch.2008.sln
index 4ffd66abac..d60de29e54 100644
--- a/Freeswitch.2008.sln
+++ b/Freeswitch.2008.sln
@@ -371,6 +371,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Li
 	ProjectSection(ProjectDependencies) = postProject
 		{8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9}
 		{89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
+		{1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}
 		{F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
 		{03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD}
 		{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
diff --git a/Makefile.am b/Makefile.am
index e701494a2e..72ad3f718c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -102,6 +102,7 @@ CORE_CFLAGS += -I$(switch_srcdir)/libs/pcre
 CORE_CFLAGS += -I$(switch_srcdir)/libs/speex/include -Ilibs/speex/include
 CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/include
 CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/crypto/include -Ilibs/srtp/crypto/include
+CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src
 
 CORE_LIBS  = libs/apr-util/libaprutil-1.la libs/apr/libapr-1.la
 CORE_LIBS += libs/sqlite/libsqlite3.la libs/pcre/libpcre.la libs/speex/libspeex/libspeexdsp.la
@@ -249,7 +250,8 @@ libfreeswitch_la_SOURCES = \
 	libs/miniupnpc/minissdpc.c \
 	libs/miniupnpc/upnperrors.c \
 	libs/libnatpmp/natpmp.c \
-	libs/libnatpmp/getgateway.c
+	libs/libnatpmp/getgateway.c\
+	libs/spandsp/src/plc.c
 
 if ENABLE_CPP
 libfreeswitch_la_SOURCES += src/switch_cpp.cpp
diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c
index 4a02a8fe38..ce582d3837 100644
--- a/libs/esl/src/esl.c
+++ b/libs/esl/src/esl.c
@@ -1177,7 +1177,6 @@ ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char *
 		return ESL_FAIL;
 	}
 
-	esl_event_safe_destroy(&handle->last_event);
 	esl_event_safe_destroy(&handle->last_sr_event);
 
 	*handle->last_sr_reply = '\0';
diff --git a/libs/freetdm/configure.gnu b/libs/freetdm/configure.gnu
index 5785ffc0e7..d00cd18473 100755
--- a/libs/freetdm/configure.gnu
+++ b/libs/freetdm/configure.gnu
@@ -1,3 +1,3 @@
 #! /bin/sh
-./configure "$@" --with-pic
-
+srcpath=$(dirname $0 2>/dev/null )  || srcpath="." 
+$srcpath/configure "$@" --with-pic
diff --git a/libs/freetdm/freetdm.2010.sln b/libs/freetdm/freetdm.2010.sln
index f4bd907a6d..44431d675a 100644
--- a/libs/freetdm/freetdm.2010.sln
+++ b/libs/freetdm/freetdm.2010.sln
@@ -119,10 +119,8 @@ Global
 		{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64
 		{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64
 		{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.Build.0 = Debug|Win32
 		{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|x64
 		{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32
-		{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32
 		{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|x64
 		{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32
 		{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|x64
diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj
index ec69333410..9f01a3b1a1 100644
--- a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj
+++ b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj
@@ -103,7 +103,7 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
@@ -127,7 +127,7 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index 1461499d2d..b43ca8ad6f 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -57,11 +57,14 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
 #define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
 #define FTDM_READ_TRACE_INDEX 0
 #define FTDM_WRITE_TRACE_INDEX 1
+#define MAX_CALLIDS 6000
 
 ftdm_time_t time_last_throttle_log = 0;
 ftdm_time_t time_current_throttle_log = 0;
 
 static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter);
+static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data);
+static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data);
 
 static int time_is_init = 0;
 
@@ -235,6 +238,10 @@ static struct {
 	ftdm_span_t *spans;
 	ftdm_group_t *groups;
 	cpu_monitor_t cpu_monitor;
+	
+	ftdm_caller_data_t *call_ids[MAX_CALLIDS+1];
+	ftdm_mutex_t *call_id_mutex;
+	uint32_t last_call_id;
 } globals;
 
 enum ftdm_enum_cpu_alarm_action_flags
@@ -1896,8 +1903,6 @@ static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan)
 		ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF;
 	}
 
-	ftdm_call_clear_vars(&ftdmchan->caller_data);
-			
 	memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len);
 
 	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) {
@@ -2483,6 +2488,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char
 
 	ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100);
 
+	ftdm_call_set_call_id(&ftdmchan->caller_data);
 	ftdm_channel_unlock(ftdmchan);
 
 	return status;
@@ -2545,9 +2551,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
 	ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n");
 
 	ftdm_mutex_lock(ftdmchan->mutex);
-
-	memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
-
 	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INUSE);
 	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
 	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK);
@@ -2587,7 +2590,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
 		sigmsg.channel = ftdmchan;
 		sigmsg.event_id = FTDM_SIGEVENT_RELEASED;
 		ftdm_span_send_signal(ftdmchan->span, &sigmsg);
-	}
+		ftdm_call_clear_call_id(&ftdmchan->caller_data);
+	}	
 
 	if (ftdmchan->txdrops || ftdmchan->rxdrops) {
 		ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", 
@@ -2595,8 +2599,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
 	}
 
 	ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
-
-
+	memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
 	ftdm_mutex_unlock(ftdmchan->mutex);
 
 	return FTDM_SUCCESS;
@@ -3455,7 +3458,7 @@ static FIO_READ_FUNCTION(ftdm_raw_read)
 	ftdm_status_t  status = ftdmchan->fio->read(ftdmchan, data, datalen);
 	if (status == FTDM_SUCCESS && ftdmchan->fds[FTDM_READ_TRACE_INDEX] > -1) {
 		ftdm_size_t dlen = *datalen;
-		if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, dlen) != dlen) {
+		if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, (int)dlen) != dlen) {
 			ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %zd bytes\n", dlen);
 		}
 	}
@@ -3468,7 +3471,7 @@ static FIO_READ_FUNCTION(ftdm_raw_read)
 		ftdm_size_t dlen = *datalen;
 		ftdm_size_t rc = 0;
 
-		write_chan_io_dump(&ftdmchan->rxdump, data, dlen);
+		write_chan_io_dump(&ftdmchan->rxdump, data, (int)dlen);
 
 		/* if dtmf debug is enabled and initialized, write there too */
 		if (ftdmchan->dtmfdbg.file) {
@@ -5336,7 +5339,7 @@ static void execute_safety_hangup(void *data)
 FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
 {
 	if (sigmsg->channel) {
-		ftdm_mutex_lock(sigmsg->channel->mutex);
+		ftdm_mutex_lock(sigmsg->channel->mutex);		
 	}
 	
 	/* some core things to do on special events */
@@ -5355,6 +5358,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
 
 	case FTDM_SIGEVENT_START:
 		{
+			ftdm_call_set_call_id(&sigmsg->channel->caller_data);
 			ftdm_set_echocancel_call_begin(sigmsg->channel);
 			if (sigmsg->channel->dtmfdbg.requested) {
 				ftdm_channel_command(sigmsg->channel, FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL);
@@ -5384,7 +5388,10 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
 		break;	
 
 	}
-	
+
+	if (sigmsg->channel) {
+		sigmsg->call_id = sigmsg->channel->caller_data.call_id;
+	}
 	/* if the signaling module uses a queue for signaling notifications, then enqueue it */
 	if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
 		ftdm_span_queue_signal(span, sigmsg);
@@ -5493,6 +5500,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
 	ftdm_mutex_create(&globals.mutex);
 	ftdm_mutex_create(&globals.span_mutex);
 	ftdm_mutex_create(&globals.group_mutex);
+	ftdm_mutex_create(&globals.call_id_mutex);
+	
 	ftdm_sched_global_init();
 	if (ftdm_sched_create(&globals.timingsched, "freetdm-master") != FTDM_SUCCESS) {
 		ftdm_log(FTDM_LOG_CRIT, "Failed to create master timing schedule context\n");
@@ -5502,6 +5511,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
 		ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n");
 		return FTDM_FAIL;
 	}
+
 	globals.running = 1;
 	return FTDM_SUCCESS;
 }
@@ -5605,6 +5615,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
 	ftdm_mutex_destroy(&globals.mutex);
 	ftdm_mutex_destroy(&globals.span_mutex);
 	ftdm_mutex_destroy(&globals.group_mutex);
+	ftdm_mutex_destroy(&globals.call_id_mutex);
 
 	memset(&globals, 0, sizeof(globals));
 	return FTDM_SUCCESS;
@@ -5963,6 +5974,47 @@ FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
 	return stream.data;
 }
 
+static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data)
+{
+	uint32_t current_call_id;
+	ftdm_assert_return(!caller_data->call_id, FTDM_FAIL, "Overwriting non-cleared call-id");
+
+	ftdm_mutex_lock(globals.call_id_mutex);
+	current_call_id = globals.last_call_id;
+
+	do {
+		if (++current_call_id > MAX_CALLIDS) {
+			current_call_id = 1;
+		}
+		if (globals.call_ids[current_call_id] != NULL) {
+			continue;
+		}
+	} while (0);
+
+	globals.last_call_id = current_call_id;
+	caller_data->call_id = current_call_id;
+
+	globals.call_ids[current_call_id] = caller_data;
+	ftdm_mutex_unlock(globals.call_id_mutex);
+	return FTDM_SUCCESS;
+}
+
+static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data)
+{
+	ftdm_assert_return((caller_data->call_id && caller_data->call_id <= MAX_CALLIDS), FTDM_FAIL, "Clearing call with invalid call-id\n");
+	ftdm_mutex_lock(globals.call_id_mutex);
+	if (globals.call_ids[caller_data->call_id]) {
+		caller_data->call_id = 0;
+		globals.call_ids[caller_data->call_id] = NULL;
+	} else {
+		ftdm_log(FTDM_LOG_CRIT, "call-id did not exist %u\n", caller_data->call_id);
+	} 
+	ftdm_mutex_unlock(globals.call_id_mutex);
+	return FTDM_SUCCESS;
+}
+
+
+
 
 /* For Emacs:
  * Local Variables:
diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
index e95a74bc25..9d94c6d088 100644
--- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
+++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
@@ -515,13 +515,20 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons
 	ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
 
 	ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Call offered with ANI = %s, DNIS = %s, Category = (%d)\n", ani, dnis, category);
-	ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
 
 	/* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */
 	if (r2data->mf_dump_size) {
 		ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL);
 		ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL);
 	}
+
+	/* check if this is a collect call and if we should accept it */
+	if (!r2data->allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
+		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Rejecting collect call\n");
+		openr2_chan_disconnect_call(r2chan, OR2_CAUSE_COLLECT_CALL_REJECTED);
+	} else {
+		ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
+	}
 }
 
 /*
@@ -900,7 +907,7 @@ static int ftdm_r2_io_write(openr2_chan_t *r2chan, const void *buf, int size)
 	if (FTDM_FAIL == status) {
 		return -1;
 	}
-	return outsize;
+	return (int)outsize;
 }
 
 static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size)
@@ -911,7 +918,7 @@ static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size)
 	if (FTDM_FAIL == status) {
 		return -1;
 	}
-	return outsize;
+	return (int)outsize;
 }
 
 static int ftdm_r2_io_wait(openr2_chan_t *r2chan, int *flags, int block)
@@ -993,6 +1000,10 @@ static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *e
 		return -1;
 	}
 
+	if (fevent->e_type != FTDM_EVENT_OOB) {
+		return 0;
+	}
+
 	switch (fevent->enum_id) {
 	case FTDM_OOB_CAS_BITS_CHANGE:
 		{
@@ -1598,6 +1609,13 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
 				}
 				break;
 
+				/* INDICATE_RINGING doesn't apply to MFC/R2. maybe we could generate a tone */
+			case FTDM_CHANNEL_STATE_RINGING: 
+				{
+					ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RINGING indicated, ignoring it as it doesn't apply to MFC/R2\n");
+				}
+				break;
+
 			default:
 				{
 					ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state));
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
index 304e9d6ce3..5c171a9f6b 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
@@ -502,6 +502,8 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
 	/**************************************************************************/
 	case FTDM_CHANNEL_STATE_COLLECT:	/* IAM received but wating on digits */
 
+		isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
+
 		if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 			SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 			break;
@@ -521,8 +523,8 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
 			/*now go to the RING state */
 			ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
 			
-		} else if (i >= g_ftdm_sngss7_data.min_digits) {
-			SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, g_ftdm_sngss7_data.min_digits);
+		} else if (i >= isup_intf->min_digits) {
+			SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, isup_intf->min_digits);
 
 			/*now go to the RING state */
 			ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
@@ -532,7 +534,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
 			if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) {
 				SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
 										i,
-										g_ftdm_sngss7_data.min_digits,
+										isup_intf->min_digits,
 										ftdmchan->caller_data.dnis.digits);
 		
 				/* start ISUP t35 */
@@ -1520,9 +1522,6 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
 	/* initalize the global gen_config flag */
 	g_ftdm_sngss7_data.gen_config = 0;
 
-	/* min. number of digitis to wait for */
-	g_ftdm_sngss7_data.min_digits = 7;
-
 	/* function trace initizalation */
 	g_ftdm_sngss7_data.function_trace = 1;
 	g_ftdm_sngss7_data.function_trace_level = 7;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
index 378b50e0ad..fe4b6f45c4 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
@@ -50,7 +50,7 @@
 /******************************************************************************/
 
 /* DEFINES ********************************************************************/
-#define MAX_NAME_LEN			10
+#define MAX_NAME_LEN			25
 #define MAX_PATH				255
 
 #define MAX_CIC_LENGTH			5
@@ -224,6 +224,7 @@ typedef struct sng_isup_intf {
 	uint32_t		isap;
 	uint32_t		clg_nadi;
 	uint32_t		cld_nadi;
+	uint32_t		min_digits;
 	uint16_t		t4;
 	uint32_t		t10;
 	uint32_t		t11;
@@ -326,7 +327,6 @@ typedef struct sng_ss7_cfg {
 typedef struct ftdm_sngss7_data {
 	sng_ss7_cfg_t		cfg;
 	int					gen_config;
-	int					min_digits;
 	int					function_trace;
 	int					function_trace_level;
 	int					message_trace;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
index 8a24f971ed..d4fd1ca9b3 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
@@ -142,7 +142,7 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
 
 		if (!strcasecmp(var, "ch_map")) {
 		/**********************************************************************/
-			strcpy(isupCkt.ch_map, val);
+			strncpy(isupCkt.ch_map, val, MAX_CIC_MAP_LENGTH-1);
 			SS7_DEBUG("\tFound channel map \"%s\"\n", isupCkt.ch_map);
 		/**********************************************************************/
 		} else if (!strcasecmp(var, "typeCntrl")) {
@@ -393,7 +393,7 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset)
 	for (i = 0; i < num_parms; i++) {
 		/**********************************************************************/
 		if (!strcasecmp(parm->var, "name")) {
-			strcpy((char *)mtpLinkSet.name, parm->val);
+			strncpy((char *)mtpLinkSet.name, parm->val, MAX_NAME_LEN-1);
 			SS7_DEBUG("\tFound an \"mtp_linkset\" named = %s\n", mtpLinkSet.name);
 		/**********************************************************************/
 		} else if (!strcasecmp(parm->var, "apc")) {
@@ -508,7 +508,7 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
 		/* try to match the parameter to what we expect */
 		/**********************************************************************/
 		if (!strcasecmp(parm->var, "name")) {
-			strcpy((char *)mtpLink->name, parm->val);
+			strncpy((char *)mtpLink->name, parm->val, MAX_NAME_LEN-1);
 			SS7_DEBUG("\tFound an \"mtp_link\" named = %s\n", mtpLink->name);
 		/**********************************************************************/
 		} else if (!strcasecmp(parm->var, "span")) {
@@ -827,7 +827,7 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route)
 		/* try to match the parameter to what we expect */
 		/**********************************************************************/
 		if (!strcasecmp(parm->var, "name")) {
-			strcpy((char *)mtpRoute.name, parm->val);
+			strncpy((char *)mtpRoute.name, parm->val, MAX_NAME_LEN-1);
 			SS7_DEBUG("\tFound an \"mtp_route\" named = %s\n", mtpRoute.name);
 		/**********************************************************************/
 		} else if (!strcasecmp(parm->var, "dpc")) {
@@ -999,7 +999,7 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
 		/* try to match the parameter to what we expect */
 		/**********************************************************************/
 		if (!strcasecmp(parm->var, "name")) {
-			strcpy((char *)sng_isup.name, parm->val);
+			strncpy((char *)sng_isup.name, parm->val, MAX_NAME_LEN-1);
 			SS7_DEBUG("\tFound an \"isup_interface\" named = %s\n", sng_isup.name);
 		/**********************************************************************/
 		} else if (!strcasecmp(parm->var, "spc")) {
@@ -1047,6 +1047,11 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
 				SS7_DEBUG("\tFound MTP3 Route = %s\n", parm->val);
 			}
 		/**********************************************************************/
+		} else if (!strcasecmp(parm->var, "min_digits")) {
+			sng_isup.min_digits = atoi(parm->val);
+
+			SS7_DEBUG("\tFound min_digits = %d\n", sng_isup.min_digits);
+		/**********************************************************************/
 		} else if (!strcasecmp(parm->var, "ssf")) {
 			if (!strcasecmp(parm->val, "nat")) {
 				sng_isup.ssf = SSF_NAT;
@@ -1067,8 +1072,8 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
 		/**********************************************************************/
 		} else if (!strcasecmp(parm->var, "license")) {
 		/**********************************************************************/
-			strcpy(g_ftdm_sngss7_data.cfg.license, parm->val);
-			strcpy(g_ftdm_sngss7_data.cfg.signature, parm->val);
+			strncpy(g_ftdm_sngss7_data.cfg.license, parm->val, MAX_PATH-1);
+			strncpy(g_ftdm_sngss7_data.cfg.signature, parm->val, MAX_PATH-1);
 			strcat(g_ftdm_sngss7_data.cfg.signature, ".sig");
 			SS7_DEBUG("\tFound license file = %s\n", g_ftdm_sngss7_data.cfg.license);
 			SS7_DEBUG("\tFound signature file = %s\n", g_ftdm_sngss7_data.cfg.signature);	
@@ -1304,6 +1309,13 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
 		sng_isup.clg_nadi = 0x03;
 	}
 
+	/* check if the user requested min_digits value */
+	if (sng_isup.min_digits == 0) {
+		/* default to 7 */
+		sng_isup.min_digits = 7;
+	}
+		
+
 	/* trickle down the SPC to all sub entities */
 	linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId;
 
@@ -1359,7 +1371,7 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink)
 	}
 
 	/* fill in the information */
-	strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name);
+	strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name, MAX_NAME_LEN-1);
 
 	g_ftdm_sngss7_data.cfg.mtpLink[i].id				= mtpLink->id;
 
@@ -1521,7 +1533,7 @@ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet)
 {
 	int	i = mtpLinkSet->id;
 
-	strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name);
+	strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name, MAX_NAME_LEN-1);
 
 	g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id			= mtpLinkSet->id;
 	g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc		= mtpLinkSet->apc;
@@ -1559,7 +1571,7 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route)
 		SS7_DEBUG("found existing mtp3_route, id is = %d\n", mtp3_route->id);
 	}
 
-	strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name);
+	strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name, MAX_NAME_LEN-1);
 
 	g_ftdm_sngss7_data.cfg.mtpRoute[i].id			= mtp3_route->id;
 	g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc			= mtp3_route->dpc;
@@ -1693,7 +1705,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
 		SS7_DEBUG("found existing isup interface, id is = %d\n", sng_isup->id);
 	}
 
-	strcpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name);
+	strncpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name, MAX_NAME_LEN-1);
 
 	g_ftdm_sngss7_data.cfg.isupIntf[i].id			= sng_isup->id;
 	g_ftdm_sngss7_data.cfg.isupIntf[i].mtpRouteId	= sng_isup->mtpRouteId;
@@ -1705,6 +1717,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
 	g_ftdm_sngss7_data.cfg.isupIntf[i].isap			= sng_isup->isap;
 	g_ftdm_sngss7_data.cfg.isupIntf[i].cld_nadi		= sng_isup->cld_nadi;
 	g_ftdm_sngss7_data.cfg.isupIntf[i].clg_nadi		= sng_isup->clg_nadi;
+	g_ftdm_sngss7_data.cfg.isupIntf[i].min_digits	= sng_isup->min_digits;
 	g_ftdm_sngss7_data.cfg.isupIntf[i].options		= sng_isup->options;
 	if (sng_isup->t4 != 0) {
 		g_ftdm_sngss7_data.cfg.isupIntf[i].t4		= sng_isup->t4;
@@ -1976,7 +1989,7 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
 		return FTDM_FAIL;
 	}
 
-	strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-rt");
+	strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-route", MAX_NAME_LEN-1);
 
 	g_ftdm_sngss7_data.cfg.mtpRoute[0].id			= 0;
 	g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc			= spc;
@@ -2230,7 +2243,7 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
 	int			lower;
 	int			upper;
 	char		tmp[5]; /*KONRAD FIX ME*/
-	char		new_ch_map[MAX_CIC_LENGTH];
+	char		new_ch_map[MAX_CIC_MAP_LENGTH];
 
 	memset(&tmp[0], '\0', sizeof(tmp));
 	memset(&new_ch_map[0], '\0', sizeof(new_ch_map));
@@ -2337,7 +2350,9 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
 		/* the the rest of ch_map to new_ch_map */
 		strncat(new_ch_map, &ch_map[x], strlen(&ch_map[x]));
 
+
 		/* set the new cic map to ch_map*/
+		memset(ch_map, '\0', sizeof(ch_map));
 		strcpy(ch_map, new_ch_map);
 
 	} else if (ch_map[x] == ',') {
@@ -2345,16 +2360,21 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
 		x++;
 
 		/* copy the rest of the list to new_ch_map */
+		memset(new_ch_map, '\0', sizeof(new_ch_map));
 		strcpy(new_ch_map, &ch_map[x]);
 
 		/* copy the new_ch_map over the old one */
+		memset(ch_map, '\0', sizeof(ch_map));
 		strcpy(ch_map, new_ch_map);
 
 	} else if (ch_map[x] == '\0') {
+
 		/* we're at the end of the string...copy the rest of the list to new_ch_map */
+		memset(new_ch_map, '\0', sizeof(new_ch_map));
 		strcpy(new_ch_map, &ch_map[x]);
 
 		/* set the new cic map to ch_map*/
+		memset(ch_map, '\0', sizeof(ch_map));
 		strcpy(ch_map, new_ch_map);
 	} else { 
 		/* nothing to do */
diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h
index 4ee6ff5f52..cc32d66bdd 100644
--- a/libs/freetdm/src/include/freetdm.h
+++ b/libs/freetdm/src/include/freetdm.h
@@ -295,6 +295,11 @@ typedef struct ftdm_caller_data {
 	/* user information layer 1 protocol */
 	ftdm_user_layer1_prot_t bearer_layer1;
 	ftdm_variable_container_t variables; /*!<variables attached to this call */
+	/* We need call_id inside caller_data for the user to be able to retrieve 
+	 * the call_id when ftdm_channel_call_place is called. This is the only time
+	 * that the user can use caller_data.call_id to obtain the call_id. The user
+	 * should use the call_id from sigmsg otherwise */
+	uint32_t call_id; /*!< Unique call ID for this call */
 } ftdm_caller_data_t;
 
 /*! \brief Tone type */
@@ -381,9 +386,10 @@ struct ftdm_sigmsg {
 	ftdm_channel_t *channel; /*!< Related channel */
 	uint32_t chan_id; /*!< easy access to chan id */
 	uint32_t span_id; /*!< easy access to span_id */
-	ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */	
+	ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */
 	void *raw_data; /*!< Message specific data if any */
 	uint32_t raw_data_len; /*!< Data len in case is needed */
+	uint32_t call_id; /*!< unique call id for this call */
 };
 
 /*! \brief Crash policy 
diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c
index 7174d1e7f7..529dbbe5e2 100644
--- a/libs/freetdm/src/testsangomaboost.c
+++ b/libs/freetdm/src/testsangomaboost.c
@@ -52,11 +52,9 @@
 #if defined(__linux__) && !defined(__USE_BSD)
 #define __USE_BSD
 #endif
-
 #ifndef WIN32
 #include <unistd.h>
 #endif
-
 #include "freetdm.h"
 
 
diff --git a/libs/spandsp/src/spandsp.h.in b/libs/spandsp/src/spandsp.h.in
index 9167c1c2cc..eaed548c97 100644
--- a/libs/spandsp/src/spandsp.h.in
+++ b/libs/spandsp/src/spandsp.h.in
@@ -39,8 +39,9 @@
 #include <limits.h>
 #include <time.h>
 @INSERT_MATH_HEADER@
+#if !defined(SPANDSP_NO_TIFF)
 #include <tiffio.h>
-
+#endif
 #include <spandsp/telephony.h>
 #include <spandsp/fast_convert.h>
 #include <spandsp/logging.h>
diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c
index 0422cd2081..fce968c990 100644
--- a/libs/stfu/stfu.c
+++ b/libs/stfu/stfu.c
@@ -27,6 +27,7 @@
  */
 #include "stfu.h"
 
+//#define DB_JB 1
 #ifdef _MSC_VER
 /* warning C4706: assignment within conditional expression*/
 #pragma warning(disable: 4706)
@@ -35,9 +36,12 @@
 struct stfu_queue {
 	struct stfu_frame *array;
 	struct stfu_frame int_frame;
+	uint32_t real_array_size;
 	uint32_t array_size;
 	uint32_t array_len;	
 	uint32_t wr_len;
+    uint32_t last_index;
+    int32_t last_jitter;
 };
 typedef struct stfu_queue stfu_queue_t;
 
@@ -48,27 +52,72 @@ struct stfu_instance {
 	struct stfu_queue *out_queue;
     struct stfu_frame *last_frame;
 	uint32_t cur_ts;
+	uint32_t cur_seq;
 	uint32_t last_wr_ts;
+	uint32_t last_wr_seq;
 	uint32_t last_rd_ts;
-	uint32_t interval;
+	uint32_t samples_per_packet;
+	uint32_t samples_per_second;
 	uint32_t miss_count;
 	uint32_t max_plc;
+    uint32_t qlen;
+    uint32_t max_qlen;
+    uint32_t orig_qlen;
+    uint32_t packet_count;
+    uint32_t consecutive_good_count;
+    uint32_t consecutive_bad_count;
+    uint32_t period_good_count;
+    uint32_t period_bad_count;
+    uint32_t period_packet_in_count;
+    uint32_t period_packet_out_count;
+    uint32_t period_missing_count;
+    uint32_t period_need_range;
+    uint32_t period_need_range_avg;
+    uint32_t period_clean_count;
+
+    uint32_t session_clean_count;
+    uint32_t session_missing_count;
+
+    uint32_t session_packet_in_count;
+    uint32_t session_packet_out_count;
+
+    uint32_t sync;
+
+
+    int32_t ts_diff;
+    int32_t last_ts_diff;
+    int32_t same_ts;
+    
+    uint32_t last_seq;
+
+    uint32_t period_time;
+    uint32_t decrement_time;
+    
+    uint32_t plc_len;
+
+    stfu_n_call_me_t callback;
+    void *udata;
 };
 
+static void stfu_n_reset_counters(stfu_instance_t *i);
 
 static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen)
 {
     unsigned char *m;
 
-    if (qlen <= queue->array_size) {
-        return STFU_IT_FAILED;;
+    if (qlen <= queue->real_array_size) {
+        queue->array_size = qlen;
+        if (queue->array_len > qlen) {
+            queue->array_len = qlen;
+        }
+    } else {
+        m = realloc(queue->array, qlen * sizeof(struct stfu_frame));
+        assert(m);
+        memset(m + queue->array_size * sizeof(struct stfu_frame), 0, (qlen * sizeof(struct stfu_frame)) - (queue->array_size * sizeof(struct stfu_frame)));
+        queue->array = (struct stfu_frame *) m;
+        queue->real_array_size = queue->array_size = qlen;
     }
 
-	m = realloc(queue->array, qlen * sizeof(struct stfu_frame));
-    assert(m);
-    memset(m + queue->array_size, 0, qlen * sizeof(struct stfu_frame) - queue->array_size);
-    queue->array = (struct stfu_frame *) m;
-	queue->array_size = qlen;
 	return STFU_IT_WORKED;
 }
 
@@ -77,8 +126,16 @@ static void stfu_n_init_aqueue(stfu_queue_t *queue, uint32_t qlen)
 	queue->array = calloc(qlen, sizeof(struct stfu_frame));
 	assert(queue->array != NULL);
 	memset(queue->array, 0, sizeof(struct stfu_frame) * qlen);	
-	queue->array_size = qlen;
+	queue->real_array_size = queue->array_size = qlen;
 	queue->int_frame.plc = 1;
+    memset(queue->int_frame.data, 255, sizeof(queue->int_frame.data));
+}
+
+
+void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata)
+{
+    i->callback = callback;
+    i->udata = udata;
 }
 
 void stfu_n_destroy(stfu_instance_t **i)
@@ -97,24 +154,40 @@ void stfu_n_destroy(stfu_instance_t **i)
 void stfu_n_report(stfu_instance_t *i, stfu_report_t *r)
 {
     assert(i);
-    r->in_len = i->in_queue->array_len;
-    r->in_size = i->in_queue->array_size;
-    r->out_len = i->out_queue->array_len;
-    r->out_size = i->out_queue->array_size;
+	r->qlen = i->qlen;
+	r->packet_in_count = i->period_packet_in_count;
+	r->clean_count = i->period_clean_count;
+	r->consecutive_good_count = i->consecutive_good_count;
+	r->consecutive_bad_count = i->consecutive_bad_count;
 }
 
 stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen) 
 {
     stfu_status_t s;
 
+    if (i->qlen == i->max_qlen) {
+        return STFU_IT_FAILED;
+    }
+    
+    if (i->max_qlen && qlen > i->max_qlen) {
+        if (i->qlen < i->max_qlen) {
+            qlen = i->max_qlen;
+        } else {
+            return STFU_IT_FAILED;
+        }
+    }
+
     if ((s = stfu_n_resize_aqueue(&i->a_queue, qlen)) == STFU_IT_WORKED) {
         s = stfu_n_resize_aqueue(&i->b_queue, qlen);
+        i->qlen = qlen;
+        i->max_plc = 5;
+        i->last_frame = NULL;
     }
     
     return s;
 }
 
-stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc)
+stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second)
 {
 	struct stfu_instance *i;
 
@@ -123,82 +196,172 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc)
 		return NULL;
 	}
 	memset(i, 0, sizeof(*i));
+    i->qlen = qlen;
+    i->max_qlen = max_qlen;
+    i->orig_qlen = qlen;
+    i->samples_per_packet = samples_per_packet;
+
 	stfu_n_init_aqueue(&i->a_queue, qlen);
 	stfu_n_init_aqueue(&i->b_queue, qlen);
 	i->in_queue = &i->a_queue;
 	i->out_queue = &i->b_queue;
+    
+    i->max_plc = i->qlen / 2;
 
-    if (max_plc) {
-        i->max_plc = max_plc;
-    } else {
-        i->max_plc = qlen / 2;
-    }
+    i->samples_per_second = samples_per_second ? samples_per_second : 8000;
+    
+    i->period_time = ((i->samples_per_second * 20) / i->samples_per_packet);
+    i->decrement_time = ((i->samples_per_second * 15) / i->samples_per_packet);
 
 	return i;
 }
 
+static void stfu_n_reset_counters(stfu_instance_t *i)
+{
+#ifdef DB_JB
+    printf("COUNTER RESET........\n");
+#endif
+
+    if (i->callback) {
+        i->callback(i, i->udata);
+    }
+
+    i->consecutive_good_count = 0;
+    i->consecutive_bad_count = 0;
+    i->period_good_count = 0;
+    i->period_clean_count = 0;
+    i->period_bad_count = 0;
+    i->period_packet_in_count = 0;
+    i->period_packet_out_count = 0;
+    i->period_missing_count = 0;
+    i->period_need_range = 0;
+    i->period_need_range_avg = 0;
+}
+
 void stfu_n_reset(stfu_instance_t *i)
 {
+#ifdef DB_JB
+    printf("RESET\n");
+#endif
 	i->in_queue = &i->a_queue;
 	i->out_queue = &i->b_queue;
 	i->in_queue->array_len = 0;
 	i->out_queue->array_len = 0;
 	i->out_queue->wr_len = 0;
 	i->last_frame = NULL;
-	i->miss_count = 0;	
+
+    i->in_queue->last_jitter = 0;
+    i->out_queue->last_jitter = 0;
+
+    stfu_n_reset_counters(i);
+
+    i->last_seq = 0;
+
+    i->cur_ts = 0;
+    i->cur_seq = 0;
 	i->last_wr_ts = 0;
-	i->miss_count = 0;
-	i->interval = 0;
+	i->last_wr_seq = 0;
+	i->last_rd_ts = 0;
+	i->miss_count = 0;	
+    i->packet_count = 0;
 }
 
-static int32_t stfu_n_measure_interval(stfu_queue_t *queue)
+stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets)
 {
-	uint32_t index;
-	int32_t d, most = 0, last = 0, this, track[STFU_MAX_TRACK] = {0};
 
-	for(index = 0; index < queue->array_len; index++) {
-		this = queue->array[index].ts;
-		if (last) {
+    if (packets > i->qlen) {
+        stfu_n_reset(i);
+    } else {
+        i->sync = packets;
+    }
 
-			if ((d = this - last) > 0 && d / 10 < STFU_MAX_TRACK) {
-				track[(d/10)]++;
-			}
-		}
-
-		last = this;
-	}
-
-	for(index = 0; index < STFU_MAX_TRACK; index++) {
-		if (track[index] > track[most]) {
-			most = index;
-		}
-	}
-
-	return most * 10;
+    return STFU_IT_WORKED;
 }
 
-static int16_t stfu_n_process(stfu_instance_t *i, stfu_queue_t *queue)
-{
-	if (!i->interval && !(i->interval = stfu_n_measure_interval(queue))) {
-		return -1;
-	}
 
-	return 0;
-}
-
-stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last)
+stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uint32_t pt, void *data, size_t datalen, int last)
 {
 	uint32_t index;
 	stfu_frame_t *frame;
 	size_t cplen = 0;
+    int good_seq = 0, good_ts = 0;
+
+    if (!i->samples_per_packet && ts && i->last_rd_ts) {
+        i->ts_diff = ts - i->last_rd_ts;
+
+        if (i->last_ts_diff == i->ts_diff) {
+            if (++i->same_ts == 5) {
+                i->samples_per_packet = i->ts_diff;
+            }
+        } else {
+            i->same_ts = 0;
+        }
+            
+        i->last_ts_diff = i->ts_diff;
+
+        if (!i->samples_per_packet) {
+            i->last_rd_ts = ts;
+            return STFU_IT_FAILED;
+        }
+    }
+ 
+    if (seq && seq == i->last_seq + 1) {
+        good_seq = 1;
+    }
+
+    if (ts && ts == i->last_rd_ts + i->samples_per_packet) {
+        good_ts = 1;
+    }
+
+
+    if (good_seq || good_ts) {
+        i->period_clean_count++;
+        i->session_clean_count++;
+    }
+
+    i->period_packet_in_count++;
+    i->session_packet_in_count++;
+
+    if (i->session_packet_in_count == 150) {
+        return STFU_IT_WORKED;
+    }
+
+    i->period_need_range_avg = i->period_need_range / (i->period_missing_count || 1);
+    
+    if (i->period_missing_count > i->qlen * 2) {
+        stfu_n_resize(i, i->qlen + 1);
+        stfu_n_reset_counters(i);
+    }
+
+    if (i->qlen > i->orig_qlen && (i->consecutive_good_count > i->decrement_time || i->period_clean_count > i->decrement_time)) {
+        stfu_n_resize(i, i->qlen - 1);
+        stfu_n_reset_counters(i);
+        stfu_n_sync(i, i->qlen);
+    }
+
+    if ((i->period_packet_in_count > i->period_time)) {
+        i->period_packet_in_count = 0;
+
+        if (i->period_missing_count == 0 && i->qlen > i->orig_qlen) {
+            stfu_n_resize(i, i->qlen - 1);
+            stfu_n_sync(i, i->qlen);
+        }
+
+        stfu_n_reset_counters(i);
+    }
+
+#ifdef DB_JB
+    printf("%u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u/%u - %u %d\n", 
+           i->qlen, i->period_packet_in_count, i->period_time, i->consecutive_good_count, 
+           i->decrement_time, i->period_clean_count, i->decrement_time, i->consecutive_bad_count,
+           seq, ts, 
+           i->period_missing_count, i->period_need_range_avg);
+#endif
+
 
 	if (last || i->in_queue->array_len == i->in_queue->array_size) {
 		stfu_queue_t *other_queue;
 
-		if (i->out_queue->wr_len < i->out_queue->array_len) {
-			return STFU_IT_FAILED;
-		}
-
 		other_queue = i->in_queue;
 		i->in_queue = i->out_queue;
 		i->out_queue = other_queue;
@@ -207,57 +370,92 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void
 		i->out_queue->wr_len = 0;
 		i->last_frame = NULL;
 		i->miss_count = 0;
-
-		if (stfu_n_process(i, i->out_queue) < 0) {
-            if (i->in_queue->array_len == i->in_queue->array_size && i->out_queue->array_len == i->out_queue->array_size) {
-                stfu_n_resize(i, i->out_queue->array_size * 2);
-            }
-			//return STFU_IT_FAILED;
-		}
-		for(index = 0; index < i->out_queue->array_len; index++) {
-			i->out_queue->array[index].was_read = 0;
-		}
-	}
+        i->in_queue->last_index = 0;
+        i->out_queue->last_index = 0;
+        i->out_queue->last_jitter = 0;
+    }
 
 	if (last) {
 		return STFU_IM_DONE;
 	}
 
-	index = i->in_queue->array_len++;
+    for(index = 0; index < i->out_queue->array_size; index++) {
+        if (i->in_queue->array[index].was_read) {
+            break;
+        }
+    }
+
+    index = i->in_queue->array_len++;
+
 	frame = &i->in_queue->array[index];
 
 	if ((cplen = datalen) > sizeof(frame->data)) {
 		cplen = sizeof(frame->data);
 	}
 
+    i->last_seq = seq;
     i->last_rd_ts = ts;
+    i->packet_count++;
 
 	memcpy(frame->data, data, cplen);
+
     frame->pt = pt;
 	frame->ts = ts;
+    frame->seq = seq;
 	frame->dlen = cplen;
 	frame->was_read = 0;	
 
 	return STFU_IT_WORKED;
 }
 
-static int stfu_n_find_frame(stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_frame, uint32_t *index)
+static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_frame_t **r_frame)
+{
+    uint32_t i = 0;
+    stfu_frame_t *frame = NULL;
+    stfu_queue_t *queue;
+
+    assert(r_frame);
+    
+    *r_frame = NULL;
+
+    for (queue = in->out_queue ; queue && queue != in->in_queue ; queue = in->in_queue) {
+
+        for(i = 0; i < queue->real_array_size; i++) {
+            frame = &queue->array[i];
+            if (!frame->was_read) {
+                *r_frame = frame;
+                queue->last_index = i;
+                frame->was_read = 1;
+                in->period_packet_out_count++;
+                in->session_packet_out_count++;
+                return 1;
+            }
+        }
+
+    }
+
+    return 0;    
+}
+
+
+static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t ts, uint32_t seq, stfu_frame_t **r_frame)
 {
     uint32_t i = 0;
     stfu_frame_t *frame = NULL;
 
     assert(r_frame);
-    assert(index);
     
     *r_frame = NULL;
 
-    for(i = 0; i < queue->array_len; i++) {
+    for(i = 0; i < queue->real_array_size; i++) {
         frame = &queue->array[i];
         
-        if (frame->ts == ts) {
+        if ((seq && frame->seq == seq) || frame->ts == ts) {
             *r_frame = frame;
-            *index = i;
+            queue->last_index = i;
             frame->was_read = 1;
+            in->period_packet_out_count++;
+            in->session_packet_out_count++;
             return 1;
         }
     }
@@ -267,40 +465,139 @@ static int stfu_n_find_frame(stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_
 
 stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
 {
-	uint32_t index;
 	stfu_frame_t *rframe = NULL;
-    
-	if (((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
+    int found = 0;
+
+	if (!i->samples_per_packet || ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
 		return NULL;
 	}
 
     if (i->cur_ts == 0) {
 		i->cur_ts = i->out_queue->array[0].ts;
     } else {
-		i->cur_ts += i->interval;
+		i->cur_ts += i->samples_per_packet;
     }
     
+    if (i->cur_seq == 0) {
+        i->cur_seq = i->out_queue->array[0].seq;
+    } else {
+        i->cur_seq++;
+    }
 
-    if (stfu_n_find_frame(i->out_queue, i->cur_ts, &rframe, &index) || stfu_n_find_frame(i->in_queue, i->cur_ts, &rframe, &index)) {
+    if (!(found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, i->cur_seq, &rframe))) {
+        found = stfu_n_find_frame(i, i->in_queue, i->cur_ts, i->cur_seq, &rframe);
+    }
+
+    if (!found && i->sync) {
+#ifdef DB_JB
+        printf("SYNC %u\n", i->sync);
+#endif
+        if ((found = stfu_n_find_any_frame(i, &rframe))) {
+            i->cur_seq = rframe->seq;
+            i->cur_ts = rframe->ts;
+        }
+        i->sync--;
+    }
+
+
+    if (!found && i->samples_per_packet) {
+#ifdef DB_JB
+        int y;
+        stfu_frame_t *frame = NULL;
+#endif
+        int32_t delay = i->last_rd_ts - i->cur_ts;
+        uint32_t need  = abs(i->last_rd_ts - i->cur_ts) / i->samples_per_packet;
+
+        
+        i->period_missing_count++;
+        i->session_missing_count++;
+        i->period_need_range += need;
+
+#ifdef DB_JB        
+        printf("MISSING %u %u %u %u %d %u %d\n", i->cur_seq, i->cur_ts, i->packet_count, i->last_rd_ts, delay, i->qlen, need);        
+#endif
+
+        if (i->packet_count > i->orig_qlen * 100 && delay > 0 && need > i->qlen && need < (i->qlen + 5)) {
+            i->packet_count = 0;
+        }
+
+#ifdef DB_JB        
+        for(y = 0; y < i->out_queue->array_size; y++) {
+            if ((y % 5) == 0) printf("\n");
+            frame = &i->out_queue->array[y];
+            printf("%u:%u\t", frame->seq, frame->ts);
+        }
+        printf("\n\n");
+
+
+        for(y = 0; y < i->in_queue->array_size; y++) {
+            if ((y % 5) == 0) printf("\n");
+            frame = &i->in_queue->array[y];
+            printf("%u:%u\t", frame->seq, frame->ts);
+        }
+        printf("\n\n");
+#endif
+
+        if (delay < 0) {
+            stfu_n_reset(i);
+            return NULL;
+        }
+    }
+
+#ifdef DB_JB
+    if (found) {
+        printf("O: %u:%u %u\n", rframe->seq, rframe->seq, rframe->plc);
+        assert(found && rframe->seq);
+    } else {
+        printf("DATA: %u %u %d %s %d\n", i->packet_count, i->consecutive_good_count, i->out_queue->last_jitter, found ? "found" : "not found", i->qlen);
+    }
+#endif
+
+
+    if (found) {
+        i->consecutive_good_count++;
+        i->period_good_count++;
+        i->consecutive_bad_count = 0;
+    } else {
+        i->consecutive_bad_count++;
+        i->period_bad_count++;
+        i->consecutive_good_count = 0;
+    }
+
+    if (found) {
         i->last_frame = rframe;
 		i->out_queue->wr_len++;
 		i->last_wr_ts = rframe->ts;
+        i->last_wr_seq = rframe->seq;
 		i->miss_count = 0;
+        if (rframe->dlen) {
+            i->plc_len = rframe->dlen;
+        }
     } else {
         i->last_wr_ts = i->cur_ts;
+        i->last_wr_seq = i->cur_seq;
         rframe = &i->out_queue->int_frame;
-
-        if (i->last_frame && i->last_frame != rframe) {
-            rframe->dlen = i->last_frame->dlen;
+        rframe->dlen = i->plc_len;
+        
+        if (i->last_frame) {
             /* poor man's plc..  Copy the last frame, but we flag it so you can use a better one if you wish */
-            memcpy(rframe->data, i->last_frame->data, rframe->dlen);
+            if (i->miss_count) {
+                memset(rframe->data, 255, rframe->dlen);
+            } else {
+                memcpy(rframe->data, i->last_frame->data, rframe->dlen);
+            }
         }
 
         rframe->ts = i->cur_ts;
 
-        if (++i->miss_count > i->max_plc) {
-            i->out_queue->wr_len = i->out_queue->array_size;
-            i->cur_ts = 0;
+        i->miss_count++;
+
+#ifdef DB_JB
+        printf("PLC %d %d %ld %u %u\n", i->miss_count, rframe->plc, rframe->dlen, rframe->seq, rframe->ts);
+#endif
+
+        if (i->miss_count > i->max_plc) {
+            stfu_n_reset(i);
             rframe = NULL;
         }
     }
diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h
index 900db6f9ac..d2760b27bc 100644
--- a/libs/stfu/stfu.h
+++ b/libs/stfu/stfu.h
@@ -75,6 +75,7 @@ typedef enum {
 struct stfu_frame {
 	uint32_t ts;
 	uint32_t pt;
+	uint32_t seq;
 	uint8_t data[STFU_DATALEN];
 	size_t dlen;
 	uint8_t was_read;
@@ -86,24 +87,27 @@ struct stfu_instance;
 typedef struct stfu_instance stfu_instance_t;
 
 typedef struct {
-	uint32_t in_len;
-	uint32_t in_size;
-	uint32_t out_len;
-	uint32_t out_size;
-
+	uint32_t qlen;
+	uint32_t packet_in_count;
+	uint32_t clean_count;
+	uint32_t consecutive_good_count;
+	uint32_t consecutive_bad_count;
 } stfu_report_t;
 
+typedef void (*stfu_n_call_me_t)(stfu_instance_t *i, void *);
 
 void stfu_n_report(stfu_instance_t *i, stfu_report_t *r);
 void stfu_n_destroy(stfu_instance_t **i);
-stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc);
+stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second);
 stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen);
-stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last);
+stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uint32_t pt, void *data, size_t datalen, int last);
 stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i);
 void stfu_n_reset(stfu_instance_t *i);
+stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets);
+void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata);
 
 #define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 1)
-#define stfu_n_eat(i,t,p,d,l) stfu_n_add_data(i, t, p, d, l, 0)
+#define stfu_n_eat(i,t,s,p,d,l) stfu_n_add_data(i, t, s, p, d, l, 0)
 
 #ifdef __cplusplus
 }
diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h
index 13410a00ae..422d5f2930 100644
--- a/src/include/private/switch_core_pvt.h
+++ b/src/include/private/switch_core_pvt.h
@@ -31,7 +31,8 @@
  * this file does not exist!!!!
  *
  */
-
+#define SPANDSP_NO_TIFF 1
+#include "spandsp.h"
 #include "switch_profile.h"
 
 #ifndef WIN32
@@ -169,6 +170,7 @@ struct switch_core_session {
 	switch_log_level_t loglevel;
 	uint32_t soft_lock;
 	switch_ivr_dmachine_t *dmachine;
+	plc_state_t *plc;
 };
 
 struct switch_media_bug {
diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h
index dc81d1a522..d89a13bb30 100644
--- a/src/include/switch_apr.h
+++ b/src/include/switch_apr.h
@@ -1110,6 +1110,8 @@ SWITCH_DECLARE(int) switch_sockaddr_equal(const switch_sockaddr_t *sa1, const sw
 SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t ** sa, const char *hostname,
 														 int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool);
 
+SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool);
+
 /**
  * Send data over a network.
  * @param sock The socket to send the data over.
diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h
index 7269a2b8d9..e3e9f665a3 100644
--- a/src/include/switch_rtp.h
+++ b/src/include/switch_rtp.h
@@ -229,7 +229,12 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_sessi
   \param queue_frames the number of frames to delay
   \return SWITCH_STATUS_SUCCESS
 */
-SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames);
+SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, 
+																  uint32_t queue_frames,
+																  uint32_t max_queue_frames,
+																  uint32_t samples_per_packet, uint32_t samples_per_second);
+
+SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session);
 
 /*!
   \brief Set an RTP Flag
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index c01638089f..d020775d48 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -790,6 +790,7 @@ typedef enum {
 	SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION,
 	SWITCH_MESSAGE_INDICATE_UDPTL_MODE,
 	SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS,
+	SWITCH_MESSAGE_INDICATE_JITTER_BUFFER,
 	SWITCH_MESSAGE_INVALID
 } switch_core_session_message_types_t;
 
@@ -1093,6 +1094,7 @@ typedef enum {
 	CF_PASSTHRU_PTIME_MISMATCH,
 	CF_BRIDGE_NOWRITE,
 	CF_RECOVERED,
+	CF_JITTERBUFFER,
 	/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
 	CF_FLAG_MAX
 } switch_channel_flag_t;
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index eacde59949..dba86e3103 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -2542,6 +2542,60 @@ SWITCH_STANDARD_API(uuid_simplify_function)
 }
 
 
+#define JITTERBUFFER_SYNTAX "<uuid> [0|<min_msec>[:<max_msec>]]"
+SWITCH_STANDARD_API(uuid_jitterbuffer_function)
+{
+	char *mydata = NULL, *argv[2] = { 0 };
+	int argc = 0;
+
+	switch_status_t status = SWITCH_STATUS_FALSE;
+
+	if (zstr(cmd)) {
+		goto error;
+	}
+
+	mydata = strdup(cmd);
+	switch_assert(mydata);
+
+	argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+
+	if (argc < 2) {
+		goto error;
+	}
+	if (argv[1]) {
+		switch_core_session_message_t msg = { 0 };
+		switch_core_session_t *lsession = NULL;
+
+		msg.message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER;
+		msg.string_arg = argv[1];
+		msg.from = __FILE__;
+
+		if ((lsession = switch_core_session_locate(argv[0]))) {
+			status = switch_core_session_receive_message(lsession, &msg);
+			switch_core_session_rwunlock(lsession);
+		}
+		goto ok;
+	} else {
+		goto error;
+	}
+
+  error:
+	stream->write_function(stream, "-USAGE: %s\n", JITTERBUFFER_SYNTAX);
+	switch_safe_free(mydata);
+	return SWITCH_STATUS_SUCCESS;
+  ok:
+	switch_safe_free(mydata);
+
+	if (status == SWITCH_STATUS_SUCCESS) {
+		stream->write_function(stream, "+OK Success\n");
+	} else {
+		stream->write_function(stream, "-ERR Operation Failed\n");
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+
 #define PHONE_EVENT_SYNTAX "<uuid>"
 SWITCH_STANDARD_API(uuid_phone_event_function)
 {
@@ -4278,21 +4332,33 @@ SWITCH_STANDARD_API(strftime_tz_api_function)
 	char *format = NULL;
 	const char *tz_name = NULL;
 	char date[80] = "";
+	char *mycmd = NULL, *p;
+	switch_time_t when = 0;
 
-	if (!zstr(cmd)) {
-		format = strchr(cmd, ' ');
-		tz_name = cmd;
-		if (format) {
+	if (cmd) mycmd = strdup(cmd);
+
+	if (!zstr(mycmd)) {
+		tz_name = mycmd;
+
+		if ((format = strchr(mycmd, ' '))) {
 			*format++ = '\0';
 		}
+		
+		if ((p = strchr(format, '|'))) {
+			*p++ = '\0';
+			when = atol(format);
+			format = p;
+		}
 	}
 
-	if (switch_strftime_tz(tz_name, format, date, sizeof(date), 0) == SWITCH_STATUS_SUCCESS) {	/* The lookup of the zone may fail. */
+	if (switch_strftime_tz(tz_name, format, date, sizeof(date), when * 1000000) == SWITCH_STATUS_SUCCESS) {	/* The lookup of the zone may fail. */
 		stream->write_function(stream, "%s", date);
 	} else {
 		stream->write_function(stream, "-ERR Invalid Timezone\n");
 	}
 
+	switch_safe_free(mycmd);
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -4715,7 +4781,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
 	SWITCH_ADD_API(commands_api_interface, "show", "Show", show_function, SHOW_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "sql_escape", "Escape a string to prevent sql injection", sql_escape, SQL_ESCAPE_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "status", "status", status_function, "");
-	SWITCH_ADD_API(commands_api_interface, "strftime_tz", "strftime_tz", strftime_tz_api_function, "<Timezone_name> [format string]");
+	SWITCH_ADD_API(commands_api_interface, "strftime_tz", "strftime_tz", strftime_tz_api_function, "<Timezone_name> [<epoch>|][format string]");
 	SWITCH_ADD_API(commands_api_interface, "stun", "stun", stun_function, "<stun_server>[:port]");
 	SWITCH_ADD_API(commands_api_interface, "system", "Execute a system command", system_function, SYSTEM_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "time_test", "time_test", time_test_function, "<mss> [count]");
@@ -4758,6 +4824,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
 	SWITCH_ADD_API(commands_api_interface, "uuid_transfer", "Transfer a session", transfer_function, TRANSFER_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "uuid_dual_transfer", "Transfer a session and its partner", dual_transfer_function, DUAL_TRANSFER_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "uuid_simplify", "Try to cut out of a call path / attended xfer", uuid_simplify_function, SIMPLIFY_SYNTAX);
+	SWITCH_ADD_API(commands_api_interface, "uuid_jitterbuffer", "Try to cut out of a call path / attended xfer", 
+				   uuid_jitterbuffer_function, JITTERBUFFER_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "xml_locate", "find some xml", xml_locate_function, "[root | <section> <tag> <tag_attr_name> <tag_attr_val>]");
 	SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, "<command> <args>");
 	switch_console_set_complete("add alias add");
@@ -4854,6 +4922,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
 	switch_console_set_complete("add uuid_flush_dtmf ::console::list_uuid");
 	switch_console_set_complete("add uuid_getvar ::console::list_uuid");
 	switch_console_set_complete("add uuid_hold ::console::list_uuid");
+	switch_console_set_complete("add uuid_jitterbuffer ::console::list_uuid");
 	switch_console_set_complete("add uuid_kill ::console::list_uuid");
 	switch_console_set_complete("add uuid_limit_release ::console::list_uuid");
 	switch_console_set_complete("add uuid_loglevel ::console::list_uuid console");
diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c
index 4fd6a676ea..e508486380 100755
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@ -269,7 +269,7 @@ SWITCH_STANDARD_APP(bind_digit_action_function)
 }
 
 
-#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume"
+#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR pause OR resume OR stop OR param <name> <value>"
 SWITCH_STANDARD_APP(detect_speech_function)
 {
 	char *argv[4];
@@ -957,6 +957,17 @@ SWITCH_STANDARD_APP(redirect_function)
 	switch_core_session_receive_message(session, &msg);
 }
 
+SWITCH_STANDARD_APP(jitterbuffer_function)
+{
+	switch_core_session_message_t msg = { 0 };
+
+	/* Tell the channel to change the jitter buffer */
+	msg.from = __FILE__;
+	msg.string_arg = data;
+	msg.message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER;
+	switch_core_session_receive_message(session, &msg);
+}
+
 SWITCH_STANDARD_APP(display_function)
 {
 	switch_core_session_message_t msg = { 0 };
@@ -1303,13 +1314,22 @@ SWITCH_STANDARD_API(strftime_api_function)
 	char date[80] = "";
 	switch_time_t thetime;
 	char *p;
-	if (!zstr(cmd) && (p = strchr(cmd, '|'))) {
-		thetime = switch_time_make(atoi(cmd), 0);
+	char *mycmd = NULL;
+
+	if (!zstr(cmd)) {
+		mycmd = strdup(cmd);
+	}
+
+	if (!zstr(mycmd) && (p = strchr(cmd, '|'))) {
+		*p++ = '\0';
+		
+		thetime = switch_time_make(atol(cmd), 0);
 		cmd = p + 1;
 	} else {
 		thetime = switch_micro_time_now();
 	}
 	switch_time_exp_lt(&tm, thetime);
+
 	if (zstr(cmd)) {
 		switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
 	} else {
@@ -3513,6 +3533,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
 	SWITCH_ADD_APP(app_interface, "ivr", "Run an ivr menu", "Run an ivr menu.", ivr_application_function, "<menu_name>", SAF_NONE);
 	SWITCH_ADD_APP(app_interface, "redirect", "Send session redirect", "Send a redirect message to a session.", redirect_function, "<redirect_data>",
 				   SAF_SUPPORT_NOMEDIA);
+	SWITCH_ADD_APP(app_interface, "jitterbuffer", "Send session jitterbuffer", "Send a jitterbuffer message to a session.", 
+				   jitterbuffer_function, "<jitterbuffer_data>", SAF_SUPPORT_NOMEDIA);
 	SWITCH_ADD_APP(app_interface, "send_display", "Send session a new display", "Send session a new display.", display_function, "<text>",
 				   SAF_SUPPORT_NOMEDIA);
 	SWITCH_ADD_APP(app_interface, "respond", "Send session respond", "Send a respond message to a session.", respond_function, "<respond_data>",
diff --git a/src/mod/endpoints/mod_skypopen/oss/Makefile b/src/mod/endpoints/mod_skypopen/oss/Makefile
new file mode 100644
index 0000000000..91cc61ba1e
--- /dev/null
+++ b/src/mod/endpoints/mod_skypopen/oss/Makefile
@@ -0,0 +1,43 @@
+# Comment/uncomment the following line to disable/enable debugging
+#DEBUG = y
+LDDINC=/usr/src/linux-headers-2.6.32-26-server/include
+
+# Add your debugging flag (or not) to CFLAGS
+ifeq ($(DEBUG),y)
+  DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+else
+  DEBFLAGS = -O2 -Wall
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS)
+EXTRA_CFLAGS += -I$(LDDINC)
+
+ifneq ($(KERNELRELEASE),)
+# call from kernel build system
+
+scull-objs := main.o
+
+obj-m	:= scull.o
+
+else
+
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+PWD       := $(shell pwd)
+
+modules:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules
+
+endif
+
+
+
+clean:
+	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
+
+depend .depend dep:
+	$(CC) $(EXTRA_CFLAGS) -M *.c > .depend
+
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c
new file mode 100644
index 0000000000..4d36ac00d5
--- /dev/null
+++ b/src/mod/endpoints/mod_skypopen/oss/main.c
@@ -0,0 +1,335 @@
+/*
+ * main.c -- the bare scull char module
+ *
+ * Copyright (C) 2010 Giovanni Maruzzelli
+ * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
+ * Copyright (C) 2001 O'Reilly & Associates
+ *
+ * The source code in this file can be freely used, adapted,
+ * and redistributed in source or binary form, so long as an
+ * acknowledgment appears in derived source files.  The citation
+ * should list that the code comes from the book "Linux Device
+ * Drivers" by Alessandro Rubini and Jonathan Corbet, published
+ * by O'Reilly & Associates.   No warranty is attached;
+ * we cannot take responsibility for errors or fitness for use.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h>	/* printk() */
+#include <linux/slab.h>		/* kmalloc() */
+#include <linux/fs.h>		/* everything... */
+#include <linux/errno.h>	/* error codes */
+#include <linux/types.h>	/* size_t */
+#include <linux/proc_fs.h>
+#include <linux/fcntl.h>	/* O_ACCMODE */
+#include <linux/seq_file.h>
+#include <linux/cdev.h>
+
+#include <asm/system.h>		/* cli(), *_flags */
+#include <asm/uaccess.h>	/* copy_*_user */
+
+#include <linux/soundcard.h>
+#include <linux/delay.h>
+#include <linux/hrtimer.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/jiffies.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+
+#include "scull.h"		/* local definitions */
+
+/*
+ * Our parameters which can be set at load time.
+ */
+
+int scull_major =   SCULL_MAJOR;
+int scull_minor =   3;
+int scull_nr_devs = SCULL_NR_DEVS;	/* number of bare scull devices */
+
+module_param(scull_major, int, S_IRUGO);
+module_param(scull_minor, int, S_IRUGO);
+module_param(scull_nr_devs, int, S_IRUGO);
+
+MODULE_AUTHOR("Original: Alessandro Rubini, Jonathan Corbet. Heavy modified by: Giovanni Maruzzelli");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static struct scull_dev *scull_devices;	/* allocated in scull_init_module */
+
+#define GIOVA_BLK 3840
+#define GIOVA_SLEEP 40000
+
+void my_timer_callback_inq( unsigned long data )
+{
+	struct scull_dev *dev = (void *)data;
+
+	wake_up_interruptible(&dev->inq);
+	mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) );
+
+}
+
+void my_timer_callback_outq( unsigned long data )
+{
+	struct scull_dev *dev = (void *)data;
+
+	wake_up_interruptible(&dev->outq);
+	mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) );
+}
+
+/* The clone-specific data structure includes a key field */
+
+struct scull_listitem {
+	struct scull_dev device;
+	dev_t key;
+	struct list_head list;
+
+};
+
+/* The list of devices, and a lock to protect it */
+static LIST_HEAD(scull_c_list);
+static spinlock_t scull_c_lock = SPIN_LOCK_UNLOCKED;
+
+/* Look for a device or create one if missing */
+static struct scull_dev *scull_c_lookfor_device(dev_t key)
+{
+	struct scull_listitem *lptr;
+
+	list_for_each_entry(lptr, &scull_c_list, list) {
+		if (lptr->key == key)
+			return &(lptr->device);
+	}
+
+	/* not found */
+	lptr = kmalloc(sizeof(struct scull_listitem), GFP_KERNEL);
+	if (!lptr)
+		return NULL;
+
+	/* initialize the device */
+	memset(lptr, 0, sizeof(struct scull_listitem));
+	lptr->key = key;
+
+	init_waitqueue_head(&lptr->device.inq);
+	init_waitqueue_head(&lptr->device.outq);
+	printk(" Timer installing\n");
+	setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr );
+	setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr );
+	printk( "Starting timer to fire in %dms (%ld)\n", GIOVA_SLEEP/1000, jiffies );
+	mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) );
+	mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) );
+	/* place it in the list */
+	list_add(&lptr->list, &scull_c_list);
+
+	return &(lptr->device);
+}
+static int scull_c_open(struct inode *inode, struct file *filp)
+{
+	struct scull_dev *dev;
+	dev_t key;
+
+	if (!current->pid) { 
+		printk("Process \"%s\" has no pid\n", current->comm);
+		return -EINVAL;
+	}
+	key = current->pid;
+
+	/* look for a scullc device in the list */
+	spin_lock(&scull_c_lock);
+	dev = scull_c_lookfor_device(key);
+	spin_unlock(&scull_c_lock);
+
+	if (!dev)
+		return -ENOMEM;
+
+	/* then, everything else is copied from the bare scull device */
+	filp->private_data = dev;
+	return 0;          /* success */
+}
+
+static int scull_c_release(struct inode *inode, struct file *filp)
+{
+	/*
+	 * Nothing to do, because the device is persistent.
+	 * A `real' cloned device should be freed on last close
+	 */
+	return 0;
+}
+
+
+
+/*************************************************************/
+/*
+ * Open and close
+ */
+
+ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
+		loff_t *f_pos)
+{
+	struct scull_dev *dev = filp->private_data;
+
+		DEFINE_WAIT(wait);
+		prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
+			schedule();
+		finish_wait(&dev->inq, &wait);
+	return count;
+
+}
+
+ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,
+		loff_t *f_pos)
+{
+	struct scull_dev *dev = filp->private_data;
+		DEFINE_WAIT(wait);
+		prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);
+			schedule();
+		finish_wait(&dev->outq, &wait);
+
+	return count;
+
+}
+/*
+ * The ioctl() implementation
+ */
+
+int scull_ioctl(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+
+	switch (cmd) {
+		case OSS_GETVERSION:
+			return put_user(SOUND_VERSION, p);
+		case SNDCTL_DSP_GETBLKSIZE:
+			return put_user(GIOVA_BLK, p);
+		case SNDCTL_DSP_GETFMTS:
+			return put_user(28731, p);
+
+		default:
+			return 0;
+	}
+
+}
+
+struct file_operations scull_fops = {
+	.owner =    THIS_MODULE,
+	.llseek =   no_llseek,
+	.read =     scull_read,
+	.write =    scull_write,
+	.ioctl =    scull_ioctl,
+	.open =     scull_c_open,
+	.release =  scull_c_release,
+};
+
+/*
+ * Finally, the module stuff
+ */
+
+/*
+ * The cleanup function is used to handle initialization failures as well.
+ * Thefore, it must be careful to work correctly even if some of the items
+ * have not been initialized
+ */
+
+void scull_cleanup_module(void)
+{
+	int i;
+	int ret;
+	struct scull_listitem *lptr, *next;
+	dev_t devno = MKDEV(scull_major, scull_minor);
+
+	/* Get rid of our char dev entries */
+	if (scull_devices) {
+		for (i = 0; i < scull_nr_devs; i++) {
+			cdev_del(&scull_devices[i].cdev);
+		}
+		kfree(scull_devices);
+	}
+
+
+    	/* And all the cloned devices */
+	list_for_each_entry_safe(lptr, next, &scull_c_list, list) {
+		ret= del_timer( &lptr->device.timer_inq );
+		if (ret) printk("The inq timer was still in use...\n");
+		ret= del_timer( &lptr->device.timer_outq );
+		if (ret) printk("The outq timer was still in use...\n");
+		list_del(&lptr->list);
+		kfree(lptr);
+	}
+		printk("Timer uninstalling\n");
+	/* cleanup_module is never called if registering failed */
+	unregister_chrdev_region(devno, scull_nr_devs);
+
+}
+
+
+/*
+ * Set up the char_dev structure for this device.
+ */
+static void scull_setup_cdev(struct scull_dev *dev, int index)
+{
+	int err, devno = MKDEV(scull_major, scull_minor + index);
+
+	cdev_init(&dev->cdev, &scull_fops);
+	dev->cdev.owner = THIS_MODULE;
+	dev->cdev.ops = &scull_fops;
+	err = cdev_add (&dev->cdev, devno, 1);
+	/* Fail gracefully if need be */
+	if (err)
+		printk(KERN_NOTICE "Error %d adding scull%d", err, index);
+}
+
+
+
+int scull_init_module(void)
+{
+	int result, i;
+	dev_t dev = 0;
+
+	/*
+	 * Get a range of minor numbers to work with, asking for a dynamic
+	 * major unless directed otherwise at load time.
+	 */
+	if (scull_major) {
+		dev = MKDEV(scull_major, scull_minor);
+		result = register_chrdev_region(dev, scull_nr_devs, "dsp");
+	} else {
+		result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,
+				"dsp");
+		scull_major = MAJOR(dev);
+	}
+	if (result < 0) {
+		printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
+		return result;
+	}
+
+	/* 
+	 * allocate the devices -- we can't have them static, as the number
+	 * can be specified at load time
+	 */
+	scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL);
+	if (!scull_devices) {
+		result = -ENOMEM;
+		goto fail;  /* Make this more graceful */
+	}
+	memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));
+
+	/* Initialize each device. */
+	for (i = 0; i < scull_nr_devs; i++) {
+		scull_setup_cdev(&scull_devices[i], i);
+	}
+
+	/* At this point call the init function for any friend device */
+	dev = MKDEV(scull_major, scull_minor + scull_nr_devs);
+	return 0; /* succeed */
+
+fail:
+	scull_cleanup_module();
+	return result;
+}
+
+module_init(scull_init_module);
+module_exit(scull_cleanup_module);
diff --git a/src/mod/endpoints/mod_skypopen/oss/scull.h b/src/mod/endpoints/mod_skypopen/oss/scull.h
new file mode 100644
index 0000000000..e86281bd94
--- /dev/null
+++ b/src/mod/endpoints/mod_skypopen/oss/scull.h
@@ -0,0 +1,64 @@
+/*
+ * scull.h -- definitions for the char module
+ *
+ * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
+ * Copyright (C) 2001 O'Reilly & Associates
+ *
+ * The source code in this file can be freely used, adapted,
+ * and redistributed in source or binary form, so long as an
+ * acknowledgment appears in derived source files.  The citation
+ * should list that the code comes from the book "Linux Device
+ * Drivers" by Alessandro Rubini and Jonathan Corbet, published
+ * by O'Reilly & Associates.   No warranty is attached;
+ * we cannot take responsibility for errors or fitness for use.
+ *
+ * $Id: scull.h,v 1.15 2004/11/04 17:51:18 rubini Exp $
+ */
+
+#ifndef _SCULL_H_
+#define _SCULL_H_
+
+#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
+
+#ifndef SCULL_MAJOR
+#define SCULL_MAJOR 14   /* dynamic major by default */
+#endif
+
+#ifndef SCULL_NR_DEVS
+#define SCULL_NR_DEVS 1    /* scull0 through scull3 */
+#endif
+
+struct scull_dev {
+	struct cdev cdev;	  /* Char device structure		*/
+	wait_queue_head_t inq; /* read and write queues */
+	wait_queue_head_t outq; /* read and write queues */
+	struct timer_list timer_inq;
+	struct timer_list timer_outq;
+	//unsigned long read_howmany;
+	//unsigned long write_howmany;
+	//unsigned long read_sleeped_acc;
+	//unsigned long write_sleeped_acc;
+	//double read_delay; /* how much delay last time */
+	//double write_delay; /* how much delay last time */
+};
+
+
+/*
+ * The different configurable parameters
+ */
+extern int scull_major;     /* main.c */
+extern int scull_nr_devs;
+
+
+/*
+ * Prototypes for shared functions
+ */
+
+ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
+                   loff_t *f_pos);
+ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,
+                    loff_t *f_pos);
+int     scull_ioctl(struct inode *inode, struct file *filp,
+                    unsigned int cmd, unsigned long arg);
+
+#endif /* _SCULL_H_ */
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 74c4c0897e..0e64d54a0a 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -906,7 +906,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
 			tech_pvt->read_frame.flags = SFF_NONE;
 
 			status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame, flags);
-
+			
 			if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
 				if (status == SWITCH_STATUS_TIMEOUT) {
 
@@ -1332,6 +1332,49 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 			}
 		}
 		break;
+	case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER:
+		{
+			if (switch_rtp_ready(tech_pvt->rtp_session)) {
+				int len, maxlen = 0, qlen = 0, maxqlen = 50;
+
+				if (msg->string_arg) {
+					char *p;
+					
+					if ((len = atoi(msg->string_arg))) {
+						qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
+					}
+					
+					if (qlen) {
+						if ((p = strchr(msg->string_arg, ':'))) {
+							p++;
+							maxlen = atol(p);
+						}
+					}
+
+
+					if (maxlen) {
+						maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000);
+					}
+				}
+
+				if (qlen) {
+					if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen,
+														  tech_pvt->read_impl.samples_per_packet, 
+														  tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) {
+						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), 
+										  SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n", len, qlen, maxqlen);
+						switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER);
+					} else {
+						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), 
+										  SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
+					}
+					
+				} else {
+					switch_rtp_deactivate_jitter_buffer(tech_pvt->rtp_session);
+				}
+			}
+		}
+		break;
 	case SWITCH_MESSAGE_INDICATE_DEBUG_AUDIO:
 		{
 			if (switch_rtp_ready(tech_pvt->rtp_session) && !zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) {
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 6970a7ab05..61d165753c 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -225,6 +225,7 @@ typedef enum {
 	PFLAG_DEL_SUBS_ON_REG,
 	PFLAG_IGNORE_183NOSDP,
 	PFLAG_PRESENCE_PROBE_ON_REGISTER,
+	PFLAG_NO_CONNECTION_REUSE,
 	/* No new flags below this line */
 	PFLAG_MAX
 } PFLAGS;
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 2e13b544d0..e34d7aef9d 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -1486,6 +1486,8 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
 							  TAG_IF(profile->timer_t2, NTATAG_SIP_T2(profile->timer_t2)),
 							  TAG_IF(profile->timer_t4, NTATAG_SIP_T4(profile->timer_t4)),
 							  SIPTAG_ACCEPT_STR("application/sdp, multipart/mixed"),
+							  TAG_IF(sofia_test_pflag(profile, PFLAG_NO_CONNECTION_REUSE),
+									TPTAG_REUSE(0)),
 							  TAG_END());	/* Last tag should always finish the sequence */
 	
 	if (!profile->nua) {
@@ -3673,6 +3675,13 @@ switch_status_t config_sofia(int reload, char *profile_name)
 						} else {
 							profile->timer_t4 = 4000;
 						}
+					} else if (!strcasecmp(var, "reuse-connections")) {
+						switch_bool_t value = switch_true(val);
+						if (!value) {
+							sofia_set_pflag(profile, PFLAG_NO_CONNECTION_REUSE);
+						} else {
+							sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE);
+						}
 					}
 				}
 
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 6416778ab0..74f5d3d764 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -3153,18 +3153,37 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
 
 		if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec"))) {
 			int len = atoi(val);
+			int maxlen = 50;
+			char *p;
 
-			if (len < 100 || len > 1000) {
+			if ((p = strchr(val, ':'))) {
+				p++;
+				maxlen = atoi(val);
+			}
+
+			if (len < 20 || len > 10000) {
 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR,
-								  "Invalid Jitterbuffer spec [%d] must be between 100 and 1000\n", len);
+								  "Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", len);
 			} else {
-				int qlen;
-
+				int qlen, maxqlen = 0;
+				
 				qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
 
-				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len,
-								  qlen);
-				switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen);
+				if (maxlen) {
+					maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000);
+				}
+
+				if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen,
+													  tech_pvt->read_impl.samples_per_packet, 
+													  tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) {
+					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), 
+									  SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
+					switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER);
+				} else {
+					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), 
+									  SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
+				}
+				
 			}
 		}
 
diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c
index 143666ceb8..5d666f03ee 100644
--- a/src/mod/endpoints/mod_sofia/sofia_presence.c
+++ b/src/mod/endpoints/mod_sofia/sofia_presence.c
@@ -90,6 +90,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
 	char *user_via = NULL;
 	char *contact_str = NULL;
 	char *dup_dest = NULL;
+	char *remote_host = NULL;
 
 	if (!to) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n");
@@ -185,11 +186,9 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
 	
 		/* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */
 
-		remote_ip = malloc(sizeof(80));
 		dup_dest = strdup(dst->contact);
 
 		if (switch_stristr("fs_path", dst->contact)) {
-			char *remote_host = NULL;
 			const char *s;
 
 			if ((s = switch_stristr("fs_path=", dst->contact))) {
@@ -202,7 +201,6 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
 			if (!zstr(remote_host)) {
 				switch_split_user_domain(remote_host, NULL, &remote_ip);
 			}
-			switch_safe_free(remote_host);
 		}
 
 		if (zstr(remote_ip)) {
@@ -236,7 +234,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
 		}
 
 		switch_safe_free(dup_dest);
-		free(remote_ip);
+		switch_safe_free(remote_host);
 
 		status = SWITCH_STATUS_SUCCESS;
 
diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx
index 8033a8faa5..1ad1b16b9a 100644
--- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx
+++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx
@@ -28290,15 +28290,33 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_rtcp(void * jarg1, int jar
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2) {
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5) {
   int jresult ;
   switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
   uint32_t arg2 ;
+  uint32_t arg3 ;
+  uint32_t arg4 ;
+  uint32_t arg5 ;
   switch_status_t result;
   
   arg1 = (switch_rtp_t *)jarg1; 
   arg2 = (uint32_t)jarg2; 
-  result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2);
+  arg3 = (uint32_t)jarg3; 
+  arg4 = (uint32_t)jarg4; 
+  arg5 = (uint32_t)jarg5; 
+  result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2,arg3,arg4,arg5);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_deactivate_jitter_buffer(void * jarg1) {
+  int jresult ;
+  switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_rtp_t *)jarg1; 
+  result = (switch_status_t)switch_rtp_deactivate_jitter_buffer(arg1);
   jresult = result; 
   return jresult;
 }
diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx
index a65d82d9cb..1d3c5d60ce 100644
--- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx
+++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx
@@ -28993,15 +28993,33 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_rtcp(void * jarg1, int jar
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2) {
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5) {
   int jresult ;
   switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
   uint32_t arg2 ;
+  uint32_t arg3 ;
+  uint32_t arg4 ;
+  uint32_t arg5 ;
   switch_status_t result;
   
   arg1 = (switch_rtp_t *)jarg1; 
   arg2 = (uint32_t)jarg2; 
-  result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2);
+  arg3 = (uint32_t)jarg3; 
+  arg4 = (uint32_t)jarg4; 
+  arg5 = (uint32_t)jarg5; 
+  result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2,arg3,arg4,arg5);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_deactivate_jitter_buffer(void * jarg1) {
+  int jresult ;
+  switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_rtp_t *)jarg1; 
+  result = (switch_status_t)switch_rtp_deactivate_jitter_buffer(arg1);
   jresult = result; 
   return jresult;
 }
diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs
index 4d14f10879..4b9ce71e60 100644
--- a/src/mod/languages/mod_managed/managed/swig.2010.cs
+++ b/src/mod/languages/mod_managed/managed/swig.2010.cs
@@ -4640,8 +4640,13 @@ public class freeswitch {
     return ret;
   }
 
-  public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames) {
-    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames);
+  public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames, uint max_queue_frames, uint samples_per_packet, uint samples_per_second) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames, max_queue_frames, samples_per_packet, samples_per_second);
+    return ret;
+  }
+
+  public static switch_status_t switch_rtp_deactivate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_deactivate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session));
     return ret;
   }
 
@@ -12448,7 +12453,10 @@ class freeswitchPINVOKE {
   public static extern int switch_rtp_activate_rtcp(HandleRef jarg1, int jarg2, ushort jarg3);
 
   [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_activate_jitter_buffer")]
-  public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2);
+  public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_deactivate_jitter_buffer")]
+  public static extern int switch_rtp_deactivate_jitter_buffer(HandleRef jarg1);
 
   [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_flag")]
   public static extern void switch_rtp_set_flag(HandleRef jarg1, uint jarg2);
@@ -21554,6 +21562,7 @@ public enum switch_channel_flag_t {
   CF_PASSTHRU_PTIME_MISMATCH,
   CF_BRIDGE_NOWRITE,
   CF_RECOVERED,
+  CF_JITTERBUFFER,
   CF_FLAG_MAX
 }
 
@@ -23243,6 +23252,7 @@ public enum switch_core_session_message_types_t {
   SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION,
   SWITCH_MESSAGE_INDICATE_UDPTL_MODE,
   SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS,
+  SWITCH_MESSAGE_INDICATE_JITTER_BUFFER,
   SWITCH_MESSAGE_INVALID
 }
 
diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs
index e024c586f8..9decf74045 100644
--- a/src/mod/languages/mod_managed/managed/swig.cs
+++ b/src/mod/languages/mod_managed/managed/swig.cs
@@ -4630,8 +4630,13 @@ public class freeswitch {
     return ret;
   }
 
-  public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames) {
-    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames);
+  public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames, uint max_queue_frames, uint samples_per_packet, uint samples_per_second) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames, max_queue_frames, samples_per_packet, samples_per_second);
+    return ret;
+  }
+
+  public static switch_status_t switch_rtp_deactivate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_deactivate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session));
     return ret;
   }
 
@@ -12434,7 +12439,10 @@ class freeswitchPINVOKE {
   public static extern int switch_rtp_activate_rtcp(HandleRef jarg1, int jarg2, ushort jarg3);
 
   [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_activate_jitter_buffer")]
-  public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2);
+  public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_deactivate_jitter_buffer")]
+  public static extern int switch_rtp_deactivate_jitter_buffer(HandleRef jarg1);
 
   [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_flag")]
   public static extern void switch_rtp_set_flag(HandleRef jarg1, uint jarg2);
@@ -21500,6 +21508,7 @@ public enum switch_channel_flag_t {
   CF_PASSTHRU_PTIME_MISMATCH,
   CF_BRIDGE_NOWRITE,
   CF_RECOVERED,
+  CF_JITTERBUFFER,
   CF_FLAG_MAX
 }
 
@@ -23167,6 +23176,7 @@ public enum switch_core_session_message_types_t {
   SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION,
   SWITCH_MESSAGE_INDICATE_UDPTL_MODE,
   SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS,
+  SWITCH_MESSAGE_INDICATE_JITTER_BUFFER,
   SWITCH_MESSAGE_INVALID
 }
 
diff --git a/src/mod/languages/mod_perl/mod_perl_wrap.cpp b/src/mod/languages/mod_perl/mod_perl_wrap.cpp
index 2efbdf1abc..370c88bc99 100644
--- a/src/mod/languages/mod_perl/mod_perl_wrap.cpp
+++ b/src/mod/languages/mod_perl/mod_perl_wrap.cpp
@@ -9732,17 +9732,17 @@ XS(SWIG_init) {
   SWIG_TypeClientData(SWIGTYPE_p_IVRMenu, (void*) "freeswitch::IVRMenu");
   SWIG_TypeClientData(SWIGTYPE_p_API, (void*) "freeswitch::API");
   SWIG_TypeClientData(SWIGTYPE_p_input_callback_state, (void*) "freeswitch::input_callback_state_t");
-  /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
+  /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
     SV *sv = get_sv((char*) SWIG_prefix "S_HUP", TRUE | 0x2 | GV_ADDMULTI);
     sv_setsv(sv, SWIG_From_int  SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_HUP)));
     SvREADONLY_on(sv);
   } while(0) /*@SWIG@*/;
-  /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
+  /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
     SV *sv = get_sv((char*) SWIG_prefix "S_FREE", TRUE | 0x2 | GV_ADDMULTI);
     sv_setsv(sv, SWIG_From_int  SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_FREE)));
     SvREADONLY_on(sv);
   } while(0) /*@SWIG@*/;
-  /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
+  /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
     SV *sv = get_sv((char*) SWIG_prefix "S_RDLOCK", TRUE | 0x2 | GV_ADDMULTI);
     sv_setsv(sv, SWIG_From_int  SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_RDLOCK)));
     SvREADONLY_on(sv);
diff --git a/src/switch_apr.c b/src/switch_apr.c
index dccc37be96..7c027f8c68 100644
--- a/src/switch_apr.c
+++ b/src/switch_apr.c
@@ -729,6 +729,18 @@ SWITCH_DECLARE(switch_status_t) switch_socket_recv(switch_socket_t *sock, char *
 	return apr_socket_recv(sock, buf, len);
 }
 
+SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool)
+{
+	switch_sockaddr_t *new_sa;
+
+	new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t));
+	switch_assert(new_sa);
+	new_sa->pool = pool;
+	memset(new_sa, 0, sizeof(new_sa));
+	*sa = new_sa;
+	return SWITCH_STATUS_SUCCESS;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t ** sa, const char *hostname, int32_t family,
 														 switch_port_t port, int32_t flags, switch_memory_pool_t *pool)
 {
diff --git a/src/switch_core_io.c b/src/switch_core_io.c
index 6f3e65a9f4..a2df79d1bc 100644
--- a/src/switch_core_io.c
+++ b/src/switch_core_io.c
@@ -235,7 +235,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 
 	if (switch_test_flag(*frame, SFF_CNG)) {
 		status = SWITCH_STATUS_SUCCESS;
-		if (!session->bugs) {
+		if (!session->bugs && !session->plc) {
 			goto done;
 		}
 		is_cng = 1;
@@ -303,7 +303,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 			session->raw_read_frame.datalen = session->raw_read_frame.buflen;
 
 			if (is_cng) {
-				memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet);
+				if (session->plc) {
+					plc_fillin(session->plc, session->raw_read_frame.data, read_frame->codec->implementation->decoded_bytes_per_packet / 2);
+					is_cng = 0;
+					flag &= !SFF_CNG;
+				} else {
+					memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet);
+				}
 				session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet;
 				session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
 				read_frame = &session->raw_read_frame;
@@ -326,6 +332,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 												  session->read_impl.actual_samples_per_second,
 												  session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, 
 												  &read_frame->flags);
+				
+				if (status == SWITCH_STATUS_SUCCESS) {
+					if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && !session->plc) {
+						session->plc = plc_init(NULL);
+					}
+				
+					if (session->plc) {
+						if (switch_test_flag(read_frame, SFF_PLC)) {
+							plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
+							switch_clear_flag(read_frame, SFF_PLC);
+						} else {
+							plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
+						}
+					}
+				}
+
+
 			}
 
 			if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) {
@@ -361,6 +384,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 				session->raw_read_frame.seq = read_frame->seq;
 				session->raw_read_frame.m = read_frame->m;
 				session->raw_read_frame.payload = read_frame->payload;
+				session->raw_read_frame.flags = 0;
+				if (switch_test_flag(read_frame, SFF_PLC)) {
+					session->raw_read_frame.flags |= SFF_PLC;
+				}
 				read_frame = &session->raw_read_frame;
 				break;
 			case SWITCH_STATUS_NOOP:
@@ -383,6 +410,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 				session->raw_read_frame.seq = read_frame->seq;
 				session->raw_read_frame.m = read_frame->m;
 				session->raw_read_frame.payload = read_frame->payload;
+				session->raw_read_frame.flags = 0;
+				if (switch_test_flag(read_frame, SFF_PLC)) {
+					session->raw_read_frame.flags |= SFF_PLC;
+				}
+
 				read_frame = &session->raw_read_frame;
 				status = SWITCH_STATUS_SUCCESS;
 				break;
@@ -462,7 +494,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 				read_frame->datalen = session->read_resampler->to_len * 2;
 				read_frame->rate = session->read_resampler->to_rate;
 				switch_mutex_unlock(session->resample_mutex);
-
 			}
 
 			if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) {
@@ -481,7 +512,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 				}
 			}
 
-
 			if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) {
 				if (perfect) {
 					enc_frame = read_frame;
@@ -810,6 +840,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
 			session->raw_write_frame.ssrc = frame->ssrc;
 			session->raw_write_frame.seq = frame->seq;
 			session->raw_write_frame.payload = frame->payload;
+			session->raw_write_frame.flags = 0;
+			if (switch_test_flag(frame, SFF_PLC)) {
+				session->raw_write_frame.flags |= SFF_PLC;
+			}
+
 			write_frame = &session->raw_write_frame;
 			break;
 		case SWITCH_STATUS_BREAK:
diff --git a/src/switch_core_session.c b/src/switch_core_session.c
index 2567d17712..c2766170a8 100644
--- a/src/switch_core_session.c
+++ b/src/switch_core_session.c
@@ -1118,6 +1118,11 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t *
 	}
 	switch_mutex_unlock(runtime.session_hash_mutex);
 
+	if ((*session)->plc) {
+		plc_free((*session)->plc);
+		(*session)->plc = NULL;
+	}
+
 	if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DESTROY) == SWITCH_STATUS_SUCCESS) {
 		switch_channel_event_set_data((*session)->channel, event);
 		switch_event_fire(&event);
diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c
index 4364ff2844..b561ebe775 100644
--- a/src/switch_core_sqldb.c
+++ b/src/switch_core_sqldb.c
@@ -1624,6 +1624,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
 			runtime.odbc_dsn = NULL;
 			runtime.odbc_user = NULL;
 			runtime.odbc_pass = NULL;
+			runtime.odbc_dbtype = DBTYPE_DEFAULT;
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Falling back to core_db.\n");
 			goto top;
 		}
diff --git a/src/switch_ivr.c b/src/switch_ivr.c
index 46ba4e6659..6e2aeaf637 100644
--- a/src/switch_ivr.c
+++ b/src/switch_ivr.c
@@ -2290,7 +2290,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3
 
 	qlen = delay_ms / (interval);
 	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen);
-	jb = stfu_n_init(qlen, 0);
+	jb = stfu_n_init(qlen, qlen, read_impl.samples_per_packet, read_impl.samples_per_second);
 
 	write_frame.codec = switch_core_session_get_read_codec(session);
 
@@ -2300,7 +2300,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3
 			break;
 		}
 
-		stfu_n_eat(jb, ts, read_frame->payload, read_frame->data, read_frame->datalen);
+		stfu_n_eat(jb, ts, 0, read_frame->payload, read_frame->data, read_frame->datalen);
 		ts += interval;
 
 		if ((jb_frame = stfu_n_read_a_frame(jb))) {
diff --git a/src/switch_rtp.c b/src/switch_rtp.c
index ee1c4acf5e..772c2508a0 100644
--- a/src/switch_rtp.c
+++ b/src/switch_rtp.c
@@ -1367,9 +1367,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
 	switch_rtp_set_flag(rtp_session, flags);
 
 	/* for from address on recvfrom calls */
-	switch_sockaddr_info_get(&rtp_session->from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
+	switch_sockaddr_create(&rtp_session->from_addr, pool);
+
 	if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
-		switch_sockaddr_info_get(&rtp_session->rtcp_from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
+		switch_sockaddr_create(&rtp_session->rtcp_from_addr, pool);
 	}
 	rtp_session->seq = (uint16_t) rand();
 	rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL));
@@ -1618,12 +1619,65 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_stun_ping(switch_rtp_t *rtp_
 	return SWITCH_STATUS_SUCCESS;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames)
+static void jb_callback(stfu_instance_t *i, void *udata)
+{
+	switch_core_session_t *session = (switch_core_session_t *) udata;
+	stfu_report_t r = { 0 };
+
+	stfu_n_report(i, &r);
+
+	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, 
+					  "%s JB REPORT:\nlen: %u\nin: %u\nclean: %u\ngood: %u\nbad: %u\n",
+					  switch_core_session_get_name(session),
+					  r.qlen,
+					  r.packet_in_count,
+					  r.clean_count,
+					  r.consecutive_good_count,
+					  r.consecutive_bad_count
+					  );
+
+}
+
+SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session)
+{
+	
+	if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	READ_INC(rtp_session);
+	stfu_n_destroy(&rtp_session->jb);
+	READ_DEC(rtp_session);
+	
+	return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, 
+																  uint32_t queue_frames, 
+																  uint32_t max_queue_frames, 
+																  uint32_t samples_per_packet, 
+																  uint32_t samples_per_second)
 {
 
-	rtp_session->jb = stfu_n_init(queue_frames, 0);
+	if (!switch_rtp_ready(rtp_session)) {
+		return SWITCH_STATUS_FALSE;
+	}
 
-	return SWITCH_STATUS_SUCCESS;
+	READ_INC(rtp_session);
+	if (rtp_session->jb) {
+		stfu_n_resize(rtp_session->jb, queue_frames);
+	} else {
+		rtp_session->jb = stfu_n_init(queue_frames, max_queue_frames || 50, samples_per_packet, samples_per_second);
+	}
+	READ_DEC(rtp_session);
+	
+	if (rtp_session->jb) {
+		switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
+		stfu_n_call_me(rtp_session->jb, jb_callback, session);
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	return SWITCH_STATUS_FALSE;
 }
 
 SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port)
@@ -2016,14 +2070,18 @@ static void do_flush(switch_rtp_t *rtp_session)
 	switch_size_t bytes;
 	switch_status_t status;
 
-	if (!switch_rtp_ready(rtp_session) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) {
+	if (!switch_rtp_ready(rtp_session) || 
+		switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) || 
+		switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) 
+		) {
 		return;
 	}
 
 	READ_INC(rtp_session);
 
 	if (switch_rtp_ready(rtp_session)) {
-
+		uint32_t flushed = 0;
+		
 		if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_DEBUG_RTP_READ)) {
 			switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
 			if (!session) {
@@ -2047,6 +2105,16 @@ static void do_flush(switch_rtp_t *rtp_session)
 				bytes = sizeof(rtp_msg_t);
 				status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes);
 				if (bytes) {
+
+					flushed++;
+
+					if (rtp_session->jb) {
+						stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), 
+								   ntohs((uint16_t) rtp_session->recv_msg.header.seq),
+								   rtp_session->recv_msg.header.pt,
+								   rtp_session->recv_msg.body, bytes - rtp_header_len);
+					}
+
 					rtp_session->stats.inbound.raw_bytes += bytes;
 					rtp_session->stats.inbound.flush_packet_count++;
 					rtp_session->stats.inbound.packet_count++;
@@ -2056,6 +2124,10 @@ static void do_flush(switch_rtp_t *rtp_session)
 			}
 		} while (bytes > 0);
 
+		if (rtp_session->jb && flushed) {
+			stfu_n_sync(rtp_session->jb, flushed);
+		}
+
 		if (was_blocking && switch_rtp_ready(rtp_session)) {
 			switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
 			switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, FALSE);
@@ -2104,7 +2176,9 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
 			stfu_n_reset(rtp_session->jb);
 		}
 
-		stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), rtp_session->recv_msg.header.pt,
+		stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), 
+				   ntohs((uint16_t) rtp_session->recv_msg.header.seq),
+				   rtp_session->recv_msg.header.pt,
 				   rtp_session->recv_msg.body, *bytes - rtp_header_len);
 		*bytes = 0;
 		status = SWITCH_STATUS_FALSE;
@@ -2114,14 +2188,14 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
 		if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) {
 			memcpy(rtp_session->recv_msg.body, jb_frame->data, jb_frame->dlen);
 			if (jb_frame->plc) {
-				*flags |= SFF_PLC;
+				(*flags) |= SFF_PLC;
 			} else {
 				rtp_session->stats.inbound.jb_packet_count++;
 			}
 			*bytes = jb_frame->dlen + rtp_header_len;
 			rtp_session->recv_msg.header.ts = htonl(jb_frame->ts);
 			rtp_session->recv_msg.header.pt = jb_frame->pt;
-
+			rtp_session->recv_msg.header.seq = htons((uint16_t)jb_frame->seq);
 			status = SWITCH_STATUS_SUCCESS;
 		}
 	}
@@ -2824,7 +2898,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
 			if ((poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, 0)) == SWITCH_STATUS_SUCCESS) {
 				goto recvfrom;
 			}
-
+			
 			memset(data, 0, 2);
 			data[0] = 65;
 			rtp_session->recv_msg.header.pt = (uint32_t) rtp_session->cng_pt ? rtp_session->cng_pt : SWITCH_RTP_CNG_PAYLOAD;
@@ -3053,6 +3127,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
 	frame->packet = &rtp_session->recv_msg;
 	frame->packetlen = bytes;
 	frame->source = __FILE__;
+
 	switch_set_flag(frame, SFF_RAW_RTP);
 	if (frame->payload == rtp_session->recv_te) {
 		switch_set_flag(frame, SFF_RFC2833);
diff --git a/w32/Console/FreeSwitchConsole.2008.vcproj b/w32/Console/FreeSwitchConsole.2008.vcproj
index 80f062abe0..7fc1784d14 100644
--- a/w32/Console/FreeSwitchConsole.2008.vcproj
+++ b/w32/Console/FreeSwitchConsole.2008.vcproj
@@ -46,7 +46,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\libs\include&quot;"
+				AdditionalIncludeDirectories="&quot;$(InputDir)include&quot;;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;&quot;$(InputDir)..\libs\include&quot;"
 				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
@@ -128,7 +128,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\libs\include&quot;"
+				AdditionalIncludeDirectories="&quot;$(InputDir)include&quot;;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;&quot;$(InputDir)..\libs\include&quot;"
 				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
@@ -208,7 +208,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\libs\include&quot;"
+				AdditionalIncludeDirectories="&quot;$(InputDir)include&quot;;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;&quot;$(InputDir)..\libs\include&quot;"
 				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
 				RuntimeLibrary="2"
 				UsePrecompiledHeader="0"
@@ -288,7 +288,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\libs\include&quot;"
+				AdditionalIncludeDirectories="&quot;$(InputDir)include&quot;;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;&quot;$(InputDir)..\libs\include&quot;"
 				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
 				RuntimeLibrary="2"
 				UsePrecompiledHeader="0"
diff --git a/w32/Console/FreeSwitchConsole.2010.vcxproj b/w32/Console/FreeSwitchConsole.2010.vcxproj
index 488abc8b6f..b9c47e79bf 100644
--- a/w32/Console/FreeSwitchConsole.2010.vcxproj
+++ b/w32/Console/FreeSwitchConsole.2010.vcxproj
@@ -80,7 +80,7 @@
     <BuildLog />
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>%(RootDir)%(Directory)include;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>%(RootDir)%(Directory)include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -109,7 +109,7 @@
     </Midl>
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>%(RootDir)%(Directory)include;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>%(RootDir)%(Directory)include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -134,7 +134,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <BuildLog />
     <ClCompile>
-      <AdditionalIncludeDirectories>%(RootDir)%(Directory)include;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>%(RootDir)%(Directory)include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <PrecompiledHeader>
@@ -161,7 +161,7 @@
       <TargetEnvironment>X64</TargetEnvironment>
     </Midl>
     <ClCompile>
-      <AdditionalIncludeDirectories>%(RootDir)%(Directory)include;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>%(RootDir)%(Directory)include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <PrecompiledHeader>
diff --git a/w32/Library/FreeSwitchCore.2008.vcproj b/w32/Library/FreeSwitchCore.2008.vcproj
index ca15da8b52..6ba5b95959 100644
--- a/w32/Library/FreeSwitchCore.2008.vcproj
+++ b/w32/Library/FreeSwitchCore.2008.vcproj
@@ -47,7 +47,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include"
+				AdditionalIncludeDirectories="..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
@@ -141,7 +141,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include"
+				AdditionalIncludeDirectories="..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
@@ -234,7 +234,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include"
+				AdditionalIncludeDirectories="..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC"
 				RuntimeLibrary="2"
 				UsePrecompiledHeader="2"
@@ -324,7 +324,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include"
+				AdditionalIncludeDirectories="..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC"
 				RuntimeLibrary="2"
 				UsePrecompiledHeader="2"
diff --git a/w32/Library/FreeSwitchCore.2010.vcxproj b/w32/Library/FreeSwitchCore.2010.vcxproj
index 2595793d1f..e218445a02 100644
--- a/w32/Library/FreeSwitchCore.2010.vcxproj
+++ b/w32/Library/FreeSwitchCore.2010.vcxproj
@@ -88,7 +88,7 @@
     </PreBuildEvent>
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -147,7 +147,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs
     </Midl>
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -199,7 +199,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs
     </PreBuildEvent>
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <PrecompiledHeader>Use</PrecompiledHeader>
@@ -248,7 +248,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs
     </Midl>
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <PrecompiledHeader>Use</PrecompiledHeader>
@@ -766,6 +766,9 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs
       <Project>{89385c74-5860-4174-9caf-a39e7c48909c}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\..\libs\spandsp\src\libspandsp.2010.vcxproj">
+      <Project>{1cbb0077-18c5-455f-801c-0a0ce7b0bbf5}</Project>
+    </ProjectReference>
     <ProjectReference Include="..\..\libs\speex\win32\VS2008\libspeexdsp\libspeexdsp.vcxproj">
       <Project>{03207781-0d1c-4db3-a71d-45c608f28dbd}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>