[Freeswitch-branches] [commit] r5172 - in freeswitch/branches/greenlizard: . build conf libs libs/curl libs/iax/src libs/libedit libs/libedit/doc libs/libedit/examples libs/libedit/src libs/portaudio libs/sofia-sip/libsofia-sip-ua libs/sofia-sip/libsofia-sip-ua-glib/su-glib libs/sofia-sip/libsofia-sip-ua/bnf libs/sofia-sip/libsofia-sip-ua/docs libs/sofia-sip/libsofia-sip-ua/features libs/sofia-sip/libsofia-sip-ua/http libs/sofia-sip/libsofia-sip-ua/ipt libs/sofia-sip/libsofia-sip-ua/iptsec libs/sofia-sip/libsofia-sip-ua/msg libs/sofia-sip/libsofia-sip-ua/nea libs/sofia-sip/libsofia-sip-ua/nta libs/sofia-sip/libsofia-sip-ua/nth libs/sofia-sip/libsofia-sip-ua/nua libs/sofia-sip/libsofia-sip-ua/sdp libs/sofia-sip/libsofia-sip-ua/sip libs/sofia-sip/libsofia-sip-ua/soa libs/sofia-sip/libsofia-sip-ua/sresolv libs/sofia-sip/libsofia-sip-ua/stun libs/sofia-sip/libsofia-sip-ua/su libs/sofia-sip/libsofia-sip-ua/tport libs/sofia-sip/libsofia-sip-ua/url libs/sofia-sip/utils libs/xmlrpc-c/src/cpp scripts/socket/socket2me src src/include src/mod/applications/mod_commands src/mod/applications/mod_conference src/mod/applications/mod_dptools src/mod/applications/mod_enum src/mod/applications/mod_esf src/mod/codecs/mod_speex src/mod/endpoints/mod_alsa src/mod/endpoints/mod_dingaling src/mod/endpoints/mod_iax src/mod/endpoints/mod_portaudio src/mod/endpoints/mod_sofia src/mod/endpoints/mod_wanpipe src/mod/endpoints/mod_woomera src/mod/event_handlers/mod_cdr src/mod/event_handlers/mod_radius_cdr src/mod/languages/mod_python src/mod/languages/mod_spidermonkey src/mod/xml_int/mod_xml_curl w32/Library

Freeswitch SVN greenlizard at freeswitch.org
Mon May 14 10:50:39 EDT 2007


Author: greenlizard
Date: Mon May 14 10:50:37 2007
New Revision: 5172

Added:
   freeswitch/branches/greenlizard/build/ignore_helper.pl
      - copied unchanged from r5170, /freeswitch/trunk/build/ignore_helper.pl
   freeswitch/branches/greenlizard/src/mod/event_handlers/mod_radius_cdr/
      - copied from r5170, /freeswitch/trunk/src/mod/event_handlers/mod_radius_cdr/
Modified:
   freeswitch/branches/greenlizard/   (props changed)
   freeswitch/branches/greenlizard/Makefile.am
   freeswitch/branches/greenlizard/bootstrap.sh
   freeswitch/branches/greenlizard/conf/default_context.xml
   freeswitch/branches/greenlizard/conf/directory.xml
   freeswitch/branches/greenlizard/conf/iax.conf.xml
   freeswitch/branches/greenlizard/conf/sofia.conf.xml
   freeswitch/branches/greenlizard/conf/xml_curl.conf.xml
   freeswitch/branches/greenlizard/libs/   (props changed)
   freeswitch/branches/greenlizard/libs/curl/   (props changed)
   freeswitch/branches/greenlizard/libs/iax/src/iax-client.h
   freeswitch/branches/greenlizard/libs/iax/src/iax-mutex.c
   freeswitch/branches/greenlizard/libs/iax/src/iax.c
   freeswitch/branches/greenlizard/libs/iax/src/iax.h
   freeswitch/branches/greenlizard/libs/iax/src/iax2-parser.h
   freeswitch/branches/greenlizard/libs/iax/src/iax2.h
   freeswitch/branches/greenlizard/libs/iax/src/jitterbuf.c
   freeswitch/branches/greenlizard/libs/iax/src/jitterbuf.h
   freeswitch/branches/greenlizard/libs/iax/src/md5.h
   freeswitch/branches/greenlizard/libs/libedit/   (props changed)
   freeswitch/branches/greenlizard/libs/libedit/doc/   (props changed)
   freeswitch/branches/greenlizard/libs/libedit/examples/   (props changed)
   freeswitch/branches/greenlizard/libs/libedit/src/   (props changed)
   freeswitch/branches/greenlizard/libs/portaudio/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua-glib/su-glib/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/Makefile.am
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/bnf/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/docs/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/features/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/ipt/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/msg/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nea/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.c
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sdp/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/stun/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/url/   (props changed)
   freeswitch/branches/greenlizard/libs/sofia-sip/utils/   (props changed)
   freeswitch/branches/greenlizard/libs/xmlrpc-c/src/cpp/   (props changed)
   freeswitch/branches/greenlizard/scripts/socket/socket2me/   (props changed)
   freeswitch/branches/greenlizard/src/include/switch_buffer.h
   freeswitch/branches/greenlizard/src/include/switch_caller.h
   freeswitch/branches/greenlizard/src/include/switch_channel.h
   freeswitch/branches/greenlizard/src/include/switch_core.h
   freeswitch/branches/greenlizard/src/include/switch_cpp.h
   freeswitch/branches/greenlizard/src/include/switch_loadable_module.h
   freeswitch/branches/greenlizard/src/include/switch_regex.h
   freeswitch/branches/greenlizard/src/include/switch_rtp.h
   freeswitch/branches/greenlizard/src/include/switch_scheduler.h
   freeswitch/branches/greenlizard/src/include/switch_types.h
   freeswitch/branches/greenlizard/src/include/switch_utils.h
   freeswitch/branches/greenlizard/src/mod/applications/mod_commands/mod_commands.c
   freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c
   freeswitch/branches/greenlizard/src/mod/applications/mod_dptools/mod_dptools.c
   freeswitch/branches/greenlizard/src/mod/applications/mod_enum/mod_enum.c
   freeswitch/branches/greenlizard/src/mod/applications/mod_esf/   (props changed)
   freeswitch/branches/greenlizard/src/mod/codecs/mod_speex/mod_speex.c
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_alsa/mod_alsa.c
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_dingaling/mod_dingaling.c
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_iax/mod_iax.c
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_portaudio/mod_portaudio.c
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/   (props changed)
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/Makefile.am
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.c
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.h
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c
   freeswitch/branches/greenlizard/src/mod/endpoints/mod_woomera/mod_woomera.c
   freeswitch/branches/greenlizard/src/mod/event_handlers/mod_cdr/basecdr.h
   freeswitch/branches/greenlizard/src/mod/event_handlers/mod_cdr/mod_cdr.cpp
   freeswitch/branches/greenlizard/src/mod/languages/mod_python/freeswitch_python.cpp
   freeswitch/branches/greenlizard/src/mod/languages/mod_python/freeswitch_python.h
   freeswitch/branches/greenlizard/src/mod/languages/mod_python/mod_python.c
   freeswitch/branches/greenlizard/src/mod/languages/mod_python/mod_python_wrap.cpp
   freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
   freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
   freeswitch/branches/greenlizard/src/switch_buffer.c
   freeswitch/branches/greenlizard/src/switch_caller.c
   freeswitch/branches/greenlizard/src/switch_channel.c
   freeswitch/branches/greenlizard/src/switch_core.c
   freeswitch/branches/greenlizard/src/switch_core_session.c
   freeswitch/branches/greenlizard/src/switch_cpp.cpp
   freeswitch/branches/greenlizard/src/switch_ivr_async.c
   freeswitch/branches/greenlizard/src/switch_ivr_play_say.c
   freeswitch/branches/greenlizard/src/switch_loadable_module.c
   freeswitch/branches/greenlizard/src/switch_regex.c
   freeswitch/branches/greenlizard/src/switch_rtp.c
   freeswitch/branches/greenlizard/src/switch_scheduler.c
   freeswitch/branches/greenlizard/src/switch_utils.c
   freeswitch/branches/greenlizard/w32/Library/FreeSwitchCore.vcproj

Log:
Sync up changes from trunk version 5123 to 5170

Modified: freeswitch/branches/greenlizard/Makefile.am
==============================================================================
--- freeswitch/branches/greenlizard/Makefile.am	(original)
+++ freeswitch/branches/greenlizard/Makefile.am	Mon May 14 10:50:37 2007
@@ -139,7 +139,7 @@
 
 
 libs/libedit/Makefile:
-	cd libs/libedit && ./configure --disable-shared --with-pic
+	cd libs/libedit && ./configure CFLAGS="-D_XOPEN_SOURCE=600 -D_BSD_SOURCE=1" --disable-shared --with-pic
 libs/libedit/src/.libs/libedit.a: libs/libedit/Makefile
 	cd libs/libedit && $(MAKE)
 

Modified: freeswitch/branches/greenlizard/bootstrap.sh
==============================================================================
--- freeswitch/branches/greenlizard/bootstrap.sh	(original)
+++ freeswitch/branches/greenlizard/bootstrap.sh	Mon May 14 10:50:37 2007
@@ -33,6 +33,7 @@
 fi
 
 # automake 1.7 or newer
+
 am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|sed -e 's/^[^0-9]*//;s/[a-z]* *$//;s/[- ].*//g;q'`
 if test -z "$am_version"; then
 echo "bootstrap: automake not found."
@@ -40,6 +41,8 @@
 echo "           to build FreeSWITCH from SVN."
 exit 1
 fi
+IFS=_; set $am_version; IFS=' '
+am_version=$1
 IFS=.; set $am_version; IFS=' '
 if test "$1" = "1" -a "$2" -lt "7"; then
 echo "bootstrap: automake version $am_version found."

Modified: freeswitch/branches/greenlizard/conf/default_context.xml
==============================================================================
--- freeswitch/branches/greenlizard/conf/default_context.xml	(original)
+++ freeswitch/branches/greenlizard/conf/default_context.xml	Mon May 14 10:50:37 2007
@@ -42,8 +42,8 @@
 
   <extension name="set_codec" continue="true">
     <condition field="source" expression="mod_portaudio">
-      <action application="set" data="absolute_codec_string=PCMU"/>
-      <action application="set" data="export_vars=absolute_codec_string"/>
+      <action application="export" data="absolute_codec_string=$${global_codec_prefs}"/>
+      <action application="export" data="nolocal:jitterbuffer_msec=180"/>
     </condition>
   </extension>
 

Modified: freeswitch/branches/greenlizard/conf/directory.xml
==============================================================================
--- freeswitch/branches/greenlizard/conf/directory.xml	(original)
+++ freeswitch/branches/greenlizard/conf/directory.xml	Mon May 14 10:50:37 2007
@@ -9,6 +9,8 @@
       <!--<param name="username" value="cluecon"/>-->
       <!--/// auth realm: *optional* same as gateway name, if blank ///-->
       <!--<param name="realm" value="asterlink.com"/>-->
+      <!--/// domain to use in from: *optional* same as  realm, if blank ///-->
+      <!--<param name="from-domain" value="asterlink.com"/>-->
       <!--/// account password *required* ///-->
       <!--<param name="password" value="2007"/>--> 
       <!--/// replace the INVITE from user with the channel's caller-id ///-->
@@ -21,6 +23,10 @@
       <!--<param name="expire-seconds" value="60"/>-->
       <!--/// do not register ///-->
       <!--<param name="register" value="false"/>-->
+      <!--How many seconds before a retry when a failure or timeout occurs -->
+      <!--<param name="retry_seconds" value="30"/>-->
+      <!--Use the callerid of an inbound call in the from field on outbound calls via this gateway -->
+      <!--<param name="caller-id-in-from" value="false"/>-->
       <!--</gateway>-->
     </gateways>
     <params>

Modified: freeswitch/branches/greenlizard/conf/iax.conf.xml
==============================================================================
--- freeswitch/branches/greenlizard/conf/iax.conf.xml	(original)
+++ freeswitch/branches/greenlizard/conf/iax.conf.xml	Mon May 14 10:50:37 2007
@@ -1,7 +1,7 @@
 <configuration name="iax.conf" description="IAX Configuration">
   <settings>
     <param name="debug" value="0"/>
-    <!-- <param name="ip" value="1.2.3.4"> -->
+    <!-- <param name="ip" value="1.2.3.4"/> -->
     <param name="port" value="4569"/>
     <param name="dialplan" value="XML"/>
     <param name="codec-prefs" value="PCMU at 20i,PCMA,speex,L16"/>

Modified: freeswitch/branches/greenlizard/conf/sofia.conf.xml
==============================================================================
--- freeswitch/branches/greenlizard/conf/sofia.conf.xml	(original)
+++ freeswitch/branches/greenlizard/conf/sofia.conf.xml	Mon May 14 10:50:37 2007
@@ -12,6 +12,8 @@
 	  <!--<param name="username" value="cluecon"/>-->
 	  <!--/// auth realm: *optional* same as gateway name, if blank ///-->
 	  <!--<param name="realm" value="asterlink.com"/>-->
+	  <!--/// domain to use in from: *optional* same as  realm, if blank ///-->
+	  <!--<param name="from-domain" value="asterlink.com"/>-->
 	  <!--/// account password *required* ///-->
 	  <!--<param name="password" value="2007"/>--> 
 	  <!--/// replace the INVITE from user with the channel's caller-id ///-->
@@ -26,6 +28,8 @@
 	  <!--<param name="register" value="false"/>-->
 	  <!--How many seconds before a retry when a failure or timeout occurs -->
 	  <!--<param name="retry_seconds" value="30"/>-->
+	  <!--Use the callerid of an inbound call in the from field on outbound calls via this gateway -->
+	  <!--<param name="caller-id-in-from" value="false"/>-->
 	<!--</gateway>-->
       </gateways>
 

Modified: freeswitch/branches/greenlizard/conf/xml_curl.conf.xml
==============================================================================
--- freeswitch/branches/greenlizard/conf/xml_curl.conf.xml	(original)
+++ freeswitch/branches/greenlizard/conf/xml_curl.conf.xml	Mon May 14 10:50:37 2007
@@ -8,6 +8,8 @@
       <param name="gateway-url" value="http://www.mydomain.com/test.cgi" bindings="dialplan"/>
       <!-- set this to provide authentication credentials to the server -->
       <!--<param name="gateway-credentials" value="muser:mypass"/>-->
+      <!-- set to true to disable Expect: 100-continue lighttpd requires this setting -->
+      <!--<param name="disable-100-continue" value="true"/>-->
     </binding>
   </bindings>
 </configuration>

Modified: freeswitch/branches/greenlizard/libs/iax/src/iax-client.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/iax/src/iax-client.h	(original)
+++ freeswitch/branches/greenlizard/libs/iax/src/iax-client.h	Mon May 14 10:50:37 2007
@@ -81,6 +81,7 @@
 #define IAX_EVENT_REGREJ  30		/* Registration reply */
 #define IAX_EVENT_LINKURL	31		/* Unlink */
 #define IAX_EVENT_CNG	32		/* Comfort-noise (almost silence) */
+#define IAX_EVENT_POKE   33
 
 /* moved from iax.c to support attended transfer */
 #define IAX_EVENT_REREQUEST	999
@@ -161,6 +162,9 @@
 extern int iax_send_ping(struct iax_session *session);
 extern int iax_load_complete(struct iax_session *session);
 extern int iax_reject(struct iax_session *session, char *reason);
+int iax_reject_registration(struct iax_session *session, char *reason);
+int iax_ack_registration(struct iax_session *session);
+int iax_auth_registration(struct iax_session *session);
 extern int iax_busy(struct iax_session *session);
 extern int iax_congestion(struct iax_session *session);
 extern int iax_hangup(struct iax_session *session, char *byemsg);
@@ -225,6 +229,10 @@
 extern char iax_pref_codec_add(struct iax_session *session, unsigned int format);
 extern void iax_pref_codec_del(struct iax_session *session, unsigned int format);
 extern int iax_pref_codec_get(struct iax_session *session, unsigned int *array, int len);
+
+/* Fine tune jitterbuffer */
+extern void iax_set_jb_target_extra( long value );
+
 extern char *iax_get_peer_ip(struct iax_session *session);
 extern char *iax_event_get_apparent_ip(struct iax_event *event);
 extern void iax_set_samplerate(struct iax_session *session, unsigned short samplemask);

Modified: freeswitch/branches/greenlizard/libs/iax/src/iax-mutex.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/iax/src/iax-mutex.c	(original)
+++ freeswitch/branches/greenlizard/libs/iax/src/iax-mutex.c	Mon May 14 10:50:37 2007
@@ -17,7 +17,8 @@
  *
  */
 
-
+#define _XOPEN_SOURCE 600
+#include <stdlib.h>
 #include "iax-mutex.h"
 
 
@@ -40,22 +41,40 @@
 
 mutex_status_t iax_mutex_create(mutex_t **mutex)
 {
+	mutex_status_t status = MUTEX_FAILURE;
+#ifndef WIN32
+	pthread_mutexattr_t attr;
+#endif
 	mutex_t *check = NULL;
 
 	check = (mutex_t *)malloc(sizeof(**mutex));
 	if (!check)
-		return MUTEX_FAILURE;
+		goto done;
 #ifdef WIN32
 	InitializeCriticalSection(&check->mutex);
 #else
-	if (pthread_mutex_init(&check->mutex, NULL))
-		return MUTEX_FAILURE;
+	if (pthread_mutexattr_init(&attr))
+		goto done;
 
-#endif
+	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
+		goto fail;
 
+	if (pthread_mutex_init(&check->mutex, &attr))
+		goto fail;
+
+	goto success;
+
+fail:
+        pthread_mutexattr_destroy(&attr);
+		goto done;
+
+success:
+#endif
 	*mutex = check;
+	status = MUTEX_SUCCESS;
 
-	return MUTEX_SUCCESS;
+done:
+	return status;
 }
 
 mutex_status_t iax_mutex_destroy(mutex_t *mutex)

Modified: freeswitch/branches/greenlizard/libs/iax/src/iax.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/iax/src/iax.c	(original)
+++ freeswitch/branches/greenlizard/libs/iax/src/iax.c	Mon May 14 10:50:37 2007
@@ -40,16 +40,12 @@
 
 #else
 
+#define _BSD_SOURCE 1
 #include <netdb.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <sys/time.h>
 #include <stdlib.h>
-#ifdef __GNUC__
-#ifndef __USE_SVID
-#define __USE_SVID
-#endif
-#endif
 #include <string.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -60,7 +56,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <time.h>
-
+       
 #endif
 
 #include "iax2.h"
@@ -70,7 +66,7 @@
 #ifdef NEWJB
 #include "jitterbuf.h"
 #endif
-
+#include "iax-mutex.h"
 /*
 	work around jitter-buffer shrinking in asterisk:
 	channels/chan_iax2.c:schedule_delivery() shrinks jitter buffer by 2.
@@ -144,6 +140,9 @@
 /* Max timeouts */
 static int maxretries = 10;
 
+/* configurable jitterbuffer options */
+static long jb_target_extra = -1; 
+
 static int do_shutdown = 0;
 
 /* external global networking replacements */
@@ -330,6 +329,8 @@
 	struct iax_sched *next;
 };
 
+static mutex_t *sched_mutex = NULL;
+static mutex_t *session_mutex = NULL;
 static struct iax_sched *schedq = NULL;
 static struct iax_session *sessions = NULL;
 static int callnums = 1;
@@ -412,6 +413,7 @@
 		sched->func = func;
 		sched->arg = arg;
 		/* Put it in the list, in order */
+		iax_mutex_lock(sched_mutex);
 		cur = schedq;
 		while(cur && cur->when <= sched->when) {
 			prev = cur;
@@ -423,6 +425,7 @@
 		} else {
 			schedq = sched;
 		}
+		iax_mutex_unlock(sched_mutex);
 		return 0;
 	} else {
 		DEBU(G "Out of memory!\n");
@@ -433,7 +436,9 @@
 static int iax_sched_del(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int all)
 {
 	struct iax_sched *cur, *tmp, *prev = NULL;
+	int ret = 0;
 
+	iax_mutex_lock(sched_mutex);
 	cur = schedq;
 	while (cur) {
 		if (cur->event == event && cur->frame == frame && cur->func == func && cur->arg == arg) {
@@ -444,13 +449,18 @@
 			tmp = cur;
 			cur = cur->next;	
 			free(tmp);
-			if (!all)
-				return -1;
+			if (!all) {
+				ret = -1;
+				goto done;
+			}
 		} else {
 			prev = cur;
 			cur = cur->next;
 		}
 	}
+ done:
+	iax_mutex_unlock(sched_mutex);
+
 	return 0;
 
 }
@@ -458,24 +468,31 @@
 
 time_in_ms_t iax_time_to_next_event(void)
 {
-	struct iax_sched *cur = schedq;
+	struct iax_sched *cur = NULL;
 	time_in_ms_t minimum = 999999999;
 	
+	iax_mutex_lock(sched_mutex);
+	cur = schedq;
+
 	/* If there are no pending events, we don't need to timeout */
-	if (!cur)
+	if (!cur) {
+		iax_mutex_unlock(sched_mutex);
 		return -1;
-
+	}
 	while(cur) {
 		if (cur->when < minimum) {
 			minimum = cur->when;
 		}
 		cur = cur->next;
 	}
+	iax_mutex_unlock(sched_mutex);
 
 	if (minimum <= 0) {
 		return -1;
 	}
 
+
+
 	return minimum - current_time_in_ms();
 }
 
@@ -497,7 +514,7 @@
 			callnums = 1;
 		s->peercallno = 0;
 		s->transferpeer = 0;		/* for attended transfer */
-		s->next = sessions;
+
 		s->sendto = iax_sendto;
 		s->pingid = -1;
 #ifdef NEWJB
@@ -507,10 +524,14 @@
 			jbconf.max_jitterbuf = 0;
 			jbconf.resync_threshold = 1000;
 			jbconf.max_contig_interp = 0;
+			jbconf.target_extra = jb_target_extra;
 			jb_setconf(s->jb, &jbconf);
 		}
 #endif
+		iax_mutex_lock(session_mutex);
+		s->next = sessions;
 		sessions = s;
+		iax_mutex_unlock(session_mutex);
 	}
 	return s;
 }
@@ -518,12 +539,19 @@
 static int iax_session_valid(struct iax_session *session)
 {
 	/* Return -1 on a valid iax session pointer, 0 on a failure */
-	struct iax_session *cur = sessions;
+	struct iax_session *cur;
+
+	iax_mutex_lock(session_mutex);
+	cur = sessions;
 	while(cur) {
-		if (session == cur)
+		if (session == cur) {
+			iax_mutex_unlock(session_mutex);
 			return -1;
+		}
 		cur = cur->next;
 	}
+	iax_mutex_unlock(session_mutex);
+
 	return 0;
 }
 
@@ -764,9 +792,22 @@
 	return cnt;
 }
 
+static inline int get_interp_len(int format)
+{
+	return (format == AST_FORMAT_ILBC) ? 30 : 20;
+}
+
 static int get_sample_cnt(struct iax_event *e)
 {
 	int cnt = 0;
+
+	/*
+	 * In the case of zero length frames, do not return a cnt of 0
+	 */
+	if ( e->datalen == 0 ) {
+		return get_interp_len( e->subclass ) * 8;
+	}
+
 	switch (e->subclass) {
 	  case AST_FORMAT_SPEEX:
 	    cnt = speex_get_samples(e->data, e->datalen);
@@ -865,26 +906,29 @@
 
 int __iax_shutdown(void)
 {
+	struct iax_sched *sp, *fp;
+
 	/* Hangup Calls */
 	if (sessions) {
 		struct iax_session *sp = NULL, *fp = NULL;
+		iax_mutex_lock(session_mutex); 
 		for(sp = sessions; sp ;) {
 			iax_hangup(sp, "System Shutdown");
 			fp = sp;
 			sp = sp->next;
 			destroy_session(fp);
 		}
+		iax_mutex_unlock(session_mutex); 
 	}
 
 	/* Clear Scheduler */
-	if(schedq) {
-		struct iax_sched *sp, *fp;
-		for(sp = schedq; sp ;) {
-			fp = sp;
-			sp = sp->next;
-			free(fp);
-		}
+	iax_mutex_lock(sched_mutex);
+	for(sp = schedq; sp ;) {
+		fp = sp;
+		sp = sp->next;
+		free(fp);
 	}
+	iax_mutex_unlock(sched_mutex);
 	
 	if (netfd > -1) {
 		shutdown(netfd, 2);
@@ -893,6 +937,9 @@
 
 	time_end();
 
+	iax_mutex_destroy(sched_mutex);
+	iax_mutex_destroy(session_mutex);
+
 	return 0;
 }
 
@@ -901,6 +948,12 @@
 	return do_shutdown++;
 }
 
+void iax_set_jb_target_extra( long value )
+{
+	/* store in jb_target_extra, a static global */
+	jb_target_extra = value ;
+}
+
 int iax_init(char *ip, int preferredportno)
 {
 	int portno = preferredportno;
@@ -910,6 +963,9 @@
 
 	init_time();
 
+	iax_mutex_create(&sched_mutex);
+	iax_mutex_create(&session_mutex);
+
 	if(iax_recvfrom == (recvfrom_t) recvfrom) {
 	    if (netfd > -1) {
 		    /* Sokay, just don't do anything */
@@ -923,23 +979,35 @@
 		    return -1;
 	    }
 	    
-	    if (preferredportno == 0) 
-		    preferredportno = IAX_DEFAULT_PORTNO;
-		    
-	    if (preferredportno > 0) {
-		    sin.sin_family = AF_INET;
-			if (ip) {
-				inet_aton(ip, &sin.sin_addr);
-			} else {
-				sin.sin_addr.s_addr = 0;
-			}
-
-		    sin.sin_port = htons((short)preferredportno);
-		    if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
-			    DEBU(G "Unable to bind to preferred port.  Using random one instead.");
-		    }
-	    }
-	    sinlen = sizeof(sin);
+	    if (preferredportno == 0) preferredportno = IAX_DEFAULT_PORTNO;
+		if (preferredportno < 0)  preferredportno = 0;
+
+		sin.sin_family = AF_INET;
+		sin.sin_addr.s_addr = 0;
+		sin.sin_port = htons((short)preferredportno);
+		if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0) 
+		{
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+			if (WSAGetLastError() == WSAEADDRINUSE)
+#else
+			if (errno == EADDRINUSE)
+#endif
+			{
+				/*the port is already in use, so bind to a free port chosen by the IP stack*/
+				DEBU(G "Unable to bind to preferred port - port is in use. Trying to bind to a free one");
+				sin.sin_port = htons((short)0);
+				if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0)
+				{
+					IAXERROR "Unable to bind UDP socket\n");
+					return -1;
+				}
+			} else
+			{
+				IAXERROR "Unable to bind UDP socket\n");
+				return -1;
+			}
+		}
+		sinlen = sizeof(sin);
 	    if (getsockname(netfd, (struct sockaddr *) &sin, &sinlen) < 0) {
 		    close(netfd);
 		    netfd = -1;
@@ -1187,7 +1255,11 @@
 #endif	
 	int r;
 	r = __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1, 0);
-	if (r >= 0) destroy_session(i);
+	if (r >= 0) {
+		iax_mutex_lock(session_mutex); 
+		destroy_session(i);
+		iax_mutex_unlock(session_mutex);
+	}
 	return r;
 }
 
@@ -1229,12 +1301,14 @@
 {
 	struct iax_sched *sch;
 
+	iax_mutex_lock(sched_mutex);
 	sch = schedq;
 	while(sch) {
 		if (sch->frame && (sch->frame->session == session))
 					sch->frame->retries = -1;
 		sch = sch->next;
 	}
+	iax_mutex_unlock(sched_mutex);
 }	/* stop_transfer */
 
 static void complete_transfer(struct iax_session *session, int peercallno, int xfr2peer, int preserveSeq)
@@ -1356,14 +1430,18 @@
 
 static struct iax_session *iax_find_session2(short callno)
 {
-	struct iax_session *cur = sessions;
+	struct iax_session *cur;
 
+	iax_mutex_lock(session_mutex); 
+	cur = sessions;
 	while(cur) {
 		if (callno == cur->callno && callno != 0)  {
+			iax_mutex_unlock(session_mutex); 
 			return cur;
 		}
 		cur = cur->next;
 	}
+	iax_mutex_unlock(session_mutex); 
 
 	return NULL;
 }
@@ -1431,6 +1509,8 @@
 	struct iax_session *cur, *prev=NULL;
 	struct iax_sched *curs, *prevs=NULL, *nexts=NULL;
 	int    loop_cnt=0;
+
+	iax_mutex_lock(sched_mutex);
 	curs = schedq;
 	while(curs) {
 		nexts = curs->next;
@@ -1451,7 +1531,9 @@
 		curs = nexts;
 		loop_cnt++;
 	}
-		
+	iax_mutex_unlock(sched_mutex);
+	
+
 	cur = sessions;
 	while(cur) {
 		if (cur == session) {
@@ -1505,6 +1587,12 @@
 				iax_send_pong(event->session, event->ts);
 				iax_event_free(event);
 				break;
+			case IAX_EVENT_POKE:
+				event->etype = IAX_EVENT_PONG;
+				iax_send_pong(event->session, event->ts);
+				iax_destroy(event->session);
+				iax_event_free(event);
+				break;         
 			default:
 				return event;
 			}
@@ -1585,6 +1673,24 @@
 	return res;
 }
 
+int iax_reject_registration(struct iax_session *session, char *reason)
+{
+	struct iax_ie_data ied;
+	memset(&ied, 0, sizeof(ied));
+	iax_ie_append_str(&ied, IAX_IE_CAUSE, reason ? (unsigned char *) reason : (unsigned char *) "Unspecified");
+	return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REGREJ, 0, ied.buf, ied.pos, -1);
+}
+
+int iax_ack_registration(struct iax_session *session)
+{
+	return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, NULL, 0, -1);
+}
+
+int iax_auth_registration(struct iax_session *session)
+{
+	return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, NULL, 0, -1);
+}
+
 int iax_reject(struct iax_session *session, char *reason)
 {
 	struct iax_ie_data ied;
@@ -2081,9 +2187,13 @@
 											short dcallno,
 											int makenew)
 {
-	struct iax_session *cur = sessions;
+	struct iax_session *cur;
+
+	iax_mutex_lock(session_mutex); 
+	cur = sessions;
 	while(cur) {
 		if (forward_match(sin, callno, dcallno, cur)) {
+			iax_mutex_unlock(session_mutex); 
 			return cur;
 		}
 		cur = cur->next;
@@ -2092,11 +2202,14 @@
 	cur = sessions;
 	while(cur) {
 		if (reverse_match(sin, callno, cur)) {
+			iax_mutex_unlock(session_mutex); 
 			return cur;
 		}
 		cur = cur->next;
 	}
 
+	iax_mutex_unlock(session_mutex); 
+
 	if (makenew && !dcallno) {
 		cur = iax_session_new();
 		cur->peercallno = callno;
@@ -2108,6 +2221,7 @@
 	} else {
 		DEBU(G "No session, peer = %d, us = %d\n", callno, dcallno);
 	}
+
 	return cur;	
 }
 
@@ -2428,6 +2542,7 @@
 				for (x=session->rseqno; x != fh->iseqno; x++) {
 					/* Ack the packet with the given timestamp */
 					DEBU(G "Cancelling transmission of packet %d\n", x);
+					iax_mutex_lock(sched_mutex);
 					sch = schedq;
 					while(sch) {
 						if (sch->frame && (sch->frame->session == session) && 
@@ -2435,6 +2550,7 @@
 							sch->frame->retries = -1;
 						sch = sch->next;
 					}
+					iax_mutex_unlock(sched_mutex);
 				}
 				/* Note how much we've received acknowledgement for */
 				session->rseqno = fh->iseqno;
@@ -2586,8 +2702,11 @@
 				e->ts = ts;
 				e = schedule_delivery(e, ts, updatehistory);
 				break;
+			case IAX_COMMAND_POKE:
+				e->etype = IAX_EVENT_POKE;
+				e->ts = ts;
+				break;
 			case IAX_COMMAND_PING:
-			case IAX_COMMAND_POKE:
 				/* PINGS and PONGS don't get scheduled; */
 				e->etype = IAX_EVENT_PING;
 				e->ts = ts;
@@ -2622,6 +2741,14 @@
 				}
 				e = schedule_delivery(e, ts, updatehistory);
 				break;
+			case IAX_COMMAND_REGREQ:
+				e->etype = IAX_EVENT_REGREQ;
+				e = schedule_delivery(e, ts, updatehistory);
+				break;
+			case IAX_COMMAND_REGREL:
+				e->etype = IAX_EVENT_REGREQ;
+				e = schedule_delivery(e, ts, updatehistory);
+				break;
 			case IAX_COMMAND_REGACK:
 				e->etype = IAX_EVENT_REGACK;
 				e = schedule_delivery(e, ts, updatehistory);
@@ -2846,15 +2973,17 @@
 
 void iax_destroy(struct iax_session *session)
 {
+	iax_mutex_lock(session_mutex); 
 	destroy_session(session);
+	iax_mutex_unlock(session_mutex); 
 }
 
 static struct iax_event *iax_net_read(void)
 {
 	unsigned char buf[65536];
-	int res;
+	int res, sinlen;
 	struct sockaddr_in sin;
-	unsigned int sinlen;
+
 	sinlen = sizeof(sin);
 	res = iax_recvfrom(netfd, buf, sizeof(buf), 0, (struct sockaddr *) &sin, &sinlen);
 
@@ -2894,6 +3023,7 @@
 	if (!ies.transferid) {
 		return NULL;	/* TXCNT without proper IAX_IE_TRANSFERID */
 	}
+	iax_mutex_lock(session_mutex); 
 	for( cur=sessions; cur; cur=cur->next ) {
 		if ((cur->transferring) && (cur->transferid == ies.transferid) &&
 		   	(cur->callno == dcallno) && (cur->transfercallno == callno)) {
@@ -2906,6 +3036,7 @@
 			break;		
 		}
 	}
+	iax_mutex_unlock(session_mutex); 
 	return cur;
 }
 
@@ -2923,6 +3054,7 @@
 		if (len < sizeof(struct ast_iax2_full_hdr)) {
 			DEBU(G "Short header received from %s\n", inet_ntoa(sin->sin_addr));
 			IAXERROR "Short header received from %s\n", inet_ntoa(sin->sin_addr));
+			return NULL;
 		}
 		/* Only allow it to make new sessions on types where that makes sense */
 		if ((fh->type == AST_FRAME_IAX) && ((subclass == IAX_COMMAND_NEW) ||
@@ -2945,6 +3077,7 @@
 		if (len < sizeof(struct ast_iax2_mini_hdr)) {
 			DEBU(G "Short header received from %s\n", inet_ntoa(sin->sin_addr));
 			IAXERROR "Short header received from %s\n", inet_ntoa(sin->sin_addr));
+			return NULL;
 		}
 		/* Miniature, voice frame */
 		session = iax_find_session(sin, ntohs(fh->scallno), 0, 0);
@@ -2958,6 +3091,7 @@
 static struct iax_sched *iax_get_sched(time_in_ms_t time_in_ms)
 {
 	struct iax_sched *cur, *prev=NULL;
+	iax_mutex_lock(sched_mutex);
 	cur = schedq;
 	/* Check the event schedule first. */
 	while(cur) {
@@ -2968,10 +3102,12 @@
 			} else {
 				schedq = cur->next;
 			}
+			iax_mutex_unlock(sched_mutex);
 			return cur;
 		}
 		cur = cur->next;
 	}
+	iax_mutex_unlock(sched_mutex);
 	return NULL;
 }
 
@@ -3005,8 +3141,11 @@
 			if (frame->retries < 0) {
 				/* It's been acked.  No need to send it.   Destroy the old
 				   frame. If final, destroy the session. */
-				if (frame->final)
+				if (frame->final) {
+					iax_mutex_lock(session_mutex); 
 					destroy_session(frame->session);
+					iax_mutex_unlock(session_mutex); 
+				}
 				if (frame->data)
 					free(frame->data);
 				free(frame);
@@ -3023,7 +3162,9 @@
 					/* We haven't been able to get an ACK on this packet. If a 
 					   final frame, destroy the session, otherwise, pass up timeout */
 					if (frame->final) {
+						iax_mutex_lock(session_mutex); 
 						destroy_session(frame->session);
+						iax_mutex_unlock(session_mutex); 
 						if (frame->data)
 							free(frame->data);
 						free(frame);
@@ -3070,54 +3211,58 @@
 	{
 	    struct iax_session *cur;
 	    jb_frame frame;
+		iax_mutex_lock(session_mutex); 
 	    for(cur=sessions; cur; cur=cur->next) {
-		int ret;
-		time_in_ms_t now;
-		time_in_ms_t next;
-
-		now = time_in_ms - cur->rxcore;
-		if(now > (next = jb_next(cur->jb))) {
-		    /* FIXME don't hardcode interpolation frame length in jb_get */
-		    ret = jb_get(cur->jb,&frame,now,20);
-		    switch(ret) {
-			case JB_OK:
-//			    if(frame.type == JB_TYPE_VOICE && next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
-			    event = frame.data;
-			    event = handle_event(event);
-			    if (event) {
-				    return event;
-			    }
-			break;
-			case JB_INTERP:
-//			    if(next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
-			    /* create an interpolation frame */
-			    //fprintf(stderr, "Making Interpolation frame\n");
-			    event = (struct iax_event *)malloc(sizeof(struct iax_event));
-			    if (event) {
-				    event->etype    = IAX_EVENT_VOICE;
-				    event->subclass = cur->voiceformat;
-				    event->ts	    = now; /* XXX: ??? applications probably ignore this anyway */
-				    event->session  = cur;
-				    event->datalen  = 0;
-				    event = handle_event(event);
-				    if(event)
-					return event;
-			    }
-			break;
-			case JB_DROP:
-//			    if(next != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not next %ld!\n", jb_next(cur->jb), next);
-			    iax_event_free(frame.data);
-			break;
-			case JB_NOFRAME:
-			case JB_EMPTY:
-			    /* do nothing */
-			break;
-			default:
-			    /* shouldn't happen */
-			break;
-		    }
-		}
+			int ret;
+			time_in_ms_t now;
+			time_in_ms_t next;
+
+			now = time_in_ms - cur->rxcore;
+			if(now > (next = jb_next(cur->jb))) {
+				ret = jb_get(cur->jb,&frame,now,get_interp_len(cur->voiceformat));
+				switch(ret) {
+				case JB_OK:
+					//			    if(frame.type == JB_TYPE_VOICE && next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
+					event = frame.data;
+					event = handle_event(event);
+					if (event) {
+						iax_mutex_unlock(session_mutex);
+						return event;
+					}
+					break;
+				case JB_INTERP:
+					//			    if(next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
+					/* create an interpolation frame */
+					//fprintf(stderr, "Making Interpolation frame\n");
+					event = (struct iax_event *)malloc(sizeof(struct iax_event));
+					if (event) {
+						event->etype    = IAX_EVENT_VOICE;
+						event->subclass = cur->voiceformat;
+						event->ts	    = now; /* XXX: ??? applications probably ignore this anyway */
+						event->session  = cur;
+						event->datalen  = 0;
+						event = handle_event(event);
+						if(event) {
+							iax_mutex_unlock(session_mutex);
+							return event;
+						}
+					}
+					break;
+				case JB_DROP:
+					//			    if(next != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not next %ld!\n", jb_next(cur->jb), next);
+					iax_event_free(frame.data);
+					break;
+				case JB_NOFRAME:
+				case JB_EMPTY:
+					/* do nothing */
+					break;
+				default:
+					/* shouldn't happen */
+					break;
+				}
+			}
 	    }
+		iax_mutex_unlock(session_mutex);
 	}
 
 #endif
@@ -3169,8 +3314,10 @@
 
 void iax_session_destroy(struct iax_session **session) 
 {
+	iax_mutex_lock(session_mutex); 
 	destroy_session(*session);
 	*session = NULL;
+	iax_mutex_unlock(session_mutex); 
 }
 
 void iax_event_free(struct iax_event *event)
@@ -3185,7 +3332,9 @@
 	case IAX_EVENT_HANGUP:
 		/* Destroy this session -- it's no longer valid */
 		if (event->session) { /* maybe the user did it already */
+			iax_mutex_lock(session_mutex); 
 			destroy_session(event->session);
+			iax_mutex_unlock(session_mutex); 
 		}
 		break;
 	}

Modified: freeswitch/branches/greenlizard/libs/iax/src/iax.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/iax/src/iax.h	(original)
+++ freeswitch/branches/greenlizard/libs/iax/src/iax.h	Mon May 14 10:50:37 2007
@@ -8,7 +8,7 @@
  * Mark Spencer <markster at linux-support.net>
  *
  * This program is free software, distributed under the terms of
- * the GNU General Public License
+ * the GNU Lesser (Library) General Public License
  */
  
 #ifndef _IAX_H

Modified: freeswitch/branches/greenlizard/libs/iax/src/iax2-parser.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/iax/src/iax2-parser.h	(original)
+++ freeswitch/branches/greenlizard/libs/iax/src/iax2-parser.h	Mon May 14 10:50:37 2007
@@ -8,7 +8,7 @@
  * Mark Spencer <markster at digium.com>
  *
  * This program is free software, distributed under the terms of
- * the GNU General Public License
+ * the GNU Lesser (Library) General Public License
  */
  
 #ifndef _IAX2_PARSER_H

Modified: freeswitch/branches/greenlizard/libs/iax/src/iax2.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/iax/src/iax2.h	(original)
+++ freeswitch/branches/greenlizard/libs/iax/src/iax2.h	Mon May 14 10:50:37 2007
@@ -8,7 +8,7 @@
  * Mark Spencer <markster at linux-support.net>
  *
  * This program is free software, distributed under the terms of
- * the GNU General Public License
+ * the GNU Lesser (Library) General Public License
  */
  
 #ifndef _IAX2_H

Modified: freeswitch/branches/greenlizard/libs/iax/src/jitterbuf.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/iax/src/jitterbuf.c	(original)
+++ freeswitch/branches/greenlizard/libs/iax/src/jitterbuf.c	Mon May 14 10:50:37 2007
@@ -1,810 +1,834 @@
-/*
- * jitterbuf: an application-independent jitterbuffer
- *
- * Copyrights:
- * Copyright (C) 2004-2005, Horizon Wimba, Inc.
- *
- * Contributors:
- * Steve Kann <stevek at stevek.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU Lesser (Library) General Public License
- *
- * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
- */
-
-#include "iax2.h"
-#include "jitterbuf.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* define these here, just for ancient compiler systems */
-#define JB_LONGMAX 2147483647L
-#define JB_LONGMIN (-JB_LONGMAX - 1L)
-
-/* MS VC can't do __VA_ARGS__ */
-#if defined(WIN32) && defined(_MSC_VER)
-#define jb_warn if (warnf) warnf
-#define jb_err if (errf) errf
-#define jb_dbg if (dbgf) dbgf
-
-#ifdef DEEP_DEBUG
-  #define jb_dbg2 if (dbgf) dbgf
-#else
-  #define jb_dbg2 if (0) dbgf
-#endif
-
-#else
-
-#define jb_warn(...) (warnf ? warnf(__VA_ARGS__) : (void)0)
-#define jb_err(...) (errf ? errf(__VA_ARGS__) : (void)0)
-#define jb_dbg(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
-
-#ifdef DEEP_DEBUG
-#define jb_dbg2(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
-#else
-#define jb_dbg2(...) ((void)0)
-#endif
-
-#endif
-
-static jb_output_function_t warnf, errf, dbgf;
-
-void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg) 
-{
-	errf = err;
-	warnf = warn;
-	dbgf = dbg;
-}
-
-static void increment_losspct(jitterbuf *jb) 
-{
-    jb->info.losspct = (100000 + 499 * jb->info.losspct)/500;    
-}
-
-static void decrement_losspct(jitterbuf *jb) 
-{
-    jb->info.losspct = (499 * jb->info.losspct)/500;    
-}
-
-void jb_reset(jitterbuf *jb) 
-{
-	/* only save settings */
-	jb_conf s = jb->info.conf;
-	memset(jb,0,sizeof(jitterbuf));
-	jb->info.conf = s;
-
-	/* initialize length */
-	jb->info.current = jb->info.target = JB_TARGET_EXTRA; 
-	jb->info.silence_begin_ts = -1; 
-}
-
-jitterbuf * jb_new() 
-{
-    jitterbuf *jb;
-
-
-    jb = malloc(sizeof(jitterbuf));
-    if(!jb) return NULL;
-
-    jb_reset(jb);
-
-    jb_dbg2("jb_new() = %x\n", jb);
-    return jb;
-}
-
-void jb_destroy(jitterbuf *jb) 
-{
-    jb_frame *frame; 
-    jb_dbg2("jb_destroy(%x)\n", jb);
-
-    /* free all the frames on the "free list" */
-    frame = jb->free;
-    while(frame != NULL) {
-      jb_frame *next = frame->next;
-      free(frame);
-      frame = next;
-    }
-
-    /* free ourselves! */ 
-    free(jb);
-}
-
-
-
-/* simple history manipulation */
-/* maybe later we can make the history buckets variable size, or something? */
-/* drop parameter determines whether we will drop outliers to minimize
- * delay */
-#if 0
-static int longcmp(const void *a, const void *b) 
-{
-    return *(long *)a - *(long *)b;
-}
-#endif
-
-static int history_put(jitterbuf *jb, time_in_ms_t ts, time_in_ms_t now, long ms) 
-{
-	time_in_ms_t delay = now - (ts - jb->info.resync_offset);
-	time_in_ms_t threshold = 2 * jb->info.jitter + jb->info.conf.resync_threshold;
-	time_in_ms_t kicked;
-
-	/* don't add special/negative times to history */
-	if (ts <= 0) 
-		return 0;
-
-	/* check for drastic change in delay */
-	if (jb->info.conf.resync_threshold != -1) {
-		if (iax_abs(delay - jb->info.last_delay) > threshold) {
-			jb->info.cnt_delay_discont++;
-			if (jb->info.cnt_delay_discont > 3) {
-				/* resync the jitterbuffer */
-				jb->info.cnt_delay_discont = 0;
-				jb->hist_ptr = 0;
-				jb->hist_maxbuf_valid = 0;
-
-				jb_warn("Resyncing the jb. last_delay %ld, this delay %ld, threshold %ld, new offset %ld\n", jb->info.last_delay, delay, threshold, ts - now);
-				jb->info.resync_offset = ts - now;
-				jb->info.last_delay = delay = 0; /* after resync, frame is right on time */
-			} else {
-				return -1;
-			}
-		} else {
-			jb->info.last_delay = delay;
-			jb->info.cnt_delay_discont = 0;
-		}
-	}
-
-    kicked = jb->history[jb->hist_ptr & JB_HISTORY_SZ];
-
-    jb->history[(jb->hist_ptr++) % JB_HISTORY_SZ] = delay;
-
-    /* optimization; the max/min buffers don't need to be recalculated, if this packet's
-     * entry doesn't change them.  This happens if this packet is not involved, _and_ any packet
-     * that got kicked out of the history is also not involved 
-     * We do a number of comparisons, but it's probably still worthwhile, because it will usually
-     * succeed, and should be a lot faster than going through all 500 packets in history */
-    if(!jb->hist_maxbuf_valid)
-      return 0;
-
-    /* don't do this until we've filled history 
-     * (reduces some edge cases below) */
-    if(jb->hist_ptr < JB_HISTORY_SZ)
-      goto invalidate;
-
-    /* if the new delay would go into min */
-    if(delay < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
-      goto invalidate;
-    
-    /* or max.. */
-    if(delay > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
-      goto invalidate;
-
-    /* or the kicked delay would be in min */
-    if(kicked <= jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1]) 
-      goto invalidate;
-
-    if(kicked >= jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1]) 
-      goto invalidate;
-
-    /* if we got here, we don't need to invalidate, 'cause this delay didn't 
-     * affect things */
-    return 0;
-    /* end optimization */
-
-
-invalidate:
-    jb->hist_maxbuf_valid = 0;
-    return 0;
-}
-
-static void history_calc_maxbuf(jitterbuf *jb) 
-{
-    int i,j;
-
-    if(jb->hist_ptr == 0) return;
-
-
-    /* initialize maxbuf/minbuf to the latest value */
-    for(i=0;i<JB_HISTORY_MAXBUF_SZ;i++) {
-/*
- * jb->hist_maxbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
- * jb->hist_minbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
- */
-      jb->hist_maxbuf[i] = JB_LONGMIN;
-      jb->hist_minbuf[i] = JB_LONGMAX;
-    }
-
-    /* use insertion sort to populate maxbuf */
-    /* we want it to be the top "n" values, in order */
-
-    /* start at the beginning, or JB_HISTORY_SZ frames ago */
-    i = (jb->hist_ptr > JB_HISTORY_SZ) ? (jb->hist_ptr - JB_HISTORY_SZ) : 0; 
-
-    for(;i<jb->hist_ptr;i++) {
-	time_in_ms_t toins = jb->history[i % JB_HISTORY_SZ];
-
-	/* if the maxbuf should get this */
-	if(toins > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])  {
-
-	    /* insertion-sort it into the maxbuf */
-	    for(j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
-		/* found where it fits */
-		if(toins > jb->hist_maxbuf[j]) {
-		    /* move over */
-		    memmove(jb->hist_maxbuf+j+1,jb->hist_maxbuf+j, (JB_HISTORY_MAXBUF_SZ-(j+1)) * sizeof(long));
-		    /* insert */
-		    jb->hist_maxbuf[j] = toins;
-
-		    break;
-		}
-	    }
-	}
-
-	/* if the minbuf should get this */
-	if(toins < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])  {
-
-	    /* insertion-sort it into the maxbuf */
-	    for(j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
-		/* found where it fits */
-		if(toins < jb->hist_minbuf[j]) {
-		    /* move over */
-		    memmove(jb->hist_minbuf+j+1,jb->hist_minbuf+j, (JB_HISTORY_MAXBUF_SZ-(j+1)) * sizeof(long));
-		    /* insert */
-		    jb->hist_minbuf[j] = toins;
-
-		    break;
-		}
-	    }
-	}
-
-	if(0) { 
-	  int k;
-	  fprintf(stderr, "toins = %ld\n", toins);
-	  fprintf(stderr, "maxbuf =");
-	  for(k=0;k<JB_HISTORY_MAXBUF_SZ;k++) 
-	      fprintf(stderr, "%ld ", jb->hist_maxbuf[k]);
-	  fprintf(stderr, "\nminbuf =");
-	  for(k=0;k<JB_HISTORY_MAXBUF_SZ;k++) 
-	      fprintf(stderr, "%ld ", jb->hist_minbuf[k]);
-	  fprintf(stderr, "\n");
-	}
-    }
-
-    jb->hist_maxbuf_valid = 1;
-}
-
-static void history_get(jitterbuf *jb) 
-{
-    time_in_ms_t max, min, jitter;
-    int index;
-    int count;
-
-    if(!jb->hist_maxbuf_valid) 
-      history_calc_maxbuf(jb);
-
-    /* count is how many items in history we're examining */
-    count = (jb->hist_ptr < JB_HISTORY_SZ) ? jb->hist_ptr : JB_HISTORY_SZ;
-
-    /* index is the "n"ths highest/lowest that we'll look for */
-    index = count * JB_HISTORY_DROPPCT / 100;
-
-    /* sanity checks for index */
-    if(index > (JB_HISTORY_MAXBUF_SZ - 1)) index = JB_HISTORY_MAXBUF_SZ - 1;
-
-
-    if(index < 0) {
-      jb->info.min = 0;
-      jb->info.jitter = 0;
-      return;
-    }
-
-    max = jb->hist_maxbuf[index];
-    min = jb->hist_minbuf[index];
-
-    jitter = max - min;
-
-    /* these debug stmts compare the difference between looking at the absolute jitter, and the
-     * values we get by throwing away the outliers */
-    /*
-    fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", index, min, max, jitter);
-    fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", 0, jb->hist_minbuf[0], jb->hist_maxbuf[0], jb->hist_maxbuf[0]-jb->hist_minbuf[0]);
-    */
-
-    jb->info.min = min;
-    jb->info.jitter = jitter;
-}
-
-/* returns 1 if frame was inserted into head of queue, 0 otherwise */
-static int queue_put(jitterbuf *jb, void *data, int type, long ms, time_in_ms_t ts) 
-{
-    jb_frame *frame;
-    jb_frame *p;
-	int head = 0;
-	time_in_ms_t resync_ts = ts - jb->info.resync_offset;
-
-    frame = jb->free;
-    if(frame) {
-	jb->free = frame->next;
-    } else {
-	frame = malloc(sizeof(jb_frame));
-    }
-
-    if(!frame) {
-	jb_err("cannot allocate frame\n");
-	return 0;
-    }
-
-    jb->info.frames_cur++;
-
-    frame->data = data;
-	frame->ts = resync_ts;
-    frame->ms = ms;
-    frame->type = type;
-
-    /* 
-     * frames are a circular list, jb-frames points to to the lowest ts, 
-     * jb->frames->prev points to the highest ts
-     */
-
-    if(!jb->frames) {  /* queue is empty */
-	jb->frames = frame;
-	frame->next = frame;
-	frame->prev = frame;
-		head = 1;
-	} else if (resync_ts < jb->frames->ts) {
-	frame->next = jb->frames;
-	frame->prev = jb->frames->prev;
-
-	frame->next->prev = frame;
-	frame->prev->next = frame;
-
-	/* frame is out of order */
-	jb->info.frames_ooo++;
-
-	jb->frames = frame;
-		head = 1;
-    } else { 
-	p = jb->frames;
-
-	/* frame is out of order */
-	if(ts < p->prev->ts) jb->info.frames_ooo++;
-
-		while (resync_ts < p->prev->ts && p->prev != jb->frames) 
-	    p = p->prev;
-
-	frame->next = p;
-	frame->prev = p->prev;
-
-	frame->next->prev = frame;
-	frame->prev->next = frame;
-    }
-	return head;
-}
-
-static time_in_ms_t queue_next(jitterbuf *jb) 
-{
-    if(jb->frames) return jb->frames->ts;
-    else return -1;
-}
-
-static time_in_ms_t queue_last(jitterbuf *jb) 
-{
-    if(jb->frames) return jb->frames->prev->ts;
-    else return -1;
-}
-
-static jb_frame *_queue_get(jitterbuf *jb, time_in_ms_t ts, int all) 
-{
-    jb_frame *frame;
-    frame = jb->frames;
-
-    if(!frame)
-	return NULL;
-
-    /*jb_warn("queue_get: ASK %ld FIRST %ld\n", ts, frame->ts); */
-
-    if(all || ts >= frame->ts) {
-	/* remove this frame */
-	frame->prev->next = frame->next;
-	frame->next->prev = frame->prev;
-
-	if(frame->next == frame)
-	  jb->frames = NULL;
-	else
-	  jb->frames = frame->next;
-
-
-	/* insert onto "free" single-linked list */
-	frame->next = jb->free;
-	jb->free = frame;
-
-	jb->info.frames_cur--;
-
-	/* we return the frame pointer, even though it's on free list, 
-	 * but caller must copy data */
-	return frame;
-    } 
-
-    return NULL;
-}
-
-static jb_frame *queue_get(jitterbuf *jb, time_in_ms_t ts) 
-{
-    return _queue_get(jb,ts,0);
-}
-
-static jb_frame *queue_getall(jitterbuf *jb) 
-{
-    return _queue_get(jb,0,1);
-}
-
-#if 0
-/* some diagnostics */
-static void jb_dbginfo(jitterbuf *jb) 
-{
-    if(dbgf == NULL) return;
-
-    jb_dbg("\njb info: fin=%ld fout=%ld flate=%ld flost=%ld fdrop=%ld fcur=%ld\n",
-	    jb->info.frames_in, jb->info.frames_out, jb->info.frames_late, jb->info.frames_lost, jb->info.frames_dropped, jb->info.frames_cur);
-	
-    jb_dbg("	jitter=%ld current=%ld target=%ld min=%ld sil=%d len=%d len/fcur=%ld\n",
-	    jb->info.jitter, jb->info.current, jb->info.target, jb->info.min, jb->info.silence_begin_ts, jb->info.current - jb->info.min, 
-	    jb->info.frames_cur ? (jb->info.current - jb->info.min)/jb->info.frames_cur : -8);
-    if(jb->info.frames_in > 0) 
-	jb_dbg("jb info: Loss PCT = %ld%%, Late PCT = %ld%%\n",
-	    jb->info.frames_lost * 100/(jb->info.frames_in + jb->info.frames_lost), 
-	    jb->info.frames_late * 100/jb->info.frames_in);
-	jb_dbg("jb info: queue %d -> %d.  last_ts %d (queue len: %d) last_ms %d\n",
-	    queue_next(jb), 
-	    queue_last(jb),
-	    jb->info.next_voice_ts, 
-	    queue_last(jb) - queue_next(jb),
-	    jb->info.last_voice_ms);
-}
-#endif
-
-#ifdef DEEP_DEBUG
-static void jb_chkqueue(jitterbuf *jb) 
-{
-    int i=0;
-    jb_frame *p = jb->frames;
-
-    if(!p) {
-      return;
-    }
-
-    do {
-	if(p->next == NULL)  {
-	  jb_err("Queue is BROKEN at item [%d]", i);	
-	}
-	i++;
-	p=p->next;
-    } while (p->next != jb->frames);
-}
-
-static void jb_dbgqueue(jitterbuf *jb) 
-{
-    int i=0;
-    jb_frame *p = jb->frames;
-
-    jb_dbg("queue: ");
-
-    if(!p) {
-      jb_dbg("EMPTY\n");
-      return;
-    }
-
-    do {
-	jb_dbg("[%d]=%ld ", i++, p->ts);
-	p=p->next;
-    } while (p->next != jb->frames);
-
-    jb_dbg("\n");
-}
-#endif
-
-int jb_put(jitterbuf *jb, void *data, int type, long ms, time_in_ms_t ts, time_in_ms_t now) 
-{
-    jb_dbg2("jb_put(%x,%x,%ld,%ld,%ld)\n", jb, data, ms, ts, now);
-
-    jb->info.frames_in++;
-
-    if(type == JB_TYPE_VOICE) {
-      /* presently, I'm only adding VOICE frames to history and drift calculations; mostly because with the
-       * IAX integrations, I'm sending retransmitted control frames with their awkward timestamps through */
-		if (history_put(jb,ts,now,ms))
-			return JB_DROP;
-    }
-
-	/* if put into head of queue, caller needs to reschedule */
-	if (queue_put(jb,data,type,ms,ts)) {
-		return JB_SCHED;
-	}
-
-    return JB_OK;
-}
-
-
-static int _jb_get(jitterbuf *jb, jb_frame *frameout, time_in_ms_t now, long interpl) 
-{
-    jb_frame *frame;
-    time_in_ms_t diff;
-
-    /*if((now - jb_next(jb)) > 2 * jb->info.last_voice_ms) jb_warn("SCHED: %ld", (now - jb_next(jb))); */
-    /* get jitter info */
-    history_get(jb);
-
-
-    /* target */
-    jb->info.target = jb->info.jitter + jb->info.min + JB_TARGET_EXTRA; 
-
-    /* if a hard clamp was requested, use it */
-    if((jb->info.conf.max_jitterbuf) && ((jb->info.target - jb->info.min) > jb->info.conf.max_jitterbuf)) {
-	jb_dbg("clamping target from %d to %d\n", (jb->info.target - jb->info.min), jb->info.conf.max_jitterbuf);
-	jb->info.target = jb->info.min + jb->info.conf.max_jitterbuf;
-    }
-
-    diff = jb->info.target - jb->info.current;
-
-    /*    jb_warn("diff = %d lms=%d last = %d now = %d\n", diff,  */
-    /*	jb->info.last_voice_ms, jb->info.last_adjustment, now); */
-
-    /* let's work on non-silent case first */
-    if(!jb->info.silence_begin_ts) { 
-      /* we want to grow */
-      if( (diff > 0) && 
-	  /* we haven't grown in the delay length */
-	  (((jb->info.last_adjustment + JB_ADJUST_DELAY) < now) || 
-	   /* we need to grow more than the "length" we have left */
-	   (diff > queue_last(jb)  - queue_next(jb)) ) ) {
-              /* grow by interp frame len */
-	      jb->info.current += interpl;
-              jb->info.next_voice_ts += interpl;
-              jb->info.last_voice_ms = interpl;
-	      jb->info.last_adjustment = now;
-              jb->info.cnt_contig_interp++;
-	      jb_dbg("G");
-              /* assume silence instead of continuing to interpolate */
-              if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp)
-                  jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
-	      return JB_INTERP;
-      }
-
-      frame = queue_get(jb, jb->info.next_voice_ts - jb->info.current);
-
-      /* not a voice frame; just return it. */
-      if(frame && frame->type != JB_TYPE_VOICE) {
-        /* track start of silence */
-	if(frame->type == JB_TYPE_SILENCE) {
-	  jb->info.silence_begin_ts = frame->ts;
-          jb->info.cnt_contig_interp = 0;
-        }
-
-	*frameout = *frame;
-	jb->info.frames_out++;
-	jb_dbg("o");
-	return JB_OK;
-      }
-
-      /* voice frame is later than expected */
-      if(frame && frame->ts + jb->info.current < jb->info.next_voice_ts) {
-        if (frame->ts + jb->info.current > jb->info.next_voice_ts - jb->info.last_voice_ms) {
-            /* either we interpolated past this frame in the last jb_get */
-            /* or the frame is still in order, but came a little too quick */ 
-            *frameout = *frame;
-            /* reset expectation for next frame */
-            jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
-            jb->info.frames_out++;
-            decrement_losspct(jb);
-            jb->info.cnt_contig_interp = 0;
-            jb_dbg("v");
-            return JB_OK;
-        } else {
-      	    /* voice frame is late */
-            *frameout = *frame;
-            jb->info.frames_out++;
-            decrement_losspct(jb);
-            jb->info.frames_late++;
-            jb->info.frames_lost--;
-            jb_dbg("l");
-            /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
-            jb_warninfo(jb); */
-            return JB_DROP;
-        }
-      }
-
-      /* keep track of frame sizes, to allow for variable sized-frames */
-      if(frame && frame->ms > 0) {
-	jb->info.last_voice_ms = frame->ms;
-      }
-
-      /* we want to shrink; shrink at 1 frame / 500ms */
-      /* unless we don't have a frame, then shrink 1 frame */
-      /* every 80ms (though perhaps we can shrink even faster */
-      /* in this case) */
-      if(diff < -JB_TARGET_EXTRA && 
-		((!frame && jb->info.last_adjustment + 80 < now) || 
-		 (jb->info.last_adjustment + 500 < now))) {
-	jb->info.last_adjustment = now;
-        jb->info.cnt_contig_interp = 0;
-
-	if(frame)  {
-	  *frameout = *frame;
-          /* shrink by frame size we're throwing out */
-          jb->info.current -= frame->ms;
-	  jb->info.frames_out++;
-	  decrement_losspct(jb);
-	  jb->info.frames_dropped++;
-	  jb_dbg("s");
-	  return JB_DROP;
-	} else {
-          /* shrink by last_voice_ms */
-          jb->info.current -= jb->info.last_voice_ms;
-	  jb->info.frames_lost++;
-	  increment_losspct(jb);
-	  jb_dbg("S");
-	  return JB_NOFRAME;
-	}
-      }
-
-      /* lost frame */
-      if(!frame) {
-	  /* this is a bit of a hack for now, but if we're close to
-	   * target, and we find a missing frame, it makes sense to
-	   * grow, because the frame might just be a bit late;
-	   * otherwise, we presently get into a pattern where we return
-	   * INTERP for the lost frame, then it shows up next, and we
-	   * throw it away because it's late */
-	  /* I've recently only been able to replicate this using
-	   * iaxclient talking to app_echo on asterisk.  In this case,
-	   * my outgoing packets go through asterisk's (old)
-	   * jitterbuffer, and then might get an unusual increasing delay 
-	   * there if it decides to grow?? */
-	  /* Update: that might have been a different bug, that has been fixed..
-	   * But, this still seemed like a good idea, except that it ended up making a single actual
-	   * lost frame get interpolated two or more times, when there was "room" to grow, so it might
-	   * be a bit of a bad idea overall */
-	  /*if(diff > -1 * jb->info.last_voice_ms) { 
-	      jb->info.current += jb->info.last_voice_ms;
-	      jb->info.last_adjustment = now;
-	      jb_warn("g");
-	      return JB_INTERP;
-	  } */
-	  jb->info.frames_lost++;
-	  increment_losspct(jb);
-          jb->info.next_voice_ts += interpl;
-          jb->info.last_voice_ms = interpl;
-          jb->info.cnt_contig_interp++;
-          /* assume silence instead of continuing to interpolate */
-          if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp)
-            jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
-	  jb_dbg("L");
-	  return JB_INTERP;
-      }
-
-      /* normal case; return the frame, increment stuff */
-      *frameout = *frame;
-      jb->info.next_voice_ts += frame->ms;
-      jb->info.frames_out++;
-      decrement_losspct(jb);
-      jb->info.cnt_contig_interp = 0;
-      jb_dbg("v");
-      return JB_OK;
-  } else {     
-      /* TODO: after we get the non-silent case down, we'll make the
-       * silent case -- basically, we'll just grow and shrink faster
-       * here, plus handle next_voice_ts a bit differently */
-      
-      /* to disable silent special case altogether, just uncomment this: */
-       /* jb->info.silence_begin_ts = 0; */
-
-       /* shrink interpl len every 10ms during silence */
-       if (diff < -JB_TARGET_EXTRA &&
-           jb->info.last_adjustment + 10 <= now) {
-         jb->info.current -= interpl;
-         jb->info.last_adjustment = now;
-       }
-
-       frame = queue_get(jb, now - jb->info.current);
-       if(!frame) {
-	  return JB_NOFRAME;
-       } else if (frame->type != JB_TYPE_VOICE) {
-          /* normal case; in silent mode, got a non-voice frame */
-          *frameout = *frame;
-	  jb->info.frames_out++;
-          return JB_OK;
-       }
-       if (frame->ts < jb->info.silence_begin_ts) {
-          /* voice frame is late */
-	  *frameout = *frame;
-	  jb->info.frames_out++;
-	  decrement_losspct(jb);
-	  jb->info.frames_late++;
-	  jb->info.frames_lost--;
-	  jb_dbg("l");
-	  /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
-	jb_warninfo(jb); */
-	  return JB_DROP;
-       } else { 
-          /* voice frame */
-	  /* try setting current to target right away here */
-	  jb->info.current = jb->info.target;
-	  jb->info.silence_begin_ts = 0;
-	  jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
-	  jb->info.last_voice_ms = frame->ms;
-	  jb->info.frames_out++;
-	  decrement_losspct(jb);
-	  *frameout = *frame;
-	  jb_dbg("V");
-	  return JB_OK;
-       }
-  }
-}
-
-time_in_ms_t jb_next(jitterbuf *jb) 
-{
-    if(jb->info.silence_begin_ts) {
-      time_in_ms_t next = queue_next(jb);
-      if(next > 0) { 
-        /* shrink during silence */
-        if (jb->info.target - jb->info.current < -JB_TARGET_EXTRA)
-          return jb->info.last_adjustment + 10;
-        return next + jb->info.target;
-      }
-      else return JB_LONGMAX;
-    } else {
-      return jb->info.next_voice_ts;
-    }
-}
-
-int jb_get(jitterbuf *jb, jb_frame *frameout, time_in_ms_t now, long interpl) 
-{
-    int ret = _jb_get(jb,frameout,now,interpl);
-#if 0
-    static int lastts=0;
-    int thists = ((ret == JB_OK) || (ret == JB_DROP)) ? frameout->ts : 0;
-    jb_warn("jb_get(%x,%x,%ld) = %d (%d)\n", jb, frameout, now, ret, thists);
-    if(thists && thists < lastts) jb_warn("XXXX timestamp roll-back!!!\n");
-    lastts = thists;
-#endif
-    return ret;
-}
-
-int jb_getall(jitterbuf *jb, jb_frame *frameout) 
-{
-    jb_frame *frame;
-    frame = queue_getall(jb);
-
-    if(!frame) {
-      return JB_NOFRAME;
-    }
-
-    *frameout = *frame;
-    return JB_OK;
-}
-
-
-int jb_getinfo(jitterbuf *jb, jb_info *stats) 
-{
-
-    history_get(jb);
-
-    *stats = jb->info;
-
-  return JB_OK;
-}
-
-int jb_setconf(jitterbuf *jb, jb_conf *conf) 
-{
-  /* take selected settings from the struct */
-
-	jb->info.conf.max_jitterbuf = conf->max_jitterbuf;
- 	jb->info.conf.resync_threshold = conf->resync_threshold;
-	jb->info.conf.max_contig_interp = conf->max_contig_interp;
-
-  return JB_OK;
-}
-
-
+/*
+ * jitterbuf: an application-independent jitterbuffer
+ *
+ * Copyrights:
+ * Copyright (C) 2004-2005, Horizon Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek at stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ *
+ * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
+ */
+
+#include "iax2.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "jitterbuf.h"
+
+/* define these here, just for ancient compiler systems */
+#define JB_LONGMAX 2147483647L
+#define JB_LONGMIN (-JB_LONGMAX - 1L)
+
+/* MS VC can't do __VA_ARGS__ */
+#if (defined(WIN32)  ||  defined(_WIN32_WCE))  &&  defined(_MSC_VER)
+#define jb_warn if (warnf) warnf
+#define jb_err if (errf) errf
+#define jb_dbg if (dbgf) dbgf
+
+#ifdef DEEP_DEBUG
+  #define jb_dbg2 if (dbgf) dbgf
+#else
+  #define jb_dbg2 if (0) dbgf
+#endif
+
+#else
+
+#define jb_warn(...) (warnf ? warnf(__VA_ARGS__) : (void)0)
+#define jb_err(...) (errf ? errf(__VA_ARGS__) : (void)0)
+#define jb_dbg(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
+
+#ifdef DEEP_DEBUG
+#define jb_dbg2(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
+#else
+#define jb_dbg2(...) ((void)0)
+#endif
+
+#endif
+
+static jb_output_function_t warnf, errf, dbgf;
+
+void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg)
+{
+	errf = err;
+	warnf = warn;
+	dbgf = dbg;
+}
+
+static void increment_losspct(jitterbuf *jb)
+{
+	jb->info.losspct = (100000 + 499 * jb->info.losspct)/500;
+}
+
+static void decrement_losspct(jitterbuf *jb)
+{
+	jb->info.losspct = (499 * jb->info.losspct)/500;
+}
+
+void jb_reset(jitterbuf *jb)
+{
+	/* only save settings */
+	jb_conf s = jb->info.conf;
+	memset(jb, 0, sizeof(*jb));
+	jb->info.conf = s;
+
+	/* initialize length, using the configured value */
+	jb->info.current = jb->info.target = jb->info.conf.target_extra;
+	jb->info.silence_begin_ts = -1;
+}
+
+jitterbuf * jb_new()
+{
+	jitterbuf *jb;
+
+	if (!(jb = (jitterbuf *)malloc(sizeof(*jb))))
+		return NULL;
+
+	jb->info.conf.target_extra = JB_TARGET_EXTRA;
+
+	jb_reset(jb);
+
+	jb_dbg2("jb_new() = %x\n", jb);
+	return jb;
+}
+
+void jb_destroy(jitterbuf *jb)
+{
+	jb_frame *frame;
+	jb_dbg2("jb_destroy(%x)\n", jb);
+
+	/* free all the frames on the "free list" */
+	frame = jb->free;
+	while (frame != NULL) {
+		jb_frame *next = frame->next;
+		free(frame);
+		frame = next;
+	}
+
+	/* free ourselves! */
+	free(jb);
+}
+
+
+
+#if 0
+static int longcmp(const void *a, const void *b)
+{
+	return *(long *)a - *(long *)b;
+}
+#endif
+
+/* simple history manipulation */
+/* maybe later we can make the history buckets variable size, or something? */
+/* drop parameter determines whether we will drop outliers to minimize
+ * delay */
+static int history_put(jitterbuf *jb, time_in_ms_t ts, time_in_ms_t now, long ms)
+{
+	time_in_ms_t delay = now - (ts - jb->info.resync_offset);
+	time_in_ms_t threshold = 2 * jb->info.jitter + jb->info.conf.resync_threshold;
+	time_in_ms_t kicked;
+
+	/* don't add special/negative times to history */
+	if (ts <= 0)
+		return 0;
+
+	/* check for drastic change in delay */
+	if (jb->info.conf.resync_threshold != -1) {
+		if (iax_abs(delay - jb->info.last_delay) > threshold) {
+			jb->info.cnt_delay_discont++;
+			if (jb->info.cnt_delay_discont > 3) {
+				/* resync the jitterbuffer */
+				jb->info.cnt_delay_discont = 0;
+				jb->hist_ptr = 0;
+				jb->hist_maxbuf_valid = 0;
+
+				jb_warn("Resyncing the jb. last_delay %ld, this delay %ld, threshold %ld, new offset %ld\n", jb->info.last_delay, delay, threshold, ts - now);
+				jb->info.resync_offset = ts - now;
+				jb->info.last_delay = delay = 0; /* after resync, frame is right on time */
+			} else {
+				return -1;
+			}
+		} else {
+			jb->info.last_delay = delay;
+			jb->info.cnt_delay_discont = 0;
+		}
+	}
+
+	kicked = jb->history[jb->hist_ptr % JB_HISTORY_SZ];
+
+	jb->history[(jb->hist_ptr++) % JB_HISTORY_SZ] = delay;
+
+	/* optimization; the max/min buffers don't need to be recalculated,
+	 * if this packet's entry doesn't change them. This happens if this
+	 * packet is not involved, _and_ any packet that got kicked out of
+	 * the history is also not involved. We do a number of comparisons,
+	 * but it's probably still worthwhile, because it will usually
+	 * succeed, and should be a lot faster than going through all 500
+	 * packets in history */
+	if (!jb->hist_maxbuf_valid)
+		return 0;
+
+	/* don't do this until we've filled history
+	 * (reduces some edge cases below) */
+	if (jb->hist_ptr < JB_HISTORY_SZ)
+		goto invalidate;
+
+	/* if the new delay would go into min */
+	if (delay < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
+		goto invalidate;
+
+	/* or max.. */
+	if (delay > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
+		goto invalidate;
+
+	/* or the kicked delay would be in min */
+	if (kicked <= jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
+		goto invalidate;
+
+	if (kicked >= jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
+		goto invalidate;
+
+	/* if we got here, we don't need to invalidate, 'cause this delay didn't
+	 * affect things */
+	return 0;
+	/* end optimization */
+
+
+invalidate:
+	jb->hist_maxbuf_valid = 0;
+	return 0;
+}
+
+static void history_calc_maxbuf(jitterbuf *jb)
+{
+	int i,j;
+
+	if (jb->hist_ptr == 0)
+		return;
+
+
+	/* initialize maxbuf/minbuf to the latest value */
+	for (i=0;i<JB_HISTORY_MAXBUF_SZ;i++) {
+		/*
+		 * jb->hist_maxbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
+		 * jb->hist_minbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
+		 */
+		jb->hist_maxbuf[i] = JB_LONGMIN;
+		jb->hist_minbuf[i] = JB_LONGMAX;
+	}
+
+	/* use insertion sort to populate maxbuf */
+	/* we want it to be the top "n" values, in order */
+
+	/* start at the beginning, or JB_HISTORY_SZ frames ago */
+	i = (jb->hist_ptr > JB_HISTORY_SZ) ? (jb->hist_ptr - JB_HISTORY_SZ) : 0;
+
+	for (;i<jb->hist_ptr;i++) {
+	time_in_ms_t toins = jb->history[i % JB_HISTORY_SZ];
+
+		/* if the maxbuf should get this */
+		if (toins > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])  {
+
+			/* insertion-sort it into the maxbuf */
+			for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
+				/* found where it fits */
+				if (toins > jb->hist_maxbuf[j]) {
+					/* move over */
+					memmove(jb->hist_maxbuf + j + 1, jb->hist_maxbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_maxbuf[0]));
+					/* insert */
+					jb->hist_maxbuf[j] = toins;
+
+					break;
+				}
+			}
+		}
+
+		/* if the minbuf should get this */
+		if (toins < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])  {
+
+			/* insertion-sort it into the maxbuf */
+			for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
+				/* found where it fits */
+				if (toins < jb->hist_minbuf[j]) {
+					/* move over */
+					memmove(jb->hist_minbuf + j + 1, jb->hist_minbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_minbuf[0]));
+					/* insert */
+					jb->hist_minbuf[j] = toins;
+
+					break;
+				}
+			}
+		}
+
+		if (0) {
+			int k;
+			fprintf(stderr, "toins = %ld\n", toins);
+			fprintf(stderr, "maxbuf =");
+			for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
+				fprintf(stderr, "%ld ", jb->hist_maxbuf[k]);
+			fprintf(stderr, "\nminbuf =");
+			for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
+				fprintf(stderr, "%ld ", jb->hist_minbuf[k]);
+			fprintf(stderr, "\n");
+		}
+	}
+
+	jb->hist_maxbuf_valid = 1;
+}
+
+static void history_get(jitterbuf *jb)
+{
+    time_in_ms_t max, min, jitter;
+	int index;
+	int count;
+
+	if (!jb->hist_maxbuf_valid)
+		history_calc_maxbuf(jb);
+
+	/* count is how many items in history we're examining */
+	count = (jb->hist_ptr < JB_HISTORY_SZ) ? jb->hist_ptr : JB_HISTORY_SZ;
+
+	/* index is the "n"ths highest/lowest that we'll look for */
+	index = count * JB_HISTORY_DROPPCT / 100;
+
+	/* sanity checks for index */
+	if (index > (JB_HISTORY_MAXBUF_SZ - 1))
+		index = JB_HISTORY_MAXBUF_SZ - 1;
+
+
+	if (index < 0) {
+		jb->info.min = 0;
+		jb->info.jitter = 0;
+		return;
+	}
+
+	max = jb->hist_maxbuf[index];
+	min = jb->hist_minbuf[index];
+
+	jitter = max - min;
+
+	/* these debug stmts compare the difference between looking at the absolute jitter, and the
+	 * values we get by throwing away the outliers */
+	/*
+	fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", index, min, max, jitter);
+	fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", 0, jb->hist_minbuf[0], jb->hist_maxbuf[0], jb->hist_maxbuf[0]-jb->hist_minbuf[0]);
+	*/
+
+	jb->info.min = min;
+	jb->info.jitter = jitter;
+}
+
+/* returns 1 if frame was inserted into head of queue, 0 otherwise */
+static int queue_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, time_in_ms_t ts)
+{
+	jb_frame *frame;
+	jb_frame *p;
+	int head = 0;
+	time_in_ms_t resync_ts = ts - jb->info.resync_offset;
+
+	if ((frame = jb->free)) {
+		jb->free = frame->next;
+	} else if (!(frame = (jb_frame *)malloc(sizeof(*frame)))) {
+		jb_err("cannot allocate frame\n");
+		return 0;
+	}
+
+	jb->info.frames_cur++;
+
+	frame->data = data;
+	frame->ts = resync_ts;
+	frame->ms = ms;
+	frame->type = type;
+
+	/*
+	 * frames are a circular list, jb-frames points to to the lowest ts,
+	 * jb->frames->prev points to the highest ts
+	 */
+
+	if (!jb->frames) {  /* queue is empty */
+		jb->frames = frame;
+		frame->next = frame;
+		frame->prev = frame;
+		head = 1;
+	} else if (resync_ts < jb->frames->ts) {
+		frame->next = jb->frames;
+		frame->prev = jb->frames->prev;
+
+		frame->next->prev = frame;
+		frame->prev->next = frame;
+
+		/* frame is out of order */
+		jb->info.frames_ooo++;
+
+		jb->frames = frame;
+		head = 1;
+	} else {
+		p = jb->frames;
+
+		/* frame is out of order */
+		if (resync_ts < p->prev->ts) jb->info.frames_ooo++;
+
+		while (resync_ts < p->prev->ts && p->prev != jb->frames)
+			p = p->prev;
+
+		frame->next = p;
+		frame->prev = p->prev;
+
+		frame->next->prev = frame;
+		frame->prev->next = frame;
+	}
+	return head;
+}
+
+static time_in_ms_t queue_next(jitterbuf *jb) 
+{
+	if (jb->frames)
+		return jb->frames->ts;
+	else
+		return -1;
+}
+
+static time_in_ms_t queue_last(jitterbuf *jb) 
+{
+	if (jb->frames)
+		return jb->frames->prev->ts;
+	else
+		return -1;
+}
+
+static jb_frame *_queue_get(jitterbuf *jb, time_in_ms_t ts, int all) 
+{
+	jb_frame *frame;
+	frame = jb->frames;
+
+	if (!frame)
+		return NULL;
+
+	/*jb_warn("queue_get: ASK %ld FIRST %ld\n", ts, frame->ts); */
+
+	if (all || ts >= frame->ts) {
+		/* remove this frame */
+		frame->prev->next = frame->next;
+		frame->next->prev = frame->prev;
+
+		if (frame->next == frame)
+			jb->frames = NULL;
+		else
+			jb->frames = frame->next;
+
+
+		/* insert onto "free" single-linked list */
+		frame->next = jb->free;
+		jb->free = frame;
+
+		jb->info.frames_cur--;
+
+		/* we return the frame pointer, even though it's on free list,
+		 * but caller must copy data */
+		return frame;
+	}
+
+	return NULL;
+}
+
+static jb_frame *queue_get(jitterbuf *jb, time_in_ms_t ts) 
+{
+	return _queue_get(jb,ts,0);
+}
+
+static jb_frame *queue_getall(jitterbuf *jb)
+{
+	return _queue_get(jb,0,1);
+}
+
+#if 0
+/* some diagnostics */
+static void jb_dbginfo(jitterbuf *jb)
+{
+	if (dbgf == NULL)
+		return;
+
+	jb_dbg("\njb info: fin=%ld fout=%ld flate=%ld flost=%ld fdrop=%ld fcur=%ld\n",
+		jb->info.frames_in, jb->info.frames_out, jb->info.frames_late, jb->info.frames_lost, jb->info.frames_dropped, jb->info.frames_cur);
+
+	jb_dbg("jitter=%ld current=%ld target=%ld min=%ld sil=%d len=%d len/fcur=%ld\n",
+		jb->info.jitter, jb->info.current, jb->info.target, jb->info.min, jb->info.silence_begin_ts, jb->info.current - jb->info.min,
+		jb->info.frames_cur ? (jb->info.current - jb->info.min)/jb->info.frames_cur : -8);
+	if (jb->info.frames_in > 0)
+		jb_dbg("jb info: Loss PCT = %ld%%, Late PCT = %ld%%\n",
+		jb->info.frames_lost * 100/(jb->info.frames_in + jb->info.frames_lost),
+		jb->info.frames_late * 100/jb->info.frames_in);
+	jb_dbg("jb info: queue %d -> %d.  last_ts %d (queue len: %d) last_ms %d\n",
+		queue_next(jb),
+		queue_last(jb),
+		jb->info.next_voice_ts,
+		queue_last(jb) - queue_next(jb),
+		jb->info.last_voice_ms);
+}
+#endif
+
+#ifdef DEEP_DEBUG
+static void jb_chkqueue(jitterbuf *jb)
+{
+	int i=0;
+	jb_frame *p = jb->frames;
+
+	if (!p) {
+		return;
+	}
+
+	do {
+		if (p->next == NULL)  {
+			jb_err("Queue is BROKEN at item [%d]", i);
+		}
+		i++;
+		p=p->next;
+	} while (p->next != jb->frames);
+}
+
+static void jb_dbgqueue(jitterbuf *jb)
+{
+	int i=0;
+	jb_frame *p = jb->frames;
+
+	jb_dbg("queue: ");
+
+	if (!p) {
+		jb_dbg("EMPTY\n");
+		return;
+	}
+
+	do {
+		jb_dbg("[%d]=%ld ", i++, p->ts);
+		p=p->next;
+	} while (p->next != jb->frames);
+
+	jb_dbg("\n");
+}
+#endif
+
+enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, time_in_ms_t ts, time_in_ms_t now)
+{
+	jb_dbg2("jb_put(%x,%x,%ld,%ld,%ld)\n", jb, data, ms, ts, now);
+
+	jb->info.frames_in++;
+
+	if (type == JB_TYPE_VOICE) {
+		/* presently, I'm only adding VOICE frames to history and drift
+		 * calculations; mostly because with the IAX integrations, I'm
+		 * sending retransmitted control frames with their awkward
+		 * timestamps through
+		 */
+		if (history_put(jb,ts,now,ms))
+			return JB_DROP;
+	}
+
+	/* if put into head of queue, caller needs to reschedule */
+	if (queue_put(jb,data,type,ms,ts)) {
+		return JB_SCHED;
+	}
+
+	return JB_OK;
+}
+
+
+static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, time_in_ms_t now, long interpl)
+{
+	jb_frame *frame;
+	time_in_ms_t diff;
+
+	/*if ((now - jb_next(jb)) > 2 * jb->info.last_voice_ms) jb_warn("SCHED: %ld", (now - jb_next(jb))); */
+	/* get jitter info */
+	history_get(jb);
+
+
+	/* target */
+	jb->info.target = jb->info.jitter + jb->info.min + jb->info.conf.target_extra;
+
+	/* if a hard clamp was requested, use it */
+	if ((jb->info.conf.max_jitterbuf) && ((jb->info.target - jb->info.min) > jb->info.conf.max_jitterbuf)) {
+		jb_dbg("clamping target from %d to %d\n", (jb->info.target - jb->info.min), jb->info.conf.max_jitterbuf);
+		jb->info.target = jb->info.min + jb->info.conf.max_jitterbuf;
+	}
+
+	diff = jb->info.target - jb->info.current;
+
+	/* jb_warn("diff = %d lms=%d last = %d now = %d\n", diff,  */
+	/*	jb->info.last_voice_ms, jb->info.last_adjustment, now); */
+
+	/* let's work on non-silent case first */
+	if (!jb->info.silence_begin_ts) {
+		/* we want to grow */
+		if ((diff > 0) &&
+			/* we haven't grown in the delay length */
+			(((jb->info.last_adjustment + JB_ADJUST_DELAY) < now) ||
+			/* we need to grow more than the "length" we have left */
+			(diff > queue_last(jb) - queue_next(jb)) ) ) {
+			/* grow by interp frame length */
+			jb->info.current += interpl;
+			jb->info.next_voice_ts += interpl;
+			jb->info.last_voice_ms = interpl;
+			jb->info.last_adjustment = now;
+			jb->info.cnt_contig_interp++;
+			/* assume silence instead of continuing to interpolate */
+			if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
+				jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
+			}
+			jb_dbg("G");
+			return JB_INTERP;
+		}
+
+		frame = queue_get(jb, jb->info.next_voice_ts - jb->info.current);
+
+		/* not a voice frame; just return it. */
+		if (frame && frame->type != JB_TYPE_VOICE) {
+			/* track start of silence */
+			if (frame->type == JB_TYPE_SILENCE) {
+				jb->info.silence_begin_ts = frame->ts;
+				jb->info.cnt_contig_interp = 0;
+			}
+
+			*frameout = *frame;
+			jb->info.frames_out++;
+			jb_dbg("o");
+			return JB_OK;
+		}
+
+		/* voice frame is later than expected */
+		if (frame && frame->ts + jb->info.current < jb->info.next_voice_ts) {
+			if (frame->ts + jb->info.current > jb->info.next_voice_ts - jb->info.last_voice_ms) {
+				/* either we interpolated past this frame in the last jb_get */
+				/* or the frame is still in order, but came a little too quick */
+				*frameout = *frame;
+				/* reset expectation for next frame */
+				jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
+				jb->info.frames_out++;
+				decrement_losspct(jb);
+				jb->info.cnt_contig_interp = 0;
+				jb_dbg("v");
+				return JB_OK;
+			} else {
+				/* voice frame is late */
+				*frameout = *frame;
+				jb->info.frames_out++;
+				decrement_losspct(jb);
+				jb->info.frames_late++;
+				jb->info.frames_lost--;
+				jb_dbg("l");
+				/*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
+				  jb_warninfo(jb); */
+				return JB_DROP;
+			}
+		}
+
+		/* keep track of frame sizes, to allow for variable sized-frames */
+		if (frame && frame->ms > 0) {
+			jb->info.last_voice_ms = frame->ms;
+		}
+
+		/* we want to shrink; shrink at 1 frame / 500ms */
+		/* unless we don't have a frame, then shrink 1 frame */
+		/* every 80ms (though perhaps we can shrink even faster */
+		/* in this case) */
+		if (diff < -jb->info.conf.target_extra &&
+				((!frame && jb->info.last_adjustment + 80 < now) ||
+				 (jb->info.last_adjustment + 500 < now))) {
+
+			jb->info.last_adjustment = now;
+			jb->info.cnt_contig_interp = 0;
+
+			if (frame) {
+				*frameout = *frame;
+				/* shrink by frame size we're throwing out */
+				jb->info.current -= frame->ms;
+				jb->info.frames_out++;
+				decrement_losspct(jb);
+				jb->info.frames_dropped++;
+				jb_dbg("s");
+				return JB_DROP;
+			} else {
+				/* shrink by last_voice_ms */
+				jb->info.current -= jb->info.last_voice_ms;
+				jb->info.frames_lost++;
+				increment_losspct(jb);
+				jb_dbg("S");
+				return JB_NOFRAME;
+			}
+		}
+
+		/* lost frame */
+		if (!frame) {
+			/* this is a bit of a hack for now, but if we're close to
+			 * target, and we find a missing frame, it makes sense to
+			 * grow, because the frame might just be a bit late;
+			 * otherwise, we presently get into a pattern where we return
+			 * INTERP for the lost frame, then it shows up next, and we
+			 * throw it away because it's late */
+			/* I've recently only been able to replicate this using
+			 * iaxclient talking to app_echo on asterisk.  In this case,
+			 * my outgoing packets go through asterisk's (old)
+			 * jitterbuffer, and then might get an unusual increasing delay
+			 * there if it decides to grow?? */
+			/* Update: that might have been a different bug, that has been fixed..
+			 * But, this still seemed like a good idea, except that it ended up making a single actual
+			 * lost frame get interpolated two or more times, when there was "room" to grow, so it might
+			 * be a bit of a bad idea overall */
+			/*if (diff > -1 * jb->info.last_voice_ms) {
+				jb->info.current += jb->info.last_voice_ms;
+				jb->info.last_adjustment = now;
+				jb_warn("g");
+				return JB_INTERP;
+			} */
+			jb->info.frames_lost++;
+			increment_losspct(jb);
+			jb->info.next_voice_ts += interpl;
+			jb->info.last_voice_ms = interpl;
+			jb->info.cnt_contig_interp++;
+			/* assume silence instead of continuing to interpolate */
+			if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
+				jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
+			}
+			jb_dbg("L");
+			return JB_INTERP;
+		}
+
+		/* normal case; return the frame, increment stuff */
+		*frameout = *frame;
+		jb->info.next_voice_ts += frame->ms;
+		jb->info.frames_out++;
+		jb->info.cnt_contig_interp = 0;
+		decrement_losspct(jb);
+		jb_dbg("v");
+		return JB_OK;
+	} else {
+		/* TODO: after we get the non-silent case down, we'll make the
+		 * silent case -- basically, we'll just grow and shrink faster
+		 * here, plus handle next_voice_ts a bit differently */
+
+		/* to disable silent special case altogether, just uncomment this: */
+		/* jb->info.silence_begin_ts = 0; */
+
+		/* shrink interpl len every 10ms during silence */
+		if (diff < -jb->info.conf.target_extra &&
+			jb->info.last_adjustment + 10 <= now) {
+			jb->info.current -= interpl;
+			jb->info.last_adjustment = now;
+		}
+
+		frame = queue_get(jb, now - jb->info.current);
+		if (!frame) {
+			return JB_NOFRAME;
+		} else if (frame->type != JB_TYPE_VOICE) {
+			/* normal case; in silent mode, got a non-voice frame */
+			*frameout = *frame;
+			jb->info.frames_out++;
+			return JB_OK;
+		}
+		if (frame->ts < jb->info.silence_begin_ts) {
+			/* voice frame is late */
+			*frameout = *frame;
+			jb->info.frames_out++;
+			decrement_losspct(jb);
+			jb->info.frames_late++;
+			jb->info.frames_lost--;
+			jb_dbg("l");
+			/*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
+			  jb_warninfo(jb); */
+			return JB_DROP;
+		} else {
+			/* voice frame */
+			/* try setting current to target right away here */
+			jb->info.current = jb->info.target;
+			jb->info.silence_begin_ts = 0;
+			jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
+			jb->info.last_voice_ms = frame->ms;
+			jb->info.frames_out++;
+			decrement_losspct(jb);
+			*frameout = *frame;
+			jb_dbg("V");
+			return JB_OK;
+		}
+	}
+}
+
+time_in_ms_t jb_next(jitterbuf *jb)
+{
+	if (jb->info.silence_begin_ts) {
+		if (jb->frames) {
+			time_in_ms_t next = queue_next(jb);
+			history_get(jb);
+			/* shrink during silence */
+			if (jb->info.target - jb->info.current < -jb->info.conf.target_extra)
+				return jb->info.last_adjustment + 10;
+			return next + jb->info.target;
+		}
+		else
+			return JB_LONGMAX;
+	} else {
+		return jb->info.next_voice_ts;
+	}
+}
+
+enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frameout, time_in_ms_t now, long interpl)
+{
+	enum jb_return_code ret = _jb_get(jb, frameout, now, interpl);
+#if 0
+	static int lastts=0;
+	int thists = ((ret == JB_OK) || (ret == JB_DROP)) ? frameout->ts : 0;
+	jb_warn("jb_get(%x,%x,%ld) = %d (%d)\n", jb, frameout, now, ret, thists);
+	if (thists && thists < lastts) jb_warn("XXXX timestamp roll-back!!!\n");
+	lastts = thists;
+#endif
+	return ret;
+}
+
+enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
+{
+	jb_frame *frame;
+	frame = queue_getall(jb);
+
+	if (!frame) {
+		return JB_NOFRAME;
+	}
+
+	*frameout = *frame;
+	return JB_OK;
+}
+
+
+enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats)
+{
+	history_get(jb);
+
+	*stats = jb->info;
+
+	return JB_OK;
+}
+
+enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
+{
+	/* take selected settings from the struct */
+
+	jb->info.conf.max_jitterbuf = conf->max_jitterbuf;
+	jb->info.conf.resync_threshold = conf->resync_threshold;
+	jb->info.conf.max_contig_interp = conf->max_contig_interp;
+
+	/* -1 indicates use of the default JB_TARGET_EXTRA value */
+	jb->info.conf.target_extra = ( conf->target_extra == -1 )
+		? JB_TARGET_EXTRA
+		: conf->target_extra
+		;
+
+	/* update these to match new target_extra setting */
+	jb->info.current = jb->info.conf.target_extra;
+	jb->info.target = jb->info.conf.target_extra;
+
+	return JB_OK;
+}
+
+

Modified: freeswitch/branches/greenlizard/libs/iax/src/jitterbuf.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/iax/src/jitterbuf.h	(original)
+++ freeswitch/branches/greenlizard/libs/iax/src/jitterbuf.h	Mon May 14 10:50:37 2007
@@ -1,160 +1,162 @@
-/*
- * jitterbuf: an application-independent jitterbuffer
- *
- * Copyrights:
- * Copyright (C) 2004-2005, Horizon Wimba, Inc.
- *
- * Contributors:
- * Steve Kann <stevek at stevek.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU Lesser (Library) General Public License
- *
- * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
- */
-
-#ifndef _JITTERBUF_H_
-#define _JITTERBUF_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* configuration constants */
-	/* Number of historical timestamps to use in calculating jitter and drift */
-#define JB_HISTORY_SZ		500	
-	/* what percentage of timestamps should we drop from the history when we examine it;
-	 * this might eventually be something made configurable */
-#define JB_HISTORY_DROPPCT	3
-	/* the maximum droppct we can handle (say it was configurable). */
-#define JB_HISTORY_DROPPCT_MAX	4
-	/* the size of the buffer we use to keep the top and botton timestamps for dropping */
-#define JB_HISTORY_MAXBUF_SZ	JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100 
-	/* amount of additional jitterbuffer adjustment  */
-#define JB_TARGET_EXTRA 40
-	/* ms between growing and shrinking; may not be honored if jitterbuffer runs out of space */
-#define JB_ADJUST_DELAY 40
-
-
-/* return codes */
-#define JB_OK		0
-#define JB_EMPTY	1
-#define JB_NOFRAME	2
-#define JB_INTERP	3
-#define JB_DROP		4
-#define JB_SCHED	5
-
-/* frame types */
-#define JB_TYPE_CONTROL	0
-#define JB_TYPE_VOICE	1
-#define JB_TYPE_VIDEO	2  /* reserved */
-#define JB_TYPE_SILENCE	3
-
-
-typedef struct jb_conf {
-	/* settings */
-	long max_jitterbuf;	/* defines a hard clamp to use in setting the jitter buffer delay */
- 	long resync_threshold;  /* the jb will resync when delay increases to (2 * jitter) + this param */
-	long max_contig_interp; /* the max interp frames to return in a row */
-} jb_conf;
-
-typedef struct jb_info {
-	jb_conf conf;
-
-	/* statistics */
-	long frames_in;  	/* number of frames input to the jitterbuffer.*/
-	long frames_out;  	/* number of frames output from the jitterbuffer.*/
-	long frames_late; 	/* number of frames which were too late, and dropped.*/
-	long frames_lost; 	/* number of missing frames.*/
-	long frames_dropped; 	/* number of frames dropped (shrinkage) */
-	long frames_ooo; 	/* number of frames received out-of-order */
-	long frames_cur; 	/* number of frames presently in jb, awaiting delivery.*/
-	time_in_ms_t jitter; 		/* jitter measured within current history interval*/
-	time_in_ms_t min;		/* minimum lateness within current history interval */
-	time_in_ms_t current; 		/* the present jitterbuffer adjustment */
-	time_in_ms_t target; 		/* the target jitterbuffer adjustment */
-	long losspct; 		/* recent lost frame percentage (* 1000) */
-	time_in_ms_t next_voice_ts;	/* the ts of the next frame to be read from the jb - in receiver's time */
-	long last_voice_ms;	/* the duration of the last voice frame */
-	time_in_ms_t silence_begin_ts;	/* the time of the last CNG frame, when in silence */
-	time_in_ms_t last_adjustment;   /* the time of the last adjustment */
-	time_in_ms_t last_delay;        /* the last now added to history */
-	long cnt_delay_discont;	/* the count of discontinuous delays */
-	time_in_ms_t resync_offset;     /* the amount to offset ts to support resyncs */
-	long cnt_contig_interp; /* the number of contiguous interp frames returned */
-} jb_info;
-
-typedef struct jb_frame {
-	void *data;		/* the frame data */
-	time_in_ms_t ts;	/* the relative delivery time expected */
-	long ms;	/* the time covered by this frame, in sec/8000 */
-	int  type;	/* the type of frame */
-	struct jb_frame *next, *prev;
-} jb_frame;
-
-typedef struct jitterbuf {
-	jb_info info;
-
-	/* history */
-	time_in_ms_t history[JB_HISTORY_SZ];   		/* history */
-	int  hist_ptr;				/* points to index in history for next entry */
-	time_in_ms_t hist_maxbuf[JB_HISTORY_MAXBUF_SZ];	/* a sorted buffer of the max delays (highest first) */
-	time_in_ms_t hist_minbuf[JB_HISTORY_MAXBUF_SZ];	/* a sorted buffer of the min delays (lowest first) */
-	int  hist_maxbuf_valid;			/* are the "maxbuf"/minbuf valid? */
-
-
-	jb_frame *frames; 		/* queued frames */
-	jb_frame *free; 		/* free frames (avoid malloc?) */
-} jitterbuf;
-
-
-/* new jitterbuf */
-extern jitterbuf *		jb_new(void);
-
-/* destroy jitterbuf */
-extern void			jb_destroy(jitterbuf *jb);
-
-/* reset jitterbuf */
-/* NOTE:  The jitterbuffer should be empty before you call this, otherwise
- * you will leak queued frames, and some internal structures */
-extern void			jb_reset(jitterbuf *jb);
-
-/* queue a frame data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time) 
- * now=now (in receiver's time) return value is one of 
- * JB_OK: Frame added. Last call to jb_next() still valid
- * JB_DROP: Drop this frame immediately
- * JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame
- */
-extern int 			jb_put(jitterbuf *jb, void *data, int type, long ms, time_in_ms_t ts, time_in_ms_t now);
-
-/* get a frame for time now (receiver's time)  return value is one of
- * JB_OK:  You've got frame!
- * JB_DROP: Here's an audio frame you should just drop.  Ask me again for this time..
- * JB_NOFRAME: There's no frame scheduled for this time.
- * JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame) 
- * JB_EMPTY: The jb is empty.
- */
-extern int			jb_get(jitterbuf *jb, jb_frame *frame, time_in_ms_t now, long interpl);
-
-/* unconditionally get frames from jitterbuf until empty */
-extern int jb_getall(jitterbuf *jb, jb_frame *frameout);
-
-/* when is the next frame due out, in receiver's time (0=EMPTY) 
- * This value may change as frames are added (esp non-audio frames) */
-extern time_in_ms_t		jb_next(jitterbuf *jb);
-
-/* get jitterbuf info: only "statistics" may be valid */
-extern int			jb_getinfo(jitterbuf *jb, jb_info *stats);
-
-/* set jitterbuf conf */
-extern int			jb_setconf(jitterbuf *jb, jb_conf *conf);
-
-typedef 		void (*jb_output_function_t)(const char *fmt, ...);
-extern void 			jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
+/*
+ * jitterbuf: an application-independent jitterbuffer
+ *
+ * Copyrights:
+ * Copyright (C) 2004-2005, Horizon Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek at stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ *
+ * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
+ */
+
+#ifndef _JITTERBUF_H_
+#define _JITTERBUF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* configuration constants */
+	/* Number of historical timestamps to use in calculating jitter and drift */
+#define JB_HISTORY_SZ		500
+	/* what percentage of timestamps should we drop from the history when we examine it;
+	 * this might eventually be something made configurable */
+#define JB_HISTORY_DROPPCT	3
+	/* the maximum droppct we can handle (say it was configurable). */
+#define JB_HISTORY_DROPPCT_MAX	4
+	/* the size of the buffer we use to keep the top and botton timestamps for dropping */
+#define JB_HISTORY_MAXBUF_SZ	JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100
+	/* amount of additional jitterbuffer adjustment  */
+#define JB_TARGET_EXTRA 40
+	/* ms between growing and shrinking; may not be honored if jitterbuffer runs out of space */
+#define JB_ADJUST_DELAY 40
+
+enum jb_return_code {
+	/* return codes */
+	JB_OK,            /* 0 */
+	JB_EMPTY,         /* 1 */
+	JB_NOFRAME,       /* 2 */
+	JB_INTERP,        /* 3 */
+	JB_DROP,          /* 4 */
+	JB_SCHED          /* 5 */
+};
+
+enum jb_frame_type {
+/* frame types */
+	JB_TYPE_CONTROL,  /* 0            */
+	JB_TYPE_VOICE,    /* 1            */
+	JB_TYPE_VIDEO,    /* 2 - reserved */
+	JB_TYPE_SILENCE   /* 3            */
+};
+
+typedef struct jb_conf {
+	/* settings */
+	long max_jitterbuf;     /* defines a hard clamp to use in setting the jitter buffer delay */
+	long resync_threshold;  /* the jb will resync when delay increases to (2 * jitter) + this param */
+	long max_contig_interp; /* the max interp frames to return in a row */
+	long target_extra;      /* amount of additional jitterbuffer adjustment, overrides JB_TARGET_EXTRA */
+} jb_conf;
+
+typedef struct jb_info {
+	jb_conf conf;
+
+	/* statistics */
+	long frames_in;		/* number of frames input to the jitterbuffer.*/
+	long frames_out;	/* number of frames output from the jitterbuffer.*/
+	long frames_late;	/* number of frames which were too late, and dropped.*/
+	long frames_lost;	/* number of missing frames.*/
+	long frames_dropped;	/* number of frames dropped (shrinkage) */
+	long frames_ooo;	/* number of frames received out-of-order */
+	long frames_cur;	/* number of frames presently in jb, awaiting delivery.*/
+	time_in_ms_t jitter; 		/* jitter measured within current history interval*/
+	time_in_ms_t min;		/* minimum lateness within current history interval */
+	time_in_ms_t current; 		/* the present jitterbuffer adjustment */
+	time_in_ms_t target; 		/* the target jitterbuffer adjustment */
+	long losspct;		/* recent lost frame percentage (* 1000) */
+	time_in_ms_t next_voice_ts;	/* the ts of the next frame to be read from the jb - in receiver's time */
+	long last_voice_ms;	/* the duration of the last voice frame */
+	time_in_ms_t silence_begin_ts;	/* the time of the last CNG frame, when in silence */
+	time_in_ms_t last_adjustment;   /* the time of the last adjustment */
+	time_in_ms_t last_delay;        /* the last now added to history */
+	long cnt_delay_discont;	/* the count of discontinuous delays */
+	time_in_ms_t resync_offset;     /* the amount to offset ts to support resyncs */
+	long cnt_contig_interp;	/* the number of contiguous interp frames returned */
+} jb_info;
+
+typedef struct jb_frame {
+	void *data;               /* the frame data */
+	time_in_ms_t ts;	/* the relative delivery time expected */
+	long ms;                  /* the time covered by this frame, in sec/8000 */
+	enum jb_frame_type type;  /* the type of frame */
+	struct jb_frame *next, *prev;
+} jb_frame;
+
+typedef struct jitterbuf {
+	jb_info info;
+
+	/* history */
+	time_in_ms_t history[JB_HISTORY_SZ];   		/* history */
+	int  hist_ptr;				/* points to index in history for next entry */
+	time_in_ms_t hist_maxbuf[JB_HISTORY_MAXBUF_SZ];	/* a sorted buffer of the max delays (highest first) */
+	time_in_ms_t hist_minbuf[JB_HISTORY_MAXBUF_SZ];	/* a sorted buffer of the min delays (lowest first) */
+	int  hist_maxbuf_valid;			/* are the "maxbuf"/minbuf valid? */
+
+	jb_frame *frames;		/* queued frames */
+	jb_frame *free;			/* free frames (avoid malloc?) */
+} jitterbuf;
+
+
+/* new jitterbuf */
+jitterbuf *		jb_new(void);
+
+/* destroy jitterbuf */
+void			jb_destroy(jitterbuf *jb);
+
+/* reset jitterbuf */
+/* NOTE:  The jitterbuffer should be empty before you call this, otherwise
+ * you will leak queued frames, and some internal structures */
+void			jb_reset(jitterbuf *jb);
+
+/* queue a frame data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time)
+ * now=now (in receiver's time) return value is one of
+ * JB_OK: Frame added. Last call to jb_next() still valid
+ * JB_DROP: Drop this frame immediately
+ * JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame
+ */
+enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, time_in_ms_t ts, time_in_ms_t now);
+
+/* get a frame for time now (receiver's time)  return value is one of
+ * JB_OK:  You've got frame!
+ * JB_DROP: Here's an audio frame you should just drop.  Ask me again for this time..
+ * JB_NOFRAME: There's no frame scheduled for this time.
+ * JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame)
+ * JB_EMPTY: The jb is empty.
+ */
+enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, time_in_ms_t now, long interpl);
+
+/* unconditionally get frames from jitterbuf until empty */
+enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout);
+
+/* when is the next frame due out, in receiver's time (0=EMPTY)
+ * This value may change as frames are added (esp non-audio frames) */
+time_in_ms_t			jb_next(jitterbuf *jb);
+
+/* get jitterbuf info: only "statistics" may be valid */
+enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats);
+
+/* set jitterbuf conf */
+enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf);
+
+typedef			void (*jb_output_function_t)(const char *fmt, ...);
+extern void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif

Modified: freeswitch/branches/greenlizard/libs/iax/src/md5.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/iax/src/md5.h	(original)
+++ freeswitch/branches/greenlizard/libs/iax/src/md5.h	Mon May 14 10:50:37 2007
@@ -1,7 +1,7 @@
 #ifndef MD5_H
 #define MD5_H
 
-#ifdef __alpha
+#if defined(__alpha) || defined(__x86_64)
 typedef unsigned int uint32;
 #else
 typedef unsigned long uint32;

Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/Makefile.am
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/Makefile.am	(original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/Makefile.am	Mon May 14 10:50:37 2007
@@ -30,7 +30,7 @@
 
 DOXYGEN = doxygen
 
-lib_LTLIBRARIES = libsofia-sip-ua.la
+noinst_LTLIBRARIES = libsofia-sip-ua.la
 
 libsofia_sip_ua_la_SOURCES = 
 libsofia_sip_ua_la_LIBADD = 	bnf/libbnf.la \

Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.c	(original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.c	Mon May 14 10:50:37 2007
@@ -927,7 +927,7 @@
   size_t len, xtra, e_len, l_len = 0, l_xtra = 0;
   ta_list ta;
 
-  if (nua == NULL || (nua->nua_shutdown_started && event != nua_r_shutdown))
+  if (nua == NULL)
     return;
 
   ta_start(ta, tag, value);

Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c	(original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c	Mon May 14 10:50:37 2007
@@ -378,7 +378,8 @@
 		    901, "Stack is going down",
 		    NULL);
   }
-  else switch (event) {
+
+ switch (event) {
   case nua_r_get_params:
     nua_stack_get_params(nua, nh ? nh : nua->nua_dhandle, event, tags);
     break;
@@ -485,8 +486,7 @@
   su_timer_set(t, nua_stack_timer, a);
 
   if (nua->nua_shutdown) {
-    nua_stack_shutdown(nua);
-    return;
+	  nua_stack_shutdown(nua);
   }
 
   for (nh = nua->nua_handles; nh; nh = nh_next) {

Modified: freeswitch/branches/greenlizard/src/include/switch_buffer.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_buffer.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_buffer.h	Mon May 14 10:50:37 2007
@@ -117,7 +117,7 @@
  * \param datalen amount of data to be written
  * \return int amount of buffer used after the write, or 0 if no space available
  */
-SWITCH_DECLARE(switch_size_t) switch_buffer_write(switch_buffer_t *buffer, void *data, switch_size_t datalen);
+SWITCH_DECLARE(switch_size_t) switch_buffer_write(switch_buffer_t *buffer, const void *data, switch_size_t datalen);
 
 /*! \brief Remove data from the buffer
  * \param buffer any buffer of type switch_buffer_t

Modified: freeswitch/branches/greenlizard/src/include/switch_caller.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_caller.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_caller.h	Mon May 14 10:50:37 2007
@@ -128,7 +128,7 @@
   \param extension_number extension number
   \return a new extension object allocated from the session's memory pool
 */
-SWITCH_DECLARE(switch_caller_extension_t *) switch_caller_extension_new(switch_core_session_t *session, char *extension_name, char *extension_number);
+SWITCH_DECLARE(switch_caller_extension_t *) switch_caller_extension_new(switch_core_session_t *session, const char *extension_name, const char *extension_number);
 
 /*!
   \brief Add an application (instruction) to the given extension
@@ -138,7 +138,7 @@
   \param extra_data optional argument to the application
 */
 SWITCH_DECLARE(void) switch_caller_extension_add_application(switch_core_session_t *session,
-															 switch_caller_extension_t *caller_extension, char *application_name, char *extra_data);
+															 switch_caller_extension_t *caller_extension, const char *application_name, const char *extra_data);
 
 
 /*!
@@ -147,7 +147,7 @@
   \param name the name
   \note this function is meant for situations where the name paramater is the contents of the variable
 */
-SWITCH_DECLARE(char *) switch_caller_get_field_by_name(switch_caller_profile_t *caller_profile, char *name);
+SWITCH_DECLARE(char *) switch_caller_get_field_by_name(switch_caller_profile_t *caller_profile, const char *name);
 
 /*!
   \brief Create a new caller profile object
@@ -191,7 +191,7 @@
   \param event the event to add the information to
 */
 
-SWITCH_DECLARE(void) switch_caller_profile_event_set_data(switch_caller_profile_t *caller_profile, char *prefix, switch_event_t *event);
+SWITCH_DECLARE(void) switch_caller_profile_event_set_data(switch_caller_profile_t *caller_profile, const char *prefix, switch_event_t *event);
 
 SWITCH_END_EXTERN_C
 /** @} */

Modified: freeswitch/branches/greenlizard/src/include/switch_channel.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_channel.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_channel.h	Mon May 14 10:50:37 2007
@@ -89,7 +89,7 @@
   \param str the string to check
   \return the code
 */
-SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2cause(char *str);
+SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2cause(const char *str);
 
 /*!
   \brief return the cause code for a given channel
@@ -103,7 +103,7 @@
   \param cause the code to check
   \return the string
 */
-SWITCH_DECLARE(char *) switch_channel_cause2str(switch_call_cause_t cause);
+SWITCH_DECLARE(const char *) switch_channel_cause2str(switch_call_cause_t cause);
 
 /*!
   \brief View the timetable of a channel
@@ -136,7 +136,7 @@
   \param rpid the rpid if for the icon to use
   \param status the status message
 */
-SWITCH_DECLARE(void) switch_channel_presence(switch_channel_t *channel, char *rpid, char *status);
+SWITCH_DECLARE(void) switch_channel_presence(switch_channel_t *channel, const char *rpid, const char *status);
 
 /*!
   \brief Uninitalize a channel
@@ -218,7 +218,7 @@
   \param varname the name of the variable
   \return the value of the requested variable
 */
-SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, char *varname);
+SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, const char *varname);
 
 /*!
  * Start iterating over the entries in the channel variable list.
@@ -373,7 +373,7 @@
   \param private_info void pointer to private data
   \return SWITCH_STATUS_SUCCESS if data was set
 */
-SWITCH_DECLARE(switch_status_t) switch_channel_set_private(switch_channel_t *channel, char *key, void *private_info);
+SWITCH_DECLARE(switch_status_t) switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info);
 
 /*!
   \brief Retrieve private from a given channel
@@ -381,7 +381,7 @@
   \param key unique keyname to retrieve your private data
   \return void pointer to channel's private data
 */
-SWITCH_DECLARE(void *) switch_channel_get_private(switch_channel_t *channel, char *key);
+SWITCH_DECLARE(void *) switch_channel_get_private(switch_channel_t *channel, const char *key);
 
 /*!
   \brief Assign a name to a given channel
@@ -389,7 +389,7 @@
   \param name name to assign
   \return SWITCH_STATUS_SUCCESS if name was assigned
 */
-SWITCH_DECLARE(switch_status_t) switch_channel_set_name(switch_channel_t *channel, char *name);
+SWITCH_DECLARE(switch_status_t) switch_channel_set_name(switch_channel_t *channel, const char *name);
 
 /*!
   \brief Retrieve the name of a given channel
@@ -423,7 +423,7 @@
   \param dtmf string of digits to queue
   \return SWITCH_STATUS_SUCCESS if successful
 */
-SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *channel, char *dtmf);
+SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *channel, const char *dtmf);
 
 /*!
   \brief Retrieve DTMF digits from a given channel
@@ -446,7 +446,7 @@
   \param name the name of the state
   \return the enum value (numeric)
 */
-SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(char *name);
+SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(const char *name);
 
 /*!
   \brief Add information about a given channel to an event object

Modified: freeswitch/branches/greenlizard/src/include/switch_core.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_core.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_core.h	Mon May 14 10:50:37 2007
@@ -220,7 +220,7 @@
   \param err a pointer to set any errors to
   \note to be called at application startup
 */
-SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err);
+SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, const char **err);
 
 /*! 
   \brief Initilize the core and load modules
@@ -228,7 +228,7 @@
   \param err a pointer to set any errors to
   \note to be called at application startup instead of switch_core_init.  Includes module loading.
 */
-SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(char *console, const char **err);
+SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(const char *console, const char **err);
 
 /*! 
   \brief Set/Get Session Limit
@@ -428,12 +428,15 @@
 SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch_endpoint_interface_t
 																	*endpoint_interface, switch_memory_pool_t **pool);
 
+
+SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t **session, const char *file, const char *func, int line);
+
 /*! 
   \brief Destroy a session and return the memory pool to the core
   \param session pointer to a pointer of the session to destroy
   \return
 */
-SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session);
+#define switch_core_session_destroy(session) switch_core_session_perform_destroy(session, __FILE__, __SWITCH_FUNC__, __LINE__)
 
 /*! 
   \brief Provide the total number of sessions
@@ -458,8 +461,9 @@
 /*! 
   \brief Launch the session thread (state machine) on a given session
   \param session the session to activate the state machine on
+  \return SWITCH_STATUS_SUCCESS if the thread was launched
 */
-SWITCH_DECLARE(void) switch_core_session_thread_launch(switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_core_session_thread_launch(switch_core_session_t *session);
 
 /*! 
   \brief Retrieve a pointer to the channel object associated with a given session
@@ -499,7 +503,7 @@
 #ifdef SWITCH_DEBUG_RWLOCKS
 #define switch_core_session_locate(uuid_str) switch_core_session_perform_locate(uuid_str, __FILE__, __SWITCH_FUNC__, __LINE__)
 #else
-SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str);
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(const char *uuid_str);
 #endif
 
 /*! 
@@ -507,14 +511,14 @@
   \param varname the name of the variable
   \return the value of the desired variable
 */
-SWITCH_DECLARE(char *) switch_core_get_variable(char *varname);
+SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname);
 
 /*! 
   \brief Add a global variable to the core
   \param varname the name of the variable
   \param value the value of the variable
 */
-SWITCH_DECLARE(void) switch_core_set_variable(char *varname, char *value);
+SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value);
 
 /*! 
   \brief Hangup All Sessions
@@ -1391,7 +1395,7 @@
   \brief Set the output console to the desired file
   \param console the file path
 */
-SWITCH_DECLARE(switch_status_t) switch_core_set_console(char *console);
+SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console);
 
 /*!
   \brief Breakdown a number of milliseconds into various time spec

Modified: freeswitch/branches/greenlizard/src/include/switch_cpp.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_cpp.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_cpp.h	Mon May 14 10:50:37 2007
@@ -26,7 +26,7 @@
 	int preAnswer();
 	void hangup(char *cause);
 	void setVariable(char *var, char *val);
-	void getVariable(char *var, char *val);
+	char *getVariable(char *var);
 	int playFile(char *file, char *timer_name);
 	void setDTMFCallback(switch_input_callback_function_t cb, void *buf, uint32_t buflen);
 	int speakText(char *text);

Modified: freeswitch/branches/greenlizard/src/include/switch_loadable_module.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_loadable_module.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_loadable_module.h	Mon May 14 10:50:37 2007
@@ -97,21 +97,21 @@
   \param name the name of the endpoint
   \return the desired endpoint interface
  */
-SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoint_interface(char *name);
+SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoint_interface(const char *name);
 
 /*!
   \brief Retrieve the codec interface by it's registered name
   \param name the name of the codec
   \return the desired codec interface
  */
-SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(char *name);
+SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(const char *name);
 
 /*!
   \brief Retrieve the dialplan interface by it's registered name
   \param name the name of the dialplan
   \return the desired dialplan interface
  */
-SWITCH_DECLARE(switch_dialplan_interface_t *) switch_loadable_module_get_dialplan_interface(char *name);
+SWITCH_DECLARE(switch_dialplan_interface_t *) switch_loadable_module_get_dialplan_interface(const char *name);
 
 /*!
   \brief build a dynamic module object and register it (for use in double embeded modules)
@@ -132,70 +132,70 @@
   \param name the name of the timer
   \return the desired timer interface
  */
-SWITCH_DECLARE(switch_timer_interface_t *) switch_loadable_module_get_timer_interface(char *name);
+SWITCH_DECLARE(switch_timer_interface_t *) switch_loadable_module_get_timer_interface(const char *name);
 
 /*!
   \brief Retrieve the application interface by it's registered name
   \param name the name of the application
   \return the desired application interface
  */
-SWITCH_DECLARE(switch_application_interface_t *) switch_loadable_module_get_application_interface(char *name);
+SWITCH_DECLARE(switch_application_interface_t *) switch_loadable_module_get_application_interface(const char *name);
 
 /*!
   \brief Retrieve the API interface by it's registered name
   \param name the name of the API
   \return the desired API interface
  */
-SWITCH_DECLARE(switch_api_interface_t *) switch_loadable_module_get_api_interface(char *name);
+SWITCH_DECLARE(switch_api_interface_t *) switch_loadable_module_get_api_interface(const char *name);
 
 /*!
   \brief Retrieve the file format interface by it's registered name
   \param name the name of the file format
   \return the desired file format interface
  */
-SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(char *name);
+SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(const char *name);
 
 /*!
   \brief Retrieve the speech interface by it's registered name
   \param name the name of the speech interface
   \return the desired speech interface
  */
-SWITCH_DECLARE(switch_speech_interface_t *) switch_loadable_module_get_speech_interface(char *name);
+SWITCH_DECLARE(switch_speech_interface_t *) switch_loadable_module_get_speech_interface(const char *name);
 
 /*!
   \brief Retrieve the asr interface by it's registered name
   \param name the name of the asr interface
   \return the desired asr interface
  */
-SWITCH_DECLARE(switch_asr_interface_t *) switch_loadable_module_get_asr_interface(char *name);
+SWITCH_DECLARE(switch_asr_interface_t *) switch_loadable_module_get_asr_interface(const char *name);
 
 /*!
   \brief Retrieve the directory interface by it's registered name
   \param name the name of the directory interface
   \return the desired directory interface
  */
-SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_directory_interface(char *name);
+SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_directory_interface(const char *name);
 
 /*!
   \brief Retrieve the chat interface by it's registered name
   \param name the name of the chat interface
   \return the desired chat interface
  */
-SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(char *name);
+SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(const char *name);
 
 /*!
   \brief Retrieve the say interface by it's registered name
   \param name the name of the say interface
   \return the desired say interface
  */
-SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(char *name);
+SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(const char *name);
 
 /*!
   \brief Retrieve the management interface by it's registered name
   \param relative_oid the relative oid of the management interface
   \return the desired management interface
  */
-SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(char *relative_oid);
+SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(const char *relative_oid);
 
 /*!
   \brief Retrieve the list of loaded codecs into an array
@@ -226,7 +226,7 @@
   \param stream stream for output
   \return the status returned by the API call
 */
-SWITCH_DECLARE(switch_status_t) switch_api_execute(char *cmd, char *arg, switch_core_session_t *session, switch_stream_handle_t *stream);
+SWITCH_DECLARE(switch_status_t) switch_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream);
 
 /*!
   \brief Load a module

Modified: freeswitch/branches/greenlizard/src/include/switch_regex.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_regex.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_regex.h	Mon May 14 10:50:37 2007
@@ -49,8 +49,8 @@
 
 SWITCH_DECLARE(void) switch_regex_free(void *data);
 
-SWITCH_DECLARE(int) switch_regex_perform(char *field, char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen);
-SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_count, char *data, char *field_data,
+SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen);
+SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data,
 												 char *substituted, uint32_t len, int *ovector);
 
 /*!
@@ -59,7 +59,7 @@
  \param expression The regular expression to run against the string
  \return Boolean if a match was found or not
 */
-SWITCH_DECLARE(switch_status_t) switch_regex_match(char *target, char *expression);
+SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const char *expression);
 
 #define switch_regex_safe_free(re)	if (re) {\
 				switch_regex_free(re);\

Modified: freeswitch/branches/greenlizard/src/include/switch_rtp.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_rtp.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_rtp.h	Mon May 14 10:50:37 2007
@@ -111,9 +111,9 @@
   \param pool a memory pool to use for the session
   \return the new RTP session or NULL on failure
 */
-SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(char *rx_host,
+SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host,
 											  switch_port_t rx_port,
-											  char *tx_host,
+											  const char *tx_host,
 											  switch_port_t tx_port,
 											  switch_payload_t payload,
 											  uint32_t samples_per_interval,
@@ -128,7 +128,7 @@
   \param port the remote port
   \param err pointer for error messages
 */
-SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, char *host, switch_port_t port, const char **err);
+SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err);
 
 /*! 
   \brief Assign a local address to the RTP session
@@ -138,7 +138,7 @@
   \param err pointer for error messages
   \note this call also binds the RTP session's socket to the new address
 */
-SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, char *host, switch_port_t port, const char **err);
+SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err);
 
 /*! 
   \brief Kill the socket on an existing RTP session

Modified: freeswitch/branches/greenlizard/src/include/switch_scheduler.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_scheduler.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_scheduler.h	Mon May 14 10:50:37 2007
@@ -62,7 +62,7 @@
 */
 SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime,
 												   switch_scheduler_func_t func,
-												   char *desc, char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags);
+												   const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags);
 
 /*!
   \brief Delete a scheduled task
@@ -76,7 +76,7 @@
   \param group the group name
   \return the number of jobs deleted
 */
-SWITCH_DECLARE(uint32_t) switch_scheduler_del_task_group(char *group);
+SWITCH_DECLARE(uint32_t) switch_scheduler_del_task_group(const char *group);
 
 
 /*!

Modified: freeswitch/branches/greenlizard/src/include/switch_types.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_types.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_types.h	Mon May 14 10:50:37 2007
@@ -1013,12 +1013,21 @@
 typedef void (*switch_application_function_t) (switch_core_session_t *, char *);
 typedef void (*switch_event_callback_t) (switch_event_t *);
 typedef switch_caller_extension_t *(*switch_dialplan_hunt_function_t) (switch_core_session_t *, void *, switch_caller_profile_t *);
+
 typedef struct switch_scheduler_task switch_scheduler_task_t;
+
 typedef void (*switch_scheduler_func_t) (switch_scheduler_task_t *task);
+
+#define SWITCH_STANDARD_SCHED_FUNC(name) static void name (switch_scheduler_task_t *task)
+
 typedef switch_status_t (*switch_state_handler_t) (switch_core_session_t *);
 typedef struct switch_stream_handle switch_stream_handle_t;
 typedef switch_status_t (*switch_stream_handle_write_function_t) (switch_stream_handle_t *handle, const char *fmt, ...);
-typedef switch_status_t (*switch_api_function_t) (char *in, switch_core_session_t *session, switch_stream_handle_t *stream);
+
+typedef switch_status_t (*switch_api_function_t) (const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream);
+
+#define SWITCH_STANDARD_API(name) static switch_status_t name (const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream)
+
 typedef switch_status_t (*switch_input_callback_function_t) (switch_core_session_t *session, void *input,
 															 switch_input_type_t input_type, void *buf, unsigned int buflen);
 typedef struct switch_say_interface switch_say_interface_t;

Modified: freeswitch/branches/greenlizard/src/include/switch_utils.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_utils.h	(original)
+++ freeswitch/branches/greenlizard/src/include/switch_utils.h	Mon May 14 10:50:37 2007
@@ -55,7 +55,7 @@
 #define switch_is_file_path(file) ((*file == '/') || strstr(file, SWITCH_URL_SEPARATOR))
 #endif
 
-static inline switch_bool_t switch_is_digit_string(char *s) {
+static inline switch_bool_t switch_is_digit_string(const char *s) {
 
 	while(s && *s) {
 		if (*s < 48 || *s > 57) {
@@ -104,7 +104,7 @@
   \param priority the priority to get the name of
   \return the printable form of the priority
 */
-SWITCH_DECLARE(char *) switch_priority_name(switch_priority_t priority);
+SWITCH_DECLARE(const char *) switch_priority_name(switch_priority_t priority);
 
 /*!
   \brief Return the RFC2833 character based on an event id
@@ -260,7 +260,7 @@
   \param in the string
   \return the epoch time in usec
 */
-SWITCH_DECLARE(switch_time_t) switch_str_time(char *in);
+SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in);
 
 /*!
   \brief Declares a function designed to set a dymaic global string
@@ -288,7 +288,7 @@
   \param esc the escape character
   \return the escaped string
 */
-SWITCH_DECLARE(char *) switch_escape_char(switch_memory_pool_t *pool, char *in, char *delim, char esc);
+SWITCH_DECLARE(char *) switch_escape_char(switch_memory_pool_t *pool, char *in, const char *delim, char esc);
 
 /*!
   \brief Wait for a socket

Modified: freeswitch/branches/greenlizard/src/mod/applications/mod_commands/mod_commands.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/applications/mod_commands/mod_commands.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/applications/mod_commands/mod_commands.c	Mon May 14 10:50:37 2007
@@ -57,7 +57,7 @@
 static switch_api_interface_t sched_transfer_api_interface;
 static switch_api_interface_t sched_hangup_api_interface;
 
-static switch_status_t status_function(char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(status_function)
 {
 	uint8_t html = 0;
 	switch_core_time_duration_t duration;
@@ -107,18 +107,18 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t ctl_function(char *data, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(ctl_function)
 {
 	int argc;
 	char *mydata, *argv[5];
 	uint32_t arg = 0;
 
-	if (switch_strlen_zero(data)) {
+	if (switch_strlen_zero(cmd)) {
 		stream->write_function(stream, "USAGE: %s\n", ctl_api_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
-	if ((mydata = strdup(data))) {
+	if ((mydata = strdup(cmd))) {
 		argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
 
 		if (!strcmp(argv[0], "hupall")) {
@@ -149,7 +149,7 @@
 
 }
 
-static switch_status_t load_function(char *mod, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(load_function)
 {
 	const char *err;
 
@@ -157,12 +157,12 @@
 		return SWITCH_STATUS_FALSE;
 	}
 
-	if (switch_strlen_zero(mod)) {
+	if (switch_strlen_zero(cmd)) {
 		stream->write_function(stream, "USAGE: %s\n", load_api_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
-	if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) mod, SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS) {
+	if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) cmd, SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS) {
 		stream->write_function(stream, "OK\n");
 	} else {
 		stream->write_function(stream, "ERROR [%s]\n", err);
@@ -171,7 +171,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t unload_function(char *mod, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(unload_function)
 {
 	const char *err;
 
@@ -179,12 +179,12 @@
 		return SWITCH_STATUS_FALSE;
 	}
 
-	if (switch_strlen_zero(mod)) {
+	if (switch_strlen_zero(cmd)) {
 		stream->write_function(stream, "USAGE: %s\n", unload_api_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
-	if (switch_loadable_module_unload_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) mod, &err) == SWITCH_STATUS_SUCCESS) {
+	if (switch_loadable_module_unload_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) cmd, &err) == SWITCH_STATUS_SUCCESS) {
 		stream->write_function(stream, "OK\n");
 	} else {
 		stream->write_function(stream, "ERROR [%s]\n", err);
@@ -193,7 +193,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t reload_function(char *args, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(reload_function)
 {
 	const char *err;
 	switch_xml_t xml_root;
@@ -211,20 +211,20 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t kill_function(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(kill_function)
 {
-	switch_core_session_t *session = NULL;
+	switch_core_session_t *ksession = NULL;
 
-	if (isession) {
+	if (session) {
 		return SWITCH_STATUS_FALSE;
 	}
 
-	if (!dest) {
+	if (!cmd) {
 		stream->write_function(stream, "USAGE: %s\n", kill_api_interface.syntax);
-	} else if ((session = switch_core_session_locate(dest))) {
-		switch_channel_t *channel = switch_core_session_get_channel(session);
+	} else if ((ksession = switch_core_session_locate(cmd))) {
+		switch_channel_t *channel = switch_core_session_get_channel(ksession);
 		switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-		switch_core_session_rwunlock(session);
+		switch_core_session_rwunlock(ksession);
 		stream->write_function(stream, "OK\n");
 	} else {
 		stream->write_function(stream, "No Such Channel!\n");
@@ -233,56 +233,62 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t transfer_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(transfer_function)
 {
-	switch_core_session_t *session = NULL;
-	char *argv[4] = { 0 };
+	switch_core_session_t *tsession = NULL;
+	char *mycmd = NULL, *argv[4] = { 0 };
 	int argc = 0;
 
-	if (isession) {
+	if (session) {
 		return SWITCH_STATUS_FALSE;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
-
-	if (switch_strlen_zero(cmd) || argc < 2 || argc > 4) {
-		stream->write_function(stream, "USAGE: %s\n", transfer_api_interface.syntax);
-	} else {
-		char *uuid = argv[0];
-		char *dest = argv[1];
-		char *dp = argv[2];
-		char *context = argv[3];
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+		if (argc >= 2 && argc <= 4) {
+			char *uuid = argv[0];
+			char *dest = argv[1];
+			char *dp = argv[2];
+			char *context = argv[3];
+
+			if ((tsession = switch_core_session_locate(uuid))) {
+
+				if (switch_ivr_session_transfer(tsession, dest, dp, context) == SWITCH_STATUS_SUCCESS) {
+					stream->write_function(stream, "OK\n");
+				} else {
+					stream->write_function(stream, "ERROR\n");
+				}
 
-		if ((session = switch_core_session_locate(uuid))) {
+				switch_core_session_rwunlock(tsession);
 
-			if (switch_ivr_session_transfer(session, dest, dp, context) == SWITCH_STATUS_SUCCESS) {
-				stream->write_function(stream, "OK\n");
 			} else {
-				stream->write_function(stream, "ERROR\n");
+				stream->write_function(stream, "No Such Channel!\n");
 			}
-
-			switch_core_session_rwunlock(session);
-
-		} else {
-			stream->write_function(stream, "No Such Channel!\n");
+			goto done;
 		}
 	}
 
+	stream->write_function(stream, "USAGE: %s\n", transfer_api_interface.syntax);
+
+done:
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
 
-static switch_status_t sched_transfer_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(sched_transfer_function)
 {
-	switch_core_session_t *session = NULL;
-	char *argv[6] = { 0 };
+	switch_core_session_t *tsession = NULL;
+	char *mycmd = NULL, *argv[6] = { 0 };
 	int argc = 0;
 
-	if (isession) {
+	if (session) {
 		return SWITCH_STATUS_FALSE;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	}
 
 	if (switch_strlen_zero(cmd) || argc < 2 || argc > 5) {
 		stream->write_function(stream, "USAGE: %s\n", sched_transfer_api_interface.syntax);
@@ -299,29 +305,32 @@
 			when = atol(argv[0]);
 		}
 
-		if ((session = switch_core_session_locate(uuid))) {
+		if ((tsession = switch_core_session_locate(uuid))) {
 			switch_ivr_schedule_transfer(when, uuid, dest, dp, context);
 			stream->write_function(stream, "OK\n");
-			switch_core_session_rwunlock(session);
+			switch_core_session_rwunlock(tsession);
 		} else {
 			stream->write_function(stream, "No Such Channel!\n");
 		}
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t sched_hangup_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(sched_hangup_function)
 {
-	switch_core_session_t *session = NULL;
-	char *argv[4] = { 0 };
+	switch_core_session_t *hsession = NULL;
+	char *mycmd = NULL, *argv[4] = { 0 };
 	int argc = 0;
 
-	if (isession) {
+	if (session) {
 		return SWITCH_STATUS_FALSE;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	}
 
 	if (switch_strlen_zero(cmd) || argc < 1) {
 		stream->write_function(stream, "USAGE: %s\n", sched_hangup_api_interface.syntax);
@@ -341,30 +350,33 @@
 			cause = switch_channel_str2cause(cause_str);
 		}
 
-		if ((session = switch_core_session_locate(uuid))) {
+		if ((hsession = switch_core_session_locate(uuid))) {
 			switch_ivr_schedule_hangup(when, uuid, cause, SWITCH_FALSE);
 			stream->write_function(stream, "OK\n");
-			switch_core_session_rwunlock(session);
+			switch_core_session_rwunlock(hsession);
 		} else {
 			stream->write_function(stream, "No Such Channel!\n");
 		}
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
 
-static switch_status_t uuid_media_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(uuid_media_function)
 {
-	char *argv[4] = { 0 };
+	char *mycmd = NULL, *argv[4] = { 0 };
 	int argc = 0;
 	switch_status_t status = SWITCH_STATUS_FALSE;
 
-	if (isession) {
+	if (session) {
 		return status;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	}
 
 	if (switch_strlen_zero(cmd) || argc < 1) {
 		stream->write_function(stream, "USAGE: %s\n", media_api_interface.syntax);
@@ -382,21 +394,24 @@
 		stream->write_function(stream, "-ERR Operation Failed\n");
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
 
-static switch_status_t uuid_broadcast_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(uuid_broadcast_function)
 {
-	char *argv[4] = { 0 };
+	char *mycmd = NULL, *argv[4] = { 0 };
 	int argc = 0;
 	switch_status_t status = SWITCH_STATUS_FALSE;
 
-	if (isession) {
+	if (session) {
 		return status;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	}
 
 	if (switch_strlen_zero(cmd) || argc < 2) {
 		stream->write_function(stream, "USAGE: %s\n", broadcast_api_interface.syntax);
@@ -419,21 +434,24 @@
 		stream->write_function(stream, "+OK Message Sent\n");
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
 
-static switch_status_t sched_broadcast_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(sched_broadcast_function)
 {
-	char *argv[4] = { 0 };
+	char *mycmd = NULL, *argv[4] = { 0 };
 	int argc = 0;
 	switch_status_t status = SWITCH_STATUS_FALSE;
 
-	if (isession) {
+	if (session) {
 		return status;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	}
 
 	if (switch_strlen_zero(cmd) || argc < 3) {
 		stream->write_function(stream, "USAGE: %s\n", sched_broadcast_api_interface.syntax);
@@ -463,20 +481,23 @@
 		stream->write_function(stream, "+OK Message Scheduled\n");
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t uuid_hold_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(uuid_hold_function)
 {
-	char *argv[4] = { 0 };
+	char *mycmd = NULL, *argv[4] = { 0 };
 	int argc = 0;
 	switch_status_t status = SWITCH_STATUS_FALSE;
 
-	if (isession) {
+	if (session) {
 		return status;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	}
 
 	if (switch_strlen_zero(cmd) || argc < 1) {
 		stream->write_function(stream, "USAGE: %s\n", hold_api_interface.syntax);
@@ -494,19 +515,22 @@
 		stream->write_function(stream, "-ERR Operation Failed\n");
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t uuid_bridge_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(uuid_bridge_function)
 {
-	char *argv[4] = { 0 };
+	char *mycmd = NULL, *argv[4] = { 0 };
 	int argc = 0;
 
-	if (isession) {
+	if (session) {
 		return SWITCH_STATUS_FALSE;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	}
 
 	if (switch_strlen_zero(cmd) || argc != 2) {
 		stream->write_function(stream, "USAGE: %s\n", uuid_bridge_api_interface.syntax);
@@ -516,17 +540,18 @@
 		}
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t session_record_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(session_record_function)
 {
-	switch_core_session_t *session = NULL;
-	char *argv[4] = { 0 };
+	switch_core_session_t *rsession = NULL;
+	char *mycmd = NULL, *argv[4] = { 0 };
 	char *uuid = NULL, *action = NULL, *path = NULL;
 	int argc = 0;
 
-	if (isession) {
+	if (session) {
 		return SWITCH_STATUS_FALSE;
 	}
 
@@ -534,7 +559,11 @@
 		goto usage;
 	}
 
-	if ((argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) != 3) {
+	if (!(mycmd = strdup(cmd))) {
+		goto usage;
+	}
+
+	if ((argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) != 3) {
 		goto usage;
 	}
 
@@ -542,7 +571,7 @@
 	action = argv[1];
 	path = argv[2];
 
-	if (!(session = switch_core_session_locate(uuid))) {
+	if (!(rsession = switch_core_session_locate(uuid))) {
 		stream->write_function(stream, "-Error Cannot locate session!\n");
 		return SWITCH_STATUS_SUCCESS;
 	}
@@ -552,9 +581,9 @@
 	}
 
 	if (!strcasecmp(action, "start")) {
-		switch_ivr_record_session(session, path, NULL);
+		switch_ivr_record_session(rsession, path, NULL);
 	} else if (!strcasecmp(action, "stop")) {
-		switch_ivr_stop_record_session(session, path);
+		switch_ivr_stop_record_session(rsession, path);
 	} else {
 		goto usage;
 	}
@@ -564,28 +593,32 @@
   usage:
 
 	stream->write_function(stream, "USAGE: %s\n", session_record_api_interface.syntax);
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 
   done:
 
 	if (session) {
-		switch_core_session_rwunlock(session);
+		switch_core_session_rwunlock(rsession);
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t pause_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(pause_function)
 {
-	switch_core_session_t *session = NULL;
-	char *argv[4] = { 0 };
+	switch_core_session_t *psession = NULL;
+	char *mycmd = NULL, *argv[4] = { 0 };
 	int argc = 0;
 
-	if (isession) {
+	if (session) {
 		return SWITCH_STATUS_FALSE;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	}
 
 	if (switch_strlen_zero(cmd) || argc < 2) {
 		stream->write_function(stream, "USAGE: %s\n", pause_api_interface.syntax);
@@ -593,8 +626,8 @@
 		char *uuid = argv[0];
 		char *dest = argv[1];
 
-		if ((session = switch_core_session_locate(uuid))) {
-			switch_channel_t *channel = switch_core_session_get_channel(session);
+		if ((psession = switch_core_session_locate(uuid))) {
+			switch_channel_t *channel = switch_core_session_get_channel(psession);
 
 			if (!strcasecmp(dest, "on")) {
 				switch_channel_set_flag(channel, CF_HOLD);
@@ -602,36 +635,40 @@
 				switch_channel_clear_flag(channel, CF_HOLD);
 			}
 
-			switch_core_session_rwunlock(session);
+			switch_core_session_rwunlock(psession);
 
 		} else {
 			stream->write_function(stream, "No Such Channel!\n");
 		}
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t originate_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(originate_function)
 {
 	switch_channel_t *caller_channel;
 	switch_core_session_t *caller_session = NULL;
-	char *argv[7] = { 0 };
+	char *mycmd = NULL, *argv[7] = { 0 };
 	int i = 0, x, argc = 0;
 	char *aleg, *exten, *dp, *context, *cid_name, *cid_num;
 	uint32_t timeout = 60;
 	switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
 	uint8_t machine = 1;
 
-	if (isession) {
+	if (session) {
 		stream->write_function(stream, "Illegal Usage\n");
 		return SWITCH_STATUS_SUCCESS;
 	}
 
-	argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+		argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+	}
 
 	if (switch_strlen_zero(cmd) || argc < 2 || argc > 7) {
 		stream->write_function(stream, "USAGE: %s\n", originate_api_interface.syntax);
+		switch_safe_free(mycmd);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
@@ -671,6 +708,7 @@
 		} else {
 			stream->write_function(stream, "Cannot Create Outgoing Channel! [%s] cause: %s\n", aleg, switch_channel_cause2str(cause));
 		}
+		switch_safe_free(mycmd);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
@@ -694,6 +732,7 @@
 		if ((extension = switch_caller_extension_new(caller_session, app_name, arg)) == 0) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "memory error!\n");
 			switch_channel_hangup(caller_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+			switch_safe_free(mycmd);
 			return SWITCH_STATUS_MEMERR;
 		}
 		switch_caller_extension_add_application(caller_session, extension, app_name, arg);
@@ -713,6 +752,7 @@
 		switch_core_session_rwunlock(caller_session);
 	}
 
+	switch_safe_free(mycmd);
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -735,7 +775,7 @@
 	switch_safe_free(stream.data);
 }
 
-static switch_status_t sched_del_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(sched_del_function)
 {
 	uint32_t cnt = 0;
 	
@@ -754,7 +794,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t xml_wrap_api_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(xml_wrap_api_function)
 {
 	char *dcommand, *edata = NULL, *send = NULL, *command, *arg = NULL;
 	switch_stream_handle_t mystream = { 0 };
@@ -803,7 +843,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t sched_api_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(sched_api_function)
 {
 	char *tm = NULL, *dcmd, *group;
 	time_t when;
@@ -939,7 +979,7 @@
 	return 0;
 }
 
-static switch_status_t show_function(char *data, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(show_function)
 {
 	char sql[1024];
 	char *errmsg;
@@ -948,18 +988,15 @@
 	int help = 0;
 	char *mydata = NULL, *argv[6] = {0};
 	int argc;
-	char *cmd = NULL, *as = NULL;
+	char *command = NULL, *as = NULL;
 
 	if (session) {
 		return SWITCH_STATUS_FALSE;
 	}
 
-	if (data) {
-		if ((mydata = strdup(data))) {
-			argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
-		}	
-
-		cmd = argv[0];
+	if (cmd && (mydata = strdup(cmd))) {
+		argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+		command = argv[0];
 		if (argv[2] && !strcasecmp(argv[1], "as")) {
 			as = argv[2];
 		}
@@ -973,25 +1010,25 @@
 
 	// If you changes the field qty or order of any of these select
 	// statmements, you must also change show_callback and friends to match!
-	if (!cmd) {
+	if (!command) {
 		stream->write_function(stream, "USAGE: %s\n", show_api_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
-	} else if (!strcmp(cmd, "codec") || !strcmp(cmd, "dialplan") || !strcmp(cmd, "file") || !strcmp(cmd, "timer")) {
-		sprintf(sql, "select type, name from interfaces where type = '%s'", cmd);
-	} else if (!strcmp(cmd, "tasks")) {
-		sprintf(sql, "select * from %s", cmd);
-	} else if (!strcmp(cmd, "application") || !strcmp(cmd, "api")) {
-		sprintf(sql, "select name, description, syntax from interfaces where type = '%s' and description != ''", cmd);
-	} else if (!strcmp(cmd, "calls")) {
+	} else if (!strcmp(command, "codec") || !strcmp(command, "dialplan") || !strcmp(command, "file") || !strcmp(command, "timer")) {
+		sprintf(sql, "select type, name from interfaces where type = '%s'", command);
+	} else if (!strcmp(command, "tasks")) {
+		sprintf(sql, "select * from %s", command);
+	} else if (!strcmp(command, "application") || !strcmp(command, "api")) {
+		sprintf(sql, "select name, description, syntax from interfaces where type = '%s' and description != ''", command);
+	} else if (!strcmp(command, "calls")) {
 		sprintf(sql, "select * from calls");
-	} else if (!strcmp(cmd, "channels")) {
+	} else if (!strcmp(command, "channels")) {
 		sprintf(sql, "select * from channels");
-	} else if (!strncasecmp(cmd, "help", 4)) {
+	} else if (!strncasecmp(command, "help", 4)) {
 		char *cmdname = NULL;
 
 		help = 1;
 		holder.print_title = 0;
-		if ((cmdname = strchr(cmd, ' ')) != 0) {
+		if ((cmdname = strchr(command, ' ')) != 0) {
 			*cmdname++ = '\0';
 			snprintf(sql, sizeof(sql) - 1, "select name, syntax, description from interfaces where type = 'api' and name = '%s'", cmdname);
 		} else {
@@ -1063,7 +1100,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t version_function(char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(version_function)
 {
 	char version_string[1024];
 	snprintf(version_string, sizeof(version_string) - 1, "FreeSwitch Version %s\n", SWITCH_VERSION_FULL);
@@ -1072,7 +1109,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t help_function(char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(help_function)
 {
 	char showcmd[1024];
 	int all = 0;

Modified: freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c	Mon May 14 10:50:37 2007
@@ -292,7 +292,7 @@
 static switch_status_t conference_play_file(conference_obj_t * conference, char *file, uint32_t leadin, switch_channel_t *channel, uint8_t async);
 static switch_status_t conference_say(conference_obj_t * conference, const char *text, uint32_t leadin);
 static void conference_list(conference_obj_t * conference, switch_stream_handle_t *stream, char *delim);
-static switch_status_t conf_api_main(char *buf, switch_core_session_t *session, switch_stream_handle_t *stream);
+static switch_status_t conf_api_main(const char *buf, switch_core_session_t *session, switch_stream_handle_t *stream);
 static switch_status_t audio_bridge_on_ring(switch_core_session_t *session);
 static switch_status_t conference_outcall(conference_obj_t * conference,
 										  char *conference_name,
@@ -3445,7 +3445,7 @@
 }
 
 /* API Interface Function */
-static switch_status_t conf_api_main(char *buf, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(conf_api_main)
 {
 	char *lbuf = NULL;
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
@@ -3453,8 +3453,8 @@
 	int argc;
 	char *argv[25] = { 0 };
 
-	if (!buf) {
-		buf = "help";
+	if (!cmd) {
+		cmd = "help";
 	}
 
 	if (session) {
@@ -3470,7 +3470,7 @@
 		stream->write_function(stream, "<pre>\n");
 	}
 
-	if (!(lbuf = strdup(buf))) {
+	if (!(lbuf = strdup(cmd))) {
 		return status;
 	}
 
@@ -3486,7 +3486,7 @@
 				goto done;
 			}
 			if (argc >= 2) {
-				conf_api_dispatch(conference, stream, argc, argv, (const char *) buf, 1);
+				conf_api_dispatch(conference, stream, argc, argv, cmd, 1);
 			} else {
 				stream->write_function(stream, "Conference command, not specified.\nTry 'help'\n");
 			}

Modified: freeswitch/branches/greenlizard/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/applications/mod_dptools/mod_dptools.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/applications/mod_dptools/mod_dptools.c	Mon May 14 10:50:37 2007
@@ -502,14 +502,14 @@
 }
 
 
-static switch_status_t strepoch_api_function(char *data, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(strepoch_api_function)
 {
 	switch_time_t out;
 
-	if (switch_strlen_zero(data)) {
+	if (switch_strlen_zero(cmd)) {
 		out = switch_time_now();
 	} else {
-		out = switch_str_time(data);
+		out = switch_str_time(cmd);
 	}
 
 	stream->write_function(stream, "%d", (uint32_t) ((out) / (int64_t) (1000000)));
@@ -517,7 +517,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t strftime_api_function(char *fmt, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(strftime_api_function)
 {
 
 	switch_size_t retsize;
@@ -525,20 +525,20 @@
 	char date[80] = "";
 
 	switch_time_exp_lt(&tm, switch_time_now());
-	switch_strftime(date, &retsize, sizeof(date), fmt ? fmt : "%Y-%m-%d %T", &tm);
+	switch_strftime(date, &retsize, sizeof(date), cmd ? cmd : "%Y-%m-%d %T", &tm);
 	stream->write_function(stream, "%s", date);
 
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t presence_api_function(char *fmt, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(presence_api_function)
 {
 	switch_event_t *event;
 	char *lbuf, *argv[4];
 	int argc = 0;
 	switch_event_types_t type = SWITCH_EVENT_PRESENCE_IN;
 
-	if (fmt && (lbuf = strdup(fmt))
+	if (cmd && (lbuf = strdup(cmd))
 		&& (argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])))) > 0) {
 		if (!strcasecmp(argv[0], "out")) {
 			type = SWITCH_EVENT_PRESENCE_OUT;
@@ -568,12 +568,12 @@
 }
 
 
-static switch_status_t chat_api_function(char *fmt, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(chat_api_function)
 {
 	char *lbuf, *argv[4];
 	int argc = 0;
 
-	if (fmt && (lbuf = strdup(fmt))
+	if (cmd && (lbuf = strdup(cmd))
 		&& (argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])))) == 4) {
 		switch_chat_interface_t *ci;
 

Modified: freeswitch/branches/greenlizard/src/mod/applications/mod_enum/mod_enum.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/applications/mod_enum/mod_enum.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/applications/mod_enum/mod_enum.c	Mon May 14 10:50:37 2007
@@ -625,7 +625,7 @@
 
 }
 
-static switch_status_t enum_function(char *data, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(enum_function)
 {
 
 	int argc = 0;
@@ -640,7 +640,7 @@
 		return SWITCH_STATUS_FALSE;
 	}
 
-	if (!(mydata = strdup(data))) {
+	if (!cmd || !(mydata = strdup(cmd))) {
 		stream->write_function(stream, "Error!\n");
 		return SWITCH_STATUS_FALSE;
 	}
@@ -649,7 +649,7 @@
 		dest = argv[0];
 		root = argv[1] ? argv[1] : globals.root;
 
-		if (!enum_lookup(root, data, &results) == SWITCH_STATUS_SUCCESS) {
+		if (!enum_lookup(root, dest, &results) == SWITCH_STATUS_SUCCESS) {
 			stream->write_function(stream, "No Match!\n");
 			return SWITCH_STATUS_SUCCESS;
 		}

Modified: freeswitch/branches/greenlizard/src/mod/codecs/mod_speex/mod_speex.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/codecs/mod_speex/mod_speex.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/codecs/mod_speex/mod_speex.c	Mon May 14 10:50:37 2007
@@ -302,7 +302,73 @@
 	/*.next */ &speex_32k_implementation
 };
 
-static const switch_codec_implementation_t speex_8k_implementation = {
+
+static const switch_codec_implementation_t speex_8k_60ms_implementation = {
+	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
+	/*.ianacode */ 98,
+	/*.iananame */ "speex",
+	/*.fmtp */ NULL,
+	/*.samples_per_second */ 8000,
+	/*.bits_per_second */ 3300,
+	/*.nanoseconds_per_frame */ 60000,
+	/*.samples_per_frame */ 480,
+	/*.bytes_per_frame */ 960,
+	/*.encoded_bytes_per_frame */ 0,
+	/*.number_of_channels */ 1,
+	/*.pref_frames_per_packet */ 1,
+	/*.max_frames_per_packet */ 1,
+	/*.init */ switch_speex_init,
+	/*.encode */ switch_speex_encode,
+	/*.decode */ switch_speex_decode,
+	/*.destroy */ switch_speex_destroy,
+	/*.next */ &speex_16k_implementation
+};
+
+static const switch_codec_implementation_t speex_8k_40ms_implementation = {
+	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
+	/*.ianacode */ 98,
+	/*.iananame */ "speex",
+	/*.fmtp */ NULL,
+	/*.samples_per_second */ 8000,
+	/*.bits_per_second */ 22000,
+	/*.nanoseconds_per_frame */ 40000,
+	/*.samples_per_frame */ 240,
+	/*.bytes_per_frame */ 640,
+	/*.encoded_bytes_per_frame */ 0,
+	/*.number_of_channels */ 1,
+	/*.pref_frames_per_packet */ 1,
+	/*.max_frames_per_packet */ 1,
+	/*.init */ switch_speex_init,
+	/*.encode */ switch_speex_encode,
+	/*.decode */ switch_speex_decode,
+	/*.destroy */ switch_speex_destroy,
+	/*.next */ &speex_8k_60ms_implementation
+
+};
+
+
+static const switch_codec_implementation_t speex_8k_30ms_implementation = {
+	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
+	/*.ianacode */ 98,
+	/*.iananame */ "speex",
+	/*.fmtp */ NULL,
+	/*.samples_per_second */ 8000,
+	/*.bits_per_second */ 1650,
+	/*.nanoseconds_per_frame */ 30000,
+	/*.samples_per_frame */ 240,
+	/*.bytes_per_frame */ 480,
+	/*.encoded_bytes_per_frame */ 0,
+	/*.number_of_channels */ 1,
+	/*.pref_frames_per_packet */ 1,
+	/*.max_frames_per_packet */ 1,
+	/*.init */ switch_speex_init,
+	/*.encode */ switch_speex_encode,
+	/*.decode */ switch_speex_decode,
+	/*.destroy */ switch_speex_destroy,
+	/*.next */ &speex_8k_40ms_implementation
+};
+
+static const switch_codec_implementation_t speex_8k_20ms_implementation = {
 	/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
 	/*.ianacode */ 98,
 	/*.iananame */ "speex",
@@ -320,12 +386,12 @@
 	/*.encode */ switch_speex_encode,
 	/*.decode */ switch_speex_decode,
 	/*.destroy */ switch_speex_destroy,
-	/*.next */ &speex_16k_implementation
+	/*.next */ &speex_8k_30ms_implementation
 };
 
 static const switch_codec_interface_t speex_codec_interface = {
 	/*.interface_name */ "speex",
-	/*.implementations */ &speex_8k_implementation
+	/*.implementations */ &speex_8k_20ms_implementation
 };
 
 static switch_loadable_module_interface_t speex_module_interface = {

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_alsa/mod_alsa.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_alsa/mod_alsa.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_alsa/mod_alsa.c	Mon May 14 10:50:37 2007
@@ -1504,9 +1504,15 @@
 			switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
 			switch_channel_mark_answered(channel);
 			switch_channel_set_state(channel, CS_INIT);
-			switch_core_session_thread_launch(tech_pvt->session);
-			add_pvt(tech_pvt, PA_MASTER);
-			stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+
+			if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
+				switch_core_session_destroy(&session);
+				stream->write_function(stream, "FAIL:Thread Error!\n");
+			} else {
+				add_pvt(tech_pvt, PA_MASTER);
+				stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+			}
 		} else {
 			switch_core_session_destroy(&session);
 			stream->write_function(stream, "FAIL:Device Error!\n");
@@ -1516,7 +1522,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t pa_cmd(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(pa_cmd)
 {
 	char *argv[1024] = { 0 };
 	int argc = 0;

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_dingaling/mod_dingaling.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_dingaling/mod_dingaling.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_dingaling/mod_dingaling.c	Mon May 14 10:50:37 2007
@@ -191,10 +191,10 @@
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string)
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string)
 
-static switch_status_t dl_login(char *arg, switch_core_session_t *session, switch_stream_handle_t *stream);
-static switch_status_t dl_logout(char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream);
-static switch_status_t dl_pres(char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream);
-static switch_status_t dl_debug(char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream);
+static switch_status_t dl_login(const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream);
+static switch_status_t dl_logout(const char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream);
+static switch_status_t dl_pres(const char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream);
+static switch_status_t dl_debug(const char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream);
 static switch_status_t channel_on_init(switch_core_session_t *session);
 static switch_status_t channel_on_hangup(switch_core_session_t *session);
 static switch_status_t channel_on_ring(switch_core_session_t *session);
@@ -2028,7 +2028,7 @@
 	}
 }
 
-static switch_status_t dl_debug(char *tf, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(dl_debug)
 {
 	int on, cur;
 
@@ -2036,8 +2036,8 @@
 		return SWITCH_STATUS_FALSE;
 	}
 
-	if (tf) {
-		on = switch_true(tf);
+	if (cmd) {
+		on = switch_true(cmd);
 		cur = ldl_global_debug(on);
 	} else {
 		cur = ldl_global_debug(-1);
@@ -2049,7 +2049,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t dl_pres(char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(dl_pres)
 {
 	mdl_profile_t *profile;
 
@@ -2057,26 +2057,26 @@
 		return SWITCH_STATUS_FALSE;
 	}
 
-	if (!profile_name) {
+	if (!cmd) {
 		stream->write_function(stream, "USAGE: %s\n", pres_api_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
-	if ((profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
+	if ((profile = switch_core_hash_find(globals.profile_hash, cmd))) {
 		if (profile->user_flags & LDL_FLAG_COMPONENT) {
 			sign_on(profile);
 			stream->write_function(stream, "OK\n");
 		} else {
-			stream->write_function(stream, "NO PROFILE %s NOT A COMPONENT\n", profile_name);
+			stream->write_function(stream, "NO PROFILE %s NOT A COMPONENT\n", cmd);
 		}
 	} else {
-		stream->write_function(stream, "NO SUCH PROFILE %s\n", profile_name);
+		stream->write_function(stream, "NO SUCH PROFILE %s\n", cmd);
 	}
 
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t dl_logout(char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(dl_logout)
 {
 	mdl_profile_t *profile;
 
@@ -2084,22 +2084,22 @@
 		return SWITCH_STATUS_FALSE;
 	}
 
-	if (!profile_name) {
+	if (!cmd) {
 		stream->write_function(stream, "USAGE: %s\n", logout_api_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
-	if ((profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
+	if ((profile = switch_core_hash_find(globals.profile_hash, cmd))) {
 		ldl_handle_stop(profile->handle);
 		stream->write_function(stream, "OK\n");
 	} else {
-		stream->write_function(stream, "NO SUCH PROFILE %s\n", profile_name);
+		stream->write_function(stream, "NO SUCH PROFILE %s\n", cmd);
 	}
 
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t dl_login(char *arg, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(dl_login)
 {
 	char *argv[10] = { 0 };
 	int argc = 0;
@@ -2111,16 +2111,16 @@
 		return SWITCH_STATUS_FALSE;
 	}
 
-	if (switch_strlen_zero(arg)) {
+	if (switch_strlen_zero(cmd)) {
 		stream->write_function(stream, "USAGE: %s\n", login_api_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
-	myarg = strdup(arg);
+	myarg = strdup(cmd);
 
 	argc = switch_separate_string(myarg, ';', argv, (sizeof(argv) / sizeof(argv[0])));
 
-	if (switch_strlen_zero(arg) || argc != 1) {
+	if (switch_strlen_zero(cmd) || argc != 1) {
 		stream->write_function(stream, "USAGE: %s\n", login_api_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
 	}
@@ -2720,7 +2720,12 @@
 			tech_pvt->dlsession = dlsession;
 			switch_channel_set_name(channel, "DingaLing/new");
 			switch_channel_set_state(channel, CS_INIT);
-			switch_core_session_thread_launch(session);
+			if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
+				terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+                status = LDL_STATUS_FALSE;
+                goto done;
+			}
 		} else {
 			status = LDL_STATUS_FALSE;
 			goto done;

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_iax/mod_iax.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_iax/mod_iax.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_iax/mod_iax.c	Mon May 14 10:50:37 2007
@@ -1036,6 +1036,10 @@
 			case IAX_EVENT_REGREJ:
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Registration failed.\n");
 				break;
+			case IAX_EVENT_REGREQ:
+				/* what is the right way to handle this? */
+				iax_reject_registration(iaxevent->session, NULL);
+				break;
 			case IAX_EVENT_TIMEOUT:
 				break;
 			case IAX_EVENT_ACCEPT:
@@ -1128,7 +1132,10 @@
 							iax_accept(tech_pvt->iax_session, tech_pvt->codec);
 							iax_ring_announce(tech_pvt->iax_session);
 							switch_channel_set_state(channel, CS_INIT);
-							switch_core_session_thread_launch(session);
+							if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
+								switch_core_session_destroy(&session);
+							}
 						}
 					}
 				}

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_portaudio/mod_portaudio.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_portaudio/mod_portaudio.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_portaudio/mod_portaudio.c	Mon May 14 10:50:37 2007
@@ -155,8 +155,8 @@
 	 static switch_status_t load_config(void);
 	 static int get_dev_by_name(char *name, int in);
 	 static int get_dev_by_number(int number, int in);
-	 static switch_status_t pa_cmd(char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
-	 static switch_status_t padep(char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
+	 static switch_status_t pa_cmd(const char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
+	 static switch_status_t padep(const char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
 
 
 /* 
@@ -1694,9 +1694,14 @@
 			switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
 			switch_channel_mark_answered(channel);
 			switch_channel_set_state(channel, CS_INIT);
-			switch_core_session_thread_launch(tech_pvt->session);
-			add_pvt(tech_pvt, PA_MASTER);
-			stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+			if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
+				switch_core_session_destroy(&session);
+				stream->write_function(stream, "FAIL:Thread Error!\n");
+			} else {
+				add_pvt(tech_pvt, PA_MASTER);
+				stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+			}
 		} else {
 			switch_core_session_destroy(&session);
 			stream->write_function(stream, "FAIL:Device Error!\n");
@@ -1706,13 +1711,13 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t padep(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(padep)
 {
 	stream->write_function(stream, "This command no longer exists (try 'pa help')\n");
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t pa_cmd(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(pa_cmd)
 {
 	char *argv[1024] = { 0 };
 	int argc = 0;

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/Makefile.am
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/Makefile.am	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/Makefile.am	Mon May 14 10:50:37 2007
@@ -1,6 +1,6 @@
 AM_CFLAGS   = $(SWITCH_AM_CFLAGS)
 AM_CPPFLAGS = $(SWITCH_AM_CXXFLAGS)
-AM_LDFLAGS  = $(SWITCH_AM_LDFLAGS)
+#AM_LDFLAGS  = $(SWITCH_AM_LDFLAGS)
 #we should set all these vars from configure, no reason to have these in each Makefile.am
 LIBTOOL = echo "`link=\`echo $@|grep .la;echo $@|grep .so;echo $@|grep .dll\`;if test -n "$$link"; then echo Creating $@;fi`";`if test -z "$(VERBOSE)" ; \
 then echo $(SHELL) $(switch_builddir)/quiet_libtool ;else echo $(SHELL) $(switch_builddir)/libtool;  fi`
@@ -12,9 +12,7 @@
 
 MODNAME=mod_sofia
 
-BASE=../../../..
-
-SOFIA_DIR=$(BASE)/libs/sofia-sip
+SOFIA_DIR=$(switch_builddir)/libs/sofia-sip
 SOFIAUA_DIR=$(SOFIA_DIR)/libsofia-sip-ua
 SOFIALA=$(SOFIAUA_DIR)/libsofia-sip-ua.la
 
@@ -30,8 +28,8 @@
 mod_sofia_la_CFLAGS += -I$(SOFIAUA_DIR)/soa -I$(SOFIAUA_DIR)/sresolv
 mod_sofia_la_CFLAGS += -I$(SOFIAUA_DIR)/stun -I$(SOFIAUA_DIR)/su
 mod_sofia_la_CFLAGS += -I$(SOFIAUA_DIR)/tport -I$(SOFIAUA_DIR)/url
-mod_sofia_la_LIBADD = $(SOFIALA) $(switch_builddir)/libfreeswitch.la
-mod_sofia_la_LDFLAGS = -module -avoid-version -no-undefined
+mod_sofia_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SOFIALA)
+mod_sofia_la_LDFLAGS = -avoid-version -module -no-undefined
 
 if ADD_ODBC
 mod_sofia_la_CFLAGS += -DSWITCH_HAVE_ODBC
@@ -51,12 +49,12 @@
 
 ../../../../libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h: $(SOFIALA)
 
-install-data-am: $(DESTDIR)$(PREFIX)/$(moddir)/$(MODNAME).$(DYNAMIC_LIB_EXTEN)
+#install-data-am: $(DESTDIR)$(PREFIX)/$(moddir)/$(MODNAME).$(DYNAMIC_LIB_EXTEN)
 
-$(DESTDIR)$(PREFIX)/$(moddir)/$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).la
-	@echo installing $(MODNAME).$(DYNAMIC_LIB_EXTEN)
-	@if [ -f .libs/$(MODNAME).$(DYNAMIC_LIB_EXTEN) ] ; then \
-	  $(LIBTOOL) --mode=install $(INSTALL) .libs/$(MODNAME).$(DYNAMIC_LIB_EXTEN) $(DESTDIR)$(PREFIX)/$(moddir) >/dev/null  ; \
-	else \
-	  $(LIBTOOL) --mode=install $(INSTALL) $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(DESTDIR)$(PREFIX)/$(moddir) >/dev/null  ; \
-	fi
+#$(DESTDIR)$(PREFIX)/$(moddir)/$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).la
+#	@echo installing $(MODNAME).$(DYNAMIC_LIB_EXTEN)
+#	@if [ -f .libs/$(MODNAME).$(DYNAMIC_LIB_EXTEN) ] ; then \
+#	  $(LIBTOOL) --mode=install $(INSTALL) .libs/$(MODNAME).$(DYNAMIC_LIB_EXTEN) $(DESTDIR)$(PREFIX)/$(moddir) >/dev/null  ; \
+#	else \
+#	  $(LIBTOOL) --mode=install $(INSTALL) $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(DESTDIR)$(PREFIX)/$(moddir) >/dev/null  ; \
+#	fi

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.c	Mon May 14 10:50:37 2007
@@ -339,7 +339,7 @@
 	tech_pvt = (private_object_t *) switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
 
-	if (switch_test_flag(tech_pvt, TFLAG_HUP) || !sofia_test_pflag(tech_pvt->profile, PFLAG_RUNNING)) {
+	if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
 		return SWITCH_STATUS_FALSE;
 	}
 
@@ -411,7 +411,7 @@
 		}
 	}
 
-	if (switch_test_flag(tech_pvt, TFLAG_HUP) || !sofia_test_pflag(tech_pvt->profile, PFLAG_RUNNING)) {
+	if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
 		return SWITCH_STATUS_FALSE;
 	}
 
@@ -443,7 +443,7 @@
 	tech_pvt = (private_object_t *) switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
 
-	if (switch_test_flag(tech_pvt, TFLAG_HUP) || !sofia_test_pflag(tech_pvt->profile, PFLAG_RUNNING)) {
+	if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
 		return SWITCH_STATUS_FALSE;
 	}
 
@@ -538,7 +538,7 @@
 		}
 	}
 
-	if (switch_test_flag(tech_pvt, TFLAG_HUP) || !sofia_test_pflag(tech_pvt->profile, PFLAG_RUNNING)) {
+	if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
 		return SWITCH_STATUS_FALSE;
 	}
 
@@ -1140,7 +1140,7 @@
 
 
 	if (!strcasecmp(argv[1], "stop") || !strcasecmp(argv[1], "restart")) {
-		int rsec = 30;
+		int rsec = 3;
 		int diff = (int) (time(NULL) - profile->started);
 		int remain = rsec - diff;
 		if (diff < rsec) {
@@ -1175,7 +1175,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t sofia_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(sofia_function)
 {
 	char *argv[1024] = { 0 };
 	int argc = 0;
@@ -1190,7 +1190,7 @@
 		"sofia status [[profile | gateway] <name>]\n"
 		"--------------------------------------------------------------------------------\n";
 		
-	if (isession) {
+	if (session) {
 		return SWITCH_STATUS_FALSE;
 	}
 	

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.h	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.h	Mon May 14 10:50:37 2007
@@ -242,6 +242,7 @@
 	switch_thread_rwlock_t *rwlock;
 	switch_mutex_t *flag_mutex;
 	uint32_t inuse;
+	uint32_t soft_max;
 	time_t started;
 #ifdef SWITCH_HAVE_ODBC
 	char *odbc_dsn;

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c	Mon May 14 10:50:37 2007
@@ -363,11 +363,6 @@
 		su_root_step(profile->s_root, 1000);
 	}
 
-	while(profile->inuse) {
-		switch_yield(500000);
-	}
-
-
 
 	//sofia_reg_check_expire(profile, 0);
 	//sofia_reg_check_gateway(profile, 0);	
@@ -481,7 +476,8 @@
 				*proxy = NULL,
 				*context = "default",
 				*expire_seconds = "3600",
-				*retry_seconds = "30";
+				*retry_seconds = "30",
+				*from_domain = "";
 			
 			gateway->pool = profile->pool;
 			gateway->profile = profile;
@@ -515,6 +511,8 @@
 					expire_seconds = val;
 				} else if (!strcmp(var, "retry-seconds")) {
 					retry_seconds = val;
+				} else if (!strcmp(var, "from-domain")) {
+					from_domain = val;
 				}
 			}
 
@@ -544,6 +542,10 @@
 				gateway->state = REG_STATE_NOREG;
 			}
 
+			if (switch_strlen_zero(from_domain)) {
+				from_domain = realm;
+			}
+
 			gateway->retry_seconds = atoi(retry_seconds);
 			if (gateway->retry_seconds < 10) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "INVALID: retry_seconds correcting the value to 30\n");
@@ -557,7 +559,7 @@
 			if (switch_true(caller_id_in_from)) {
 				switch_set_flag(gateway, REG_FLAG_CALLERID);
 			}
-			gateway->register_from = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, realm);
+			gateway->register_from = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, from_domain);
 			gateway->register_contact = switch_core_sprintf(gateway->pool, "sip:%s@%s:%d", extension, profile->sipip, profile->sip_port);
 
 			if (!strncasecmp(proxy, "sip:", 4)) {
@@ -1708,10 +1710,17 @@
 	const char *context = NULL;
 	char network_ip[80];
 	switch_event_t *v_event = NULL;
+	uint32_t sess_count = switch_core_session_count();
+	uint32_t sess_max = switch_core_session_limit(0);
+
+	if ((profile->soft_max && sess_count >= profile->soft_max) || sess_count >= sess_max) {
+		nua_respond(nh, 480, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
+		return;
+	}
 
 	if (!sip || !sip->sip_request || !sip->sip_request->rq_method_name) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received an invalid packet!\n");
-		nua_respond(nh, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
+		nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, TAG_END());
 		return;
 	}
 
@@ -1911,7 +1920,33 @@
 	switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
 	nua_handle_bind(nh, tech_pvt->sofia_private);
 	tech_pvt->nh = nh;
-	switch_core_session_thread_launch(session);
+
+	if (switch_core_session_thread_launch(session) == SWITCH_STATUS_SUCCESS) {
+		return;
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "LUKE: I'm hit, but not bad.\n");
+					  
+	switch_mutex_lock(profile->flag_mutex);
+
+	profile->soft_max = sess_count - 10;
+	switch_core_session_limit(profile->soft_max);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "LUKE'S VOICE: Artoo, see what you can do with it. Hang on back there....\n"
+					  "Green laserfire moves past the beeping little robot as his head turns.  "
+					  "After a few beeps and a twist of his mechanical arm,\n"
+					  "Artoo reduces the max sessions to %d thus, saving the switch from certian doom.\n", 
+					  profile->soft_max);
+
+	switch_mutex_unlock(profile->flag_mutex);
+
+	if (tech_pvt->hash_key) {
+		switch_core_hash_delete(tech_pvt->profile->chat_hash, tech_pvt->hash_key);
+	}
+
+	nua_handle_bind(nh, NULL);
+	free(tech_pvt->sofia_private);
+	switch_core_session_destroy(&session);
+	nua_respond(nh, 480, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
 }
 
 void sofia_handle_sip_i_options(int status,

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c	Mon May 14 10:50:37 2007
@@ -281,7 +281,7 @@
 
 	if (!from_user || !from_host) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can not do authorization without a complete from header\n");
-		nua_respond(nh, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
+		nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END());
 		return 1;
 	}
 

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c	Mon May 14 10:50:37 2007
@@ -1562,6 +1562,12 @@
 		switch_copy_string(chanmap->map[pevent->ring.channel], switch_core_session_get_uuid(session), sizeof(chanmap->map[pevent->ring.channel]));
 		
 		switch_channel_set_state(channel, CS_INIT);
+		if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
+			switch_core_session_destroy(&session);
+			ret = 0;
+			goto done;
+		}
 		switch_core_session_thread_launch(session);
 	} else {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create new Inbound Channel!\n");

Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_woomera/mod_woomera.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_woomera/mod_woomera.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_woomera/mod_woomera.c	Mon May 14 10:50:37 2007
@@ -1240,7 +1240,11 @@
 						break;
 					}
 					switch_channel_set_state(channel, CS_INIT);
-					switch_core_session_thread_launch(session);
+					if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
+						switch_core_session_destroy(&session);
+						break;
+					}
 				}
 			}
 		}

Modified: freeswitch/branches/greenlizard/src/mod/event_handlers/mod_cdr/basecdr.h
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/event_handlers/mod_cdr/basecdr.h	(original)
+++ freeswitch/branches/greenlizard/src/mod/event_handlers/mod_cdr/basecdr.h	Mon May 14 10:50:37 2007
@@ -90,7 +90,7 @@
 	switch_time_t callenddate;
 	switch_time_t calltransferdate;
 	switch_call_cause_t hangupcause;
-	char *hangupcause_text;
+	const char *hangupcause_text;
 	char clid[80];
 	bool originated;			// Did they originate this call?
 	char dialplan[80];

Modified: freeswitch/branches/greenlizard/src/mod/event_handlers/mod_cdr/mod_cdr.cpp
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/event_handlers/mod_cdr/mod_cdr.cpp	(original)
+++ freeswitch/branches/greenlizard/src/mod/event_handlers/mod_cdr/mod_cdr.cpp	Mon May 14 10:50:37 2007
@@ -45,11 +45,11 @@
 static CDRContainer *newcdrcontainer;
 static switch_memory_pool_t *module_pool;
 static switch_status_t my_on_hangup(switch_core_session_t *session);
-static switch_status_t modcdr_reload(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
-static switch_status_t modcdr_queue_pause(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
-static switch_status_t modcdr_queue_resume(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
-static switch_status_t modcdr_show_active(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
-static switch_status_t modcdr_show_available(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
+static switch_status_t modcdr_reload(const char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
+static switch_status_t modcdr_queue_pause(const char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
+static switch_status_t modcdr_queue_resume(const char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
+static switch_status_t modcdr_show_active(const char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
+static switch_status_t modcdr_show_available(const char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
 static switch_thread_rwlock_t *cdr_rwlock;
 
 /* Now begins the glue that will tie this into the system.
@@ -151,7 +151,7 @@
 	return RUNNING ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_TERM;
 }
 
-static switch_status_t modcdr_reload(char *dest=0, switch_core_session_t *isession=0, switch_stream_handle_t *stream=0)
+SWITCH_STANDARD_API(modcdr_reload)
 {
 #ifdef SWITCH_QUEUE_ENHANCED
 	switch_thread_rwlock_wrlock(cdr_rwlock);
@@ -164,7 +164,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t modcdr_queue_pause(char *dest=0, switch_core_session_t *isession=0, switch_stream_handle_t *stream=0)
+SWITCH_STANDARD_API(modcdr_queue_pause)
 {
 #ifdef SWITCH_QUEUE_ENHANCED
 	newcdrcontainer->queue_pause(stream);
@@ -174,7 +174,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t modcdr_queue_resume(char *dest=0, switch_core_session_t *isession=0, switch_stream_handle_t *stream=0)
+SWITCH_STANDARD_API(modcdr_queue_resume)
 {
 #ifdef SWITCH_QUEUE_ENHANCED
 	newcdrcontainer->queue_resume(stream);
@@ -184,13 +184,13 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t modcdr_show_active(char *dest=0, switch_core_session_t *isession=0, switch_stream_handle_t *stream=0)
+SWITCH_STANDARD_API(modcdr_show_active)
 {
 	newcdrcontainer->active(stream);
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t modcdr_show_available(char *dest=0, switch_core_session_t *isession=0, switch_stream_handle_t *stream=0)
+SWITCH_STANDARD_API(modcdr_show_available)
 {
 	newcdrcontainer->available(stream);
 	return SWITCH_STATUS_SUCCESS;

Modified: freeswitch/branches/greenlizard/src/mod/languages/mod_python/freeswitch_python.cpp
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/languages/mod_python/freeswitch_python.cpp	(original)
+++ freeswitch/branches/greenlizard/src/mod/languages/mod_python/freeswitch_python.cpp	Mon May 14 10:50:37 2007
@@ -51,10 +51,10 @@
     switch_channel_set_variable(channel, var, val);
 }
 
-void SessionContainer::get_variable(char *var, char *val)
+char *SessionContainer::get_variable(char *var)
 {
-	sanity_check();
-    switch_channel_get_variable(channel, var);
+	sanity_check(NULL);
+    return switch_channel_get_variable(channel, var);
 }
 
 void SessionContainer::execute(char *app, char *data)

Modified: freeswitch/branches/greenlizard/src/mod/languages/mod_python/freeswitch_python.h
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/languages/mod_python/freeswitch_python.h	(original)
+++ freeswitch/branches/greenlizard/src/mod/languages/mod_python/freeswitch_python.h	Mon May 14 10:50:37 2007
@@ -34,7 +34,7 @@
 	int pre_answer();
 	void hangup(char *cause);
 	void set_variable(char *var, char *val);
-	void get_variable(char *var, char *val);
+	char *get_variable(char *var);
 	int play_file(char *file, char *timer_name);
 	void set_dtmf_callback(PyObject * pyfunc);
 	int speak_text(char *text);

Modified: freeswitch/branches/greenlizard/src/mod/languages/mod_python/mod_python.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/languages/mod_python/mod_python.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/languages/mod_python/mod_python.c	Mon May 14 10:50:37 2007
@@ -161,14 +161,14 @@
 	return NULL;
 }
 
-static switch_status_t launch_python(char *text, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(launch_python)
 {
 	switch_thread_t *thread;
     switch_threadattr_t *thd_attr = NULL;
 	switch_memory_pool_t *pool;
 	struct switch_py_thread *pt;
 
-	if (switch_strlen_zero(text)) {
+	if (switch_strlen_zero(cmd)) {
 		stream->write_function(stream, "USAGE: %s\n", python_run_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
 	}
@@ -180,7 +180,7 @@
 	assert(pt != NULL);
 
 	pt->pool = pool;
-	pt->args = switch_core_strdup(pt->pool, text);
+	pt->args = switch_core_strdup(pt->pool, cmd);
 	
     switch_threadattr_create(&thd_attr, pt->pool);
     switch_threadattr_detach_set(thd_attr, 1);

Modified: freeswitch/branches/greenlizard/src/mod/languages/mod_python/mod_python_wrap.cpp
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/languages/mod_python/mod_python_wrap.cpp	(original)
+++ freeswitch/branches/greenlizard/src/mod/languages/mod_python/mod_python_wrap.cpp	Mon May 14 10:50:37 2007
@@ -1045,14 +1045,14 @@
     PyObject *resultobj;
     SessionContainer *arg1 = (SessionContainer *) 0 ;
     char *arg2 ;
-    char *arg3 ;
+    char *result;
     PyObject * obj0 = 0 ;
     
-    if(!PyArg_ParseTuple(args,(char *)"Oss:SessionContainer_get_variable",&obj0,&arg2,&arg3)) goto fail;
+    if(!PyArg_ParseTuple(args,(char *)"Os:SessionContainer_get_variable",&obj0,&arg2)) goto fail;
     if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_SessionContainer,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
-    (arg1)->get_variable(arg2,arg3);
+    result = (char *)(arg1)->get_variable(arg2);
     
-    Py_INCREF(Py_None); resultobj = Py_None;
+    resultobj = result ? PyString_FromString(result) : Py_BuildValue((char*)"");
     return resultobj;
     fail:
     return NULL;

Modified: freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c	Mon May 14 10:50:37 2007
@@ -45,6 +45,7 @@
 static JSBool session_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval);
 static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval);
 static switch_api_interface_t js_run_interface;
+static switch_api_interface_t jsapi_interface;
 
 static struct {
 	size_t gStackChunkSize;
@@ -111,6 +112,190 @@
 	int32 bufsize;
 };
 
+struct request_obj {
+	const char *cmd;
+	switch_core_session_t *session;
+	switch_stream_handle_t *stream;
+};
+
+
+/* Request Object */
+/*********************************************************************************/
+
+static JSBool request_write(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
+{
+	struct request_obj *ro = JS_GetPrivate(cx, obj);
+
+	if (!ro) {
+		*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+		return JS_TRUE;
+	}
+
+	if (argc > 0) {
+		char *string = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		ro->stream->write_function(ro->stream, "%s", string);
+		*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
+		return JS_TRUE;
+	}
+
+	*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+	return JS_TRUE;
+}
+
+static JSBool request_add_header(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+	struct request_obj *ro = JS_GetPrivate(cx, obj);
+
+	if (!ro) {
+		*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+		return JS_TRUE;
+	}
+
+	if (argc > 1) {
+		char *hname = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		char *hval = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+		switch_event_add_header(ro->stream->event, SWITCH_STACK_BOTTOM, hname, "%s", hval);
+		*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
+		return JS_TRUE;
+	}
+
+	*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+	return JS_TRUE;
+}
+
+static JSBool request_get_header(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
+{
+	struct request_obj *ro = JS_GetPrivate(cx, obj);
+
+	if (!ro) {
+		*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+		return JS_TRUE;
+	}
+
+
+	if (argc > 0) {
+		char *hname = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		char *val = switch_event_get_header(ro->stream->event, hname);
+		*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val));
+		return JS_TRUE;
+	}
+
+	*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+	return JS_TRUE;
+}
+
+static JSBool request_dump_env(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+	struct request_obj *ro = JS_GetPrivate(cx, obj);
+	char *how = "text";
+
+	if (!ro) {
+		*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+		return JS_TRUE;
+	}
+
+	if (argc > 0) {
+		how = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+	}
+
+	if (!strcasecmp(how, "xml")) {
+		switch_xml_t xml;
+		char *xmlstr;
+		if ((xml = switch_event_xmlize(ro->stream->event, NULL))) {
+            xmlstr = switch_xml_toxml(xml);
+			*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, xmlstr));
+			return JS_TRUE;
+        } 
+	} else {
+		char *buf;
+		switch_event_serialize(ro->stream->event, &buf);
+		if (buf) {
+			*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
+			free(buf);
+			return JS_TRUE;
+		}
+	}
+
+	*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+	return JS_FALSE;
+}
+
+static void request_destroy(JSContext * cx, JSObject * obj)
+{
+	
+}
+
+enum request_tinyid {
+	REQUEST_COMMAND
+};
+
+static JSFunctionSpec request_methods[] = {
+	{"write", request_write, 1},
+	{"getHeader", request_get_header, 1},
+	{"addHeader", request_add_header, 1},
+	{"dumpENV", request_dump_env, 1},
+	{0}
+};
+
+static JSPropertySpec request_props[] = {
+	{"command", REQUEST_COMMAND, JSPROP_READONLY | JSPROP_PERMANENT},
+	{0}
+};
+
+
+static JSBool request_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+	JSBool res = JS_TRUE;
+	struct request_obj *ro = JS_GetPrivate(cx, obj);
+	char *name;
+	int param = 0;
+
+	if (!ro) {
+		*vp = BOOLEAN_TO_JSVAL(JS_FALSE);
+		return JS_TRUE;
+	}
+
+
+	name = JS_GetStringBytes(JS_ValueToString(cx, id));
+	/* numbers are our props anything else is a method */
+	if (name[0] >= 48 && name[0] <= 57) {
+		param = atoi(name);
+	} else {
+		return JS_TRUE;
+	}
+
+	switch (param) {
+	case REQUEST_COMMAND:
+		*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, ro->cmd));
+		break;
+	}
+
+	return res;
+}
+
+
+JSClass request_class = {
+	"Request", JSCLASS_HAS_PRIVATE,
+	JS_PropertyStub, JS_PropertyStub, request_getProperty, JS_PropertyStub,
+	JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, request_destroy, NULL, NULL, NULL, NULL
+};
+
+
+static JSObject *new_request(JSContext *cx, JSObject *obj, struct request_obj *ro)
+{
+	JSObject *Request;
+	if ((Request = JS_DefineObject(cx, obj, "request", &request_class, NULL, 0))) {
+		if ((JS_SetPrivate(cx, Request, ro) &&
+			 JS_DefineProperties(cx, Request, request_props) && JS_DefineFunctions(cx, Request, request_methods))) {
+			return Request;
+		}
+	}
+
+	return NULL;
+}
+
+
+
 struct event_obj {
 	switch_event_t *event;
 	int freed;
@@ -402,8 +587,6 @@
 };
 
 
-
-
 static void js_error(JSContext * cx, const char *message, JSErrorReport * report)
 {
 	const char *filename = __FILE__;
@@ -2649,7 +2832,7 @@
 	return 1;
 }
 
-static void js_parse_and_execute(switch_core_session_t *session, char *input_code)
+static void js_parse_and_execute(switch_core_session_t *session, char *input_code, struct request_obj *ro)
 {
 	JSObject *javascript_global_object = NULL;
 	char buf[1024], *script, *arg, *argv[512];
@@ -2671,6 +2854,10 @@
 		if (session && new_js_session(cx, javascript_global_object, session, &jss, "session", flags)) {
 			JS_SetPrivate(cx, javascript_global_object, session);
 		}
+		if (ro) {
+			new_request(cx, javascript_global_object, ro);
+		}
+
 	} else {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Allocation Error!\n");
 		return;
@@ -2683,7 +2870,11 @@
 		argc = switch_separate_string(arg, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
 	}
 
-	if (argc) {					/* create a js doppleganger of this argc/argv */
+	if (!argc) {
+		snprintf(buf, sizeof(buf), "~var argv = new Array();");
+		eval_some_js(buf, cx, javascript_global_object, &rval);
+	} else {
+		/* create a js doppleganger of this argc/argv */
 		snprintf(buf, sizeof(buf), "~var argv = new Array(%d);", argc);
 		eval_some_js(buf, cx, javascript_global_object, &rval);
 		snprintf(buf, sizeof(buf), "~var argc = %d", argc);
@@ -2701,14 +2892,16 @@
 	}
 }
 
-
-
+static void js_dp_function(switch_core_session_t *session, char *input_code)
+{
+	js_parse_and_execute(session, input_code, NULL);
+}
 
 static void *SWITCH_THREAD_FUNC js_thread_run(switch_thread_t * thread, void *obj)
 {
 	char *input_code = obj;
 
-	js_parse_and_execute(NULL, input_code);
+	js_parse_and_execute(NULL, input_code, NULL);
 
 	if (input_code) {
 		free(input_code);
@@ -2720,7 +2913,7 @@
 
 static switch_memory_pool_t *module_pool = NULL;
 
-static void js_thread_launch(char *text)
+static void js_thread_launch(const char *text)
 {
 	switch_thread_t *thread;
 	switch_threadattr_t *thd_attr = NULL;
@@ -2738,16 +2931,33 @@
 	switch_thread_create(&thread, thd_attr, js_thread_run, strdup(text), module_pool);
 }
 
+SWITCH_STANDARD_API(jsapi_function)
+{
+	struct request_obj ro = {0};
+
+	if (switch_strlen_zero(cmd)) {
+		stream->write_function(stream, "USAGE: %s\n", jsapi_interface.syntax);
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	ro.cmd = cmd;
+	ro.session = session;
+	ro.stream = stream;
+	js_parse_and_execute(session, (char *) cmd, &ro);
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
 
-static switch_status_t launch_async(char *text, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(launch_async)
 {
 
-	if (switch_strlen_zero(text)) {
+	if (switch_strlen_zero(cmd)) {
 		stream->write_function(stream, "USAGE: %s\n", js_run_interface.syntax);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
-	js_thread_launch(text);
+	js_thread_launch(cmd);
 	stream->write_function(stream, "OK\n");
 	return SWITCH_STATUS_SUCCESS;
 }
@@ -2755,7 +2965,7 @@
 
 static const switch_application_interface_t ivrtest_application_interface = {
 	/*.interface_name */ "javascript",
-	/*.application_function */ js_parse_and_execute,
+	/*.application_function */ js_dp_function,
 	/* long_desc */ "Run a javascript ivr on a channel",
 	/* short_desc */ "Launch JS ivr.",
 	/* syntax */ "<script> [additional_vars [...]]",
@@ -2764,12 +2974,21 @@
 	/*.next */ NULL
 };
 
+
+static switch_api_interface_t jsapi_interface = {
+	/*.interface_name */ "jsapi",
+	/*.desc */ "execute an api call",
+	/*.function */ jsapi_function,
+	/*.syntax */ "jsapi <script> [additional_vars [...]]",
+	/*.next */ NULL
+};
+
 static switch_api_interface_t js_run_interface = {
 	/*.interface_name */ "jsrun",
 	/*.desc */ "run a script",
 	/*.function */ launch_async,
 	/*.syntax */ "jsrun <script> [additional_vars [...]]",
-	/*.next */ NULL
+	/*.next */ &jsapi_interface
 };
 
 static switch_loadable_module_interface_t spidermonkey_module_interface = {

Modified: freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c	(original)
+++ freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c	Mon May 14 10:50:37 2007
@@ -37,6 +37,7 @@
 	char *url;
 	char *bindings;
 	char *cred;
+	int disable100continue;
 };
 
 typedef struct xml_binding xml_binding_t;
@@ -68,6 +69,7 @@
 	char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
 	xml_binding_t *binding = (xml_binding_t *) user_data;
 	char *file_url;
+	struct curl_slist *slist = NULL;
 
 	if (!binding) {
 		return NULL;
@@ -115,6 +117,12 @@
 		curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, file_callback);
 		curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
 		curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-xml/1.0");
+
+		if (binding->disable100continue) {
+			slist = curl_slist_append(slist,"Expect:"); 
+			curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, slist); 
+		}
+
 		curl_easy_perform(curl_handle);
 		curl_easy_cleanup(curl_handle);
 		close(config_data.fd);
@@ -169,6 +177,7 @@
 		char *url = NULL;
 		char *bind_cred = NULL;
 		char *bind_mask = NULL;
+		int disable100continue = 0;
 
 		for (param = switch_xml_child(binding_tag, "param"); param; param = param->next) {
 			char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -180,6 +189,8 @@
 				}
 			} else if (!strcasecmp(var, "gateway-credentials")) {
 				bind_cred = val;
+			} else if (!strcasecmp(var, "disable-100-continue") && switch_true(val)) {
+				disable100continue = 1;
 			}
 		}
 
@@ -203,6 +214,8 @@
 			binding->cred = strdup(bind_cred);
 		}
 
+		binding->disable100continue = disable100continue;
+
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding [%s] XML Fetch Function [%s] [%s]\n",
 						  switch_strlen_zero(bname) ? "N/A" : bname, binding->url, binding->bindings ? binding->bindings : "all");
 		switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(binding->bindings), binding);

Modified: freeswitch/branches/greenlizard/src/switch_buffer.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_buffer.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_buffer.c	Mon May 14 10:50:37 2007
@@ -193,7 +193,7 @@
 	return reading;
 }
 
-SWITCH_DECLARE(switch_size_t) switch_buffer_write(switch_buffer_t *buffer, void *data, switch_size_t datalen)
+SWITCH_DECLARE(switch_size_t) switch_buffer_write(switch_buffer_t *buffer, const void *data, switch_size_t datalen)
 {
 	switch_size_t freespace, actual_freespace;
 

Modified: freeswitch/branches/greenlizard/src/switch_caller.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_caller.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_caller.c	Mon May 14 10:50:37 2007
@@ -92,7 +92,7 @@
 	return profile;
 }
 
-SWITCH_DECLARE(char *) switch_caller_get_field_by_name(switch_caller_profile_t *caller_profile, char *name)
+SWITCH_DECLARE(char *) switch_caller_get_field_by_name(switch_caller_profile_t *caller_profile, const char *name)
 {
 	if (!strcasecmp(name, "dialplan")) {
 		return caller_profile->dialplan;
@@ -136,7 +136,7 @@
 	return NULL;
 }
 
-SWITCH_DECLARE(void) switch_caller_profile_event_set_data(switch_caller_profile_t *caller_profile, char *prefix, switch_event_t *event)
+SWITCH_DECLARE(void) switch_caller_profile_event_set_data(switch_caller_profile_t *caller_profile, const char *prefix, switch_event_t *event)
 {
 	char header_name[1024];
 
@@ -207,7 +207,7 @@
 
 }
 
-SWITCH_DECLARE(switch_caller_extension_t *) switch_caller_extension_new(switch_core_session_t *session, char *extension_name, char *extension_number)
+SWITCH_DECLARE(switch_caller_extension_t *) switch_caller_extension_new(switch_core_session_t *session, const char *extension_name, const char *extension_number)
 {
 	switch_caller_extension_t *caller_extension = NULL;
 
@@ -222,7 +222,7 @@
 
 
 SWITCH_DECLARE(void) switch_caller_extension_add_application(switch_core_session_t *session,
-															 switch_caller_extension_t *caller_extension, char *application_name, char *application_data)
+															 switch_caller_extension_t *caller_extension, const char *application_name, const char *application_data)
 {
 	switch_caller_application_t *caller_application = NULL;
 

Modified: freeswitch/branches/greenlizard/src/switch_channel.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_channel.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_channel.c	Mon May 14 10:50:37 2007
@@ -119,21 +119,21 @@
 };
 
 
-SWITCH_DECLARE(char *) switch_channel_cause2str(switch_call_cause_t cause)
+SWITCH_DECLARE(const char *) switch_channel_cause2str(switch_call_cause_t cause)
 {
 	uint8_t x;
-	char *str = "UNKNOWN";
+	const char *str = "UNKNOWN";
 
 	for (x = 0; CAUSE_CHART[x].name; x++) {
 		if (CAUSE_CHART[x].cause == cause) {
-			str = (char *) CAUSE_CHART[x].name;
+			str = CAUSE_CHART[x].name;
 		}
 	}
 
 	return str;
 }
 
-SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2cause(char *str)
+SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2cause(const char *str)
 {
 	uint8_t x;
 	switch_call_cause_t cause = SWITCH_CAUSE_UNALLOCATED;
@@ -198,12 +198,12 @@
 	return has;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *channel, char *dtmf)
+SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *channel, const char *dtmf)
 {
 	switch_status_t status;
 	register switch_size_t len, inuse;
 	switch_size_t wr = 0;
-	char *p;
+	const char *p;
 
 	assert(channel != NULL);
 
@@ -270,7 +270,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-SWITCH_DECLARE(void) switch_channel_presence(switch_channel_t *channel, char *rpid, char *status)
+SWITCH_DECLARE(void) switch_channel_presence(switch_channel_t *channel, const char *rpid, const char *status)
 {
 	char *id = switch_channel_get_variable(channel, "presence_id");
 	switch_event_t *event;
@@ -302,7 +302,7 @@
 }
 
 
-SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, char *varname)
+SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, const char *varname)
 {
 	char *v = NULL;
 	assert(channel != NULL);
@@ -343,7 +343,7 @@
 	return hi;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_channel_set_private(switch_channel_t *channel, char *key, void *private_info)
+SWITCH_DECLARE(switch_status_t) switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
 {
 	assert(channel != NULL);
 	switch_mutex_lock(channel->profile_mutex);
@@ -352,7 +352,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-SWITCH_DECLARE(void *) switch_channel_get_private(switch_channel_t *channel, char *key)
+SWITCH_DECLARE(void *) switch_channel_get_private(switch_channel_t *channel, const char *key)
 {
 	void *val;
 	assert(channel != NULL);
@@ -362,7 +362,7 @@
 	return val;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_channel_set_name(switch_channel_t *channel, char *name)
+SWITCH_DECLARE(switch_status_t) switch_channel_set_name(switch_channel_t *channel, const char *name)
 {
 	assert(channel != NULL);
 	channel->name = NULL;
@@ -532,7 +532,7 @@
 }
 
 
-SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(char *name)
+SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(const char *name)
 {
 	uint32_t x = 0;
 	for (x = 0; state_names[x]; x++) {

Modified: freeswitch/branches/greenlizard/src/switch_core.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_core.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_core.c	Mon May 14 10:50:37 2007
@@ -71,16 +71,16 @@
 	}
 }
 
-static void heartbeat_callback(switch_scheduler_task_t *task)
+SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback)
 {
 	send_heartbeat();
 
 	/* reschedule this task */
-	task->runtime += 20;
+	task->runtime = time(NULL) + 20;
 }
 
 
-SWITCH_DECLARE(switch_status_t) switch_core_set_console(char *console)
+SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console)
 {
 	if ((runtime.console = fopen(console, "a")) == 0) {
 		fprintf(stderr, "Cannot open output file %s.\n", console);
@@ -135,12 +135,12 @@
 }
 
 
-SWITCH_DECLARE(char *) switch_core_get_variable(char *varname)
+SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname)
 {
 	return (char *) switch_core_hash_find(runtime.global_vars, varname);
 }
 
-SWITCH_DECLARE(void) switch_core_set_variable(char *varname, char *value)
+SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value)
 {
 	switch_core_hash_insert(runtime.global_vars, switch_core_strdup(runtime.memory_pool, varname), switch_core_strdup(runtime.memory_pool, value));
 }
@@ -392,7 +392,7 @@
 }
 
 
-SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err)
+SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, const char **err)
 {
 	switch_xml_t xml = NULL, cfg = NULL;
 	switch_uuid_t uuid;
@@ -538,7 +538,7 @@
 	if (sig);
 	return;
 }
-SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(char *console, const char **err)
+SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(const char *console, const char **err)
 {
 	switch_event_t *event;
 	if (switch_core_init(console, err) != SWITCH_STATUS_SUCCESS) {

Modified: freeswitch/branches/greenlizard/src/switch_core_session.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_core_session.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_core_session.c	Mon May 14 10:50:37 2007
@@ -45,9 +45,9 @@
 
 
 #ifdef SWITCH_DEBUG_RWLOCKS
-SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_locate(char *uuid_str, const char *file, const char *func, int line)
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_locate(const char *uuid_str, const char *file, const char *func, int line)
 #else
-SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str)
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(const char *uuid_str)
 #endif
 {
 	switch_core_session_t *session = NULL;
@@ -651,13 +651,15 @@
 }
 
 
-SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session)
+SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t **session, const char *file, const char *func, int line)
 {
 	switch_memory_pool_t *pool;
 	switch_event_t *event;
 
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Close Channel %s\n", switch_channel_get_name((*session)->channel));
-
+	switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, SWITCH_LOG_NOTICE, "Close Channel %s [%s]\n", 
+					  switch_channel_get_name((*session)->channel),
+					  switch_channel_state_name(switch_channel_get_state((*session)->channel)));
+	
 	switch_ivr_deactivate_unicast(*session);
 	
 	switch_scheduler_del_task_group((*session)->uuid_str);
@@ -711,7 +713,7 @@
 }
 
 
-SWITCH_DECLARE(void) switch_core_session_thread_launch(switch_core_session_t *session)
+SWITCH_DECLARE(switch_status_t) switch_core_session_thread_launch(switch_core_session_t *session)
 {
 	switch_thread_t *thread;
 	switch_threadattr_t *thd_attr;;
@@ -720,10 +722,16 @@
 
 	if (!session->thread_running) {
 		switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
-		if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) != SWITCH_STATUS_SUCCESS) {
-			switch_core_session_destroy(&session);
+		if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) == SWITCH_STATUS_SUCCESS) {
+			return SWITCH_STATUS_SUCCESS;
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot create thread!\n");
 		}
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
 	}
+
+	return SWITCH_STATUS_FALSE;
 }
 
 

Modified: freeswitch/branches/greenlizard/src/switch_cpp.cpp
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_cpp.cpp	(original)
+++ freeswitch/branches/greenlizard/src/switch_cpp.cpp	Mon May 14 10:50:37 2007
@@ -1,6 +1,10 @@
 #include <switch.h>
 #include <switch_cpp.h>
 
+#ifdef _MSC_VER
+#pragma warning(disable:4127 4003)
+#endif
+
 #define sanity_check(x) do { if (!session) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "session is not initalized\n"); return x;}} while(0)
 #define init_vars() do { session = NULL; channel = NULL; uuid = NULL; tts_name = NULL; voice_name = NULL; memset(&args, 0, sizeof(args)); ap = NULL;} while(0)
 
@@ -45,7 +49,7 @@
 {
     switch_status_t status;
 	sanity_check(-1);
-    switch_channel_pre_answer(channel);
+    status = switch_channel_pre_answer(channel);
     return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
 }
 
@@ -61,10 +65,10 @@
     switch_channel_set_variable(channel, var, val);
 }
 
-void CoreSession::getVariable(char *var, char *val)
+char *CoreSession::getVariable(char *var)
 {
-	sanity_check();
-    switch_channel_get_variable(channel, var);
+	sanity_check(NULL);
+    return switch_channel_get_variable(channel, var);
 }
 
 void CoreSession::execute(char *app, char *data)

Modified: freeswitch/branches/greenlizard/src/switch_ivr_async.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_ivr_async.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_ivr_async.c	Mon May 14 10:50:37 2007
@@ -615,7 +615,7 @@
 	switch_call_cause_t cause;
 };
 
-static void sch_hangup_callback(switch_scheduler_task_t *task)
+SWITCH_STANDARD_SCHED_FUNC(sch_hangup_callback)
 {
 	struct hangup_helper *helper;
 	switch_core_session_t *session, *other_session;
@@ -665,7 +665,7 @@
 	char *context;
 };
 
-static void sch_transfer_callback(switch_scheduler_task_t *task)
+SWITCH_STANDARD_SCHED_FUNC(sch_transfer_callback)
 {
 	struct transfer_helper *helper;
 	switch_core_session_t *session;
@@ -732,7 +732,7 @@
 	switch_media_flag_t flags;
 };
 
-static void sch_broadcast_callback(switch_scheduler_task_t *task)
+SWITCH_STANDARD_SCHED_FUNC(sch_broadcast_callback)
 {
 	struct broadcast_helper *helper;
 	assert(task);

Modified: freeswitch/branches/greenlizard/src/switch_ivr_play_say.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_ivr_play_say.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_ivr_play_say.c	Mon May 14 10:50:37 2007
@@ -917,8 +917,7 @@
 
 		//Make sure we made it out alive
 		if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
-			switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-			break;
+			goto done;
 		}
 		//we only get one digit out of playback, see if thats all we needed and what we got
 		if (max_digits == 1 && status == SWITCH_STATUS_BREAK) {
@@ -938,8 +937,7 @@
 
 						//Make sure we made it out alive
 						if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
-							switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-							break;
+							goto done;
 						}
 					}
 				}
@@ -957,8 +955,7 @@
 		//Make sure we made it out alive
 		if (status != SWITCH_STATUS_SUCCESS) {
 			//Bail
-			switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-			break;
+			goto done;
 		}
 		//see if we got enough
 		if (min_digits <= strlen(digit_buffer)) {
@@ -977,8 +974,7 @@
 
 						//Make sure we made it out alive
 						if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
-							switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-							break;
+							goto done;
 						}
 					}
 				}
@@ -989,6 +985,7 @@
 		}
 	}
 
+ done:
 	//if we got here, we got no digits or lost the channel
 	digit_buffer = "\0";
 	return SWITCH_STATUS_FALSE;

Modified: freeswitch/branches/greenlizard/src/switch_loadable_module.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_loadable_module.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_loadable_module.c	Mon May 14 10:50:37 2007
@@ -1110,7 +1110,7 @@
 
 }
 
-SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoint_interface(char *name)
+SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoint_interface(const char *name)
 {
 	switch_endpoint_interface_t *ptr;
 
@@ -1121,7 +1121,7 @@
 	return ptr;
 }
 
-SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(char *name)
+SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(const char *name)
 {
 	char altname[256] = "";
 	switch_codec_interface_t *codec;
@@ -1143,57 +1143,57 @@
 	return codec;
 }
 
-SWITCH_DECLARE(switch_dialplan_interface_t *) switch_loadable_module_get_dialplan_interface(char *name)
+SWITCH_DECLARE(switch_dialplan_interface_t *) switch_loadable_module_get_dialplan_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.dialplan_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_timer_interface_t *) switch_loadable_module_get_timer_interface(char *name)
+SWITCH_DECLARE(switch_timer_interface_t *) switch_loadable_module_get_timer_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.timer_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_application_interface_t *) switch_loadable_module_get_application_interface(char *name)
+SWITCH_DECLARE(switch_application_interface_t *) switch_loadable_module_get_application_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.application_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_api_interface_t *) switch_loadable_module_get_api_interface(char *name)
+SWITCH_DECLARE(switch_api_interface_t *) switch_loadable_module_get_api_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.api_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(char *name)
+SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.file_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_speech_interface_t *) switch_loadable_module_get_speech_interface(char *name)
+SWITCH_DECLARE(switch_speech_interface_t *) switch_loadable_module_get_speech_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.speech_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_asr_interface_t *) switch_loadable_module_get_asr_interface(char *name)
+SWITCH_DECLARE(switch_asr_interface_t *) switch_loadable_module_get_asr_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.asr_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_directory_interface(char *name)
+SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_directory_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.directory_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(char *name)
+SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.chat_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(char *name)
+SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(const char *name)
 {
 	return switch_core_hash_find_locked(loadable_modules.say_hash, name, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(char *relative_oid)
+SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(const char *relative_oid)
 {
 	return switch_core_hash_find_locked(loadable_modules.management_hash, relative_oid, loadable_modules.mutex);
 }
@@ -1319,7 +1319,7 @@
 	return i;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_api_execute(char *cmd, char *arg, switch_core_session_t *session, switch_stream_handle_t *stream)
+SWITCH_DECLARE(switch_status_t) switch_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream)
 {
 	switch_api_interface_t *api;
 	switch_status_t status;

Modified: freeswitch/branches/greenlizard/src/switch_regex.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_regex.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_regex.c	Mon May 14 10:50:37 2007
@@ -32,12 +32,19 @@
 
 #include <switch.h>
 #include <pcre.h>
-
 
SWITCH_DECLARE(switch_regex_t *) switch_regex_compile(const char *pattern,
-														 int options, const char **errorptr, int *erroroffset, 
const unsigned char *tables) 
+
+ 
+SWITCH_DECLARE(switch_regex_t *) switch_regex_compile(const char *pattern,
+														 int options, const char **errorptr, int *erroroffset, 
+const unsigned char *tables) 
 {
-	
return pcre_compile(pattern, options, errorptr, erroroffset, tables);
-
}
-

SWITCH_DECLARE(int) switch_regex_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size)
+	
+return pcre_compile(pattern, options, errorptr, erroroffset, tables);
+
+}
+
+
+SWITCH_DECLARE(int) switch_regex_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size)
 {
 	return pcre_copy_substring(subject, ovector, stringcount, stringnumber, buffer, size);
 }
@@ -45,7 +52,10 @@
 SWITCH_DECLARE(void) switch_regex_free(void *data)
 {
 	pcre_free(data);
-
} 

SWITCH_DECLARE(int) switch_regex_perform(char *field, char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen)
+
+} 
+
+SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen)
 {
 	const char *error = NULL;
 	int erroffset = 0;
@@ -87,7 +97,7 @@
 }
 
 
-SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_count, char *data, char *field_data,
+SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data,
 												 char *substituted, uint32_t len, int *ovector)
 {
 	char index[10] = "";
@@ -124,7 +134,8 @@
 	}
 	substituted[y++] = '\0';
 }
-
SWITCH_DECLARE(switch_status_t) switch_regex_match(char *target, char *expression)
+
+SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const char *expression)
 {
 	const char *error = NULL;	//Used to hold any errors
 	int error_offset = 0;		//Holds the offset of an error

Modified: freeswitch/branches/greenlizard/src/switch_rtp.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_rtp.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_rtp.c	Mon May 14 10:50:37 2007
@@ -319,7 +319,7 @@
 }
 
 
-SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, char *host, switch_port_t port, const char **err)
+SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err)
 {
 	switch_socket_t *new_sock = NULL, *old_sock = NULL;
 	switch_status_t status = SWITCH_STATUS_FALSE;
@@ -389,7 +389,7 @@
 	return status;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, char *host, switch_port_t port, const char **err)
+SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err)
 {
 	*err = "Success";
 
@@ -545,9 +545,9 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(char *rx_host,
+SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host,
 											  switch_port_t rx_port,
-											  char *tx_host,
+											  const char *tx_host,
 											  switch_port_t tx_port,
 											  switch_payload_t payload,
 											  uint32_t samples_per_interval,

Modified: freeswitch/branches/greenlizard/src/switch_scheduler.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_scheduler.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_scheduler.c	Mon May 14 10:50:37 2007
@@ -77,6 +77,11 @@
 		} else {
 			int64_t now = time(NULL);
 			if (now >= tp->task.runtime && !tp->in_thread) {
+				int32_t diff = (int32_t)(now - tp->task.runtime);
+				if (diff > 1) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Task was executed late by %d seconds %u %s (%s)\n",
+									  diff, tp->task.task_id, tp->desc, switch_str_nil(tp->task.group));
+				}
 				tp->executed = now;
 				if (switch_test_flag(tp, SSHF_OWN_THREAD)) {
 					switch_thread_t *thread;
@@ -144,7 +149,7 @@
 
 SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime,
 												   switch_scheduler_func_t func,
-												   char *desc, char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags)
+												   const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags)
 {
 	switch_scheduler_task_container_t *container, *tp;
 	switch_event_t *event;
@@ -218,7 +223,7 @@
 	return delcnt;
 }
 
-SWITCH_DECLARE(uint32_t) switch_scheduler_del_task_group(char *group)
+SWITCH_DECLARE(uint32_t) switch_scheduler_del_task_group(const char *group)
 {
 	switch_scheduler_task_container_t *tp;
 	switch_event_t *event;

Modified: freeswitch/branches/greenlizard/src/switch_utils.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_utils.c	(original)
+++ freeswitch/branches/greenlizard/src/switch_utils.c	Mon May 14 10:50:37 2007
@@ -177,7 +177,7 @@
 }
 
 
-SWITCH_DECLARE(switch_time_t) switch_str_time(char *in)
+SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in)
 {
 	switch_time_exp_t tm = { 0 };
 	int proceed = 0, ovector[30];
@@ -229,7 +229,7 @@
 
 }
 
-SWITCH_DECLARE(char *) switch_priority_name(switch_priority_t priority)
+SWITCH_DECLARE(const char *) switch_priority_name(switch_priority_t priority)
 {
 	switch (priority) {			/*lol */
 	case SWITCH_PRIORITY_NORMAL:
@@ -284,9 +284,10 @@
 	return '\0';
 }
 
-SWITCH_DECLARE(char *) switch_escape_char(switch_memory_pool_t *pool, char *in, char *delim, char esc)
+SWITCH_DECLARE(char *) switch_escape_char(switch_memory_pool_t *pool, char *in, const char *delim, char esc)
 {
-	char *data, *p, *d;
+	char *data;
+	const char *p, *d;
 	int count = 1, i = 0;
 
 	p = in;

Modified: freeswitch/branches/greenlizard/w32/Library/FreeSwitchCore.vcproj
==============================================================================
--- freeswitch/branches/greenlizard/w32/Library/FreeSwitchCore.vcproj	(original)
+++ freeswitch/branches/greenlizard/w32/Library/FreeSwitchCore.vcproj	Mon May 14 10:50:37 2007
@@ -340,6 +340,30 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\switch_cpp.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="0"
+						PrecompiledHeaderThrough=""
+						PrecompiledHeaderFile=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="0"
+						PrecompiledHeaderThrough=""
+						PrecompiledHeaderFile=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
 				RelativePath="..\..\src\switch_event.c"
 				>
 			</File>
@@ -450,11 +474,11 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\src\include\private\switch_core.h"
+				RelativePath="..\..\src\include\switch_core.h"
 				>
 			</File>
 			<File
-				RelativePath="..\..\src\include\switch_core.h"
+				RelativePath="..\..\src\include\private\switch_core.h"
 				>
 			</File>
 			<File
@@ -466,6 +490,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\include\switch_cpp.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\include\switch_event.h"
 				>
 			</File>



More information about the Freeswitch-branches mailing list