[Freeswitch-svn] [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:37 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-svn
mailing list