From b2a3bbff9bf470d4376680535150ee8cede158ff Mon Sep 17 00:00:00 2001
From: Brian West <brian@freeswitch.org>
Date: Mon, 13 Dec 2010 10:30:00 -0600
Subject: [PATCH 01/20]  Fix samples for playback

---
 src/switch_ivr_play_say.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c
index 3c8fa5e10f..d8d18f38a4 100644
--- a/src/switch_ivr_play_say.c
+++ b/src/switch_ivr_play_say.c
@@ -1573,10 +1573,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done playing file\n");
 
 		if (read_impl.samples_per_second) {
-			switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_out / read_impl.samples_per_second);
-			switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_out / (read_impl.samples_per_second / 1000));
+			switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_in / read_impl.samples_per_second);
+			switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_in / (read_impl.samples_per_second / 1000));
 		}
-		switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_out);
+		switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_in);
 
 		switch_core_session_io_write_lock(session);
 		switch_channel_set_private(channel, "__fh", NULL);

From 3a645dee60b50ee188cb3b0a34866c728003059e Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 13 Dec 2010 09:36:45 -0600
Subject: [PATCH 02/20] FS-2913

---
 src/mod/endpoints/mod_sofia/sofia_glue.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 74f5d3d764..65aedd3431 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -5060,9 +5060,20 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
 		const char *port = switch_channel_get_variable(channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
 		const char *r_ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE);
 		const char *r_port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE);
+		const char *use_uuid;
 
 		sofia_set_flag(tech_pvt, TFLAG_RECOVERING);
 
+		if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) {
+			if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) {
+				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel),
+								  use_uuid);
+			} else {
+				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
+								  switch_channel_get_name(channel), use_uuid);
+			}
+		}
+
 		if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && ip && port) {
 			const char *tmp;
 			tech_pvt->iananame = tech_pvt->rm_encoding = (char *) switch_channel_get_variable(channel, "sip_use_codec_name");

From dfecc914876b164ce64c53c4f048aa38ed65d9c5 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 13 Dec 2010 11:20:12 -0600
Subject: [PATCH 03/20] remove check for va_list completely in sofia since i
 don't event think it happens ever

---
 src/mod/endpoints/mod_sofia/sofia.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index e34d7aef9d..591cd7f4aa 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -1717,16 +1717,9 @@ void launch_sofia_profile_thread(sofia_profile_t *profile)
 
 static void logger(void *logarg, char const *fmt, va_list ap)
 {
-	/* gcc 4.4 gets mad at us for testing if (ap) so let's try to work around it....*/
-	void *ap_ptr = (void *) (intptr_t) ap;
-	
 	if (!fmt) return;
 
-	if (ap_ptr) {
-		switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap);
-	} else {
-		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, "%s", fmt);
-	}
+	switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap);
 }
 
 static su_log_t *sofia_get_logger(const char *name)

From cb2d073632211b8459ca29aba4785c875bbfc8ec Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 13 Dec 2010 11:50:06 -0600
Subject: [PATCH 04/20] FS-2924

---
 src/switch_apr.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/switch_apr.c b/src/switch_apr.c
index 7c027f8c68..7a6bfc75d9 100644
--- a/src/switch_apr.c
+++ b/src/switch_apr.c
@@ -732,11 +732,21 @@ SWITCH_DECLARE(switch_status_t) switch_socket_recv(switch_socket_t *sock, char *
 SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool)
 {
 	switch_sockaddr_t *new_sa;
+	int family = APR_INET;
 
 	new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t));
 	switch_assert(new_sa);
 	new_sa->pool = pool;
 	memset(new_sa, 0, sizeof(new_sa));
+
+    new_sa->family = family;
+    new_sa->sa.sin.sin_family = family;
+
+    new_sa->salen = sizeof(struct sockaddr_in);
+    new_sa->addr_str_len = 16;
+    new_sa->ipaddr_ptr = &(new_sa->sa.sin.sin_addr);
+    new_sa->ipaddr_len = sizeof(struct in_addr);
+
 	*sa = new_sa;
 	return SWITCH_STATUS_SUCCESS;
 }

From 84c7fa2fbc43fadd37f406dc7cd6f20db1221386 Mon Sep 17 00:00:00 2001
From: Jeff Lenk <jeff@jefflenk.com>
Date: Mon, 13 Dec 2010 13:42:38 -0600
Subject: [PATCH 05/20] my bad fix warning

---
 src/switch_apr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/switch_apr.c b/src/switch_apr.c
index 7a6bfc75d9..c0e51f9766 100644
--- a/src/switch_apr.c
+++ b/src/switch_apr.c
@@ -732,7 +732,7 @@ SWITCH_DECLARE(switch_status_t) switch_socket_recv(switch_socket_t *sock, char *
 SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool)
 {
 	switch_sockaddr_t *new_sa;
-	int family = APR_INET;
+	unsigned short family = APR_INET;
 
 	new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t));
 	switch_assert(new_sa);

From 321013efe74037a098e261bf805a426c27b75dbf Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 13 Dec 2010 14:01:53 -0600
Subject: [PATCH 06/20] have mod_sofia always elect to be the session refresher
 so we know it will work, also make the session-expires set to 0 imply 100%
 disabled session timers

---
 src/mod/endpoints/mod_sofia/mod_sofia.c  | 4 ++--
 src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 0e64d54a0a..d4f8b1b45a 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -723,7 +723,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
 						TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
 						TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
 						NUTAG_SESSION_TIMER(session_timeout),
-						TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
+						NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
 						SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
 						SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
 						SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
@@ -739,7 +739,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
 						TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
 						TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
 						NUTAG_SESSION_TIMER(session_timeout),
-						TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
+						NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
 						SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
 						SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
 						SIPTAG_CONTENT_TYPE_STR("application/sdp"),
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 65aedd3431..3d56b6d9a1 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -2342,7 +2342,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
 		nua_invite(tech_pvt->nh,
 				   NUTAG_AUTOANSWER(0),
 				   NUTAG_SESSION_TIMER(session_timeout),
-				   TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
+				   NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
 				   TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
 				   TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
 				   TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),

From cfeae1ba99b9c6a545a9c7608eca4b7ba1f22192 Mon Sep 17 00:00:00 2001
From: Michael S Collins <msc@freeswitch.org>
Date: Mon, 13 Dec 2010 14:57:43 -0800
Subject: [PATCH 07/20] Bump Doxygen.conf version to 1.0.6... belatedly

---
 docs/Doxygen.conf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/Doxygen.conf b/docs/Doxygen.conf
index ccdb3b8a47..2c06417833 100644
--- a/docs/Doxygen.conf
+++ b/docs/Doxygen.conf
@@ -31,7 +31,7 @@ PROJECT_NAME           = FreeSWITCH
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 1.0.4
+PROJECT_NUMBER         = 1.0.6
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
 # base path where the generated documentation will be put.

From 28cab5ed46a140b70d92ea27214f445dfbd26467 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 13 Dec 2010 17:59:32 -0600
Subject: [PATCH 08/20] FS-2923

---
 src/switch_ivr_play_say.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c
index d8d18f38a4..710c0a738c 100644
--- a/src/switch_ivr_play_say.c
+++ b/src/switch_ivr_play_say.c
@@ -1761,6 +1761,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
 
 	switch_assert(session);
 
+	if (!digit_timeout) {
+		digit_timeout = timeout;
+	}
+
 	if (max_digits < min_digits) {
 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
 						  "Max digits %u is less than Min %u, forcing Max to %u\n", max_digits, min_digits, min_digits);

From 2e51b571b08d6573936ee787088a72df64d37f65 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 13 Dec 2010 18:00:10 -0600
Subject: [PATCH 09/20] update

---
 libs/stfu/stfu.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c
index fce968c990..c0d4a96ee5 100644
--- a/libs/stfu/stfu.c
+++ b/libs/stfu/stfu.c
@@ -27,7 +27,7 @@
  */
 #include "stfu.h"
 
-//#define DB_JB 1
+#define DB_JB 1
 #ifdef _MSC_VER
 /* warning C4706: assignment within conditional expression*/
 #pragma warning(disable: 4706)
@@ -305,11 +305,11 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin
         }
     }
  
-    if (seq && seq == i->last_seq + 1) {
+    if ((seq && seq == i->last_seq + 1) || (i->last_seq > 65500 && seq == 0)) {
         good_seq = 1;
     }
 
-    if (ts && ts == i->last_rd_ts + i->samples_per_packet) {
+    if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000 && ts < 5000)) {
         good_ts = 1;
     }
 
@@ -450,7 +450,7 @@ static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t
     for(i = 0; i < queue->real_array_size; i++) {
         frame = &queue->array[i];
         
-        if ((seq && frame->seq == seq) || frame->ts == ts) {
+        if (((seq || in->last_seq) && frame->seq == seq) || frame->ts == ts) {
             *r_frame = frame;
             queue->last_index = i;
             frame->was_read = 1;
@@ -547,7 +547,6 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
 #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);
     }
@@ -579,6 +578,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
         rframe = &i->out_queue->int_frame;
         rframe->dlen = i->plc_len;
         
+#if 0
         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 */
             if (i->miss_count) {
@@ -587,7 +587,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
                 memcpy(rframe->data, i->last_frame->data, rframe->dlen);
             }
         }
-
+#endif
         rframe->ts = i->cur_ts;
 
         i->miss_count++;

From 0ca7930fa3270bd71e5781539afa7af8b9c975a4 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 13 Dec 2010 18:14:39 -0600
Subject: [PATCH 10/20] small tweak to new plc code

---
 src/switch_core_io.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/src/switch_core_io.c b/src/switch_core_io.c
index a2df79d1bc..c3113e9680 100644
--- a/src/switch_core_io.c
+++ b/src/switch_core_io.c
@@ -325,13 +325,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 					switch_thread_rwlock_unlock(session->bug_rwlock);
 				}
 
-				status = switch_core_codec_decode(use_codec,
-												  session->read_codec,
-												  read_frame->data,
-												  read_frame->datalen,
-												  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 (switch_test_flag(read_frame, SFF_PLC)) {
+					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);
+					memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen);
+					status = SWITCH_STATUS_SUCCESS;
+				} else {
+					status = switch_core_codec_decode(use_codec,
+													  session->read_codec,
+													  read_frame->data,
+													  read_frame->datalen,
+													  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) {

From 7f8ba794c9d60d560968f8f61680d2fffd6c1b31 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 13 Dec 2010 18:17:11 -0600
Subject: [PATCH 11/20] doh

---
 libs/stfu/stfu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c
index c0d4a96ee5..12713201a0 100644
--- a/libs/stfu/stfu.c
+++ b/libs/stfu/stfu.c
@@ -27,7 +27,7 @@
  */
 #include "stfu.h"
 
-#define DB_JB 1
+//#define DB_JB 1
 #ifdef _MSC_VER
 /* warning C4706: assignment within conditional expression*/
 #pragma warning(disable: 4706)

From d11c83b16e79f20d00082633d03c68fd0c6c0930 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 13 Dec 2010 18:28:43 -0600
Subject: [PATCH 12/20] revert to the last transfered conference on recover

---
 src/mod/applications/mod_conference/mod_conference.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index 4cbb052994..9b170a32e0 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -4366,6 +4366,8 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc
 				}
 			}
 
+			switch_channel_set_variable(channel, "last_transfered_conference", argv[2]);
+
 			unlock_member(member);
 
 			stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]);
@@ -5374,6 +5376,14 @@ SWITCH_STANDARD_APP(conference_function)
 	}
 #endif
 
+	if (switch_channel_test_flag(channel, CF_RECOVERED)) {
+		const char *check = switch_channel_get_variable(channel, "last_transfered_conference");
+		
+		if (!zstr(check)) {
+			conf_name = (char *) check;
+		}
+	}
+
 	switch_event_create(&params, SWITCH_EVENT_COMMAND);
 	switch_assert(params);
 	switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conf_name", conf_name);

From 7e047c3fd12cf3d6a4fae02021ea561512041d8f Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Tue, 14 Dec 2010 00:15:36 -0600
Subject: [PATCH 13/20] more ongoing work on jb

---
 libs/stfu/stfu.c                         | 73 ++++++++++++++++++------
 src/mod/endpoints/mod_sofia/sofia_glue.c |  6 +-
 src/switch_rtp.c                         |  2 +-
 3 files changed, 59 insertions(+), 22 deletions(-)

diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c
index 12713201a0..547c337278 100644
--- a/libs/stfu/stfu.c
+++ b/libs/stfu/stfu.c
@@ -28,6 +28,11 @@
 #include "stfu.h"
 
 //#define DB_JB 1
+
+#ifndef UINT_MAX
+#  define UINT_MAX        4294967295U
+#endif
+
 #ifdef _MSC_VER
 /* warning C4706: assignment within conditional expression*/
 #pragma warning(disable: 4706)
@@ -123,6 +128,7 @@ static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen)
 
 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);	
@@ -166,6 +172,7 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen)
     stfu_status_t s;
 
     if (i->qlen == i->max_qlen) {
+        printf("FUCKER1\n");
         return STFU_IT_FAILED;
     }
     
@@ -173,6 +180,7 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen)
         if (i->qlen < i->max_qlen) {
             qlen = i->max_qlen;
         } else {
+            printf("FUCKER2\n");
             return STFU_IT_FAILED;
         }
     }
@@ -196,6 +204,12 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_
 		return NULL;
 	}
 	memset(i, 0, sizeof(*i));
+
+
+#ifdef DB_JB
+    printf("INIT %u %u\n", qlen, max_qlen);
+#endif
+
     i->qlen = qlen;
     i->max_qlen = max_qlen;
     i->orig_qlen = qlen;
@@ -281,10 +295,11 @@ stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets)
 
 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;
+	uint32_t index = 0;
 	stfu_frame_t *frame;
 	size_t cplen = 0;
     int good_seq = 0, good_ts = 0;
+    uint32_t min_seq = UINT_MAX, min_ts = UINT_MAX, min_index = 0;
 
     if (!i->samples_per_packet && ts && i->last_rd_ts) {
         i->ts_diff = ts - i->last_rd_ts;
@@ -322,21 +337,20 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin
     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) {
+#ifdef DB_JB
+        printf("resize %u %u\n", i->qlen, i->qlen + 1);
+#endif
         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);
+    } else {
+        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)) {
@@ -379,13 +393,31 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin
 		return STFU_IM_DONE;
 	}
 
-    for(index = 0; index < i->out_queue->array_size; index++) {
+    for(index = 0; index < i->in_queue->array_size; index++) {
+
         if (i->in_queue->array[index].was_read) {
+            min_index = index;
             break;
         }
+        
+        if (i->in_queue->array[index].seq < min_seq) {
+            min_seq = i->in_queue->array[index].seq;
+            min_index = index;
+        }
+
+        if (i->in_queue->array[index].ts < min_ts) {
+            min_ts = i->in_queue->array[index].ts;
+            min_index = index;
+        }
     }
 
-    index = i->in_queue->array_len++;
+    index = min_index;
+    
+    if (i->in_queue->array_len < i->in_queue->array_size) {
+        i->in_queue->array_len++;
+    }
+
+    assert(index < i->in_queue->array_size);
 
 	frame = &i->in_queue->array[index];
 
@@ -468,7 +500,8 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
 	stfu_frame_t *rframe = NULL;
     int found = 0;
 
-	if (!i->samples_per_packet || ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
+	if (!i->samples_per_packet || !i->out_queue->array_len) {
+        //|| ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
 		return NULL;
 	}
 
@@ -481,7 +514,11 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
     if (i->cur_seq == 0) {
         i->cur_seq = i->out_queue->array[0].seq;
     } else {
-        i->cur_seq++;
+        i->cur_seq++; 
+        /* if we bother using this for anything that doesn't have 16 bit seq, we'll make this a param */
+        if (i->cur_seq == 65535) {
+            i->cur_seq = 0;
+        }
     }
 
     if (!(found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, i->cur_seq, &rframe))) {
@@ -496,7 +533,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
             i->cur_seq = rframe->seq;
             i->cur_ts = rframe->ts;
         }
-        i->sync--;
+        i->sync = 0;
     }
 
 
@@ -546,7 +583,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
 
 #ifdef DB_JB
     if (found) {
-        printf("O: %u:%u %u\n", rframe->seq, rframe->seq, rframe->plc);
+        printf("O: %u:%u %u %d\n", rframe->seq, rframe->ts, rframe->plc, rframe->seq - i->last_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);
     }
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 3d56b6d9a1..803059a8da 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -3153,19 +3153,19 @@ 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;
+			int maxlen = 0;
 			char *p;
 
 			if ((p = strchr(val, ':'))) {
 				p++;
-				maxlen = atoi(val);
+				maxlen = atoi(p);
 			}
 
 			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 20 and 10000\n", len);
 			} else {
-				int qlen, maxqlen = 0;
+				int qlen, maxqlen = 50;
 				
 				qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
 
diff --git a/src/switch_rtp.c b/src/switch_rtp.c
index 772c2508a0..b4f60fcd55 100644
--- a/src/switch_rtp.c
+++ b/src/switch_rtp.c
@@ -1667,7 +1667,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
 	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);
+		rtp_session->jb = stfu_n_init(queue_frames, max_queue_frames ? max_queue_frames : 50, samples_per_packet, samples_per_second);
 	}
 	READ_DEC(rtp_session);
 	

From 0e83cbe5cae49a326ce687d1079471dd072b915b Mon Sep 17 00:00:00 2001
From: Giovanni Maruzzelli <gmaruzz@gmail.com>
Date: Sun, 12 Dec 2010 13:39:03 -0600
Subject: [PATCH 14/20] skypopen: slightly improve OSS audio driver

---
 src/mod/endpoints/mod_skypopen/oss/main.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c
index 4d36ac00d5..17cc5e33ed 100644
--- a/src/mod/endpoints/mod_skypopen/oss/main.c
+++ b/src/mod/endpoints/mod_skypopen/oss/main.c
@@ -60,8 +60,8 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 static struct scull_dev *scull_devices;	/* allocated in scull_init_module */
 
-#define GIOVA_BLK 3840
-#define GIOVA_SLEEP 40000
+#define GIOVA_BLK 1920
+#define GIOVA_SLEEP 20000
 
 void my_timer_callback_inq( unsigned long data )
 {
@@ -130,11 +130,11 @@ 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);
+	if (!current->tgid) { 
+		printk("Process \"%s\" has no tgid\n", current->comm);
 		return -EINVAL;
 	}
-	key = current->pid;
+	key = current->tgid;
 
 	/* look for a scullc device in the list */
 	spin_lock(&scull_c_lock);
@@ -174,6 +174,8 @@ ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
 		prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
 			schedule();
 		finish_wait(&dev->inq, &wait);
+		//memset(buf, 255, count);
+
 	return count;
 
 }

From 6e310ef8fc0d5b7e00460b7603f6b5854aa61db1 Mon Sep 17 00:00:00 2001
From: Giovanni Maruzzelli <gmaruzz@gmail.com>
Date: Mon, 13 Dec 2010 07:33:37 -0600
Subject: [PATCH 15/20] skypopen: slightly improve OSS audio driver

---
 src/mod/endpoints/mod_skypopen/oss/main.c | 34 +++++++++++------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c
index 17cc5e33ed..c1228d63f1 100644
--- a/src/mod/endpoints/mod_skypopen/oss/main.c
+++ b/src/mod/endpoints/mod_skypopen/oss/main.c
@@ -61,14 +61,14 @@ MODULE_LICENSE("Dual BSD/GPL");
 static struct scull_dev *scull_devices;	/* allocated in scull_init_module */
 
 #define GIOVA_BLK 1920
-#define GIOVA_SLEEP 20000
+#define GIOVA_SLEEP 20
 
 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) );
+	mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
 
 }
 
@@ -77,7 +77,7 @@ 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) );
+	mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
 }
 
 /* The clone-specific data structure includes a key field */
@@ -117,9 +117,9 @@ static struct scull_dev *scull_c_lookfor_device(dev_t key)
 	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) );
+	printk( "Starting timer to fire in %dms (%ld)\n", GIOVA_SLEEP, jiffies );
+	mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
+	mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
 	/* place it in the list */
 	list_add(&lptr->list, &scull_c_list);
 
@@ -170,11 +170,11 @@ ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
 {
 	struct scull_dev *dev = filp->private_data;
 
-		DEFINE_WAIT(wait);
-		prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
-			schedule();
-		finish_wait(&dev->inq, &wait);
-		//memset(buf, 255, count);
+	DEFINE_WAIT(wait);
+	prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
+	schedule();
+	finish_wait(&dev->inq, &wait);
+	//memset(buf, 255, count);
 
 	return count;
 
@@ -184,10 +184,10 @@ 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);
+	DEFINE_WAIT(wait);
+	prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);
+	schedule();
+	finish_wait(&dev->outq, &wait);
 
 	return count;
 
@@ -252,7 +252,7 @@ void scull_cleanup_module(void)
 	}
 
 
-    	/* And all the cloned 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");
@@ -261,7 +261,7 @@ void scull_cleanup_module(void)
 		list_del(&lptr->list);
 		kfree(lptr);
 	}
-		printk("Timer uninstalling\n");
+	printk("Timer uninstalling\n");
 	/* cleanup_module is never called if registering failed */
 	unregister_chrdev_region(devno, scull_nr_devs);
 

From 7997d24f33eaab50ed1e9068f8326e6e0dd706cf Mon Sep 17 00:00:00 2001
From: Giovanni Maruzzelli <gmaruzz@gmail.com>
Date: Tue, 14 Dec 2010 06:45:43 -0600
Subject: [PATCH 16/20] skypopen: tweaking the OSS audio driver

---
 src/mod/endpoints/mod_skypopen/oss/main.c  | 29 ++++++++++++++--------
 src/mod/endpoints/mod_skypopen/oss/scull.h |  2 ++
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c
index c1228d63f1..925441b254 100644
--- a/src/mod/endpoints/mod_skypopen/oss/main.c
+++ b/src/mod/endpoints/mod_skypopen/oss/main.c
@@ -67,6 +67,7 @@ void my_timer_callback_inq( unsigned long data )
 {
 	struct scull_dev *dev = (void *)data;
 
+	dev->readable=1;
 	wake_up_interruptible(&dev->inq);
 	mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
 
@@ -76,6 +77,7 @@ void my_timer_callback_outq( unsigned long data )
 {
 	struct scull_dev *dev = (void *)data;
 
+	dev->writable=1;
 	wake_up_interruptible(&dev->outq);
 	mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
 }
@@ -130,11 +132,11 @@ static int scull_c_open(struct inode *inode, struct file *filp)
 	struct scull_dev *dev;
 	dev_t key;
 
-	if (!current->tgid) { 
-		printk("Process \"%s\" has no tgid\n", current->comm);
+	if (!current->pid) { 
+		printk("Process \"%s\" has no pid\n", current->comm);
 		return -EINVAL;
 	}
-	key = current->tgid;
+	key = current->pid;
 
 	/* look for a scullc device in the list */
 	spin_lock(&scull_c_lock);
@@ -170,12 +172,14 @@ ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
 {
 	struct scull_dev *dev = filp->private_data;
 
-	DEFINE_WAIT(wait);
-	prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
-	schedule();
-	finish_wait(&dev->inq, &wait);
+	//DEFINE_WAIT(wait);
+	//prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
+	//schedule();
+	//finish_wait(&dev->inq, &wait);
 	//memset(buf, 255, count);
 
+	wait_event_interruptible(dev->inq, dev->readable);
+	dev->readable=0;
 	return count;
 
 }
@@ -184,10 +188,13 @@ 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);
+	//DEFINE_WAIT(wait);
+	//prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);
+	//schedule();
+	//finish_wait(&dev->outq, &wait);
+
+	wait_event_interruptible(dev->outq, dev->writable);
+	dev->writable=0;
 
 	return count;
 
diff --git a/src/mod/endpoints/mod_skypopen/oss/scull.h b/src/mod/endpoints/mod_skypopen/oss/scull.h
index e86281bd94..565b8b38b7 100644
--- a/src/mod/endpoints/mod_skypopen/oss/scull.h
+++ b/src/mod/endpoints/mod_skypopen/oss/scull.h
@@ -34,6 +34,8 @@ struct scull_dev {
 	wait_queue_head_t outq; /* read and write queues */
 	struct timer_list timer_inq;
 	struct timer_list timer_outq;
+	int readable;
+	int writable;
 	//unsigned long read_howmany;
 	//unsigned long write_howmany;
 	//unsigned long read_sleeped_acc;

From 739ac99e3b80a15c81def7f65e24b035a96b3602 Mon Sep 17 00:00:00 2001
From: Giovanni Maruzzelli <gmaruzz@gmail.com>
Date: Tue, 14 Dec 2010 08:38:57 -0600
Subject: [PATCH 17/20] skypopen: tweaking the OSS audio driver, still gives a
 load average higher than snd-dummy + snd-pcm-oss on CentOS 5 (but not much
 more, and lower cpu load), but now is very very good on tickless kernels, eg:
 Ubuntu 10.04 LTS

---
 src/mod/endpoints/mod_skypopen/oss/Makefile |  2 +-
 src/mod/endpoints/mod_skypopen/oss/main.c   | 28 ++++++++++-----------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/src/mod/endpoints/mod_skypopen/oss/Makefile b/src/mod/endpoints/mod_skypopen/oss/Makefile
index 91cc61ba1e..465db533e4 100644
--- a/src/mod/endpoints/mod_skypopen/oss/Makefile
+++ b/src/mod/endpoints/mod_skypopen/oss/Makefile
@@ -1,6 +1,6 @@
 # Comment/uncomment the following line to disable/enable debugging
 #DEBUG = y
-LDDINC=/usr/src/linux-headers-2.6.32-26-server/include
+#LDDINC=/usr/src/linux-headers-2.6.32-26-server/include
 
 # Add your debugging flag (or not) to CFLAGS
 ifeq ($(DEBUG),y)
diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c
index 925441b254..8da9c549ac 100644
--- a/src/mod/endpoints/mod_skypopen/oss/main.c
+++ b/src/mod/endpoints/mod_skypopen/oss/main.c
@@ -67,7 +67,7 @@ void my_timer_callback_inq( unsigned long data )
 {
 	struct scull_dev *dev = (void *)data;
 
-	dev->readable=1;
+	//dev->readable=1;
 	wake_up_interruptible(&dev->inq);
 	mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
 
@@ -77,7 +77,7 @@ void my_timer_callback_outq( unsigned long data )
 {
 	struct scull_dev *dev = (void *)data;
 
-	dev->writable=1;
+	//dev->writable=1;
 	wake_up_interruptible(&dev->outq);
 	mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
 }
@@ -172,14 +172,14 @@ ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
 {
 	struct scull_dev *dev = filp->private_data;
 
-	//DEFINE_WAIT(wait);
-	//prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
-	//schedule();
-	//finish_wait(&dev->inq, &wait);
+	DEFINE_WAIT(wait);
+	prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
+	schedule();
+	finish_wait(&dev->inq, &wait);
 	//memset(buf, 255, count);
 
-	wait_event_interruptible(dev->inq, dev->readable);
-	dev->readable=0;
+	//wait_event_interruptible(dev->inq, dev->readable);
+	//dev->readable=0;
 	return count;
 
 }
@@ -188,13 +188,13 @@ 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);
+	DEFINE_WAIT(wait);
+	prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);
+	schedule();
+	finish_wait(&dev->outq, &wait);
 
-	wait_event_interruptible(dev->outq, dev->writable);
-	dev->writable=0;
+	//wait_event_interruptible(dev->outq, dev->writable);
+	//dev->writable=0;
 
 	return count;
 

From 36b2346445188c279b8d3da2c139a0ca862f2511 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Tue, 14 Dec 2010 09:28:57 -0600
Subject: [PATCH 18/20] add path

---
 Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index 72ad3f718c..da89572c6f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -102,7 +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_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src -I$(switch_srcdir)/libs/tiff-3.8.2/libtiff
 
 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

From 6c6eab8c13d2d7dddcd078a25f8d64bf94cfa910 Mon Sep 17 00:00:00 2001
From: Brian West <brian@freeswitch.org>
Date: Tue, 14 Dec 2010 12:00:29 -0600
Subject: [PATCH 19/20] Do not set nat mode when the device's network_ip is
 within the acl also so if your FS is behind nat and your phone is too then it
 will still make the right decisions

---
 src/mod/endpoints/mod_sofia/sofia.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 591cd7f4aa..d429f59672 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -6267,6 +6267,13 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
 			for (x = 0; x < profile->nat_acl_count; x++) {
 				last_acl = profile->nat_acl[x];
 				if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
+					/* override the decision to say this is nat because the network_ip is within the acl too */
+					if ((ok = switch_check_network_list_ip(network_ip, last_acl))) { 
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Endpoint is already inside nat with us.\n");
+						ok = 0;
+					} else {
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Decision stands they are behind nat.\n");
+					}
 					break;
 				}
 			}

From 1d668e25ab8bfbf92bdaebf11a2b756f22895b33 Mon Sep 17 00:00:00 2001
From: Brian West <brian@freeswitch.org>
Date: Tue, 14 Dec 2010 12:43:51 -0600
Subject: [PATCH 20/20]  hrm

---
 src/mod/endpoints/mod_sofia/sofia.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index d429f59672..f2a555e946 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -6267,7 +6267,21 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
 			for (x = 0; x < profile->nat_acl_count; x++) {
 				last_acl = profile->nat_acl[x];
 				if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
-					/* override the decision to say this is nat because the network_ip is within the acl too */
+					/* NAT mode double check logic and examples.
+
+					   Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point 
+					   is most likely behind nat with us so we need to veto that decision to turn on nat processing.
+
+					   Example 2: the contact_host is 192.168.1.100 and the network_ip is 192.0.2.100 which is a public internet ip
+					   the remote endpoint is likely behind a remote nat traversing the public internet. 
+
+					   This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net
+					   in cases where we don't really need to be doing this. 
+
+					   Why would you want to do this?  Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind
+					   remote NAT over the public internet in addition to endpoints behind nat with you.  This simplifies that process.
+					   
+					 */
 					if ((ok = switch_check_network_list_ip(network_ip, last_acl))) { 
 						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Endpoint is already inside nat with us.\n");
 						ok = 0;