diff --git a/conf/vanilla/lang/en/ivr/sounds.xml b/conf/vanilla/lang/en/ivr/sounds.xml
index 5e8b2a1a05..0c4f0b9c70 100644
--- a/conf/vanilla/lang/en/ivr/sounds.xml
+++ b/conf/vanilla/lang/en/ivr/sounds.xml
@@ -119,13 +119,21 @@
         <!-- Note, be sure to pass in the full path to the file or else!! -->
         <action function="play-file" data="$1"/>
         <action function="sleep" data="500"/>
-        <action function="play-file" data="ivr/ivr-accept_reject_voicemail.wav"/>
+        <action function="play-file" data="ivr/ivr-to_accept_press_one.wav"/>
+        <action function="sleep" data="500"/>
+        <action function="play-file" data="ivr/ivr-to_reject.wav"/>
+        <action function="sleep" data="50"/>
+        <action function="play-file" data="ivr/ivr-hang_up.wav"/>
         <action function="sleep" data="1500"/>
         <action function="play-file" data="ivr/ivr-call_from.wav"/>
         <action function="sleep" data="250"/>
         <action function="play-file" data="$1"/>
         <action function="sleep" data="500"/>
-        <action function="play-file" data="ivr/ivr-accept_reject_voicemail.wav"/>
+        <action function="play-file" data="ivr/ivr-to_accept_press_one.wav"/>
+        <action function="sleep" data="500"/>
+        <action function="play-file" data="ivr/ivr-to_reject.wav"/>
+        <action function="sleep" data="50"/>
+        <action function="play-file" data="ivr/ivr-hang_up.wav"/>
         <action function="sleep" data="1500"/>
       </match>
     </input>
diff --git a/configure.in b/configure.in
index 6dbdfb7759..ea1ef914f6 100644
--- a/configure.in
+++ b/configure.in
@@ -3,7 +3,7 @@
 
 # Must change all of the below together
 # For a release, set revision for that tagged release as well and uncomment
-AC_INIT([freeswitch], [1.2.5.3], BUG-REPORT-ADDRESS)
+AC_INIT([freeswitch], [1.2.5.3], bugs@freeswitch.org)
 AC_SUBST(SWITCH_VERSION_MAJOR, [1])
 AC_SUBST(SWITCH_VERSION_MINOR, [2])
 AC_SUBST(SWITCH_VERSION_MICRO, [5.3])
diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh
index ad32b90895..6d444af103 100755
--- a/debian/bootstrap.sh
+++ b/debian/bootstrap.sh
@@ -174,7 +174,7 @@ Build-Depends:
  libc6-dev (>= 2.11.3), make (>= 3.81),
  wget, pkg-config,
 # configure options
- libssl-dev, unixodbc-dev,
+ libssl-dev, unixodbc-dev, libpq-dev,
  libncurses5-dev, libjpeg62-dev | libjpeg8-dev,
  python-dev, erlang-dev,
 # documentation
diff --git a/debian/copyright b/debian/copyright
index 4312f4bb88..fcea146b7a 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -3,7 +3,8 @@ Upstream-Name: freeswitch
 Source: http://freeswitch.org/
 
 Files: *
-Copyright: 2012 Anthony Minessale II <anthm@freeswitch.org> and many other contributors
+Copyright: 2005-2012 Anthony Minessale II <anthm@freeswitch.org>
+ 2005-2012 Anthony Minessale II
 License: MPL-1.1
                            MOZILLA PUBLIC LICENSE
                                  Version 1.1
@@ -1009,3 +1010,1153 @@ License: MPL-1.1 or GPL-2+
       the notices in the Source Code files of the Original Code. You should
       use the text of this Exhibit A rather than the text found in the
       Original Code Source Code for Your Modifications.]
+
+Files: libs/unimrcp/*
+Copyright: 2008-2010 Arsen Chaloyan
+ 2009-2010 Tomas Valenta, Arsen Chaloyan
+ 2001-2006 Steve Underwood
+License: Apache-2.0
+
+Files: libs/curl/*
+Copyright: 1996-2012, Daniel Stenberg <daniel@haxx.se>
+License: curl
+
+Files: libs/curl/tests/certs/scripts/genroot.sh
+ libs/curl/tests/certs/scripts/genserv.sh
+Copyright: 2000-2009, EdelWeb for EdelKey and OpenEvidence
+License: curl
+
+Files: libs/curl/tests/server/tftpd.c
+Copyright: 1983 Regents of the University of California
+License: BSD-4-clause
+
+Files: libs/curl/tests/server/fake_ntlm.c
+Copyright: 1998-2010, Mandy Wu <mandy.wu@intel.com>
+License: curl
+
+Files: libs/curl/docs/examples/fopen.c
+Copyright: 2003, Simtec Electronics
+License: BSD-3-clause
+
+Files: libs/curl/docs/examples/rtsp.c
+Copyright: 2011, Jim Hollinger / HOLDERS AND CONTRIBUTORS
+License: BSD-3-clause
+
+Files: libs/curl/docs/examples/curlgtk.c
+Copyright: 2003, The OpenEvidence Project
+License: curl
+
+Files: libs/curl/docs/examples/curlx.c
+Copyright: 2003, The OpenEvidence Project
+License:
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, the following disclaimer,
+    and the original OpenSSL and SSLeay Licences below.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, the following disclaimer
+    and the original OpenSSL and SSLeay Licences below in
+    the documentation and/or other materials provided with the
+    distribution.
+ .
+ 3. All advertising materials mentioning features or use of this
+    software must display the following acknowledgments:
+    "This product includes software developed by the Openevidence Project
+    for use in the OpenEvidence Toolkit. (http://www.openevidence.org/)"
+    This product includes software developed by the OpenSSL Project
+    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+    This product includes cryptographic software written by Eric Young
+    (eay@cryptsoft.com).  This product includes software written by Tim
+    Hudson (tjh@cryptsoft.com)."
+ .
+ 4. The names "OpenEvidence Toolkit" and "OpenEvidence Project" must not be
+    used to endorse or promote products derived from this software without
+    prior written permission. For written permission, please contact
+    openevidence-core@openevidence.org.
+ .
+ 5. Products derived from this software may not be called "OpenEvidence"
+    nor may "OpenEvidence" appear in their names without prior written
+    permission of the OpenEvidence Project.
+ .
+ 6. Redistributions of any form whatsoever must retain the following
+    acknowledgments:
+    "This product includes software developed by the OpenEvidence Project
+    for use in the OpenEvidence Toolkit (http://www.openevidence.org/)
+    This product includes software developed by the OpenSSL Project
+    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+    This product includes cryptographic software written by Eric Young
+    (eay@cryptsoft.com).  This product includes software written by Tim
+    Hudson (tjh@cryptsoft.com)."
+ .
+ THIS SOFTWARE IS PROVIDED BY THE OpenEvidence PROJECT ``AS IS'' AND ANY
+ EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenEvidence PROJECT OR
+ ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Files: libs/curl/src/macos/src/macos_main.cpp
+Copyright: 2001, Eric Lavigne
+License:
+ Permission is granted to anyone to use this software for any purpose on any computer system, and to redistribute it freely, subject to the following restrictions: - The author is not responsible for the consequences of use of this software, no matter how awful, even if they arise from defects in it. - The origin of this software must not be misrepresented, either by explicit claim or by omission. - You are allowed to distributed modified copies of the software, in source and binary form, provided they are marked plainly as altered versions, and are not misrepresented as being the original software.
+
+Files: libs/curl/lib/polarssl.*
+Copyright: 2010, Hoi-Ho Chan <hoiho.chan@gmail.com>
+License: curl
+
+Files: libs/curl/lib/curl_rtmp.*
+Copyright: 2010, Howard Chu <hyc@highlandsun.com>
+License: curl
+
+Files: libs/curl/lib/openldap.c
+Copyright: 2011, Daniel Stenberg <daniel@haxx.se>, et al
+ 2010, Howard Chu <hyc@openldap.org>
+License: curl
+
+Files: libs/curl/lib/krb5.c
+ libs/curl/lib/krb4.c
+ libs/curl/lib/security.c
+Copyright: 2004-2011 Daniel Stenberg
+ 1995-1999 Kungliga Tekniska Högskolan
+License: BSD-3-clause
+
+Files: */inet_pton.c
+ libs/curl/lib/inet_ntop.c
+ libs/curl/lib/mprintf.c
+Copyright: 1996-2001 Internet Software Consortium
+License: ISC
+
+Files: libs/curl/lib/socks_gssapi.c
+ libs/curl/lib/socks_sspi.c
+Copyright: 2009-2011, Markus Moeller <markus_moeller@compuserve.com>
+License: curl
+
+Files: libs/curl/lib/md5.c
+Copyright: 1998-2005, Daniel Stenberg, <daniel@haxx.se>, et al
+ 1991-1992, RSA Data Security, Inc.
+License: curl
+
+Files: libs/curl/lib/md4.c
+Copyright: 1990-1992, RSA Data Security, Inc
+License: RSA
+
+License: RSA
+ License to copy and use this software is granted provided that it
+ is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+ .
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD4 Message-Digest Algorithm" in all material
+ mentioning or referencing the derived work.
+ .
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+ .
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+
+License: curl
+ All rights reserved.
+ .
+ Permission to use, copy, modify, and distribute this software for any purpose
+ with or without fee is hereby granted, provided that the above copyright
+ notice and this permission notice appear in all copies.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+ OR OTHER DEALINGS IN THE SOFTWARE.
+ .
+ Except as contained in this notice, the name of a copyright holder shall not
+ be used in advertising or otherwise to promote the sale, use or other dealings
+ in this Software without prior written authorization of the copyright holder.
+
+License: BSD-3-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ .
+ 3. Neither the name of the Institute nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+License: BSD-4-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ .
+ 3. Neither the name of the Institute nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+ .
+ 4. Neither the name of the <organization> nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+License: ISC
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Files: libs/freetdm/*
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+ 2005-2012, Anthony Minessale II
+ 2009,2010 Moises Silva <moy@sangoma.com>
+ David Yat Sin <dyatsin@sangoma.com>
+ 2007, Jan Vidar Berger, Case Labs, Ltd.
+ 2007,2008 Michael Jerris
+ 2001-2006 Steve Underwood <steveu@coppice.org>
+ 2001-2006 Steve Underwood
+ 2005 Robert Krten
+ 2002,2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ 2006 Nenad Corbic <ncorbic@sangoma.com>
+ 1984-2011 Sangoma Technologies Inc.
+ 2007, Michael S. Collins
+ 2012, Kapil Gupta <kgupta@sangoma.com>
+ 2009 Konrad Hammel <konrad@sangoma.com>
+ 2010 Stefan Knoblich <s.knoblich@axsentis.de>
+ 2008 Stefan Knoblich, axsentis GmbH.
+ 2011 Sebastien Trottier
+License: BSD-3-clause
+
+Files: libs/freetdm/src/priserver.c
+ libs/freetdm/src/sangoma_pri.?
+Copyright: 2005-2012, Anthony Minessale II
+ Nenad Corbic <ncorbic@sangoma.com>
+License: GPL-2+
+
+Files: libs/freetdm/src/libteletone_detect.c
+ libs/freetdm/mod_freetdm/mod_freetdm.c
+ libs/freetdm/src/include/private/libteletone.h
+ libs/freetdm/src/include/private/libteletone_detect.h
+ libs/freetdm/src/include/private/libteletone_generate.h
+ libs/freetdm/src/libteletone_generate.c
+ libs/libteletone/src/libteletone_detect.[ch]
+ src/mod/applications/mod_spandsp/udptl.[ch]
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+ 2005-2012, Anthony Minessale II
+ 2001-2009, Steve Underwood <steveu@coppice.org>
+License: MPL-1.1
+
+Files: libs/freetdm/src/include/private/fsk.h
+ libs/freetdm/src/uart.c
+ libs/freetdm/src/fsk.c
+ libs/freetdm/src/include/private/uart.h
+ libs/freetdm/src/include/private/fsk.h
+Copyright: 2005 Robert Krten
+License: BSD-2-clause
+
+Files: libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c
+Copyright: 2011, Stefan Knoblich <stkn@openisdn.net>
+License: MIT/X11 (BSD like)
+
+Files: src/include/SimpleGlob.h
+Copyright: 2006-2007, Brodie Thiesfield
+License: MIT/X11 (BSD like)
+
+Files: src/include/switch_cpp.h
+Copyright: 2007 Yossi Neiman <freeswitch@cartissolutions.com>
+License: MPL-1.1  (well, maybe -- it refers to a COPYING file, so probably docs/COPYING, in which case MPL-1.1)
+
+Files: libs/iksemel/*
+Copyright: 2000-2007 Gurer Ozen <madcat@e-kolay.net>
+License: LGPL-2.1
+
+Files: libs/apr*/*
+Copyright: 2000-2005 The Apache Software Foundation or its licensors
+ 1991-1992, RSA Data Security, Inc.
+ 1996 by Internet Software Consortium.
+ 2000 by Martin Pool <mbp@humbug.org.au>
+ 2000-2004 Ryan Bloom
+ 1998, 1999 Thai Open Source Software Center Ltd
+ 1998, 1999 Enbridge Pipelines Inc.
+ 1999-2001 Dave Carrigan
+ 2000, Clark Cooper
+License: Apache-2.0
+
+Files: libs/apr/include/apr_fnmatch.h
+Copyright: 1992, 1993 The Regents of the University of California
+License: BSD-4-clause
+
+Files: libs/apr/strings/apr_strnatcmp.c
+Copyright: 2000 by Martin Pool <mbp@humbug.org.au>
+License: zlib/libpng
+
+Files: libs/apr/file_io/unix/mktemp.c
+ libs/apr/strings/apr_strings.c
+Copyright: 1987-1993 The Regents of the University of California
+License: Apache-2.0 or BSD-4-clause
+
+Files: libs/apr/dso/aix/dso.c
+Copyright: 1992-1998 Jens-Uwe Mager, Helios Software GmbH, Hannover, Germany.
+ 1996 John W. Eaton <jwe@bevo.che.wisc.edu>
+ 1998 Ralf S. Engelschall <rse@apache.org>
+ 2000 David Reid
+License: Apache-2.0
+
+Files: libs/apr-util/crypto/apr_md5.c
+Copyright: 1991-2, RSA Data Security, Inc.
+ 2000-2005 The Apache Software Foundation or its licensors
+ phk@login.dknet.dk
+License: RSA and Apache-2.0 and Beerware
+
+Files: libs/apr-util/ldap/apr_ldap_url.c
+Copyright: 2000-2005 The Apache Software Foundation or its licensors
+ 1998-2002 The OpenLDAP Foundation
+ 1992-1996 Regents of the University of Michigan
+License: Apache-2.0 and OpenLDAP and BSD-like
+
+Files: libs/miniupnpc/*
+Copyright: 2005-2009, Thomas Bernard
+License: BSD-3-clause
+
+Files: libs/miniupnpc/bsdqueue.h
+Copyright: 1991,1993, The Regents of the University of California
+License: BSD-3-clause
+
+Files: libs/ldns/*
+Copyright: 2001-2010, NLnet Labs
+ 2000-2001, Aaron D. Gifford
+ 2000-2003 Damien Miller
+ 1999 WIDE Project
+ 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ 1996, 1998 Internet Software Consortium.
+ 1995 International Business Machines
+License: BSD-2-clause
+
+Files: libs/ldns/compat/fake-rfc2553.[ch]
+ libs/ldns/examples/fake-rfc2553.h
+ libs/ldns/ldns/rbtree.h
+ libs/ldns/rbtree.c
+ libs/win32/ldns/ldns-lib/util.h
+Copyright: 2001-2010, NLnet Labs
+ 2000-2003 Damien Miller
+ 1999 WIDE Project
+License: BSD-3-clause
+
+Files: libs/ldns/compat/b32_pton.c
+ libs/ldns/compat/strlcpy.c
+ libs/ldns/compat/b32_ntop.c
+ libs/ldns/compat/b64_ntop.c
+ libs/ldns/compat/inet_pton.c
+Copyright: 1996, 1998 Internet Software Consortium.
+ 1995 International Business Machines, Inc.
+ 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+License: ISC
+
+Files: libs/js/*
+Copyright: 1998-2006 Mozilla <http://www.mozilla.org/>
+ 1996-2000 Netscape Communications Corporation
+ 2000 International Business Machines Corporation
+ 1989-1991, Apple Computer, Inc. 1989-1991
+ 1992 Charles Petzold, 1992
+ 1991 Lucent Technologies
+License: MPL-1.1 or GPL-2+ or LGPL-2.1+
+
+Files: libs/js/nsprpub/pr/tests/tmocon.c
+ libs/js/nsprpub/pr/src/md/beos/brng.c
+ libs/js/nsprpub/pr/src/md/unix/os_Irix.s
+ libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86.s
+ libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s
+ libs/js/nsprpub/pr/src/md/beos/bfile.c
+ libs/js/nsprpub/pr/src/linking/prlink.c
+ libs/js/nsprpub/pr/src/md/unix/os_SunOS.s
+ libs/js/nsprpub/pr/src/md/unix/os_ReliantUNIX.s
+ libs/js/nsprpub/pr/src/md/unix/os_Darwin_ppc.s
+ libs/js/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s
+ libs/js/nsprpub/pr/src/md/unix/os_Linux_ia64.s 
+ libs/js/nsprpub/pr/tests/testfile.c
+ libs/js/nsprpub/pr/src/md/unix/os_Darwin_x86.s
+ libs/js/nsprpub/pr/src/md/unix/os_AIX.s
+ libs/js/nsprpub/pr/src/md/unix/os_HPUX_ia64.s
+ libs/js/nsprpub/pr/src/md/unix/os_BSD_386_2.s
+ libs/js/nsprpub/pr/src/md/unix/unix.c
+ libs/js/nsprpub/pr/src/md/unix/os_Linux_x86_64.s
+ libs/js/nsprpub/pr/tests/testfile.c
+ libs/js/nsprpub/pr/src/md/unix/os_Darwin_x86.s
+ libs/js/nsprpub/pr/src/md/unix/os_AIX.s
+ libs/js/nsprpub/pr/src/md/unix/os_HPUX_ia64.s
+ libs/js/nsprpub/pr/src/md/unix/os_BSD_386_2.s
+ libs/js/nsprpub/pr/src/md/unix/unix.c
+ libs/js/nsprpub/pr/src/md/unix/os_Linux_x86_64.s
+ libs/js/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s
+ libs/js/nsprpub/pr/src/md/os2/os2vaclegacy.s
+ libs/js/nsprpub/pr/src/md/os2/os2emx.s
+ libs/js/nsprpub/pr/src/md/unix/os_Linux_x86.s
+ libs/js/nsprpub/pr/include/md/_beos.cfg
+ libs/js/nsprpub/configure.in
+ libs/js/nsprpub/pr/src/md/unix/os_HPUX.s
+ libs/js/nsprpub/pr/include/md/_netbsd.h
+Copyright: 1998-2004 Netscape Communications Corporation
+License: MPL-1.1 or GPL-2+
+
+Files: libs/speex/*
+Copyright: 2002-2008     Xiph.org Foundation
+ 2002-2008 Jean-Marc Valin
+ 2006-2008 CSIRO, Jean-Marc Valin, Xiph.Org Foundation
+ 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery
+ 1994-2001 the XIPHOPHORUS Company
+ 2002 Jean-Marc Valin & David Rowe
+ 2003-2004, Mark Borgerding
+ 2005-2007     Analog Devices Inc.
+ 2005-2008     Commonwealth Scientific and Industrial Research Organisation (CSIRO)
+ 1993, 2002, 2006 David Rowe
+ 2003-2006     EpicGames
+ 2003 Epic Games (written by Jean-Marc Valin)
+ 1992-1994     Jutta Degener, Carsten Bormann
+ 2008      Thorvald Natvig
+ 2002, John Edwards
+ 2005-2007 Psi Systems, Inc.
+License: BSD-3-clause
+
+Files: libs/speex/src/getopt*
+Copyright: 1987-1999 Free Software Foundation, Inc.
+License: LGPL-2+
+
+Files: libs/spandsp/*
+Copyright: 2001-2012, Steve Underwood
+ 2006 Michael Jerris
+ 1991-1997 Silicon Graphics, Inc.
+ 1990-1997 Sam Leffler
+ 1993 CMU
+ 2004, Horizon Wimba, Inc.
+ 1990, 1995  Frank D. Cringle.
+License: LGPL-2.1
+
+Files: libs/spandsp/tests/*
+ libs/spandsp/spandsp-sim/g1050.c
+ libs/spandsp/spandsp-sim/line_model.c
+ libs/spandsp/spandsp-sim/make_line_models.c
+ libs/spandsp/spandsp-sim/spandsp-sim.h
+ libs/spandsp/spandsp-sim/test_utils.c
+ libs/spandsp/src/image_translate.c
+ libs/spandsp/src/make_at_dictionary.c
+ libs/spandsp/src/make_cielab_luts.c
+ libs/spandsp/src/make_math_fixed_tables.c
+ libs/spandsp/src/make_modem_filter.c
+ libs/spandsp/test-data/etsi/fax/generate_etsi_300_242_pages.c
+ libs/spandsp/test-data/itu/fax/generate_dithered_tif.c
+ libs/spandsp/test-data/itu/fax/generate_sized_pages.c
+ libs/spandsp/test-data/itu/fax/generate_striped_pages.c
+Copyright: 2001-2012, Steve Underwood
+License: GPL-2
+
+Files: libs/spandsp/tests/ademco_contactid_tests.c
+ libs/spandsp/tests/regression_tests.sh
+ libs/spandsp/tests/timezone_tests.c
+ libs/spandsp/tests/tsb85_extra_tests.sh
+ libs/spandsp/tests/tsb85_tests.c
+ libs/spandsp/tests/tsb85_tests.sh
+ libs/spandsp/tests/v42bis_tests.sh
+ libs/spandsp/tests/fax_tests.sh
+Copyright: 2001-2012, Steve Underwood
+License: LGPL-2.1
+
+Files: src/mod/applications/mod_cluechoo/sl.h
+Copyright: 1993 Toyoda Masashi
+License: FIXME
+
+Files: src/mod/event_handlers/mod_cdr_mongodb/*
+Copyright: 2009-2012 10gen Inc.
+ 2001 Unicode, Inc.
+License: Apache-2.0
+
+Files: src/mod/applications/mod_stress/FFTReal.h
+ src/mod/applications/mod_stress/FFTReal.cpp
+Copyright: 1999 Laurent de Soras
+License: unclear
+
+Files: libs/win32/celt/float_cast.h
+Copyright: 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+License: MPL-1.1
+
+Files: src/mod/loggers/mod_syslog/mod_syslog.c
+Copyright: 2005-2010, James Martelletti <james@nerdc0re.com>
+License: MPL-1.1
+
+Files: src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+License: MPL-1.1
+
+Files: src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.[ch]
+Copyright: 1999, 2000, 2002 Aladdin Enterprises.
+License: zlib/libpng
+
+Files: src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h
+Copyright: 2006, Author: Yossi Neiman of Cartis Solutions, Inc. <freeswitch AT cartissolutions.com>
+License: MPL-1.1
+
+Files: src/mod/say/mod_say_??/mod_say_??.c
+ scripts/c/socket2me/socket2me.c
+ src/mod/xml_int/mod_xml_scgi/xml_scgi_server.pl
+Copyright: 2007-2012, Anthony Minessale II <anthm@freeswitch.org>
+ 2007-2013, Anthony Minessale II
+ 2011-2012, Shahar Hadas
+License: BSD-3-clause
+
+Files: src/mod/xml_int/mod_xml_ldap/lutil_ldap.h
+Copyright: 1998-2008 The OpenLDAP Foundation.
+License: OpenLDAP
+
+Files: libs/sofia-sip/*
+Copyright: 2005-2009 Nokia Corporation
+ 2001-2006 Nokia Research Center
+ 1996 Pekka Pessi
+ 2006 Dimitri E. Prado
+ 1996,1999 Internet Software Consortium
+ 2004 Internet Systems Consortium, Inc. ("ISC")
+ 1994 Sun Microsystems, Inc
+ 1988 The Regents of the University of California
+ 1995-1999 and WIDE Project
+ 2001 First Peer
+License: LGPL-2.1+
+
+Files: libs/sofia-sip/libsofia-sip-ua/su/poll.c
+Copyright: 2005 Nokia Corporation
+ 1994-2002 Free Software Foundation, Inc.
+License: LGPL-2.1+
+
+Files: libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_addrinfo.h
+ libs/sofia-sip/libsofia-sip-ua/su/su_addrinfo.c
+Copyright: 1995-1999, WIDE Project.
+License: BSD-3-clause
+
+Files: libs/sofia-sip/libsofia-sip-ua/su/inet_pton.c
+ libs/sofia-sip/libsofia-sip-ua/su/inet_ntop.c
+Copyright: 2004 Internet Systems Consortium, Inc. ("ISC")
+ 1996,1999 Internet Software Consortium.
+License: ISC
+
+Files: libs/win32/libshout/shout/shout.h
+Copyright: 2002-2003 the Icecast team <team@icecast.org>
+License: LGPL-2+
+
+Files: */switch_xml.[ch]
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+ 2004-2006 Aaron Voisine <aaron@voisine.org>
+License: MPL-1.1 or BSD-like
+
+Files: src/switch_mprintf.c
+License: public-domain
+
+Files: src/g711.c
+ src/include/g711.h
+Copyright: 2001,2006 Abandoned Steve Underwood
+License: public-domain
+
+Files: libs/libsndfile/src/G72x/*
+Copyright: Abandoned, Sun Microsystems, Inc.
+License: public-domain
+
+Files: libs/spandsp/src/spandsp/fast_convert.h
+Copyright: 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+ 2009 Steve Underwood
+License: LGPL-2.1
+
+Files: libs/libsndfile/*
+ libs/win32/libsndfile/*
+Copyright: 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+ 1999-2009 Erik de Castro Lopo
+ 2007 <robs@users.sourceforge.net>
+ 2007 Reuben Thomas
+ 2004 Paavo Jumppanen
+ 2004-2005 David Viens <davidv@plogue.com>
+ 2006 Paul Davis <paul@linuxaudiosystems.com>
+ 2007 Jonatan Liljedahl <lijon@kymatica.com>
+ 1993 by NuEdge Development
+ 2003 Ross Bencina <rbencina@iprimus.com.au>
+ 2004 Tobias Gehrig <tgehrig@ira.uka.de>
+License: LGPL-2.1+
+
+Files: libs/libsndfile/src/ima_oki_adpcm.c
+ libs/libsndfile/src/test_ima_oki_adpcm.c
+Copyright: 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+ 2007 <robs@users.sourceforge.net>
+License: LGPL-2+
+
+Files: libs/libsndfile/tests/*
+ libs/libsndfile/Octave/sndfile_save.m
+ libs/libsndfile/examples/sndfile-play.c
+ libs/libsndfile/examples/sndfilehandle.cc
+ libs/libsndfile/programs/sndfile-play-beos.cpp
+ libs/libsndfile/examples/sndfile-play-beos.cpp
+ libs/libsndfile/regtest/database.c
+ libs/libsndfile/Octave/sndfile_play.m
+ libs/libsndfile/regtest/sndfile-regtest.c
+ libs/libsndfile/Octave/sndfile_load.m
+ libs/libsndfile/regtest/regtest.h
+ libs/libsndfile/examples/cooledit-fixer.c
+ libs/libsndfile/examples/sndfile-info.c
+ libs/libsndfile/src/G72x/g72x_test.c
+ libs/libsndfile/regtest/checksum.c
+ libs/libsndfile/examples/sndfile-convert.c
+Copyright: 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+ 1999-2009 Erik de Castro Lopo
+ 2001 Marcus Overhagen <marcus@overhagen.de>
+License: GPL-2+
+
+Files: libs/libsndfile/programs/common.?
+ libs/libsndfile/programs/sndfile-info.c
+ libs/libsndfile/programs/sndfile-cmp.c
+ libs/libsndfile/programs/sndfile-metadata-set.c
+ libs/libsndfile/examples/make_sine.c
+ libs/libsndfile/programs/test-sndfile-metadata-set.py
+ libs/libsndfile/programs/sndfile-convert.c
+ libs/libsndfile/programs/sndfile-metadata-get.c
+ libs/libsndfile/programs/sndfile-play.c
+ libs/libsndfile/examples/list_formats.c
+ libs/libsndfile/examples/sfprocess.c
+ libs/libsndfile/examples/generate.c
+ libs/libsndfile/src/create_symbols_file.py
+ libs/libsndfile/src/binheader_writef_check.py
+ libs/libsndfile/src/ogg.c
+ libs/libsndfile/Mingw-make-dist.sh
+ libs/libsndfile/examples/sndfile-to-text.c
+ libs/libsndfile/src/sndfile.hh
+Copyright: 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+ 2008 George Blood Audio
+ 2007 John ffitch
+ 2002 Xiph.org Foundation
+License: BSD-3-clause
+
+Files: libs/libsndfile/src/GSM610/*
+Copyright: 1992, 1993, 1994 by Jutta Degener and Carsten Bormann
+License:
+ Their work was released under the following license which is 
+ assumed to be compatible with The GNU Lesser General Public License.
+ 
+ ----------------------------------------------------------------------------
+ 
+ Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
+ Technische Universitaet Berlin
+ 
+ Any use of this software is permitted provided that this notice is not
+ removed and that neither the authors nor the Technische Universitaet Berlin
+ are deemed to have made any representations as to the suitability of this
+ software for any purpose nor are held responsible for any defects of
+ this software.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ 
+ As a matter of courtesy, the authors request to be informed about uses
+ this software has found, about bugs in this software, and about any
+ improvements that may be of general interest.
+ 
+ Berlin, 28.11.1994
+ Jutta Degener (jutta@cs.tu-berlin.de)
+ Carsten Bormann (cabo@cs.tu-berlin.de)
+
+Files: src/mod/endpoints/mod_opal/*
+Copyright: 2007 Tuyan Ozipek (tuyanozipek@gmail.com)
+ 2008-2012 Vox Lucida Pty. Ltd. (robertj@voxlucida.com.au)
+License: MPL-1.1
+
+Files: src/mod/endpoints/mod_h323/mod_h323.*
+Copyright: 2010 Ilnitskiy Mixim (max.h323@gmail.com)
+ 2010 Georgiewskiy Yuriy (bottleman@icf.org.ru)
+License: MPL-1.1
+
+Files: src/mod/endpoints/mod_khomp/*
+Copyright: 2007-2010 Khomp Ind. & Com.
+License: MPL-1.1 or LGPL-2.1+
+
+Files: src/mod/endpoints/mod_khomp/mod_khomp.cpp
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+License: MPL-1.1
+
+Files: src/mod/endpoints/mod_khomp/commons/base/atomic.hpp
+Copyright: 1998 Doug Rabson
+License: BSD-2-clause
+
+Files: src/mod/languages/mod_spidermonkey/mod_spidermonkey_socket.c
+Copyright: 2007, Jonas Gauffin <jonas.gauffin@gmail.com>
+License: MPL-1.1
+
+Files: src/mod/languages/mod_java/modjava.c
+Copyright: 2007, Damjan Jovanovic <d a m j a n d o t j o v a t g m a i l d o t c o m>
+License: MPL-1.1
+
+Files: src/mod/languages/mod_managed/*
+Copyright: 2008, Michael Giagnocavo <mgg@giagnocavo.net>
+License: MPL-1.1
+
+Files: src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/*
+ src/mod/languages/mod_lua/lua-mode.el
+ libs/iksemel/ltmain.sh
+ libs/yaml/config/ltmain.sh
+Copyright: 1995-2007 Free Software Foundation, Inc.
+License: GPL-2+
+
+Files: src/mod/endpoints/mod_gsmopen/libctb-0.16/*
+Copyright: 2001-2010 Joachim Buermann
+License: wxWindows
+
+Files: src/mod/endpoints/mod_gsmopen/libctb-0.16/src/win32/getopt.cpp
+Copyright: 2001 ?
+License: clueless and unacceptable
+ FIXME -- this cannot go in Debian -- the license is stated as:
+  (I think Open Source)
+
+Files: src/mod/endpoints/mod_rtmp/libamf/src/types.[ch]
+Copyright: 2007, 2008 Marc Noirot <marc.noirot AT gmail.com>
+License: GPL-2+
+
+Files: src/mod/endpoints/mod_rtmp/rtmp.c
+ src/mod/endpoints/mod_rtmp/mod_rtmp.[ch]
+ src/mod/endpoints/mod_rtmp/rtmp_sig.c
+ src/mod/endpoints/mod_html5/mod_html5.c
+ src/mod/endpoints/mod_rtmp/rtmp_tcp.c
+Copyright: 2011-2012, Barracuda Networks Inc.
+License: MPL-1.1
+
+Files: src/mod/endpoints/mod_gsmopen/asterisk/celliax_spandsp.[ch]
+Copyright: 2001-2006 Steve Underwood
+License: GPL-2
+
+Files: src/mod/endpoints/mod_skypopen/oss/skypopen.h
+ src/mod/endpoints/mod_skypopen/oss/main.c
+Copyright: 2010 Giovanni Maruzzelli
+ 2001 Alessandro Rubini and Jonathan Corbet
+ 2001 O'Reilly & Associates
+License: MPL-1.1
+
+Files: src/mod/endpoints/mod_skypopen/old-stuff/*
+Copyright: Jaroslav Kysela <perex@perex.cz>
+License: GPL-2+
+
+Files: src/mod/endpoints/mod_skinny/*
+ src/mod/asr_tts/mod_tts_commandline/mod_tts_commandline.c
+Copyright: 2009-2010, Mathieu Parent <math.parent@gmail.com>
+License: MPL-1.1
+
+Files: src/mod/endpoints/mod_skinny/*.p[lm]
+Copyright: 2010, Mathieu Parent <math.parent@gmail.com>
+License: Perl
+
+Files: src/mod/endpoints/mod_portaudio/*
+Copyright: 1999-2000 Ross Bencina and Phil Burk
+ 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+License: MIT/X11 (BSD like)
+
+Files: src/mod/endpoints/mod_portaudio/mod_portaudio.c
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+License: MPL-1.1
+
+Files: src/mod/endpoints/mod_sofia/sip-dig.c
+Copyright: 2006 Nokia Corporation
+License: LGPL-2.1+
+
+Files: src/mod/applications/mod_fsk/fsk.[ch]
+ src/mod/applications/mod_fsk/uart.[ch]
+Copyright: 2005 Robert Krten
+License: BSD-2-clause
+
+Files: src/mod/applications/mod_redis/credis.[ch]
+Copyright: 2009-2010, Jonas Romfelt <jonas at romfelt dot se>
+License: BSD-3-clause
+
+Files: src/mod/applications/mod_*vmd/mod_vmd.c
+ src/mod/applications/mod_avmd/mod_avmd.c
+Copyright: 2008-2010, Eric des Courtis <eric.des.courtis@benbria.com>
+ Benbria.
+License: MPL-1.1
+
+Files: libs/pcre/*
+Copyright: 1997-2009 University of Cambridge
+ 2003 and onwards Google Inc.
+ 2005-2006, Google Inc
+ 2001 Alexander Tokarev <dwalin@dwalin.ru>
+ 2001 Peter S. Voronov aka Chem O'Dun <petervrn@yahoo.com>
+License: BSD-3-clause
+
+Files: libs/silk/*
+Copyright: 2006-2011, Skype Limited.
+License: BSD-2-clause
+
+Files: libs/libdingaling/*
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+ 2001-2003 Allan Saddi <allan@saddi.com>
+License: MPL-1.1
+
+Files: libs/libdingaling/src/sha1.[ch]
+Copyright: 2001-2003 Allan Saddi <allan@saddi.com>
+License: BSD-2-clause
+
+Files: libs/libcodec2/*
+Copyright: 1990-2010 David Rowe
+ 1990-2010 David Rowe 2009
+License: LGPL-2.1
+
+Files: libs/libcodec2/unittest/*
+Copyright: 2009,2010 David Rowe
+License: LGPL
+
+Files: libs/libcodec2/script/menu.sh
+Copyright: 1990-2010 David Rowe
+License: GPL-2
+
+Files: libs/libcodec2/src/pack.c
+Copyright: 2010 Perens LLC <bruce@perens.com>
+License: GPL-3+
+
+Files: src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c
+ src/include/switch_profile.h
+ src/switch_profile.c
+Copyright: 2009,2010, Sangoma Technologies
+License: BSD-3-clause
+
+Files: src/mod/codecs/mod_isac/*
+Copyright: 2011-2012 The WebRTC project authors
+License: BSD-3-clause
+
+Files: src/mod/codecs/mod_isac/mod_isac.c
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+License: MPL-1.1
+
+Files: libs/srtp/*
+Copyright: 2001-2006, Cisco Systems, Inc.
+ 2005 Ingate Systems AB
+License: BSD-3-clause
+
+Files: libs/libsndfile/src/ima_oki_adpcm.h
+Copyright: 2007 <robs@users.sourceforge.net>
+ 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+License: LGPL-2+
+
+Files: libs/portaudio/*
+Copyright: 1999-2007 Ross Bencina and Phil Burk
+ 1999-2002 Phil Burk, Ross Bencina
+ 1999-2007 Andrew Baldwin, Ross Bencina
+ 1999-2007 Ross Bencina, Andrew Baldwin
+ 1999-2006 Phil Burk, Robert Marsanyi and Ross Bencina
+ 1999-2007 Ross Bencina, Phil Burk, Robert Marsanyi
+ 1999-2007 Ross Bencina
+ 1999-2000 Phil Burk
+ 2004-2007 Arve Knudsen <aknuds-1@broadpark.no>
+ 2005-2006 Bjorn Roche
+ 2006-2007 David Viens
+ 2003 Fred Gleason
+ 2002 Joshua Haberman <joshua@haberman.com>
+ 2005,2006 Ludwig Schwardt
+ 2004 Stefan Westerfeld <stefan@space.twc.de
+License: MIT/X11 (BSD like)
+
+Files: libs/tiff-4.0.2/*
+Copyright: 1988-1997 Sam Leffler
+ 1991-1997 Silicon Graphics, Inc.
+ 2006-2010 Richard Nolde
+ 1999-2000 Frank Warmerdam
+ 1990 by Digital Equipment Corporation, Maynard, Massachusetts.
+ 1990 by Sun Microsystems, Inc.
+ Joris Van Damme <info@awaresystems.be>
+ AWare Systems <http://www.awaresystems.be/>
+License: MIT/X11 (BSD like)
+
+Files: libs/tiff-4.0.2/port/getopt.c
+ libs/tiff-4.0.2/port/strcasecmp.c
+ libs/tiff-4.0.2/port/lfind.c
+Copyright: 1987, 1993, 1994, The Regents of the University of California.
+License: BSD-3-clause
+
+Files: libs/tiff-4.0.2/port/strtoull.c
+Copyright: 1992, 1993, The Regents of the University of California.
+License: BSD-4-clause
+
+Files: src/switch_dso.c
+Copyright: 2008 Michael Jerris
+License: BSD-like
+
+Files: libs/libks/*
+ libs/libscgi/src/include/scgi_oop.h
+ libs/libscgi/src/scgi.c
+Copyright: 2007-2013, Anthony Minessale II
+ 2007 Michael Jerris
+ 1996-2000 Gray Watson
+License: BSD-3-clause
+
+Files: libs/libks/*/ks_json.[ch]
+ src/include/switch_json.h
+ src/switch_json.c
+Copyright: 2009 Dave Gamble
+License: MIT/X11 (BSD like)
+
+Files: libs/libks/*/simclist.[ch]
+Copyright: 2007-2011 Mij <mij@bitchx.it>
+License: ISC
+
+Files: libs/libtpl-1.5/src/tpl.[ch]
+Copyright: 2005-2010, Troy D. Hanson
+License: BSD-2-clause
+
+Files: libs/libnatpmp/*
+Copyright: 2007-2008, Thomas BERNARD <miniupnp@free.fr>
+License: ISC
+
+Files: libs/libwebsockets/*
+Copyright: 2010-2011 Andy Green <andy@warmcat.com>
+License: LGPL
+
+Files: libs/libwebsockets/win32port/zlib/*
+Copyright: 1995-2010 Jean-loup Gailly
+ 1995-2010 Mark Adler 
+ 1995-2010 Jean-loup Gailly and Mark Adler
+ 1995-2010 Jean-loup Gailly and Mark Adler ";
+License: zlib/libpng
+
+Files: libs/libwebsockets/lib/base64-decode.c
+Copyright: 2001 Bob Trower, Trantor Standard Systems Inc.
+License: MIT/X11 (BSD like)
+
+Files: libs/libwebsockets/lib/sha-1.c
+Copyright: 1995-1998 WIDE Project.
+License: BSD-3-clause
+
+Files: libs/libwebsockets/win32port/win32helpers/getopt_long.c
+Copyright: 1987-1996, The Regents of the University of California.
+License: BSD-4-clause
+
+Files: libs/libedit/*
+Copyright: 1992, 1993 The Regents of the University of California.
+ 1997-2005 The NetBSD Foundation, Inc.
+ 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+License: BSD-3-clause
+
+Files: libs/libedit/src/strlcat.c
+ libs/libedit/src/strlcpy.c
+Copyright: 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+License: ISC
+
+Files: libs/esl/*
+Copyright: 2007 Michael Jerris
+ 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ 2007-2012, Anthony Minessale II
+ 2000 The NetBSD Foundation, Inc.
+License: BSD-3-clause
+
+Files: libs/esl/src/esl_json.c
+ libs/esl/src/include/esl_json.h
+Copyright: 2009 Dave Gamble
+License: MIT/X11 (BSD like)
+
+Files: libs/esl/managed/ManagedEslTest/Program.cs
+Copyright: Diego Toro <dftoro@yahoo.com>
+License: MPL-1.1
+
+Files: libs/esl/getopt/getopt_long.c
+Copyright: 2000 The NetBSD Foundation, Inc.
+ 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+License: BSD-2-clause
+
+Files: libs/xmlrpc-c/*
+Copyright: 2005 Steven A. Bone, sbone@pobox.com
+ 2000 Moez Mahfoudh <mmoez@bigfoot.com>
+ 1998-2000 Thai Open Source Software Center Ltd
+ 2001 First Peer, Inc.
+ 1991-1994 Stichting Mathematisch Centrum
+ 1995-2000 The Apache Group.
+License: BSD-3-clause
+
+Files: libs/xmlrpc-c/lib/util/getoptx.h
+Copyright: 1987-1999 Free Software Foundation, Inc.
+License: GPL-1+
+
+Files: libs/broadvoice/*
+Copyright: 2000-2009 Broadcom Corporation
+ 2008-2009 Steve Underwood <steveu@coppice.org>
+ 2001-2009 Steve Underwood
+ 2006 Michael Jerris
+License: LGPL-2.1
+
+Files: libs/broadvoice/autogen.sh
+License: GPL-2
+
+Files: libs/libzrtp/*
+Copyright: 2006-2012 Philip R. Zimmermann.
+ 1993-2005 Colin Plumb
+ 1998-2006, Dr Brian Gladman, Worcester, UK.
+ 2002, Bryce "Zooko" Wilcox-O'Hearn
+ 2010 Soft Industry
+License: AGPL-3 or MPL-1.1
+
+Files: libs/libzrtp/test/cmockery/cmockery.c
+Copyright: 2008 Google Inc
+License: Apache-2.0
+
+Files: libs/libzrtp/third_party/bnlib/legal.c
+ libs/libzrtp/third_party/bnlib/*
+Copyright: 1993-2005 Colin Plumb
+License: GPL-2 or GPL-3 or MPL-1.1
+
+Files: libs/libzrtp/third_party/bnlib/test/md5.c
+Copyright: 1995 Abandoned Colin Plumb
+License: public-domain
+
+Files: libs/stfu/*
+Copyright: 2007-2012 Anthony Minessale II <anthm@freeswitch.org>
+License: MIT/X11 (BSD like)
+
+Files: libs/sqlite/*
+Copyright: 2006 Abandoned D. Richard Hipp <drh@hwaci.com>
+ 1993 Abandoned Colin Plumb
+License: public-domain
+
+Files: libs/win32/sqlite/sqlite3.[ch]
+ libs/win32/sqlite/parse.c
+Copyright: 2006 Abandoned D. Richard Hipp <drh@hwaci.com>
+License: public-domain
+
+Files: libs/win32/pcre/dftables.c
+Copyright: 1997-2008 University of Cambridge
+License: BSD-3-clause
+
+Files: libs/openzap/*
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+ 2007-2012, Anthony Minessale II, Nenad Corbic
+ 2005-2012, Anthony Minessale II
+ 2006 Nenad Corbic <ncorbic@sangoma.com>
+ 2007 Jan Vidar Berger, Case Labs, Ltd.
+ 2007,2008 Michael Jerris
+ 2008 Shane Burrell
+ 2007 Michael S. Collins
+ 2001 Steve Underwood <steveu@coppice.org>
+ 2001 Steve Underwood
+ 2002,2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ 2002 Christopher Clark
+ 1984-2007 Sangoma Technologies Inc.
+ 2007-2009, Sangoma Technologies
+ 2009, Moises Silva <moy@sangoma.com>
+ 2008, Stefan Knoblich, axsentis GmbH.
+ 2005  Xygnada Technology, Inc.
+License: BSD-3-clause
+
+Files: libs/openzap/src/fsk.c
+ libs/openzap/src/include/uart.h
+ libs/openzap/src/uart.c
+Copyright: 2009-2012, Anthony Minessale II
+ 2005 Robert Krten
+License: BSD-2-clause
+
+Files: libs/openzap/src/include/libteletone.h
+ libs/openzap/mod_openzap/mod_openzap.c
+Copyright: 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+ 2005-2012, Anthony Minessale II
+License: MPL-1.1
+
+Files: libs/openzap/src/sangoma_pri.[ch]
+ libs/openzap/src/priserver.c
+Copyright: 2005-2012 Anthony Minessale II
+ 2006 Nenad Corbic <ncorbic@sangoma.com>
+License: GPL-2+
+
+Files: libs/ilbc/*
+Copyright: 2007-2008, Steve Underwood
+ 2006 Michael Jerris
+ 2004, The Internet Society
+Comment: Disclaimer: non-comercial use, perhaps, and non-modifiable (standards compliance)
+License: GIPS
+
+Files: libs/ilbc/tests/regression_tests.sh
+License: GPL-2
+
+Files: libs/libg722_1/*
+Copyright: 2004 Polycom, Inc
+ 2006 Michael Jerris
+ 2001-2009 Steve Underwood <steveu@coppice.org>
+ 2001-2006 Steve Underwood
+Comment: Disclaimer: non-comercial use,gital Equipment Corporation, Maynard, Massachusetts. 
+License: patent-mess
+
+Files: libs/libg722_1/autogen.sh
+License: GPL-2
+
+Files: libs/libg722_1/tests/g192_bit_stream.h
+ libs/libg722_1/tests/timing.h
+Copyright: 2008-2009 Steve Underwood <steveu@coppice.org>
+ 2001 Steve Underwood
+License: LGPL-2.1
+
+License: OpenLDAP
+ /* Portions Copyright 1998-2002 The OpenLDAP Foundation
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted only as authorized by the OpenLDAP
+  * Public License.  A copy of this license is available at
+  * http://www.OpenLDAP.org/license.html or in file LICENSE in the
+  * top-level directory of the distribution.
+  * 
+  * OpenLDAP is a registered trademark of the OpenLDAP Foundation.
+  * 
+  * Individual files and/or contributed packages may be copyright by
+  * other parties and subject to additional restrictions.
+  * 
+  * This work is derived from the University of Michigan LDAP v3.3
+  * distribution.  Information concerning this software is available
+  * at: http://www.umich.edu/~dirsvcs/ldap/
+  * 
+  * This work also contains materials derived from public sources.
+  * 
+  * Additional information about OpenLDAP can be obtained at:
+  *     http://www.openldap.org/
+  */
diff --git a/debian/freeswitch-sysvinit.freeswitch.init b/debian/freeswitch-sysvinit.freeswitch.init
index 2b48cfd852..5f8b028bcc 100644
--- a/debian/freeswitch-sysvinit.freeswitch.init
+++ b/debian/freeswitch-sysvinit.freeswitch.init
@@ -18,7 +18,9 @@ NAME=freeswitch
 DAEMON=/usr/bin/freeswitch
 DAEMON_ARGS="-u freeswitch -g freeswitch -rp -nc -nonat"
 USER=freeswitch
-PIDFILE=/var/run/$NAME/$NAME.pid
+GROUP=freeswitch
+RUNDIR=/var/run/$NAME
+PIDFILE=$RUNDIR/$NAME.pid
 SCRIPTNAME=/etc/init.d/$NAME
 WORKDIR=/var/lib/$NAME
 
@@ -28,6 +30,11 @@ WORKDIR=/var/lib/$NAME
 . /lib/lsb/init-functions
 
 do_start() {
+  # Directory in /var/run may disappear on reboot (e.g. when tmpfs used for /var/run).
+  mkdir -p $RUNDIR
+  chown -R $USER:$GROUP $RUNDIR
+  chmod -R ug=rwX,o= $RUNDIR
+
   start-stop-daemon --start --quiet \
     --pidfile $PIDFILE --exec $DAEMON --name $NAME --user $USER \
     --test > /dev/null \
diff --git a/debian/license-reconcile.yml b/debian/license-reconcile.yml
new file mode 100644
index 0000000000..0e40cba01e
--- /dev/null
+++ b/debian/license-reconcile.yml
@@ -0,0 +1,290 @@
+Rules:
+ rules:
+  -
+   Glob: libs/ldns/*
+   Matches: NLnet\s*Labs,?\s*(20\d\d(|\s*-\s*20\d\d)|All\sright\sreserved)
+   Copyright: 2004-2010, NLnet Labs
+  -
+   Glob: libs/win32/ldns/ldns-lib/util.h
+   Matches: NLnet\s*Labs,?\s*(20\d\d(|\s*-\s*20\d\d)|All\sright\sreserved)
+   Copyright: 2004-2010, NLnet Labs
+  -
+   Glob: libs/miniupnpc/*
+   Matches: Thomas\sBERNARD
+   Copyright: Thomas Bernard
+  -
+   Glob: libs/miniupnpc/bsdqueue.h
+   Matches: The\sRegents\sof\sthe\sUniversity\sof\sCalifornia.\s+All\srights\sreserved.
+   Copyright: The Regents of the University of California.
+  -
+   Glob: libs/sofia-sip/libsofia-sip-ua/su/poll.c
+   Matches: Free\sSoftware\sFoundation,\sInc.
+   Copyright: Free Software Foundation, Inc.
+   Copyright: Nokia Corporation.
+  -
+   Glob: libs/sofia-sip/libsofia-sip-ua/su/strtoull.c
+   Copyright: Sun Microsystems, Inc.
+  -
+   Glob: libs/sofia-sip/libsofia-sip-ua/su/su_md5.c
+   Copyright: Nokia Corporation
+   License: LGPL-2.1+
+  -
+   Glob: libs/speex/include/speex/speex_types.h
+   Copyright: Xiph.Org Foundation
+  -
+   Glob: libs/speex/libspeex/lsp.c
+   Copyright: Jean-Marc Valin
+  -
+   Glob: libs/speex/libspeex/smallft.[ch]
+   Copyright: the XIPHOPHORUS Company
+  -
+   Glob: libs/speex/src/getopt1.c
+   Matches: Copyright\s\(C\)\s1987,88,89,90,91,92,93,94,96,97,98
+   Copyright: 1987-1998 Free Software Foundation, Inc.
+  -
+   Glob: libs/speex/src/getopt.c
+   Matches: Copyright\s\(C\)\s1987,\s88,\s89,\s90,\s91,\s92,\s93,\s94,\s95,\s96,\s97,\s98,\s99
+   Copyright: 1987-1999 Free Software Foundation, Inc.
+  -
+   Glob: libs/speex/src/getopt_win.h
+   Matches: Copyright\s\(C\)\s1989,90,91,92,93,94,96,97,98\sFree\sSoftware\sFoundation,\sInc.
+   Copyright: 1989-1998 Free Software Foundation, Inc.
+  -
+   Glob: libs/srtp/update.sh
+   Copyright: Ingate Systems AB
+  -
+   Glob: libs/libzrtp/third_party/bnlib/test/md5.c
+   Matches: This\scode\sis\sin\sthe\spublic\sdomain;\sdo\swith\sit\swhat\syou\swish.
+   Copyright: 1995 Abandoned Colin Plumb
+   License: public-domain
+  -
+   Glob: src/g711.c
+   Matches: Copyright\s\(C\)\s2006\sSteve\sUnderwood
+   Matches: \spublic\sdomain\sfor\sthe\sbenefit\sof\sall\smankind
+   Copyright: 2006 Abandoned Steve Underwood
+   License: public-domain
+  -
+   Glob: src/include/g711.h
+   Matches: Copyright\s\(C\)\s2001\sSteve\sUnderwood
+   Matches: \spublic\sdomain\sfor\sthe\sbenefit\sof\sall\smankind
+   Copyright: 2001 Abandoned Steve Underwood
+   License: public-domain
+  -
+   Glob: src/switch_mprintf.c
+   Matches: the\spublic\sdomain.
+   License: public-domain
+  -
+   Glob: src/switch_xml.c
+   Matches: without\slimitation\sthe\srights\sto\suse,\scopy,\smodify,\smerge,\spublish,
+   License: MPL-1.1 or BSD-like
+  -
+   Glob: src/include/switch_xml.h
+   Matches: without\slimitation\sthe\srights\sto\suse,\scopy,\smodify,\smerge,\spublish,
+   License: MPL-1.1 or BSD-like
+  -
+   Glob: src/include/switch_cpp.h
+   Matches: Author[:]\sYossi\sNeiman\s<freeswitch@cartissolutions.com>,\s\(C\)\s2007////\sCopyright[:]
+   Copyright: 2007 Yossi Neiman <freeswitch@cartissolutions.com>
+  -
+   Glob: libs/libzrtp/*
+   Matches: For\slicensing\sand\sother\slegal\sdetails,\ssee\sthe\sfile\szrtp_legal.c.
+   License: AGPL-3 or MPL-1.1
+  -
+   Glob: libs/libzrtp/third_party/bnlib/*
+   Matches: For\slicensing\sand\sother\slegal\sdetails,\ssee\sthe\sfile\slegal.c.
+   License: GPL-2 or GPL-3 or MPL-1.1
+  -
+   Glob: libs/libzrtp/src/zrtp_legal.c
+   Matches: As\sa\sspecial\sexception,\syou\smay\scombine\sthis\slibrary\swith\sthe\scode
+   Matches: License\sVersion\s1.1\s\(MPLv1.1\).
+   License: AGPL-3 or MPL-1.1
+  -
+   Glob: libs/libzrtp/third_party/bnlib/legal.c
+   Matches: As\sa\sspecial\sexception,\syou\smay\scombine\sthis\slibrary\swith\sthe\scode
+   Matches: License\sVersion\s1.1\s\(MPLv1.1\).
+   License: GPL-2 or GPL-3 or MPL-1.1
+  -
+   Glob: libs/libzrtp/projects/symbian/DelayRuner.h
+   Matches: Copyright\s+:\sCopyright\s\(c\)\s2010\sSoft\sIndustry
+   Copyright: 2010 Soft Industry
+  -
+   Glob: libs/sqlite/*
+   Matches: The\sauthor\sdisclaims\scopyright\sto\sthis\ssource\scode.
+   Copyright: 2006 Abandoned D. Richard Hipp <drh@hwaci.com>
+   License: public-domain
+  -
+   Glob: libs/win32/sqlite/*.[ch]
+   Matches: The\sauthor\sdisclaims\scopyright\sto\sthis\ssource\scode.
+   Copyright: 2006 Abandoned D. Richard Hipp <drh@hwaci.com>
+   License: public-domain
+  -
+   Glob: libs/sqlite/src/test_md5.c
+   Matches: written\sby\sColin\sPlumb\sin\s1993,\sno\scopyright\sis\sclaimed.
+   Matches: This\scode\sis\sin\sthe\spublic\sdomain;\sdo\swith\sit\swhat\syou\swish.
+   Copyright: 1993 Abandoned Colin Plumb
+   License: public-domain
+  -
+   Glob: libs/sqlite/src/printf.c
+   Matches: The\s\"printf\"\scode\sthat\sfollows\sdates\sfrom\sthe\s1980\'s.\s\sIt\sis\sin
+   Matches: the\spublic\sdomain.
+   License: public-domain
+  -
+   Glob: libs/sqlite/src/test_md5.c
+   Matches: This\scode\sis\sin\sthe\spublic\sdomain;\sdo\swith\sit\swhat\syou\swish.
+   License: public-domain
+  -
+   Glob: libs/libtpl-1.5/src/tpl.[ch]
+   Matches: Copyright\s\(c\)\s2005-2010,\sTroy\sD.\sHanson\s+http://tpl.sourceforge.net
+   Copyright: 2005-2010, Troy D. Hanson
+  -
+   Glob: libs/win32/sqlite/parse.c
+   Matches: The\sauthor\sdisclaims\scopyright\sto\sthis\ssource\scode.
+   License: public-domain
+  -
+   Glob: libs/apr-util/crypto/apr_md5.c
+   Matches: Licensed\sunder\sthe\sApache\sLicense,\sVersion\s2.0
+   Matches: THE\sBEER-WARE\sLICENSE
+   License: RSA and Apache-2.0 and Beerware
+   Copyright: 1991-1992, RSA Data Security, Inc.
+   Copyright: 2000-2005 The Apache Software Foundation or its licensors
+   Copyright: phk@login.dknet.dk
+  -
+   Glob: libs/apr-util/*/apr_md[45].[ch]
+   Matches: Copyright\s\(C\)\s1991-2,\sRSA\sData\sSecurity,\sInc.
+   Copyright: 1991-1992, RSA Data Security, Inc.
+  -
+   Glob: libs/apr/file_io/unix/mktemp.c
+   Matches:  The\sASF\slicenses\sthis\sfile\sto\sYou\sunder\sthe\sApache\sLicense,\sVersion\s2.0
+   Matches:  Copyright\s\(c\)\s1987,\s1993
+   Matches:  The\sRegents\sof\sthe\sUniversity\sof\sCalifornia.\s+All\srights\sreserved.
+   Copyright: 1987, 1993 The Regents of the University of California
+   License: Apache-2.0 or BSD-4-clause
+  -
+   Glob: libs/apr/strings/apr_strings.c
+   Matches:  The\sASF\slicenses\sthis\sfile\sto\sYou\sunder\sthe\sApache\sLicense,\sVersion\s2.0
+   Matches:  Copyright\s\(c\)\s1987,\s1993
+   Matches:  The\sRegents\sof\sthe\sUniversity\sof\sCalifornia.\s+All\srights\sreserved.
+   Copyright: 1990, 1993 The Regents of the University of California
+   License: Apache-2.0 or BSD-4-clause
+  -
+   Glob: libs/apr/dso/aix/dso.c
+   Matches: Copyright\s\(c\)\s1992,1993,1995,1996,1997,1988
+   Matches: Jens-Uwe\sMager,\sHelios\sSoftware\sGmbH,\sHannover,\sGermany.
+   Copyright: 1992-1998 Jens-Uwe Mager, Helios Software GmbH, Hannover, Germany.
+  -
+   Glob: libs/apr/build/NWGNUtail.inc
+   Matches: NLM_COPYRIGHT\s=\sLicensed\sto\sthe\sApache\sSoftware\sFoundation\s\(ASF\)\sunder\sone\sor\smore
+   Copyright: The Apache Software Foundation or its licensors
+  -
+   Glob: libs/apr/include/apr_fnmatch.h
+   Matches: Copyright\s\(c\)\s1992,\s1993
+   Matches:  The\sRegents\sof\sthe\sUniversity\sof\sCalifornia.
+   Copyright: 1992, 1993 The Regents of the University of California.
+  -
+   Glob: libs/apr-util/ldap/apr_ldap_url.c
+   Matches: Copyright\s2000-2005\sThe\sApache\sSoftware\sFoundation\sor\sits\slicensors
+   Copyright: 2000-2005 The Apache Software Foundation or its licensors
+   Matches: Copyright\s1998-2002\sThe\sOpenLDAP\sFoundation
+   Copyright: 1998-2002 The OpenLDAP Foundation
+   Matches: Copyright\s\(c\)\s1992-1996\sRegents\sof\sthe\sUniversity\sof\sMichigan.
+   Copyright: 1992-1996 Regents of the University of Michigan.
+   Matches: http://www.OpenLDAP.org/license.html\sor\sin\sfile\sLICENSE\sin\sthe
+   License: Apache-2.0 and OpenLDAP and BSD-like
+   Justification: silly hack to shut up the 'by' problem
+  -
+   Glob: libs/js/*
+   Matches: Version:\sMPL\s1.1/GPL\s2.0/LGPL\s2.1
+   Matches: Portions\screated\sby\sthe\sInitial\sDeveloper\sare\sCopyright\s\(C\)\s(1998-|)2000
+   Matches: GNU\sGeneral\sPublic\sLicense\sVersion\s2\sor\slater
+   Matches: GNU\sLesser\sGeneral\sPublic\sLicense\sVersion\s2.1\sor\slater
+   Matches: the\sterms\sof\sany\sone\sof\sthe\sMPL,\sthe\sGPL\sor\sthe\sLGPL.
+   License: MPL-1.1 or GPL-2+ or LGPL-2.1+
+   Copyright: 1998-2000 Netscape Communications Corporation.
+  -
+   Glob: libs/js/*
+   Matches: Version:\sMPL\s1.1/GPL\s2.0/LGPL\s2.1
+   Matches: Portions\screated\sby\sthe\sInitial\sDeveloper\sare\sCopyright\s\(C\)\s(1998-|)2000
+   License: MPL-1.1 or GPL-2 or LGPL-2.1
+   Copyright: 1998-2000 Netscape Communications Corporation.
+  -
+   Glob: libs/js/*
+   Matches: the\sLicense\sat\shttp://www.mozilla.org/MPL/
+   Matches: GNU\sGeneral\sPublic\sLicense\sVersion\s2\sor\slater
+   License: MPL-1.1 or GPL-2+
+  -
+   Glob: libs/spandsp/tests/g726_tests.c
+   Matches: Copyright\s(C)\s2006\sSteve\sUnderwood
+   Matches: specification.\sThese\sare\scopyright\smaterial,\sand\sso\scannot\sbe\sdistributed\swith\sthis\stest\ssoftware.
+   Copyright: 2006 Steve Underwood
+  -
+   Glob: libs/spandsp/*/g722.[ch]
+   Matches: Copyright\s\(c\)\sCMU\s+1993
+   Copyright: 1993 CMU
+  -
+   Glob: libs/libwebsockets/win32port/zlib/inftrees.c
+   Matches: Copyright\s1995-2010\sMark\sAdler\s.;
+   Copyright: 1995-2010 Mark Adler
+  -
+   Glob: libs/libwebsockets/lib/sha-1.c
+   Matches: Copyright\s\(C\)\s1995,\s1996,\s1997,\sand\s1998\sWIDE\sProject.
+   Copyright: 1995-1998 WIDE Project.
+  -
+   Glob: libs/libsndfile/programs/common.h
+   Matches: Copyright\s\(C\)\s1999-2009\sErik\sde\sCastro\sLopo\s<erikd@mega-nerd.com>
+   Matches: const\schar\s\*\scopyright\s;
+   Copyright: 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+   Justification: prevent false-psitive copyright detection
+  -
+   Glob: libs/tiff-4.0.2/libtiff/tif_tile.c
+   Matches: Copyright\s(c)\s1991-1997\sSam\sLeffler
+   Matches: copyright\snotices\sand\sthis\spermission\snotice\sappear\sin
+   Copyright: 1991-1997 Sam Leffler
+  -
+   Glob: libs/tiff-4.0.2/*
+   Matches: Additions\s\(c\)\sRichard\sNolde\s2006-2010
+   Matches: copyright\snotices\sand\sthis\spermission\snotice\sappear\sin
+   Copyright: 2006-2010 Richard Nolde
+  -
+   Glob: libs/tiff-4.0.2/libtiff/tiffvers.h
+   Matches: 1988-1996\sSam\sLeffler..Copyright\s\(c\)\s1991-1996\sSilicon\sGraphics,\sInc.
+   Copyright: 1991-1996 Sam Leffler
+   Copyright: 1991-1996 Silicon Graphics, Inc
+  -
+   Glob: src/mod/endpoints/mod_khomp/*
+   Matches: The\scontents\sof\sthis\sfile\sare\ssubject\sto\sthe\sMozilla\sPublic\sLicense\sVersion\s1.1
+   Matches: Alternatively,\sthe\scontents\sof\sthis\sfile\smay\sbe\sused\sunder\sthe\sterms\sof\sthe
+   Matches: GNU\sLesser\sGeneral\sPublic\sLicense\s2\.1.\slicense\s\(the\s.LGPL.\sLicense\),\sin\swhich
+   Matches: version\s2\.1\sof\sthe\sLicense,\sor\s\(at\syour\soption\)\sany\slater\sversion.
+   License: MPL-1.1 or LGPL-2.1+
+  -
+   Glob: src/mod/endpoints/mod_khomp/commons/base/atomic.hpp
+   Matches: Original\scopyright\sfollows[:]
+   Matches: Copyright\s\(c\)\s1998\sDoug\sRabson
+   Copyright: 1998 Doug Rabson
+  -
+   Glob: libs/esl/getopt/getopt_long.c
+   Matches: This\scode\sis\sderived\sfrom\ssoftware\scontributed\sto\sThe\sNetBSD\sFoundation
+   License: BSD-2-clause
+  -
+   Glob: libs/curl/lib/md5.c
+   Matches: Copyright\s\(C\)\s1991-2,\sRSA\sData\sSecurity,\sInc.\sCreated\s1991.
+   Copyright: 1991-1992, RSA Data Security, Inc.
+  -
+   Glob: libs/silk/*
+   Matches: Copyright\s\(c\)\s2006-2011,\sSkype\sLimited.
+   Matches: THIS\sSOFTWARE\sIS\sPROVIDED\sBY\sTHE\sCOPYRIGHT\sHOLDERS\sAND
+   Copyright: 2006-2011, Skype Limited.
+  -
+   Glob: libs/openzap/src/ozmod/ozmod_wanpipe/wanpipe_tdm_api_iface.h
+   Matches: Copyright\s\(c\)\s2007\s-\s08,\sSangoma\sTechnologies
+   Copyright: 2007-2008, Sangoma Technologies
+  -
+   Glob: libs/openzap/src/testm3ua.c
+   Matches: Created\sby\sShane\sBurrell\son\s4/8/08.
+   Matches: Copyright\s2008\s__MyCompanyName__.
+   Copyright: 2008, Shane Burrell
+   Justification: I presume that __MyCompanyName__ is nonsense, which is why I'm crediting Shane Burrell
+  -
+   Glob: debian/*
+   Copyright: 2012 Travis Cross <tc@traviscross.com>
+   License: MPL-1.1 or GPL-2+
diff --git a/debian/rules b/debian/rules
index 959a9e5254..d5bdadf863 100755
--- a/debian/rules
+++ b/debian/rules
@@ -64,6 +64,7 @@ override_dh_auto_clean:
 		--host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \
 		--with-gnu-ld --with-python --with-erlang --with-openssl \
 		--enable-core-odbc-support --enable-zrtp \
+		--enable-core-pgsql-support \
 		--prefix=/usr --localstatedir=/var \
 		--sysconfdir=/etc/freeswitch \
 		--with-modinstdir=/usr/lib/freeswitch/mod \
diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml
index cb25bcb141..2f3fc9b8b9 100644
--- a/docs/phrase/phrase_en.xml
+++ b/docs/phrase/phrase_en.xml
@@ -591,6 +591,18 @@
       <prompt phrase="For other options, press..." filename="ivr-for_other_options.wav"/>
       <!-- The following phrases still need to be recorded -->
       <prompt phrase="Thank you." filename="ivr-thank_you.wav"/>
+      <prompt phrase="Plus." filename="43.wav"/>
+      <prompt phrase="Your caller I.D. information is..." filename="ivr-your_caller_id_information_is.wav"/>
+      <prompt phrase="Call screening has been enabled." filename="ivr-call_screening_enabled.wav"/>
+      <prompt phrase="Call screening has been disabled." filename="ivr-call_screening_disabled.wav"/>
+      <prompt phrase="" filename=""/>
+      <prompt phrase="" filename=""/>
+      <prompt phrase="" filename=""/>
+      <prompt phrase="" filename=""/>
+      <prompt phrase="" filename=""/>
+      <prompt phrase="" filename=""/>
+      <prompt phrase="" filename=""/>
+      <prompt phrase="" filename=""/>
       <prompt phrase="" filename=""/>
 
     </ivr>
diff --git a/libs/.gitignore b/libs/.gitignore
index 5cdfe465ba..746a59991f 100644
--- a/libs/.gitignore
+++ b/libs/.gitignore
@@ -352,6 +352,7 @@ opal
 /libwebsockets/m4/ltversion.m4
 /libwebsockets/m4/lt~obsolete.m4
 /libwebsockets/stamp-h1
+/libwebsockets/compile
 /libwebsockets/test-server/Makefile
 /libwebsockets/test-server/Makefile.in
 /mongo-cxx-driver-v*/
diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c
index 9457663681..84c1820f46 100644
--- a/libs/libdingaling/src/libdingaling.c
+++ b/libs/libdingaling/src/libdingaling.c
@@ -1567,6 +1567,7 @@ static int on_stream_component(ldl_handle_t *handle, int type, iks *node)
 					}
 					globals.logger(DL_LOG_DEBUG, "XMPP authenticated\n");
 					ldl_set_flag_locked(handle, LDL_FLAG_AUTHORIZED);
+					ldl_set_flag_locked(handle, LDL_FLAG_CONNECTED);
 					handle->fail_count = 0;
 				}
 			} else {
@@ -1966,8 +1967,9 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
 				ldl_flush_queue(handle, 0);
 			}
 
-			handle->counter--;
 			if (!ldl_test_flag(handle, LDL_FLAG_CONNECTED)) {
+				handle->counter--;
+
 				if (IKS_NET_TLSFAIL == e) {
 					globals.logger(DL_LOG_CRIT, "tls handshake failed\n");
 					microsleep(500);
diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update
index b50d284902..920968ea65 100644
--- a/libs/sofia-sip/.update
+++ b/libs/sofia-sip/.update
@@ -1 +1 @@
-Tue Nov 13 15:22:19 CST 2012
+Fri Dec  7 08:42:32 CST 2012
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c
index a4ec4246af..d71c910dca 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c
@@ -1190,7 +1190,7 @@ nua_stack_init_transport(nua_t *nua, tagi_t const *tags)
 			    TPTAG_PUBLIC(tport_type_stun), /* use stun */
 			    TPTAG_CERTIFICATE(certificate_dir),
 			    TAG_NEXT(nua->nua_args)) < 0) {
-      SU_DEBUG_0(("nua: error initializing STUN transport\n"));
+      SU_DEBUG_0(("nua: error initializing STUN transport\n" VA_NONE));
     }
 #endif
   }
diff --git a/libs/sofia-sip/libsofia-sip-ua/stun/stun.c b/libs/sofia-sip/libsofia-sip-ua/stun/stun.c
index d2fabe3329..cb5c5f65f6 100644
--- a/libs/sofia-sip/libsofia-sip-ua/stun/stun.c
+++ b/libs/sofia-sip/libsofia-sip-ua/stun/stun.c
@@ -552,7 +552,7 @@ int stun_obtain_shared_secret(stun_handle_t *sh,
 
     ta_list ta;
     ta_start(ta, tag, value);
-    SU_DEBUG_5(("Delaying STUN shared-secret req. for DNS-SRV query.\n"));
+    SU_DEBUG_5(("Delaying STUN shared-secret req. for DNS-SRV query.\n" VA_NONE));
     err = priv_dns_queue_action(sh, stun_action_tls_query, sdf, magic, ta_tags(ta));
     ta_end(ta);
 
@@ -565,7 +565,7 @@ int stun_obtain_shared_secret(stun_handle_t *sh,
     SU_DEBUG_3(("%s: Obtaining shared secret.\n", __func__));
   }
   else {
-    SU_DEBUG_3(("No message integrity enabled.\n"));
+    SU_DEBUG_3(("No message integrity enabled.\n" VA_NONE));
     return errno = EFAULT, -1;
   }
 
@@ -928,12 +928,12 @@ static void priv_lookup_cb(stun_dns_lookup_t *self,
       break;
 
     default:
-      SU_DEBUG_5(("Warning: unknown pending STUN DNS-SRV action.\n"));
+      SU_DEBUG_5(("Warning: unknown pending STUN DNS-SRV action.\n" VA_NONE));
     }
       }
   else {
     /* DNS lookup failed */
-    SU_DEBUG_5(("Warning: STUN DNS-SRV lookup failed.\n"));
+    SU_DEBUG_5(("Warning: STUN DNS-SRV lookup failed.\n" VA_NONE));
     if (sh->sh_dns_pend_cb) {
       sh->sh_dns_pend_cb(sh->sh_dns_pend_ctx, sh, NULL,
 			 sh->sh_dns_pend_action, stun_error);
@@ -1045,7 +1045,7 @@ int stun_bind(stun_handle_t *sh,
     int err;
     ta_list ta;
     ta_start(ta, tag, value);
-    SU_DEBUG_5(("Delaying STUN bind for DNS-SRV query.\n"));
+    SU_DEBUG_5(("Delaying STUN bind for DNS-SRV query.\n" VA_NONE));
     err = priv_dns_queue_action(sh, stun_action_binding_request, sdf, magic, ta_tags(ta));
     ta_end(ta);
     return err;
@@ -1201,7 +1201,7 @@ int stun_test_nattype(stun_handle_t *sh,
 
     ta_list ta;
     ta_start(ta, tag, value);
-    SU_DEBUG_5(("Delaying STUN get-nat-type req. for DNS-SRV query.\n"));
+    SU_DEBUG_5(("Delaying STUN get-nat-type req. for DNS-SRV query.\n" VA_NONE));
     err = priv_dns_queue_action(sh, stun_action_test_nattype, sdf, magic, ta_tags(ta));
     ta_end(ta);
 
@@ -1453,7 +1453,7 @@ int stun_tls_callback(su_root_magic_t *m, su_wait_t *w, su_wakeup_arg_t *arg)
     su_root_eventmask(self->sh_root, sd->sd_index,
 		      sd->sd_socket, events);
 
-    SU_DEBUG_5(("Shared Secret Request sent to server:\n"));
+    SU_DEBUG_5(("Shared Secret Request sent to server:\n" VA_NONE));
     debug_print(&msg_req->enc_buf);
 
     z = SSL_read(ssl, buf, sizeof(buf));
@@ -1472,7 +1472,7 @@ int stun_tls_callback(su_root_magic_t *m, su_wait_t *w, su_wakeup_arg_t *arg)
     resp->enc_buf.size = z;
     resp->enc_buf.data = malloc(z);
     memcpy(resp->enc_buf.data, buf, z);
-    SU_DEBUG_5(("Shared Secret Response received from server:\n"));
+    SU_DEBUG_5(("Shared Secret Response received from server:\n" VA_NONE));
     debug_print(&resp->enc_buf);
 
     /* closed TLS connection */
@@ -1505,7 +1505,7 @@ int stun_tls_callback(su_root_magic_t *m, su_wait_t *w, su_wakeup_arg_t *arg)
 
     case SHARED_SECRET_ERROR_RESPONSE:
       if (stun_process_error_response(resp) < 0) {
-	SU_DEBUG_5(("Error in Shared Secret Error Response.\n"));
+	SU_DEBUG_5(("Error in Shared Secret Error Response.\n" VA_NONE));
       }
       stun_free_buffer(&resp->enc_buf);
       return -1;
@@ -1755,7 +1755,7 @@ static int do_action(stun_handle_t *sh, stun_msg_t *msg)
   id = msg->stun_hdr.tran_id;
   req = find_request(sh, id);
   if (!req) {
-    SU_DEBUG_7(("warning: unable to find matching TID for response\n"));
+    SU_DEBUG_7(("warning: unable to find matching TID for response\n" VA_NONE));
     return 0;
   }
 
@@ -2205,7 +2205,7 @@ static int action_determine_nattype(stun_request_t *req, stun_msg_t *binding_res
 
     if (err < 0) {
       SU_DEBUG_0(("WARNING: Failure in performing STUN Test-IV check. "
-		  "The results related to mapping characteristics may be incorrect."));
+		  "The results related to mapping characteristics may be incorrect." VA_NONE));
       stun_free_message(req->sr_msg);
       sd->sd_fourth = -1;
       /* call function again, sd_fourth stops the recursion */
@@ -2696,7 +2696,7 @@ int stun_test_lifetime(stun_handle_t *sh,
 
     ta_list ta;
     ta_start(ta, tag, value);
-    SU_DEBUG_5(("Delaying STUN get-lifetime req. for DNS-SRV query.\n"));
+    SU_DEBUG_5(("Delaying STUN get-lifetime req. for DNS-SRV query.\n" VA_NONE));
     err = priv_dns_queue_action(sh, stun_action_test_lifetime, sdf, magic, ta_tags(ta));
     ta_end(ta);
 
diff --git a/libs/sofia-sip/libsofia-sip-ua/stun/stun_common.c b/libs/sofia-sip/libsofia-sip-ua/stun/stun_common.c
index f67656363d..84e1215a00 100644
--- a/libs/sofia-sip/libsofia-sip-ua/stun/stun_common.c
+++ b/libs/sofia-sip/libsofia-sip-ua/stun/stun_common.c
@@ -558,9 +558,9 @@ void debug_print(stun_buffer_t *buf) {
 		*(buf->data + i*4 +2),
 		*(buf->data + i*4 +3)));
     if (i == 4)
-      SU_DEBUG_9(("---------------------\n"));
+		SU_DEBUG_9(("---------------------\n" VA_NONE));
   }
-  SU_DEBUG_9(("\n"));
+  SU_DEBUG_9(("\n" VA_NONE));
 }
 
 int stun_init_message(stun_msg_t *msg) {
diff --git a/libs/spandsp/src/async.c b/libs/spandsp/src/async.c
index 3552d644ee..1bfa65d910 100644
--- a/libs/spandsp/src/async.c
+++ b/libs/spandsp/src/async.c
@@ -183,26 +183,23 @@ SPAN_DECLARE_NONSTD(void) async_rx_put_bit(void *user_data, int bit)
             s->put_byte(s->user_data, s->byte_in_progress);
             s->bitpos = 0;
         }
+        else if (s->use_v14)
+        {
+            /* This is actually the start bit for the next character, and
+               the stop bit has been dropped from the stream. This is the
+               rate adaption specified in V.14 */
+            /* Align the received value */
+            if (s->data_bits < 8)
+                s->byte_in_progress = (s->byte_in_progress & 0xFF) >> (8 - s->data_bits);
+            s->put_byte(s->user_data, s->byte_in_progress);
+            s->bitpos = 1;
+            s->parity_bit = 0;
+            s->byte_in_progress = 0;
+        }
         else
         {
-            if (s->use_v14)
-            {
-                /* This is actually the start bit for the next character, and
-                   the stop bit has been dropped from the stream. This is the
-                   rate adaption specified in V.14 */
-                /* Align the received value */
-                if (s->data_bits < 8)
-                    s->byte_in_progress = (s->byte_in_progress & 0xFF) >> (8 - s->data_bits);
-                s->put_byte(s->user_data, s->byte_in_progress);
-                s->bitpos = 1;
-                s->parity_bit = 0;
-                s->byte_in_progress = 0;
-            }
-            else
-            {
-                s->framing_errors++;
-                s->bitpos = 0;
-            }
+            s->framing_errors++;
+            s->bitpos = 0;
         }
     }
 }
diff --git a/libs/spandsp/src/at_interpreter.c b/libs/spandsp/src/at_interpreter.c
index 9342cfc58d..c822092cd5 100644
--- a/libs/spandsp/src/at_interpreter.c
+++ b/libs/spandsp/src/at_interpreter.c
@@ -128,6 +128,68 @@ static const char *at_response_codes[] =
     "+FRH:3"
 };
 
+SPAN_DECLARE(const char *) at_call_state_to_str(int state)
+{
+    switch (state)
+    {
+    case AT_CALL_EVENT_ALERTING:
+        return "Alerting";
+    case AT_CALL_EVENT_CONNECTED:
+        return "Connected";
+    case AT_CALL_EVENT_ANSWERED:
+        return "Answered";
+    case AT_CALL_EVENT_BUSY:
+        return "Busy";
+    case AT_CALL_EVENT_NO_DIALTONE:
+        return "No dialtone";
+    case AT_CALL_EVENT_NO_ANSWER:
+        return "No answer";
+    case AT_CALL_EVENT_HANGUP:
+        return "Hangup";
+    }
+    /*endswitch*/
+    return "???";
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(const char *) at_modem_control_to_str(int state)
+{
+    switch (state)
+    {
+    case AT_MODEM_CONTROL_CALL:
+        return "Call";
+    case AT_MODEM_CONTROL_ANSWER:
+        return "Answer";
+    case AT_MODEM_CONTROL_HANGUP:
+        return "Hangup";
+    case AT_MODEM_CONTROL_OFFHOOK:
+        return "Off hook";
+    case AT_MODEM_CONTROL_ONHOOK:
+        return "On hook";
+    case AT_MODEM_CONTROL_DTR:
+        return "DTR";
+    case AT_MODEM_CONTROL_RTS:
+        return "RTS";
+    case AT_MODEM_CONTROL_CTS:
+        return "CTS";
+    case AT_MODEM_CONTROL_CAR:
+        return "CAR";
+    case AT_MODEM_CONTROL_RNG:
+        return "RNG";
+    case AT_MODEM_CONTROL_DSR:
+        return "DSR";
+    case AT_MODEM_CONTROL_SETID:
+        return "Set ID";
+    case AT_MODEM_CONTROL_RESTART:
+        return "Restart";
+    case AT_MODEM_CONTROL_DTE_TIMEOUT:
+        return "DTE timeout";
+    }
+    /*endswitch*/
+    return "???";
+}
+/*- End of function --------------------------------------------------------*/
+
 SPAN_DECLARE(void) at_set_at_rx_mode(at_state_t *s, int new_mode)
 {
     /* The use of a DTE timeout is mode dependent. Set the timeout appropriately in
@@ -363,8 +425,8 @@ SPAN_DECLARE(void) at_display_call_info(at_state_t *s)
         snprintf(buf,
                  sizeof(buf),
                  "%s=%s", 
-                 call_id->id  ?  call_id->id  :  "NULL",
-                 call_id->value  ?  call_id->value  :  "<NONE>");
+                 (call_id->id)  ?  call_id->id  :  "NULL",
+                 (call_id->value)  ?  call_id->value  :  "<NONE>");
         at_put_response(s, buf);
         call_id = call_id->next;
     }
diff --git a/libs/spandsp/src/gsm0610_lpc.c b/libs/spandsp/src/gsm0610_lpc.c
index aa1ab08e86..a7173f2086 100644
--- a/libs/spandsp/src/gsm0610_lpc.c
+++ b/libs/spandsp/src/gsm0610_lpc.c
@@ -560,8 +560,7 @@ static void quantization_and_coding(int16_t LAR[8])
 #undef STEP
 #define STEP(A,B,MAC,MIC)                                       \
         temp = saturated_mul16(A, *LAR);                        \
-        temp = saturated_add16(temp, B);                        \
-        temp = saturated_add16(temp, 256);                      \
+        temp = saturated_add16(temp, (B + 256));                \
         temp >>= 9;                                             \
         *LAR  = (int16_t) ((temp > MAC)                         \
                          ?                                      \
diff --git a/libs/spandsp/src/image_translate.c b/libs/spandsp/src/image_translate.c
index e07421269a..81be68f5db 100644
--- a/libs/spandsp/src/image_translate.c
+++ b/libs/spandsp/src/image_translate.c
@@ -201,10 +201,9 @@ static int image_gray8_to_colour16_row(uint16_t colour16[], uint8_t gray8[], int
 
     for (i = pixels - 1;  i >= 0;  i--)
     {
-        /* TODO: need to balance the colours */
-        colour16[3*i] = gray8[i] << 8;
-        colour16[3*i + 1] = gray8[i] << 8;
-        colour16[3*i + 2] = gray8[i] << 8;
+        colour16[3*i] = saturateu16((gray8[i]*36532U) >> 7);
+        colour16[3*i + 1] = saturateu16((gray8[i]*37216U) >> 8);
+        colour16[3*i + 2] = saturateu16((gray8[i]*47900U) >> 6);
     }
     return pixels;
 }
@@ -216,10 +215,9 @@ static int image_gray8_to_colour8_row(uint8_t colour8[], uint8_t gray8[], int pi
 
     for (i = pixels - 1;  i >= 0;  i--)
     {
-        /* TODO: need to balance the colours */
-        colour8[3*i] = gray8[i];
-        colour8[3*i + 1] = gray8[i];
-        colour8[3*i + 2] = gray8[i];
+        colour8[3*i] = saturateu8((gray8[i]*36532U) >> 15);
+        colour8[3*i + 1] = saturateu8((gray8[i]*37216U) >> 16);
+        colour8[3*i + 2] = saturateu8((gray8[i]*47900U) >> 14);
     }
     return pixels;
 }
diff --git a/libs/spandsp/src/lpc10_voicing.c b/libs/spandsp/src/lpc10_voicing.c
index 162fc3ea51..db45c15602 100644
--- a/libs/spandsp/src/lpc10_voicing.c
+++ b/libs/spandsp/src/lpc10_voicing.c
@@ -376,18 +376,18 @@ void lpc10_voicing(lpc10_encode_state_t *s,
         /*     -----    ----- */
         /*     0   0   0   0 */
         /*     0   0   0*  1    (If there is an onset there) */
-        /*     0   0   1*  0*    (Based on 2F and discriminant distance) */
+        /*     0   0   1*  0*   (Based on 2F and discriminant distance) */
         /*     0   0   1   1 */
         /*     0   1*  0   0    (Always) */
         /*     0   1*  0*  1    (Based on discriminant distance) */
-        /*     0*  1   1   0*    (Based on past, 2F, and discriminant distance) */
+        /*     0*  1   1   0*   (Based on past, 2F, and discriminant distance) */
         /*     0   1*  1   1    (If there is an onset there) */
         /*     1   0*  0   0    (If there is an onset there) */
         /*     1   0   0   1 */
         /*     1   0*  1*  0    (Based on discriminant distance) */
         /*     1   0*  1   1    (Always) */
         /*     1   1   0   0 */
-        /*     1   1   0*  1*    (Based on 2F and discriminant distance) */
+        /*     1   1   0*  1*   (Based on 2F and discriminant distance) */
         /*     1   1   1*  0    (If there is an onset there) */
         /*     1   1   1   1 */
 
@@ -433,7 +433,7 @@ void lpc10_voicing(lpc10_encode_state_t *s,
                 s->voibuf[1][1] = 1;
             break;
         case 11:
-            if (s->voice[1][9] < -s->voice[0][1])
+            if (s->voice[1][0] < -s->voice[0][1])
                 s->voibuf[2][0] = 0;
             else
                 s->voibuf[1][1] = 1;
diff --git a/libs/spandsp/src/modem_connect_tones.c b/libs/spandsp/src/modem_connect_tones.c
index 6bd7de8dac..63311e22c4 100644
--- a/libs/spandsp/src/modem_connect_tones.c
+++ b/libs/spandsp/src/modem_connect_tones.c
@@ -486,7 +486,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
                 if (s->tone_present != MODEM_CONNECT_TONES_FAX_CNG)
                 {
                     if (++s->tone_cycle_duration >= ms_to_samples(415))
-                        report_tone_state(s, MODEM_CONNECT_TONES_FAX_CNG, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
+                        report_tone_state(s, MODEM_CONNECT_TONES_FAX_CNG, lfastrintf(((s->channel_level == 0)  ?  (-96.329f + DBM0_MAX_POWER)  :  log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
                 }
             }
             else
@@ -565,7 +565,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
                         {
                             report_tone_state(s,
                                               (s->am_level*15/256 > s->channel_level)  ?  MODEM_CONNECT_TONES_ANSAM_PR  :  MODEM_CONNECT_TONES_ANS_PR,
-                                              lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
+                                              lfastrintf(((s->channel_level == 0)  ?  (-96.329f + DBM0_MAX_POWER)  :  log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
                         }
                     }
                     else
@@ -583,7 +583,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
                         {
                             report_tone_state(s,
                                               (s->am_level*15/256 > s->channel_level)  ?  MODEM_CONNECT_TONES_ANSAM  :  MODEM_CONNECT_TONES_ANS,
-                                              lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
+                                              lfastrintf(((s->channel_level == 0)  ?  (-96.329f + DBM0_MAX_POWER)  :  log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
                         }
                         s->good_cycles = 0;
                         s->tone_cycle_duration = ms_to_samples(450 + 100);
@@ -637,7 +637,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
                 if (s->tone_present != MODEM_CONNECT_TONES_BELL_ANS)
                 {
                     if (++s->tone_cycle_duration >= ms_to_samples(415))
-                        report_tone_state(s, MODEM_CONNECT_TONES_BELL_ANS, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
+                        report_tone_state(s, MODEM_CONNECT_TONES_BELL_ANS, lfastrintf(((s->channel_level == 0)  ?  (-96.329f + DBM0_MAX_POWER)  :  log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
                 }
             }
             else
@@ -675,7 +675,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
                 if (s->tone_present != MODEM_CONNECT_TONES_CALLING_TONE)
                 {
                     if (++s->tone_cycle_duration >= ms_to_samples(415))
-                        report_tone_state(s, MODEM_CONNECT_TONES_CALLING_TONE, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
+                        report_tone_state(s, MODEM_CONNECT_TONES_CALLING_TONE, lfastrintf(((s->channel_level == 0)  ?  (-96.329f + DBM0_MAX_POWER)  :  log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
                 }
             }
             else
diff --git a/libs/spandsp/src/spandsp/at_interpreter.h b/libs/spandsp/src/spandsp/at_interpreter.h
index d4c8f0018e..1f5bfaa33b 100644
--- a/libs/spandsp/src/spandsp/at_interpreter.h
+++ b/libs/spandsp/src/spandsp/at_interpreter.h
@@ -136,6 +136,10 @@ extern "C"
 {
 #endif
 
+SPAN_DECLARE(const char *) at_call_state_to_str(int state);
+
+SPAN_DECLARE(const char *) at_modem_control_to_str(int state);
+
 SPAN_DECLARE(void) at_set_at_rx_mode(at_state_t *s, int new_mode);
 
 SPAN_DECLARE(void) at_put_response(at_state_t *s, const char *t);
diff --git a/libs/spandsp/src/spandsp/private/t31.h b/libs/spandsp/src/spandsp/private/t31.h
index fafdf72341..62d0ad755f 100644
--- a/libs/spandsp/src/spandsp/private/t31.h
+++ b/libs/spandsp/src/spandsp/private/t31.h
@@ -63,8 +63,8 @@ typedef struct
 {
     /*! \brief Internet Aware FAX mode bit mask. */
     int iaf;
-    /*! \brief Required time between T.38 transmissions, in ms. */
-    int ms_per_tx_chunk;
+    /*! \brief Required time between T.38 transmissions, in us. */
+    int us_per_tx_chunk;
     /*! \brief Bit fields controlling the way data is packed into chunked for transmission. */
     int chunking_modes;
 
@@ -125,6 +125,8 @@ typedef struct
     int32_t samples;
     /*! \brief The value for samples at the next transmission point. */
     int32_t next_tx_samples;
+    /*! \brief The current transmit timeout. */
+    int32_t timeout_tx_samples;
     /*! \brief The current receive timeout. */
     int32_t timeout_rx_samples;
 } t31_t38_front_end_state_t;
diff --git a/libs/spandsp/src/spandsp/saturated.h b/libs/spandsp/src/spandsp/saturated.h
index 958167b4ec..10a53df22c 100644
--- a/libs/spandsp/src/spandsp/saturated.h
+++ b/libs/spandsp/src/spandsp/saturated.h
@@ -45,68 +45,123 @@ extern "C"
 /* This is the same as saturate16(), but is here for historic reasons */
 static __inline__ int16_t saturate(int32_t amp)
 {
-    int16_t amp16;
+#if defined(__GNUC__)  &&  (defined(__ARM_ARCH_6__)  ||  defined(__ARM_ARCH_7A__))
+    int16_t z;
+
+    __asm__ __volatile__(
+        " ssat %[z],#16,%[amp];\n"
+        : [z] "=r" (z)
+        : [amp] "r" (amp)
+    );
+    return z;
+#else
+    int16_t z;
 
     /* Hopefully this is optimised for the common case - not clipping */
-    amp16 = (int16_t) amp;
-    if (amp == amp16)
-        return amp16;
+    z = (int16_t) amp;
+    if (amp == z)
+        return z;
     if (amp > INT16_MAX)
         return INT16_MAX;
     return INT16_MIN;
+#endif
 }
 /*- End of function --------------------------------------------------------*/
 
 static __inline__ int16_t saturate16(int32_t amp)
 {
-    int16_t amp16;
+#if defined(__GNUC__)  &&  (defined(__ARM_ARCH_6__)  ||  defined(__ARM_ARCH_7A__))
+    int16_t z;
+
+    __asm__ __volatile__(
+        " ssat %[z],#16,%[amp];\n"
+        : [z] "=r" (z)
+        : [amp] "r" (amp)
+    );
+    return z;
+#else
+    int16_t z;
 
     /* Hopefully this is optimised for the common case - not clipping */
-    amp16 = (int16_t) amp;
-    if (amp == amp16)
-        return amp16;
+    z = (int16_t) amp;
+    if (amp == z)
+        return z;
     if (amp > INT16_MAX)
         return INT16_MAX;
     return INT16_MIN;
+#endif
 }
 /*- End of function --------------------------------------------------------*/
 
 /*! Saturate to 15 bits, rather than the usual 16 bits. This is often a useful function. */
 static __inline__ int16_t saturate15(int32_t amp)
 {
+#if defined(__GNUC__)  &&  (defined(__ARM_ARCH_6__)  ||  defined(__ARM_ARCH_7A__))
+    int16_t z;
+
+    __asm__ __volatile__(
+        " ssat %[z],#15,%[amp];\n"
+        : [z] "=r" (z)
+        : [amp] "r" (amp)
+    );
+    return z;
+#else
     if (amp > 16383)
         return 16383;
     if (amp < -16384)
         return -16384;
     return (int16_t) amp;
+#endif
 }
 /*- End of function --------------------------------------------------------*/
 
 static __inline__ uint16_t saturateu16(int32_t amp)
 {
-    uint16_t amp16;
+#if defined(__GNUC__)  &&  (defined(__ARM_ARCH_6__)  ||  defined(__ARM_ARCH_7A__))
+    uint16_t z;
+
+    __asm__ __volatile__(
+        " usat %[z],#16,%[amp];\n"
+        : [z] "=r" (z)
+        : [amp] "r" (amp)
+    );
+    return z;
+#else
+    uint16_t z;
 
     /* Hopefully this is optimised for the common case - not clipping */
-    amp16 = (uint16_t) amp;
-    if (amp == amp16)
-        return amp16;
+    z = (uint16_t) amp;
+    if (amp == z)
+        return z;
     if (amp > UINT16_MAX)
         return UINT16_MAX;
     return 0;
+#endif
 }
 /*- End of function --------------------------------------------------------*/
 
 static __inline__ uint8_t saturateu8(int32_t amp)
 {
-    uint8_t amp8;
+#if defined(__GNUC__)  &&  (defined(__ARM_ARCH_6__)  ||  defined(__ARM_ARCH_7A__))
+    uint8_t z;
+
+    __asm__ __volatile__(
+        " usat %[z],#8,%[amp];\n"
+        : [z] "=r" (z)
+        : [amp] "r" (amp)
+    );
+    return z;
+#else
+    uint8_t z;
 
     /* Hopefully this is optimised for the common case - not clipping */
-    amp8 = (uint8_t) amp;
-    if (amp == amp8)
-        return amp8;
+    z = (uint8_t) amp;
+    if (amp == z)
+        return z;
     if (amp > UINT8_MAX)
         return UINT8_MAX;
     return 0;
+#endif
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -188,15 +243,15 @@ static __inline__ int16_t saturated_add16(int16_t a, int16_t b)
         : "cc"
     );
     return a;
-#elif defined(__GNUC__)  &&  defined(__arm5__)
-    int16_t result;
+#elif defined(__GNUC__)  &&  (defined(__ARM_ARCH_6__)  ||  defined(__ARM_ARCH_7A__))
+    int16_t z;
 
     __asm__ __volatile__(
-        " sadd16 %0,%1,%2;\n"
-        : "=r" (result)
-        : "0" (a), "ir" (b)
+        " qsub16 %[z],%[a],%[b];\n"
+        : [z] "=r" (z)
+        : [a] "r" (a), [b] "r" (b)
     );
-    return result;
+    return z;
 #else
     return saturate((int32_t) a + (int32_t) b);
 #endif
@@ -217,25 +272,25 @@ static __inline__ int32_t saturated_add32(int32_t a, int32_t b)
         : "cc"
     );
     return a;
-#elif defined(__GNUC__)  &&  defined(__arm5__)
-    int32_t result;
+#elif defined(__GNUC__)  &&  (defined(__ARM_ARCH_6__)  ||  defined(__ARM_ARCH_7A__))
+    int32_t z;
 
     __asm__ __volatile__(
-        " qadd %0,%1,%2;\n"
-        : "=r" (result)
-        : "0" (a), "ir" (b)
+        " qadd %[z],%[a],%[b];\n"
+        : [z] "=r" (z)
+        : [a] "r" (a), [b] "r" (b)
     );
-    return result;
+    return z;
 #else
-    int32_t sum;
+    int32_t z;
 
-    sum = a + b;
+    z = a + b;
     if ((a ^ b) >= 0)
     {
-        if ((sum ^ a) < 0)
-            sum = (a < 0)  ?  INT32_MIN  :  INT32_MAX;
+        if ((z ^ a) < 0)
+            z = (a < 0)  ?  INT32_MIN  :  INT32_MAX;
     }
-    return sum;
+    return z;
 #endif
 }
 /*- End of function --------------------------------------------------------*/
@@ -254,15 +309,15 @@ static __inline__ int16_t saturated_sub16(int16_t a, int16_t b)
         : "cc"
     );
     return a;
-#elif defined(__GNUC__)  &&  defined(__arm5__)
-    int16_t result;
+#elif defined(__GNUC__)  &&  (defined(__ARM_ARCH_6__)  ||  defined(__ARM_ARCH_7A__))
+    int16_t z;
 
     __asm__ __volatile__(
-        " ssub16 %0,%1,%2;\n"
-        : "=r" (result)
-        : "0" (a), "ir" (b)
+        " qsub16 %[z],%[a],%[b];\n"
+        : [z] "=r" (z)
+        : [a] "r" (a), [b] "r" (b)
     );
-    return result;
+    return z;
 #else
     return saturate((int32_t) a - (int32_t) b);
 #endif
@@ -283,25 +338,25 @@ static __inline__ int32_t saturated_sub32(int32_t a, int32_t b)
         : "cc"
     );
     return a;
-#elif defined(__GNUC__)  &&  defined(__arm5__)
-    int32_t result;
+#elif defined(__GNUC__)  &&  (defined(__ARM_ARCH_6__)  ||  defined(__ARM_ARCH_7A__))
+    int32_t z;
 
     __asm__ __volatile__(
-        " qsub %0,%1,%2;\n"
-        : "=r" (result)
-        : "0" (a), "ir" (b)
+        " qsub %[z],%[a],%[b];\n"
+        : [z] "=r" (z)
+        : [a] "r" (a), [b] "r" (b)
     );
-    return result;
+    return z;
 #else
-    int32_t diff;
+    int32_t z;
 
-    diff = a - b;
+    z = a - b;
     if ((a ^ b) < 0)
     {
-        if ((diff ^ a) & INT32_MIN)
-            diff = (a < 0L)  ?  INT32_MIN  :  INT32_MAX;
+        if ((z ^ a) & INT32_MIN)
+            z = (a < 0L)  ?  INT32_MIN  :  INT32_MAX;
     }
-    return diff;
+    return z;
 #endif
 }
 /*- End of function --------------------------------------------------------*/
diff --git a/libs/spandsp/src/t30_logging.c b/libs/spandsp/src/t30_logging.c
index 8347a2615d..e951df85bd 100644
--- a/libs/spandsp/src/t30_logging.c
+++ b/libs/spandsp/src/t30_logging.c
@@ -240,6 +240,7 @@ SPAN_DECLARE(const char *) t30_completion_code_to_str(int result)
     case T30_ERR_CSA_UNACCEPTABLE:
         return "Called subscriber internet address not accepted";
     }
+    /*endswitch*/
     return "???";
 }
 /*- End of function --------------------------------------------------------*/
@@ -411,6 +412,7 @@ SPAN_DECLARE(const char *) t30_frametype(uint8_t x)
     case T4_RCP:
         return "RCP";
     }
+    /*endswitch*/
     return "???";
 }
 /*- End of function --------------------------------------------------------*/
@@ -436,6 +438,7 @@ static void octet_reserved_bit(logging_state_t *log,
         s[7 - bit_no + ((bit_no < 4)  ?  1  :  0)] = (uint8_t) (bit + '0');
         span_log(log, SPAN_LOG_FLOW, "  %s= Unexpected state for reserved bit: %d\n", s, bit);
     }
+    /*endif*/
 }
 /*- End of function --------------------------------------------------------*/
 
diff --git a/libs/spandsp/src/t31.c b/libs/spandsp/src/t31.c
index 01d948e357..3014edd174 100644
--- a/libs/spandsp/src/t31.c
+++ b/libs/spandsp/src/t31.c
@@ -112,7 +112,7 @@
 
 /* Settings suitable for paced transmission over a UDP transport */
 /*! The default number of milliseconds per transmitted IFP when sending bulk T.38 data */
-#define MS_PER_TX_CHUNK                         30
+#define US_PER_TX_CHUNK                         30000
 /*! The number of transmissions of indicator IFP packets */
 #define INDICATOR_TX_COUNT                      3
 /*! The number of transmissions of data IFP packets */
@@ -153,9 +153,11 @@ enum
 
 enum
 {
-    T38_CHUNKING_MERGE_FCS_WITH_DATA    = 0x0001,
-    T38_CHUNKING_WHOLE_FRAMES           = 0x0002,
-    T38_CHUNKING_ALLOW_TEP_TIME         = 0x0004
+    T38_CHUNKING_MERGE_FCS_WITH_DATA = 0x0001,
+    T38_CHUNKING_WHOLE_FRAMES = 0x0002,
+    T38_CHUNKING_ALLOW_TEP_TIME = 0x0004,
+    T38_CHUNKING_SEND_REGULAR_INDICATORS = 0x0008,
+    T38_CHUNKING_SEND_2S_REGULAR_INDICATORS = 0x0010
 };
 
 enum
@@ -181,7 +183,8 @@ enum
     T38_TIMED_STEP_CED_3 = 0x42,
     T38_TIMED_STEP_CNG = 0x50,
     T38_TIMED_STEP_CNG_2 = 0x51,
-    T38_TIMED_STEP_PAUSE = 0x60
+    T38_TIMED_STEP_PAUSE = 0x60,
+    T38_TIMED_STEP_NO_SIGNAL = 0x70
 };
 
 static int restart_modem(t31_state_t *s, int new_modem);
@@ -200,31 +203,7 @@ static __inline__ void t31_set_at_rx_mode(t31_state_t *s, int new_mode)
 }
 /*- End of function --------------------------------------------------------*/
 
-#if 0
-static void monitor_control_messages(t31_state_t *s, const uint8_t *buf, int len)
-{
-    /* Monitor the control messages, at the point where we have the whole message, so we can
-       see what is happening to things like training success/failure. */
-    span_log(&s->logging, SPAN_LOG_FLOW, "Monitoring %s\n", t30_frametype(buf[2]));
-    if (len < 3)
-        return;
-    /*endif*/
-    switch (buf[2])
-    {
-    case T30_DCS:
-    case T30_DCS | 1:
-        /* We need to know if ECM is about to be used, so we can fake HDLC stuff. */
-        s->t38_fe.ecm_mode = (len >= 7)  &&  (buf[6] & DISBIT3);
-        break;
-    default:
-        break;
-    }
-    /*endswitch*/
-}
-/*- End of function --------------------------------------------------------*/
-#endif
-
-static void front_end_status(t31_state_t *s, int status)
+static int front_end_status(t31_state_t *s, int status)
 {
     span_log(&s->logging, SPAN_LOG_FLOW, "Front end status %d\n", status);
     switch (status)
@@ -245,6 +224,7 @@ static void front_end_status(t31_state_t *s, int status)
             {
                 t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
             }
+            /*endif*/
             break;
         case FAX_MODEM_CED_TONE:
             /* Go directly to V.21/HDLC transmit. */
@@ -262,10 +242,16 @@ static void front_end_status(t31_state_t *s, int status)
             restart_modem(s, FAX_MODEM_SILENCE_TX);
             break;
         }
+        /*endswitch*/
         break;
     case T30_FRONT_END_RECEIVE_COMPLETE:
         break;
     }
+    /*endswitch*/
+    if (s->t38_fe.timed_step == T38_TIMED_STEP_NONE)
+        return -1;
+    /*endif*/
+    return 0;
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -295,14 +281,18 @@ static int extra_bits_in_stuffed_frame(const uint8_t buf[], int len)
                     ones = 0;
                     stuffed++;
                 }
+                /*endif*/
             }
             else
             {
                 ones = 0;
             }
+            /*endif*/
             bitstream >>= 1;
         }
+        /*endfor*/
     }
+    /*endfor*/
     /* The total length of the frame is:
           the number of bits in the body
         + the number of additional bits in the body due to stuffing
@@ -342,6 +332,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
            ignore it. Its harmless. */
         return 0;
     }
+    /*endif*/
     /* In termination mode we don't care very much about indicators telling us training
        is starting. We only care about V.21 preamble starting, for timeout control, and
        the actual data. */
@@ -354,6 +345,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
         {
             hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN);
         }
+        /*endif*/
         fe->timeout_rx_samples = 0;
         front_end_status(s, T30_FRONT_END_SIGNAL_ABSENT);
         break;
@@ -400,6 +392,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
         front_end_status(s, T30_FRONT_END_SIGNAL_ABSENT);
         break;
     }
+    /*endswitch*/
     fe->hdlc_rx.len = 0;
     fe->rx_data_missing = FALSE;
     return 0;
@@ -440,6 +433,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
     default:
         break;
     }
+    /*endswitch*/
 #endif
     switch (field_type)
     {
@@ -488,6 +482,13 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
         if (t->current_rx_data_type != data_type  ||  t->current_rx_field_type != field_type)
         {
             span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK (%s)\n", (fe->hdlc_rx.len >= 3)  ?  t30_frametype(fe->hdlc_rx.buf[2])  :  "???", (fe->rx_data_missing)  ?  "missing octets"  :  "clean");
+            if (fe->hdlc_rx.len >= 3  &&  (fe->hdlc_rx.buf[2] & 0xFE) == T30_DCS)
+            {
+                /* We need to know if ECM is about to be used, so we can fake HDLC stuff. */
+                fe->ecm_mode = (fe->hdlc_rx.len >= 7  &&  (fe->hdlc_rx.buf[6] & DISBIT3));
+                span_log(&s->logging, SPAN_LOG_FLOW, "ECM mode: %d\n", fe->ecm_mode);
+            }
+            /*endif*/
             crc_itu16_append(fe->hdlc_rx.buf, fe->hdlc_rx.len);
             hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing);
         }
@@ -524,16 +525,25 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
             /* The sender has incorrectly included data in this message. It is unclear what we should do
                with it, to maximise tolerance of buggy implementations. */
         }
+        /*endif*/
         /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK_SIG_END messages, in IFP packets with
            incrementing sequence numbers, which are actually repeats. They get through to this point because
            of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
         if (t->current_rx_data_type != data_type  ||  t->current_rx_field_type != field_type)
         {
             span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK, sig end (%s)\n", (fe->hdlc_rx.len >= 3)  ?  t30_frametype(fe->hdlc_rx.buf[2])  :  "???", (fe->rx_data_missing)  ?  "missing octets"  :  "clean");
+            if (fe->hdlc_rx.len >= 3  &&  (fe->hdlc_rx.buf[2] & 0xFE) == T30_DCS)
+            {
+                /* We need to know if ECM is about to be used, so we can fake HDLC stuff. */
+                fe->ecm_mode = (fe->hdlc_rx.len >= 7  &&  (fe->hdlc_rx.buf[6] & DISBIT3));
+                span_log(&s->logging, SPAN_LOG_FLOW, "ECM mode: %d\n", fe->ecm_mode);
+            }
+            /*endif*/
             crc_itu16_append(fe->hdlc_rx.buf, fe->hdlc_rx.len);
             hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing);
             hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN);
         }
+        /*endif*/
         fe->hdlc_rx.len = 0;
         fe->rx_data_missing = FALSE;
         fe->timeout_rx_samples = 0;
@@ -545,6 +555,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
             /* The sender has incorrectly included data in this message. We can safely ignore it, as the
                bad FCS means we will throw away the whole message, anyway. */
         }
+        /*endif*/
         /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD_SIG_END messages, in IFP packets with
            incrementing sequence numbers, which are actually repeats. They get through to this point because
            of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
@@ -554,6 +565,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
             hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE);
             hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN);
         }
+        /*endif*/
         fe->hdlc_rx.len = 0;
         fe->rx_data_missing = FALSE;
         fe->timeout_rx_samples = 0;
@@ -565,6 +577,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
             /* The sender has incorrectly included data in this message, but there seems nothing meaningful
                it could be. There could not be an FCS good/bad report beyond this. */
         }
+        /*endif*/
         /* Some T.38 implementations send multiple T38_FIELD_HDLC_SIG_END messages, in IFP packets with
            incrementing sequence numbers, which are actually repeats. They get through to this point because
            of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
@@ -581,6 +594,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
             fe->timeout_rx_samples = 0;
             hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN);
         }
+        /*endif*/
         break;
     case T38_FIELD_T4_NON_ECM_DATA:
         if (!s->at_state.rx_signal_present)
@@ -588,11 +602,13 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
             non_ecm_rx_status(s, SIG_STATUS_TRAINING_SUCCEEDED);
             s->at_state.rx_signal_present = TRUE;
         }
+        /*endif*/
         if (len > 0)
         {
             bit_reverse(buf2, buf, len);
-            non_ecm_put(s, buf, len);
+            non_ecm_put(s, buf2, len);
         }
+        /*endif*/
         fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT);
         break;
     case T38_FIELD_T4_NON_ECM_SIG_END:
@@ -608,15 +624,18 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
                     non_ecm_rx_status(s, SIG_STATUS_TRAINING_SUCCEEDED);
                     s->at_state.rx_signal_present = TRUE;
                 }
+                /*endif*/
                 bit_reverse(buf2, buf, len);
-                non_ecm_put(s, buf, len);
+                non_ecm_put(s, buf2, len);
             }
+            /*endif*/
             /* WORKAROUND: At least some Mediatrix boxes have a bug, where they can send HDLC signal end where
                            they should send non-ECM signal end. It is possible they also do the opposite.
                            We need to tolerate this, so we use the generic receive complete
                            indication, rather than the specific non-ECM carrier down. */
             non_ecm_rx_status(s, SIG_STATUS_CARRIER_DOWN);
         }
+        /*endif*/
         s->at_state.rx_signal_present = FALSE;
         fe->timeout_rx_samples = 0;
         break;
@@ -625,18 +644,21 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
             span_log(&s->logging, SPAN_LOG_FLOW, "CM profile %d - %s\n", buf[0] - '0', t38_cm_profile_to_str(buf[0]));
         else
             span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CM message - %d\n", len);
+        /*endif*/
         break;
     case T38_FIELD_JM_MESSAGE:
         if (len >= 2)
             span_log(&s->logging, SPAN_LOG_FLOW, "JM - %s\n", t38_jm_to_str(buf, len));
         else
             span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for JM message - %d\n", len);
+        /*endif*/
         break;
     case T38_FIELD_CI_MESSAGE:
         if (len >= 1)
             span_log(&s->logging, SPAN_LOG_FLOW, "CI 0x%X\n", buf[0]);
         else
             span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CI message - %d\n", len);
+        /*endif*/
         break;
     case T38_FIELD_V34RATE:
         if (len >= 3)
@@ -648,10 +670,12 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
         {
             span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for V34rate message - %d\n", len);
         }
+        /*endif*/
         break;
     default:
         break;
     }
+    /*endswitch*/
     return 0;
 }
 /*- End of function --------------------------------------------------------*/
@@ -667,18 +691,27 @@ static void send_hdlc(void *user_data, const uint8_t *msg, int len)
     }
     else
     {
+        if (len >= 3  &&  (s->hdlc_tx.buf[2] & 0xFE) == T30_DCS)
+        {
+            /* We need to know if ECM is about to be used, so we can fake HDLC stuff. */
+            s->t38_fe.ecm_mode = (len >= 7  &&  (s->hdlc_tx.buf[6] & DISBIT3));
+            span_log(&s->logging, SPAN_LOG_FLOW, "ECM mode: %d\n", s->t38_fe.ecm_mode);
+        }
+        /*endif*/
         s->t38_fe.hdlc_tx.extra_bits = extra_bits_in_stuffed_frame(msg, len);
         bit_reverse(s->hdlc_tx.buf, msg, len);
         s->hdlc_tx.len = len;
         s->hdlc_tx.ptr = 0;
     }
+    /*endif*/
 }
 /*- End of function --------------------------------------------------------*/
 
 static __inline__ int bits_to_us(t31_state_t *s, int bits)
 {
-    if (s->t38_fe.ms_per_tx_chunk == 0  ||  s->t38_fe.tx_bit_rate == 0)
+    if (s->t38_fe.us_per_tx_chunk == 0  ||  s->t38_fe.tx_bit_rate == 0)
         return 0;
+    /*endif*/
     return bits*1000000/s->t38_fe.tx_bit_rate;
 }
 /*- End of function --------------------------------------------------------*/
@@ -686,17 +719,59 @@ static __inline__ int bits_to_us(t31_state_t *s, int bits)
 static void set_octets_per_data_packet(t31_state_t *s, int bit_rate)
 {
     s->t38_fe.tx_bit_rate = bit_rate;
-    if (s->t38_fe.ms_per_tx_chunk)
+    if (s->t38_fe.us_per_tx_chunk)
     {
-        s->t38_fe.octets_per_data_packet = s->t38_fe.ms_per_tx_chunk*bit_rate/(8*1000);
+        s->t38_fe.octets_per_data_packet = (s->t38_fe.us_per_tx_chunk/1000)*bit_rate/(8*1000);
         /* Make sure we have a positive number (i.e. we didn't truncate to zero). */
         if (s->t38_fe.octets_per_data_packet < 1)
             s->t38_fe.octets_per_data_packet = 1;
+        /*endif*/
     }
     else
     {
         s->t38_fe.octets_per_data_packet = MAX_OCTETS_PER_UNPACED_CHUNK;
     }
+    /*endif*/
+}
+/*- End of function --------------------------------------------------------*/
+
+static int set_no_signal(t31_state_t *s)
+{
+    int delay;
+
+    if ((s->t38_fe.chunking_modes & T38_CHUNKING_SEND_REGULAR_INDICATORS))
+    {
+        if ((delay = t38_core_send_indicator(&s->t38_fe.t38, 0x100 | T38_IND_NO_SIGNAL)) < 0)
+            return delay;
+        /*endif*/
+        s->t38_fe.timed_step = T38_TIMED_STEP_NO_SIGNAL;
+        if ((s->t38_fe.chunking_modes & T38_CHUNKING_SEND_2S_REGULAR_INDICATORS))
+            s->t38_fe.timeout_tx_samples = s->t38_fe.next_tx_samples + us_to_samples(2000000);
+        else
+            s->t38_fe.timeout_tx_samples = 0;
+        /*endif*/
+        return s->t38_fe.us_per_tx_chunk;
+    }
+    /*endif*/
+    if ((delay = t38_core_send_indicator(&s->t38_fe.t38, T38_IND_NO_SIGNAL)) < 0)
+        return delay;
+    /*endif*/
+    s->t38_fe.timed_step = T38_TIMED_STEP_NONE;
+    return delay;
+}
+/*- End of function --------------------------------------------------------*/
+
+static int stream_no_signal(t31_state_t *s)
+{
+    int delay;
+
+    if ((delay = t38_core_send_indicator(&s->t38_fe.t38, 0x100 | T38_IND_NO_SIGNAL)) < 0)
+        return delay;
+    /*endif*/
+    if (s->t38_fe.timeout_tx_samples  &&  s->t38_fe.next_tx_samples >= s->t38_fe.timeout_tx_samples)
+        s->t38_fe.timed_step = T38_TIMED_STEP_NONE;
+    /*endif*/
+    return s->t38_fe.us_per_tx_chunk;
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -704,6 +779,7 @@ static int stream_non_ecm(t31_state_t *s)
 {
     t31_t38_front_end_state_t *fe;
     uint8_t buf[MAX_OCTETS_PER_UNPACED_CHUNK + 50];
+    int res;
     int delay;
     int len;
 
@@ -717,19 +793,37 @@ static int stream_non_ecm(t31_state_t *s)
             if (fe->t38.current_tx_indicator != T38_IND_NO_SIGNAL)
             {
                 if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0)
-                {
-                    /* ???????? */
-                }
+                    return delay;
+                /*endif*/
             }
+            else
+            {
+                if (fe->us_per_tx_chunk)
+                    delay = 75000;
+                /*endif*/
+            }
+            /*endif*/
             fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_2;
+            fe->timeout_tx_samples = fe->next_tx_samples
+                                   + us_to_samples(t38_core_send_training_delay(&fe->t38, fe->next_tx_indicator));
             fe->next_tx_samples = fe->samples;
             break;
         case T38_TIMED_STEP_NON_ECM_MODEM_2:
             /* Switch on a fast modem, and give the training time to complete */
-            if ((delay = t38_core_send_indicator(&fe->t38, fe->next_tx_indicator)) < 0)
+            if ((fe->chunking_modes & T38_CHUNKING_SEND_REGULAR_INDICATORS))
             {
-                /* ???????? */
+                if ((delay = t38_core_send_indicator(&fe->t38, 0x100 | fe->next_tx_indicator)) < 0)
+                    return delay;
+                /*endif*/
+                if (fe->next_tx_samples >= fe->timeout_tx_samples)
+                    fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_3;
+                /*endif*/
+                return fe->us_per_tx_chunk;
             }
+            /*endif*/
+            if ((delay = t38_core_send_indicator(&fe->t38, fe->next_tx_indicator)) < 0)
+                return delay;
+            /*endif*/
             fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_3;
             break;
         case T38_TIMED_STEP_NON_ECM_MODEM_3:
@@ -741,10 +835,11 @@ static int stream_non_ecm(t31_state_t *s)
             len = non_ecm_get(s, buf, fe->octets_per_data_packet);
             if (len > 0)
                 bit_reverse(buf, buf, len);
+            /*endif*/
             if (len < fe->octets_per_data_packet)
             {
                 /* That's the end of the image data. */
-                if (s->t38_fe.ms_per_tx_chunk)
+                if (fe->us_per_tx_chunk)
                 {
                     /* Pad the end of the data with some zeros. If we just stop abruptly
                        at the end of the EOLs, some ATAs fail to clean up properly before
@@ -761,59 +856,66 @@ static int stream_non_ecm(t31_state_t *s)
                 else
                 {
                     /* If we are sending quickly there seems no point in doing any padding */
-                    if (t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_SIG_END, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA_END) < 0)
-                    {
-                        /* ???????? */
-                    }
+                    if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_SIG_END, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA_END)) < 0)
+                        return res;
+                    /*endif*/
                     fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_5;
-                    delay = 0;
+                    if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
+                        return -1;
+                    /*endif*/
+                    break;
                 }
+                /*endif*/
             }
-            if (t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_DATA, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA) < 0)
-            {
-                /* ???????? */
-            }
-            delay = bits_to_us(s, 8*len);
+            /*endif*/
+            if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_DATA, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA)) < 0)
+                return res;
+            /*endif*/
+            if (fe->us_per_tx_chunk)
+                delay = bits_to_us(s, 8*len);
+            /*endif*/
             break;
         case T38_TIMED_STEP_NON_ECM_MODEM_4:
             /* Send padding */
             len = fe->octets_per_data_packet;
-            fe->non_ecm_trailer_bytes -= len;
+            fe->non_ecm_trailer_bytes -= fe->octets_per_data_packet;
             if (fe->non_ecm_trailer_bytes <= 0)
             {
                 len += fe->non_ecm_trailer_bytes;
                 memset(buf, 0, len);
-                if (t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_SIG_END, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA_END) < 0)
-                {
-                    /* ???????? */
-                }
+                if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_SIG_END, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA_END)) < 0)
+                    return res;
+                /*endif*/
                 fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_5;
                 /* Allow a bit more time than the data will take to play out, to ensure the far ATA does not
                    cut things short. */
-                delay = bits_to_us(s, 8*len);
-                if (s->t38_fe.ms_per_tx_chunk)
-                    delay += 60000;
-                front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE);
+                if (fe->us_per_tx_chunk)
+                    delay = bits_to_us(s, 8*len) + 60000;
+                /*endif*/
+                if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
+                    return -1;
+                /*endif*/
                 break;
             }
+            /*endif*/
             memset(buf, 0, len);
-            if (t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_DATA, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA) < 0)
-            {
-                /* ???????? */
-            }
-            delay = bits_to_us(s, 8*len);
+            if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_DATA, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA)) < 0)
+                return res;
+            /*endif*/
+            if (fe->us_per_tx_chunk)
+                delay = bits_to_us(s, 8*len);
+            /*endif*/
             break;
         case T38_TIMED_STEP_NON_ECM_MODEM_5:
             /* This should not be needed, since the message above indicates the end of the signal, but it
                seems like it can improve compatibility with quirky implementations. */
-            if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0)
-            {
-                /* ???????? */
-            }
+            delay = set_no_signal(s);
             fe->timed_step = T38_TIMED_STEP_NONE;
             return delay;
         }
+        /*endswitch*/
     }
+    /*endfor*/
     return delay;
 }
 /*- End of function --------------------------------------------------------*/
@@ -823,10 +925,11 @@ static int stream_hdlc(t31_state_t *s)
     t31_t38_front_end_state_t *fe;
     uint8_t buf[MAX_OCTETS_PER_UNPACED_CHUNK + 50];
     t38_data_field_t data_fields[2];
+    int category;
     int previous;
+    int res;
     int delay;
     int i;
-    int category;
 
     fe = &s->t38_fe;
     for (delay = 0;  delay == 0;  )
@@ -838,19 +941,37 @@ static int stream_hdlc(t31_state_t *s)
             if (fe->t38.current_tx_indicator != T38_IND_NO_SIGNAL)
             {
                 if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0)
-                {
-                    /* ???????? */
-                }
+                    return delay;
+                /*endif*/
             }
+            else
+            {
+                delay = (fe->us_per_tx_chunk)  ?  75000  :  0;
+            }
+            /*endif*/
             fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_2;
-            fe->next_tx_samples = fe->samples + ms_to_samples(75);
+            fe->timeout_tx_samples = fe->next_tx_samples
+                                   + us_to_samples(t38_core_send_training_delay(&fe->t38, fe->next_tx_indicator))
+                                   + us_to_samples(t38_core_send_flags_delay(&fe->t38, fe->next_tx_indicator))
+                                   + us_to_samples(delay);
+            fe->next_tx_samples = fe->samples;
             break;
         case T38_TIMED_STEP_HDLC_MODEM_2:
             /* Send HDLC preambling */
-            if ((delay = t38_core_send_indicator(&fe->t38, fe->next_tx_indicator)) < 0)
+            if ((fe->chunking_modes & T38_CHUNKING_SEND_REGULAR_INDICATORS))
             {
-                /* ???????? */
+                if ((delay = t38_core_send_indicator(&fe->t38, 0x100 | fe->next_tx_indicator)) < 0)
+                    return delay;
+                /*endif*/
+                if (fe->next_tx_samples >= fe->timeout_tx_samples)
+                    fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_3;
+                /*endif*/
+                return fe->us_per_tx_chunk;
             }
+            /*endif*/
+            if ((delay = t38_core_send_indicator(&fe->t38, fe->next_tx_indicator)) < 0)
+                return delay;
+            /*endif*/
             delay += t38_core_send_flags_delay(&fe->t38, fe->next_tx_indicator);
             at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
             fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_3;
@@ -860,14 +981,15 @@ static int stream_hdlc(t31_state_t *s)
             if (s->hdlc_tx.len == 0)
             {
                 /* We don't have a frame ready yet, so wait a little */
-                delay = MS_PER_TX_CHUNK*1000;
+                delay = US_PER_TX_CHUNK;
                 break;
             }
+            /*endif*/
             i = s->hdlc_tx.len - s->hdlc_tx.ptr;
             if (fe->octets_per_data_packet >= i)
             {
                 /* The last part of an HDLC frame */
-                if (fe->chunking_modes & T38_CHUNKING_MERGE_FCS_WITH_DATA)
+                if ((fe->chunking_modes & T38_CHUNKING_MERGE_FCS_WITH_DATA))
                 {
                     /* Copy the data, as we might be about to refill the buffer it is in */
                     memcpy(buf, &s->hdlc_tx.buf[s->hdlc_tx.ptr], i);
@@ -879,59 +1001,61 @@ static int stream_hdlc(t31_state_t *s)
                     previous = fe->current_tx_data_type;
                     s->hdlc_tx.ptr = 0;
                     s->hdlc_tx.len = 0;
-                    front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE);
-                    if (s->hdlc_tx.final)
-                    {
-                        data_fields[1].field_type = T38_FIELD_HDLC_FCS_OK_SIG_END;
-                        data_fields[1].field = NULL;
-                        data_fields[1].field_len = 0;
-                        category = (s->t38_fe.current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA_END  :  T38_PACKET_CATEGORY_IMAGE_DATA_END;
-                        if (t38_core_send_data_multi_field(&fe->t38, fe->current_tx_data_type, data_fields, 2, category) < 0)
-                        {
-                            /* ???????? */
-                        }
-                        fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_5;
-                        /* We add a bit of extra time here, as with some implementations
-                           the carrier falling too abruptly causes data loss. */
-                        delay = bits_to_us(s, i*8 + fe->hdlc_tx.extra_bits);
-                        if (s->t38_fe.ms_per_tx_chunk)
-                            delay += 100000;
-                        at_put_response_code(&s->at_state, AT_RESPONSE_CODE_OK);
-                        t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
-                    }
-                    else
+                    if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
+                        return -1;
+                    /*endif*/
+                    if (!s->hdlc_tx.final)
                     {
                         data_fields[1].field_type = T38_FIELD_HDLC_FCS_OK;
                         data_fields[1].field = NULL;
                         data_fields[1].field_len = 0;
-                        category = (s->t38_fe.current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA  :  T38_PACKET_CATEGORY_IMAGE_DATA;
-                        if (t38_core_send_data_multi_field(&fe->t38, fe->current_tx_data_type, data_fields, 2, category) < 0)
-                        {
-                            /* ???????? */
-                        }
+                        category = (fe->current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA  :  T38_PACKET_CATEGORY_IMAGE_DATA;
+                        if ((res = t38_core_send_data_multi_field(&fe->t38, fe->current_tx_data_type, data_fields, 2, category)) < 0)
+                            return res;
+                        /*endif*/
                         fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_3;
                         delay = bits_to_us(s, i*8 + fe->hdlc_tx.extra_bits);
                         at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
                     }
+                    else
+                    {
+                        data_fields[1].field_type = T38_FIELD_HDLC_FCS_OK_SIG_END;
+                        data_fields[1].field = NULL;
+                        data_fields[1].field_len = 0;
+                        category = (fe->current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA_END  :  T38_PACKET_CATEGORY_IMAGE_DATA_END;
+                        if ((res = t38_core_send_data_multi_field(&fe->t38, fe->current_tx_data_type, data_fields, 2, category)) < 0)
+                            return res;
+                        /*endif*/
+                        fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_5;
+                        /* We add a bit of extra time here, as with some implementations
+                           the carrier falling too abruptly causes data loss. */
+                        delay = bits_to_us(s, i*8 + fe->hdlc_tx.extra_bits);
+                        if (fe->us_per_tx_chunk)
+                            delay += 100000;
+                        /*endif*/
+                        at_put_response_code(&s->at_state, AT_RESPONSE_CODE_OK);
+                        t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
+                    }
+                    /*endif*/
                     break;
                 }
-                category = (s->t38_fe.current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA  :  T38_PACKET_CATEGORY_IMAGE_DATA;
-                if (t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_HDLC_DATA, &s->hdlc_tx.buf[s->hdlc_tx.ptr], i, category) < 0)
-                {
-                    /* ???????? */
-                }
+                /*endif*/
+                category = (fe->current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA  :  T38_PACKET_CATEGORY_IMAGE_DATA;
+                if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_HDLC_DATA, &s->hdlc_tx.buf[s->hdlc_tx.ptr], i, category)) < 0)
+                    return res;
+                /*endif*/
                 fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_4;
             }
             else
             {
                 i = fe->octets_per_data_packet;
-                category = (s->t38_fe.current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA  :  T38_PACKET_CATEGORY_IMAGE_DATA;
-                if (t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_HDLC_DATA, &s->hdlc_tx.buf[s->hdlc_tx.ptr], i, category) < 0)
-                {
-                    /* ???????? */
-                }
+                category = (fe->current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA  :  T38_PACKET_CATEGORY_IMAGE_DATA;
+                if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_HDLC_DATA, &s->hdlc_tx.buf[s->hdlc_tx.ptr], i, category)) < 0)
+                    return res;
+                /*endif*/
                 s->hdlc_tx.ptr += i;
             }
+            /*endif*/
             delay = bits_to_us(s, i*8);
             break;
         case T38_TIMED_STEP_HDLC_MODEM_4:
@@ -939,60 +1063,61 @@ static int stream_hdlc(t31_state_t *s)
             previous = fe->current_tx_data_type;
             s->hdlc_tx.ptr = 0;
             s->hdlc_tx.len = 0;
-            if (s->hdlc_tx.final)
+            if (!s->hdlc_tx.final)
+            {
+                /* Finish the current frame off, and prepare for the next one. */
+                category = (fe->current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA  :  T38_PACKET_CATEGORY_IMAGE_DATA;
+                if ((res = t38_core_send_data(&fe->t38, previous, T38_FIELD_HDLC_FCS_OK, NULL, 0, category)) < 0)
+                    return res;
+                /*endif*/
+                fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_3;
+                at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
+                /* We should now wait enough time for everything to clear through an analogue modem at the far end. */
+                delay = bits_to_us(s, fe->hdlc_tx.extra_bits);
+            }
+            else
             {
                 /* End of transmission */
-                s->hdlc_tx.len = 0;
                 s->hdlc_tx.final = FALSE;
-                category = (s->t38_fe.current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA  :  T38_PACKET_CATEGORY_IMAGE_DATA;
-                if (t38_core_send_data(&fe->t38, previous, T38_FIELD_HDLC_FCS_OK, NULL, 0, category) < 0)
-                {
-                    /* ???????? */
-                }
+                category = (fe->current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA_END  :  T38_PACKET_CATEGORY_IMAGE_DATA_END;
+                if ((res = t38_core_send_data(&fe->t38, previous, T38_FIELD_HDLC_FCS_OK_SIG_END, NULL, 0, category)) < 0)
+                    return res;
+                /*endif*/
                 fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_5;
                 /* We add a bit of extra time here, as with some implementations
                    the carrier falling too abruptly causes data loss. */
                 delay = bits_to_us(s, fe->hdlc_tx.extra_bits);
-                if (s->t38_fe.ms_per_tx_chunk)
+                if (fe->us_per_tx_chunk)
                     delay += 100000;
-                front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE);
-                break;
+                /*endif*/
+                if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
+                    return -1;
+                /*endif*/
             }
-            /* Finish the current frame off, and prepare for the next one. */
-            category = (s->t38_fe.current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA  :  T38_PACKET_CATEGORY_IMAGE_DATA;
-            if (t38_core_send_data(&fe->t38, previous, T38_FIELD_HDLC_FCS_OK, NULL, 0, category) < 0)
-            {
-                /* ???????? */
-            }
-            fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_3;
-            at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
-            /* We should now wait enough time for everything to clear through an analogue modem at the far end. */
-            delay = bits_to_us(s, fe->hdlc_tx.extra_bits);
-            if (s->hdlc_tx.len == 0)
-                span_log(&s->logging, SPAN_LOG_FLOW, "No new frame or end transmission condition.\n");
+            /*endif*/
             break;
         case T38_TIMED_STEP_HDLC_MODEM_5:
             /* Note that some boxes do not like us sending a T38_FIELD_HDLC_SIG_END at this point.
                A T38_IND_NO_SIGNAL should always be OK. */
-            category = (s->t38_fe.current_tx_data_type == T38_DATA_V21)  ?  T38_PACKET_CATEGORY_CONTROL_DATA_END  :  T38_PACKET_CATEGORY_IMAGE_DATA_END;
-            if (t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_HDLC_SIG_END, NULL, 0, category) < 0)
-            {
-                /* ???????? */
-            }
-            if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0)
-            {
-                /* ???????? */
-            }
+            delay = set_no_signal(s);
             fe->timed_step = T38_TIMED_STEP_NONE;
             at_put_response_code(&s->at_state, AT_RESPONSE_CODE_OK);
             t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
-            return 0;
+            return delay;
         }
+        /*endswitch*/
     }
+    /*endfor*/
     return delay;
 }
 /*- End of function --------------------------------------------------------*/
 
+static int stream_fake_hdlc(t31_state_t *s)
+{
+    return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
 static int stream_ced(t31_state_t *s)
 {
     t31_t38_front_end_state_t *fe;
@@ -1010,28 +1135,30 @@ static int stream_ced(t31_state_t *s)
                We do need a 200ms delay, as that is a specification requirement. */
             fe->timed_step = T38_TIMED_STEP_CED_2;
             if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0)
-            {
-                /* ???????? */
-            }
-            delay = 200000;
+                return delay;
+            /*endif*/
+            delay = (fe->us_per_tx_chunk)  ?  200000  :  0;
             fe->next_tx_samples = fe->samples;
             break;
         case T38_TIMED_STEP_CED_2:
             /* Initial 200ms delay over. Send the CED indicator */
             fe->timed_step = T38_TIMED_STEP_CED_3;
             if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_CED)) < 0)
-            {
-                /* ???????? */
-            }
+                return delay;
+            /*endif*/
             fe->current_tx_data_type = T38_DATA_NONE;
             break;
         case T38_TIMED_STEP_CED_3:
             /* End of CED */
             fe->timed_step = T38_TIMED_STEP_NONE;
-            front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE);
+            if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
+                return -1;
+            /*endif*/
             return 0;
         }
+        /*endswitch*/
     }
+    /*endfor*/
     return delay;
 }
 /*- End of function --------------------------------------------------------*/
@@ -1053,25 +1180,23 @@ static int stream_cng(t31_state_t *s)
                a no signal indication makes sense. */
             fe->timed_step = T38_TIMED_STEP_CNG_2;
             if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0)
-            {
-                /* ???????? */
-            }
-            delay = 200000;
+                return delay;
+            /*endif*/
+            delay = (fe->us_per_tx_chunk)  ?  200000  :  0;
             fe->next_tx_samples = fe->samples;
             break;
         case T38_TIMED_STEP_CNG_2:
             /* Initial short delay over. Send the CNG indicator. CNG persists until something
                coming the other way interrupts it, or a long timeout controlled by the T.30 engine
                expires. */
+            delay = t38_core_send_indicator(&fe->t38, T38_IND_CNG);
             fe->timed_step = T38_TIMED_STEP_NONE;
-            if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_CNG)) < 0)
-            {
-                /* ???????? */
-            }
             fe->current_tx_data_type = T38_DATA_NONE;
             return delay;
         }
+        /*endswitch*/
     }
+    /*endfor*/
     return delay;
 }
 /*- End of function --------------------------------------------------------*/
@@ -1084,6 +1209,7 @@ SPAN_DECLARE(int) t31_t38_send_timeout(t31_state_t *s, int samples)
     fe = &s->t38_fe;
     if (fe->current_rx_type == T30_MODEM_DONE  ||  fe->current_tx_type == T30_MODEM_DONE)
         return TRUE;
+    /*endif*/
 
     fe->samples += samples;
     if (fe->timeout_rx_samples  &&  fe->samples > fe->timeout_rx_samples)
@@ -1092,12 +1218,15 @@ SPAN_DECLARE(int) t31_t38_send_timeout(t31_state_t *s, int samples)
         fe->timeout_rx_samples = 0;
         front_end_status(s, T30_FRONT_END_RECEIVE_COMPLETE);
     }
+    /*endif*/
     if (fe->timed_step == T38_TIMED_STEP_NONE)
         return FALSE;
+    /*endif*/
     /* Wait until the right time comes along, unless we are working in "no delays" mode, while talking to an
        IAF terminal. */
-    if (fe->ms_per_tx_chunk  &&  fe->samples < fe->next_tx_samples)
+    if (fe->us_per_tx_chunk  &&  fe->samples < fe->next_tx_samples)
         return FALSE;
+    /*endif*/
     /* Its time to send something */
     delay = 0;
     switch (fe->timed_step & 0xFFF0)
@@ -1108,9 +1237,9 @@ SPAN_DECLARE(int) t31_t38_send_timeout(t31_state_t *s, int samples)
     case T38_TIMED_STEP_HDLC_MODEM:
         delay = stream_hdlc(s);
         break;
-    //case T38_TIMED_STEP_FAKE_HDLC_MODEM:
-    //    delay = stream_fake_hdlc(s);
-    //    break;
+    case T38_TIMED_STEP_FAKE_HDLC_MODEM:
+        delay = stream_fake_hdlc(s);
+        break;
     case T38_TIMED_STEP_CED:
         delay = stream_ced(s);
         break;
@@ -1122,7 +1251,11 @@ SPAN_DECLARE(int) t31_t38_send_timeout(t31_state_t *s, int samples)
         fe->timed_step = T38_TIMED_STEP_NONE;
         front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE);
         break;
+    case T38_TIMED_STEP_NO_SIGNAL:
+        delay = stream_no_signal(s);
+        break;
     }
+    /*endswitch*/
     fe->next_tx_samples += us_to_samples(delay);
     return FALSE;
 }
@@ -1148,6 +1281,7 @@ static int t31_modem_control_handler(at_state_t *s, void *user_data, int op, con
             /* Tell the application to release further data */
             at_modem_control(&t->at_state, AT_MODEM_CONTROL_CTS, (void *) 1);
         }
+        /*endif*/
         if (t->at_state.rx_signal_present)
         {
             t->at_state.rx_data[t->at_state.rx_data_bytes++] = DLE;
@@ -1158,6 +1292,7 @@ static int t31_modem_control_handler(at_state_t *s, void *user_data, int op, con
                                       t->at_state.rx_data_bytes);
             t->at_state.rx_data_bytes = 0;
         }
+        /*endif*/
         restart_modem(t, FAX_MODEM_SILENCE_TX);
         break;
     case AT_MODEM_CONTROL_RESTART:
@@ -1168,8 +1303,10 @@ static int t31_modem_control_handler(at_state_t *s, void *user_data, int op, con
             t->dte_data_timeout = t->call_samples + ms_to_samples((intptr_t) num);
         else
             t->dte_data_timeout = 0;
+        /*endif*/
         return 0;
     }
+    /*endswitch*/
     return t->modem_control_handler(t, t->modem_control_user_data, op, num);
 }
 /*- End of function --------------------------------------------------------*/
@@ -1209,6 +1346,7 @@ static void non_ecm_rx_status(void *user_data, int status)
             at_put_response_code(&s->at_state, AT_RESPONSE_CODE_NO_CARRIER);
             t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
         }
+        /*endif*/
         s->at_state.rx_signal_present = FALSE;
         s->at_state.rx_trained = FALSE;
         s->audio.modems.rx_trained = FALSE;
@@ -1216,8 +1354,10 @@ static void non_ecm_rx_status(void *user_data, int status)
     default:
         if (s->at_state.p.result_code_format)
             span_log(&s->logging, SPAN_LOG_FLOW, "Eh!\n");
+        /*endif*/
         break;
     }
+    /*endswitch*/
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -1230,12 +1370,14 @@ static void non_ecm_put_bit(void *user_data, int bit)
         non_ecm_rx_status(user_data, bit);
         return;
     }
+    /*endif*/
     s = (t31_state_t *) user_data;
     s->audio.current_byte = (s->audio.current_byte >> 1) | (bit << 7);
     if (++s->audio.bit_no >= 8)
     {
         if (s->audio.current_byte == DLE)
             s->at_state.rx_data[s->at_state.rx_data_bytes++] = DLE;
+        /*endif*/
         s->at_state.rx_data[s->at_state.rx_data_bytes++] = (uint8_t) s->audio.current_byte;
         if (s->at_state.rx_data_bytes >= 250)
         {
@@ -1245,9 +1387,11 @@ static void non_ecm_put_bit(void *user_data, int bit)
                                       s->at_state.rx_data_bytes);
             s->at_state.rx_data_bytes = 0;
         }
+        /*endif*/
         s->audio.bit_no = 0;
         s->audio.current_byte = 0;
     }
+    /*endif*/
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -1262,6 +1406,7 @@ static void non_ecm_put(void *user_data, const uint8_t buf[], int len)
     {
         if (buf[i] == DLE)
             s->at_state.rx_data[s->at_state.rx_data_bytes++] = DLE;
+        /*endif*/
         s->at_state.rx_data[s->at_state.rx_data_bytes++] = buf[i];
         if (s->at_state.rx_data_bytes >= 250)
         {
@@ -1271,7 +1416,9 @@ static void non_ecm_put(void *user_data, const uint8_t buf[], int len)
                                       s->at_state.rx_data_bytes);
             s->at_state.rx_data_bytes = 0;
         }
+        /*endif*/
     }
+    /*endfor*/
     s->audio.bit_no = 0;
     s->audio.current_byte = 0;
 }
@@ -1294,6 +1441,7 @@ static int non_ecm_get_bit(void *user_data)
                 s->tx.out_bytes = T31_TX_BUF_LEN - 1;
                 span_log(&s->logging, SPAN_LOG_FLOW, "End of transmit buffer reached!\n");
             }
+            /*endif*/
             if (s->tx.holding)
             {
                 /* See if the buffer is approaching empty. It might be time to
@@ -1304,7 +1452,9 @@ static int non_ecm_get_bit(void *user_data)
                     /* Tell the application to release further data */
                     at_modem_control(&s->at_state, AT_MODEM_CONTROL_CTS, (void *) 1);
                 }
+                /*endif*/
             }
+            /*endif*/
             s->tx.data_started = TRUE;
         }
         else
@@ -1316,12 +1466,15 @@ static int non_ecm_get_bit(void *user_data)
                    it has finally shut down, an OK response will be sent. */
                 return SIG_STATUS_END_OF_DATA;
             }
+            /*endif*/
             /* Fill with 0xFF bytes at the start of transmission, or 0x00 if we are in
                the middle of transmission. This follows T.31 and T.30 practice. */
             s->audio.current_byte = (s->tx.data_started)  ?  0x00  :  0xFF;
         }
+        /*endif*/
         s->audio.bit_no = 8;
     }
+    /*endif*/
     s->audio.bit_no--;
     bit = s->audio.current_byte & 1;
     s->audio.current_byte >>= 1;
@@ -1346,6 +1499,7 @@ static int non_ecm_get(void *user_data, uint8_t buf[], int len)
                 s->tx.out_bytes = T31_TX_BUF_LEN - 1;
                 span_log(&s->logging, SPAN_LOG_FLOW, "End of transmit buffer reached!\n");
             }
+            /*endif*/
             if (s->tx.holding)
             {
                 /* See if the buffer is approaching empty. It might be time to release flow control. */
@@ -1355,7 +1509,9 @@ static int non_ecm_get(void *user_data, uint8_t buf[], int len)
                     /* Tell the application to release further data */
                     at_modem_control(&s->at_state, AT_MODEM_CONTROL_CTS, (void *) 1);
                 }
+                /*endif*/
             }
+            /*endif*/
             s->tx.data_started = TRUE;
         }
         else
@@ -1368,11 +1524,14 @@ static int non_ecm_get(void *user_data, uint8_t buf[], int len)
                 //return SIG_STATUS_END_OF_DATA;
                 return i;
             }
+            /*endif*/
             /* Fill with 0xFF bytes at the start of transmission, or 0x00 if we are in
                the middle of transmission. This follows T.31 and T.30 practice. */
             buf[i] = (s->tx.data_started)  ?  0x00  :  0xFF;
         }
+        /*endif*/
     }
+    /*endfor*/
     s->audio.bit_no = 0;
     s->audio.current_byte = 0;
     return len;
@@ -1412,6 +1571,7 @@ static void hdlc_tx_underflow(void *user_data)
     {
         at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
     }
+    /*endif*/
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -1442,6 +1602,7 @@ static void hdlc_rx_status(void *user_data, int status)
             s->rx_frame_received = FALSE;
             s->audio.modems.rx_frame_received = FALSE;
         }
+        /*endif*/
         break;
     case SIG_STATUS_CARRIER_DOWN:
         if (s->rx_frame_received)
@@ -1457,6 +1618,7 @@ static void hdlc_rx_status(void *user_data, int status)
                 {
                     at_put_response_code(&s->at_state, AT_RESPONSE_CODE_NO_CARRIER);
                 }
+                /*endif*/
                 s->at_state.dte_is_waiting = FALSE;
                 t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
             }
@@ -1465,7 +1627,9 @@ static void hdlc_rx_status(void *user_data, int status)
                 buf[0] = AT_RESPONSE_CODE_NO_CARRIER;
                 queue_write_msg(s->rx_queue, buf, 1);
             }
+            /*endif*/
         }
+        /*endif*/
         s->at_state.rx_signal_present = FALSE;
         s->at_state.rx_trained = FALSE;
         s->audio.modems.rx_trained = FALSE;
@@ -1478,6 +1642,7 @@ static void hdlc_rx_status(void *user_data, int status)
             s->modem = FAX_MODEM_V21_RX;
             s->at_state.transmit = FALSE;
         }
+        /*endif*/
         if (s->modem == FAX_MODEM_V17_RX  ||  s->modem == FAX_MODEM_V27TER_RX  ||  s->modem == FAX_MODEM_V29_RX)
         {
             /* V.21 has been detected while expecting a different carrier.
@@ -1503,6 +1668,7 @@ static void hdlc_rx_status(void *user_data, int status)
                 s->audio.modems.rx_frame_received = FALSE;
                 at_put_response_code(&s->at_state, AT_RESPONSE_CODE_FCERROR);
             }
+            /*endif*/
         }
         else
         {
@@ -1520,8 +1686,11 @@ static void hdlc_rx_status(void *user_data, int status)
                     buf[0] = AT_RESPONSE_CODE_CONNECT;
                     queue_write_msg(s->rx_queue, buf, 1);
                 }
+                /*endif*/
             }
+            /*endif*/
         }
+        /*endif*/
         break;
     case SIG_STATUS_ABORT:
         /* Just ignore these */
@@ -1530,6 +1699,7 @@ static void hdlc_rx_status(void *user_data, int status)
         span_log(&s->logging, SPAN_LOG_WARNING, "Unexpected HDLC rx status - %d!\n", status);
         break;
     }
+    /*endswitch*/
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -1544,6 +1714,7 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
         hdlc_rx_status(user_data, len);
         return;
     }
+    /*endif*/
     s = (t31_state_t *) user_data;
     if (!s->rx_frame_received)
     {
@@ -1559,7 +1730,9 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
             buf[0] = AT_RESPONSE_CODE_CONNECT;
             queue_write_msg(s->rx_queue, buf, 1);
         }
+        /*endif*/
     }
+    /*endif*/
     /* If OK is pending then we just ignore whatever comes in */
     if (!s->at_state.ok_is_pending)
     {
@@ -1572,8 +1745,10 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
             {
                 if (msg[i] == DLE)
                     s->at_state.rx_data[s->at_state.rx_data_bytes++] = DLE;
+                /*endif*/
                 s->at_state.rx_data[s->at_state.rx_data_bytes++] = msg[i];
             }
+            /*endfor*/
             s->at_state.rx_data[s->at_state.rx_data_bytes++] = DLE;
             s->at_state.rx_data[s->at_state.rx_data_bytes++] = ETX;
             s->at_state.at_tx_handler(&s->at_state, s->at_state.at_tx_user_data, s->at_state.rx_data, s->at_state.rx_data_bytes);
@@ -1591,6 +1766,7 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
                 s->rx_frame_received = FALSE;
                 s->audio.modems.rx_frame_received = FALSE;
             }
+            /*endif*/
         }
         else
         {
@@ -1601,7 +1777,9 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
             memcpy(buf + 1, msg, len + 2);
             queue_write_msg(s->rx_queue, buf, len + 3);
         }
+        /*endif*/
     }
+    /*endif*/
     t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
 }
 /*- End of function --------------------------------------------------------*/
@@ -1609,8 +1787,8 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
 static void t31_v21_rx(t31_state_t *s)
 {
     s->at_state.ok_is_pending = FALSE;
-    s->hdlc_tx.final = FALSE;
     s->hdlc_tx.len = 0;
+    s->hdlc_tx.final = FALSE;
     s->dled = FALSE;
     hdlc_rx_init(&s->audio.modems.hdlc_rx, FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept_frame, s);
     fax_modems_start_slow_modem(&s->audio.modems, FAX_MODEM_V21_RX);
@@ -1621,12 +1799,14 @@ static void t31_v21_rx(t31_state_t *s)
 static int restart_modem(t31_state_t *s, int new_modem)
 {
     int use_hdlc;
+    int res;
     fax_modems_state_t *t;
 
     t = &s->audio.modems;
     span_log(&s->logging, SPAN_LOG_FLOW, "Restart modem %d\n", new_modem);
     if (s->modem == new_modem)
         return 0;
+    /*endif*/
     queue_flush(s->rx_queue);
     s->modem = new_modem;
     s->tx.final = FALSE;
@@ -1659,6 +1839,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
             fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
             fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         }
+        /*endif*/
         s->at_state.transmit = TRUE;
         break;
     case FAX_MODEM_NOCNG_TONE:
@@ -1672,6 +1853,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
             silence_gen_set(&t->silence_gen, 0);
             fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
         }
+        /*endif*/
         s->at_state.transmit = FALSE;
         break;
     case FAX_MODEM_CED_TONE:
@@ -1687,6 +1869,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
             fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
             fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         }
+        /*endif*/
         s->at_state.transmit = TRUE;
         break;
     case FAX_MODEM_V21_RX:
@@ -1698,6 +1881,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
             t31_v21_rx(s);
             fax_modems_set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
         }
+        /*endif*/
         break;
     case FAX_MODEM_V21_TX:
         if (s->t38_mode)
@@ -1717,8 +1901,9 @@ static int restart_modem(t31_state_t *s, int new_modem)
             fax_modems_set_tx_handler(t, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
             fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         }
-        s->hdlc_tx.final = FALSE;
+        /*endif*/
         s->hdlc_tx.len = 0;
+        s->hdlc_tx.final = FALSE;
         s->dled = FALSE;
         s->at_state.transmit = TRUE;
         break;
@@ -1731,6 +1916,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
             /* Allow for +FCERROR/+FRH:3 */
             t31_v21_rx(s);
         }
+        /*endif*/
         s->at_state.transmit = FALSE;
         break;
     case FAX_MODEM_V17_TX:
@@ -1755,13 +1941,15 @@ static int restart_modem(t31_state_t *s, int new_modem)
                 s->t38_fe.current_tx_data_type = T38_DATA_V17_14400;
                 break;
             }
+            /*endswitch*/
             set_octets_per_data_packet(s, s->bit_rate);
-            s->t38_fe.timed_step = (use_hdlc)  ?  T38_TIMED_STEP_HDLC_MODEM  :  T38_TIMED_STEP_NON_ECM_MODEM;
+            s->t38_fe.timed_step = (s->t38_fe.ecm_mode)  ?  T38_TIMED_STEP_FAKE_HDLC_MODEM  :  T38_TIMED_STEP_NON_ECM_MODEM;
         }
         else
         {
             fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
         }
+        /*endif*/
         s->tx.out_bytes = 0;
         s->tx.data_started = FALSE;
         s->at_state.transmit = TRUE;
@@ -1780,13 +1968,15 @@ static int restart_modem(t31_state_t *s, int new_modem)
                 s->t38_fe.current_tx_data_type = T38_DATA_V27TER_4800;
                 break;
             }
+            /*endswitch*/
             set_octets_per_data_packet(s, s->bit_rate);
-            s->t38_fe.timed_step = (use_hdlc)  ?  T38_TIMED_STEP_HDLC_MODEM  :  T38_TIMED_STEP_NON_ECM_MODEM;
+            s->t38_fe.timed_step = (s->t38_fe.ecm_mode)  ?  T38_TIMED_STEP_FAKE_HDLC_MODEM  :  T38_TIMED_STEP_NON_ECM_MODEM;
         }
         else
         {
             fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
         }
+        /*endif*/
         s->tx.out_bytes = 0;
         s->tx.data_started = FALSE;
         s->at_state.transmit = TRUE;
@@ -1805,13 +1995,15 @@ static int restart_modem(t31_state_t *s, int new_modem)
                 s->t38_fe.current_tx_data_type = T38_DATA_V29_9600;
                 break;
             }
+            /*endswitch*/
             set_octets_per_data_packet(s, s->bit_rate);
-            s->t38_fe.timed_step = (use_hdlc)  ?  T38_TIMED_STEP_HDLC_MODEM  :  T38_TIMED_STEP_NON_ECM_MODEM;
+            s->t38_fe.timed_step = (s->t38_fe.ecm_mode)  ?  T38_TIMED_STEP_FAKE_HDLC_MODEM  :  T38_TIMED_STEP_NON_ECM_MODEM;
         }
         else
         {
             fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
         }
+        /*endif*/
         s->tx.out_bytes = 0;
         s->tx.data_started = FALSE;
         s->at_state.transmit = TRUE;
@@ -1819,10 +2011,9 @@ static int restart_modem(t31_state_t *s, int new_modem)
     case FAX_MODEM_SILENCE_TX:
         if (s->t38_mode)
         {
-            if (t38_core_send_indicator(&s->t38_fe.t38, T38_IND_NO_SIGNAL) < 0)
-            {
-                /* ???????? */
-            }
+            if ((res = t38_core_send_indicator(&s->t38_fe.t38, T38_IND_NO_SIGNAL)) < 0)
+                return res;
+            /*endif*/
             s->t38_fe.next_tx_samples = s->t38_fe.samples + ms_to_samples(700);
             s->t38_fe.timed_step = T38_TIMED_STEP_PAUSE;
             s->t38_fe.current_tx_data_type = T38_DATA_NONE;
@@ -1833,6 +2024,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
             fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
             fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         }
+        /*endif*/
         s->at_state.transmit = FALSE;
         break;
     case FAX_MODEM_SILENCE_RX:
@@ -1843,16 +2035,16 @@ static int restart_modem(t31_state_t *s, int new_modem)
             fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
             fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         }
+        /*endif*/
         s->at_state.transmit = FALSE;
         break;
     case FAX_MODEM_FLUSH:
         /* Send 200ms of silence to "push" the last audio out */
         if (s->t38_mode)
         {
-            if (t38_core_send_indicator(&s->t38_fe.t38, T38_IND_NO_SIGNAL) < 0)
-            {
-                /* ???????? */
-            }
+            if ((res = t38_core_send_indicator(&s->t38_fe.t38, T38_IND_NO_SIGNAL)) < 0)
+                return res;
+            /*endif*/
         }
         else
         {
@@ -1862,8 +2054,10 @@ static int restart_modem(t31_state_t *s, int new_modem)
             fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
             s->at_state.transmit = TRUE;
         }
+        /*endif*/
         break;
     }
+    /*endswitch*/
     s->audio.bit_no = 0;
     s->audio.current_byte = 0xFF;
     s->tx.in_bytes = 0;
@@ -1893,6 +2087,7 @@ static __inline__ void dle_unstuff_hdlc(t31_state_t *s, const char *stuffed, int
                     hdlc_tx_frame(&s->audio.modems.hdlc_tx, s->hdlc_tx.buf, s->hdlc_tx.len);
                     s->hdlc_tx.len = 0;
                 }
+                /*endif*/
             }
             else if (stuffed[i] == SUB)
             {
@@ -1903,6 +2098,7 @@ static __inline__ void dle_unstuff_hdlc(t31_state_t *s, const char *stuffed, int
             {
                 s->hdlc_tx.buf[s->hdlc_tx.len++] = stuffed[i];
             }
+            /*endif*/
         }
         else
         {
@@ -1910,8 +2106,11 @@ static __inline__ void dle_unstuff_hdlc(t31_state_t *s, const char *stuffed, int
                 s->dled = TRUE;
             else
                 s->hdlc_tx.buf[s->hdlc_tx.len++] = stuffed[i];
+            /*endif*/
         }
+        /*endif*/
     }
+    /*endfor*/
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -1930,12 +2129,14 @@ static __inline__ void dle_unstuff(t31_state_t *s, const char *stuffed, int len)
                 t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
                 return;
             }
+            /*endif*/
         }
         else if (stuffed[i] == DLE)
         {
             s->dled = TRUE;
             continue;
         }
+        /*endif*/
         s->tx.data[s->tx.in_bytes++] = stuffed[i];
         if (s->tx.in_bytes > T31_TX_BUF_LEN - 1)
         {
@@ -1943,7 +2144,9 @@ static __inline__ void dle_unstuff(t31_state_t *s, const char *stuffed, int len)
             span_log(&s->logging, SPAN_LOG_FLOW, "No room in buffer for new data!\n");
             return;
         }
+        /*endif*/
     }
+    /*endfor*/
     if (!s->tx.holding)
     {
         /* See if the buffer is approaching full. We might need to apply flow control. */
@@ -1953,7 +2156,9 @@ static __inline__ void dle_unstuff(t31_state_t *s, const char *stuffed, int len)
             /* Tell the application to hold further data */
             at_modem_control(&s->at_state, AT_MODEM_CONTROL_CTS, (void *) 0);
         }
+        /*endif*/
     }
+    /*endif*/
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -1982,6 +2187,7 @@ static int process_class1_cmd(at_state_t *t, void *user_data, int direction, int
                 s->t38_fe.next_tx_samples = s->t38_fe.samples + ms_to_samples(val*10);
             else
                 silence_gen_alter(&s->audio.modems.silence_gen, ms_to_samples(val*10));
+            /*endif*/
             s->at_state.transmit = TRUE;
         }
         else
@@ -1999,7 +2205,9 @@ static int process_class1_cmd(at_state_t *t, void *user_data, int direction, int
             {
                 restart_modem(s, FAX_MODEM_SILENCE_RX);
             }
+            /*endif*/
         }
+        /*endif*/
         immediate_response = FALSE;
         span_log(&s->logging, SPAN_LOG_FLOW, "Silence %dms\n", val*10);
         break;
@@ -2014,18 +2222,21 @@ static int process_class1_cmd(at_state_t *t, void *user_data, int direction, int
         default:
             return -1;
         }
+        /*endswitch*/
         span_log(&s->logging, SPAN_LOG_FLOW, "HDLC\n");
         if (new_modem != s->modem)
         {
             restart_modem(s, new_modem);
             immediate_response = FALSE;
         }
+        /*endif*/
         s->at_state.transmit = new_transmit;
         if (new_transmit)
         {
             t31_set_at_rx_mode(s, AT_MODE_HDLC);
             if (!s->t38_mode)
                 at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
+            /*endif*/
         }
         else
         {
@@ -2042,17 +2253,21 @@ static int process_class1_cmd(at_state_t *t, void *user_data, int direction, int
                     {
                         if (msg[0] == AT_RESPONSE_CODE_OK)
                             at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
+                        /*endif*/
                         for (i = 1;  i < len;  i++)
                         {
                             if (msg[i] == DLE)
                                 s->at_state.rx_data[s->at_state.rx_data_bytes++] = DLE;
+                            /*endif*/
                             s->at_state.rx_data[s->at_state.rx_data_bytes++] = msg[i];
                         }
+                        /*endfor*/
                         s->at_state.rx_data[s->at_state.rx_data_bytes++] = DLE;
                         s->at_state.rx_data[s->at_state.rx_data_bytes++] = ETX;
                         s->at_state.at_tx_handler(&s->at_state, s->at_state.at_tx_user_data, s->at_state.rx_data, s->at_state.rx_data_bytes);
                         s->at_state.rx_data_bytes = 0;
                     }
+                    /*endif*/
                     at_put_response_code(&s->at_state, msg[0]);
                 }
                 else
@@ -2060,9 +2275,11 @@ static int process_class1_cmd(at_state_t *t, void *user_data, int direction, int
                     s->at_state.dte_is_waiting = TRUE;
                     break;
                 }
+                /*endif*/
             }
             while (msg[0] == AT_RESPONSE_CODE_CONNECT);
         }
+        /*endif*/
         immediate_response = FALSE;
         break;
     default:
@@ -2155,6 +2372,7 @@ static int process_class1_cmd(at_state_t *t, void *user_data, int direction, int
         default:
             return -1;
         }
+        /*endswitch*/
         span_log(&s->logging, SPAN_LOG_FLOW, "Short training = %d, bit rate = %d\n", s->short_train, s->bit_rate);
         if (new_transmit)
         {
@@ -2165,17 +2383,19 @@ static int process_class1_cmd(at_state_t *t, void *user_data, int direction, int
         {
             t31_set_at_rx_mode(s, AT_MODE_DELIVERY);
         }
+        /*endif*/
         restart_modem(s, new_modem);
         immediate_response = FALSE;
         break;
     }
+    /*endswitch*/
     return immediate_response;
 }
 /*- End of function --------------------------------------------------------*/
 
 SPAN_DECLARE(void) t31_call_event(t31_state_t *s, int event)
 {
-    span_log(&s->logging, SPAN_LOG_FLOW, "Call event %d received\n", event);
+    span_log(&s->logging, SPAN_LOG_FLOW, "Call event %s (%d) received\n", at_call_state_to_str(event), event);
     at_call_event(&s->at_state, event);
 }
 /*- End of function --------------------------------------------------------*/
@@ -2190,6 +2410,7 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
 {
     if (s->dte_data_timeout)
         s->dte_data_timeout = s->call_samples + ms_to_samples(5000);
+    /*endif*/
     switch (s->at_state.at_rx_mode)
     {
     case AT_MODE_ONHOOK_COMMAND:
@@ -2206,6 +2427,7 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
                 s->at_state.rx_data[s->at_state.rx_data_bytes++] = ETX;
                 s->at_state.at_tx_handler(&s->at_state, s->at_state.at_tx_user_data, s->at_state.rx_data, s->at_state.rx_data_bytes);
             }
+            /*endif*/
             s->at_state.rx_data_bytes = 0;
             s->at_state.transmit = FALSE;
             s->modem = FAX_MODEM_SILENCE_TX;
@@ -2213,6 +2435,7 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
             t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
             at_put_response_code(&s->at_state, AT_RESPONSE_CODE_OK);
         }
+        /*endif*/
         break;
     case AT_MODE_HDLC:
         dle_unstuff_hdlc(s, t, len);
@@ -2225,12 +2448,14 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
             memmove(&s->tx.data[0], &s->tx.data[s->tx.out_bytes], s->tx.in_bytes);
             s->tx.out_bytes = 0;
         }
+        /*endif*/
         dle_unstuff(s, t, len);
         break;
     case AT_MODE_CONNECTED:
         /* TODO: Implement for data modem operation */
         break;
     }
+    /*endswitch*/
     return len;
 }
 /*- End of function --------------------------------------------------------*/
@@ -2248,6 +2473,7 @@ static int silence_rx(void *user_data, const int16_t amp[], int len)
         s->audio.silence_heard = 0;
         s->silence_awaited = 0;
     }
+    /*endif*/
     return 0;
 }
 /*- End of function --------------------------------------------------------*/
@@ -2269,6 +2495,7 @@ static int cng_rx(void *user_data, const int16_t amp[], int len)
     {
         fsk_rx(&s->audio.modems.v21_rx, amp, len);
     }
+    /*endif*/
     return 0;
 }
 /*- End of function --------------------------------------------------------*/
@@ -2297,8 +2524,11 @@ SPAN_DECLARE_NONSTD(int) t31_rx(t31_state_t *s, int16_t amp[], int len)
         {        
             if (s->audio.silence_heard <= ms_to_samples(255*10))
                 s->audio.silence_heard++;
+            /*endif*/
         }
+        /*endif*/
     }
+    /*endfor*/
 
     /* Time is determined by counting the samples in audio packets coming in. */
     s->call_samples += len;
@@ -2312,6 +2542,7 @@ SPAN_DECLARE_NONSTD(int) t31_rx(t31_state_t *s, int16_t amp[], int len)
         at_put_response_code(&s->at_state, AT_RESPONSE_CODE_ERROR);
         restart_modem(s, FAX_MODEM_SILENCE_TX);
     }
+    /*endif*/
 
     s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
     return 0;
@@ -2337,6 +2568,7 @@ SPAN_DECLARE_NONSTD(int) t31_rx_fillin(t31_state_t *s, int len)
         at_put_response_code(&s->at_state, AT_RESPONSE_CODE_ERROR);
         restart_modem(s, FAX_MODEM_SILENCE_TX);
     }
+    /*endif*/
 
     s->audio.modems.rx_fillin_handler(s->audio.modems.rx_fillin_user_data, len);
     return 0;
@@ -2351,6 +2583,7 @@ static int set_next_tx_type(t31_state_t *s)
         fax_modems_set_next_tx_handler(&s->audio.modems, (span_tx_handler_t) NULL, NULL);
         return 0;
     }
+    /*endif*/
     /* There is nothing else to change to, so use zero length silence */
     silence_gen_alter(&s->audio.modems.silence_gen, 0);
     fax_modems_set_tx_handler(&s->audio.modems, (span_tx_handler_t) &silence_gen, &s->audio.modems.silence_gen);
@@ -2372,14 +2605,18 @@ SPAN_DECLARE_NONSTD(int) t31_tx(t31_state_t *s, int16_t amp[], int max_len)
             set_next_tx_type(s);
             if ((len += s->audio.modems.tx_handler(s->audio.modems.tx_user_data, amp + len, max_len - len)) < max_len)
                 front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE);
+            /*endif*/
         }
+        /*endif*/
     }
+    /*endif*/
     if (s->audio.modems.transmit_on_idle)
     {
         /* Pad to the requested length with silence */
         memset(amp + len, 0, (max_len - len)*sizeof(int16_t));
         len = max_len;        
     }
+    /*endif*/
     return len;
 }
 /*- End of function --------------------------------------------------------*/
@@ -2407,7 +2644,7 @@ SPAN_DECLARE(void) t31_set_t38_config(t31_state_t *s, int without_pacing)
         t38_set_redundancy_control(&s->t38_fe.t38, T38_PACKET_CATEGORY_CONTROL_DATA_END, 1);
         t38_set_redundancy_control(&s->t38_fe.t38, T38_PACKET_CATEGORY_IMAGE_DATA, 1);
         t38_set_redundancy_control(&s->t38_fe.t38, T38_PACKET_CATEGORY_IMAGE_DATA_END, 1);
-        s->t38_fe.ms_per_tx_chunk = 0;
+        s->t38_fe.us_per_tx_chunk = 0;
     }
     else
     {
@@ -2417,8 +2654,9 @@ SPAN_DECLARE(void) t31_set_t38_config(t31_state_t *s, int without_pacing)
         t38_set_redundancy_control(&s->t38_fe.t38, T38_PACKET_CATEGORY_CONTROL_DATA_END, DATA_END_TX_COUNT);
         t38_set_redundancy_control(&s->t38_fe.t38, T38_PACKET_CATEGORY_IMAGE_DATA, DATA_TX_COUNT);
         t38_set_redundancy_control(&s->t38_fe.t38, T38_PACKET_CATEGORY_IMAGE_DATA_END, DATA_END_TX_COUNT);
-        s->t38_fe.ms_per_tx_chunk = MS_PER_TX_CHUNK;
+        s->t38_fe.us_per_tx_chunk = US_PER_TX_CHUNK;
     }
+    /*endif*/
     set_octets_per_data_packet(s, 300);
 }
 /*- End of function --------------------------------------------------------*/
@@ -2488,14 +2726,17 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
 
     if (at_tx_handler == NULL  ||  modem_control_handler == NULL)
         return NULL;
+    /*endif*/
 
     alloced = FALSE;
     if (s == NULL)
     {
         if ((s = (t31_state_t *) malloc(sizeof (*s))) == NULL)
             return NULL;
+        /*endif*/
         alloced = TRUE;
     }
+    /*endif*/
     memset(s, 0, sizeof(*s));
     span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
     span_log_set_protocol(&s->logging, "T.31");
@@ -2546,8 +2787,10 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
     {
         if (alloced)
             free(s);
+        /*endif*/
         return NULL;
     }
+    /*endif*/
     at_init(&s->at_state, at_tx_handler, at_tx_user_data, t31_modem_control_handler, s);
     at_set_class1_handler(&s->at_state, process_class1_cmd, s);
     s->at_state.dte_inactivity_timeout = DEFAULT_DTE_TIMEOUT;
@@ -2556,6 +2799,7 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
         t31_t38_fe_init(s, tx_t38_packet_handler, tx_t38_packet_user_data);
         t31_set_t38_config(s, FALSE);
     }
+    /*endif*/
     s->t38_mode = FALSE;
     return s;
 }
diff --git a/libs/spandsp/src/t38_terminal.c b/libs/spandsp/src/t38_terminal.c
index 3a300ced9e..747832cabd 100644
--- a/libs/spandsp/src/t38_terminal.c
+++ b/libs/spandsp/src/t38_terminal.c
@@ -230,6 +230,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
     /* Protect against T.38 stuff arriving after we've actually finished. */
     if (fe->current_rx_type == T30_MODEM_DONE)
         return 0;
+    /*endif*/
 
     if (t->current_rx_indicator == indicator)
     {
@@ -333,6 +334,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
     /* Protect against T.38 stuff arriving after we've actually finished. */
     if (fe->current_rx_type == T30_MODEM_DONE)
         return 0;
+    /*endif*/
 
     /* In termination mode we don't care very much what the data type is apart from a couple of
        special cases. */
@@ -608,6 +610,7 @@ static void send_hdlc(void *user_data, const uint8_t *msg, int len)
     {
         if (s->t38_fe.us_per_tx_chunk)
             s->t38_fe.hdlc_tx.extra_bits = extra_bits_in_stuffed_frame(msg, len);
+        /*endif*/
         bit_reverse(s->t38_fe.hdlc_tx.buf, msg, len);
         s->t38_fe.hdlc_tx.len = len;
         s->t38_fe.hdlc_tx.ptr = 0;
@@ -774,6 +777,7 @@ static int stream_non_ecm(t38_terminal_state_t *s)
                     fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_5;
                     if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
                         return -1;
+                    /*endif*/
                     break;
                 }
                 /*endif*/
@@ -805,6 +809,7 @@ static int stream_non_ecm(t38_terminal_state_t *s)
                 /*endif*/
                 if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
                     return -1;
+                /*endif*/
                 break;
             }
             /*endif*/
@@ -825,6 +830,10 @@ static int stream_non_ecm(t38_terminal_state_t *s)
                 fe->timed_step = fe->queued_timed_step;
                 fe->queued_timed_step = T38_TIMED_STEP_NONE;
             }
+            else
+            {
+                fe->timed_step = T38_TIMED_STEP_NONE;
+            }
             /*endif*/
             return delay;
         }
@@ -910,6 +919,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
                     fe->hdlc_tx.len = 0;
                     if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
                         return -1;
+                    /*endif*/
                     /* The above step should have got the next HDLC step ready - either another frame, or an instruction to stop transmission. */
                     if (fe->hdlc_tx.len >= 0)
                     {
@@ -941,6 +951,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
                         /*endif*/
                         if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
                             return -1;
+                        /*endif*/
                     }
                     /*endif*/
                     break;
@@ -971,6 +982,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
             fe->hdlc_tx.len = 0;
             if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
                 return -1;
+            /*endif*/
             /* The above step should have got the next HDLC step ready - either another frame, or an instruction to stop transmission. */
             if (fe->hdlc_tx.len >= 0)
             {
@@ -1006,6 +1018,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
                 /*endif*/
                 if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
                     return -1;
+                /*endif*/
             }
             /*endif*/
             break;
@@ -1018,6 +1031,10 @@ static int stream_hdlc(t38_terminal_state_t *s)
                 fe->timed_step = fe->queued_timed_step;
                 fe->queued_timed_step = T38_TIMED_STEP_NONE;
             }
+            else
+            {
+                fe->timed_step = T38_TIMED_STEP_NONE;
+            }
             /*endif*/
             return delay;
         }
@@ -1063,6 +1080,7 @@ static int stream_ced(t38_terminal_state_t *s)
             fe->timed_step = fe->queued_timed_step;
             if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
                 return -1;
+            /*endif*/
             return 0;
         }
         /*endswitch*/
diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h
index 06679f53d3..e4e8517781 100644
--- a/src/include/switch_ivr.h
+++ b/src/include/switch_ivr.h
@@ -358,7 +358,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_inband_dtmf_generate_session(swi
   \brief - NEEDDESC -
   \param session the session to act on
 */
-SWITCH_DECLARE(void) switch_ivr_session_echo(switch_core_session_t *session, switch_input_args_t *args);
+SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *session, switch_input_args_t *args);
 
 /*!
   \brief Stop looking for TONES
diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h
index 1140aac8ba..030a7e2244 100644
--- a/src/include/switch_platform.h
+++ b/src/include/switch_platform.h
@@ -265,6 +265,11 @@ typedef intptr_t switch_ssize_t;
 #endif
 #endif
 
+
+#if UINTPTR_MAX == 0xffffffffffffffff
+#define FS_64BIT 1
+#endif
+
 #endif
 
 #define SWITCH_TIME_T_FMT SWITCH_INT64_T_FMT
diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h
index 0a4ac93643..d2421fac97 100644
--- a/src/include/switch_rtp.h
+++ b/src/include/switch_rtp.h
@@ -42,6 +42,7 @@
 SWITCH_BEGIN_EXTERN_C
 #define SWITCH_RTP_MAX_BUF_LEN 16384
 #define SWITCH_RTCP_MAX_BUF_LEN 16384
+#define SWITCH_RTP_MAX_BUF_LEN_WORDS 4094 /* (max / 4) - 2 */
 #define SWITCH_RTP_MAX_CRYPTO_LEN 64
 #define SWITCH_RTP_KEY_LEN 30
 #define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32"
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index 20c83cd898..1fa34bbce2 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -736,13 +736,18 @@ typedef enum {
 
 	 */
 
-	RTP_BUG_CHANGE_SSRC_ON_MARKER = (1 << 9)
+	RTP_BUG_CHANGE_SSRC_ON_MARKER = (1 << 9),
 
 	/*
 	  By default FS will change the SSRC when the marker is set and it detects a timestamp reset.
 	  If this setting is enabled it will NOT do this (old behaviour).
 	 */
 
+	RTP_BUG_FLUSH_JB_ON_DTMF = (1 << 10)
+	
+	/* FLUSH JITTERBUFFER When getting RFC2833 to reduce bleed through */
+
+
 } switch_rtp_bug_flag_t;
 
 #ifdef _MSC_VER
@@ -762,6 +767,11 @@ typedef struct {
 	unsigned ssrc:32;			/* synchronization source */
 } switch_rtp_hdr_t;
 
+typedef struct {
+	unsigned length:16;			/* length                 */
+	unsigned profile:16;		/* defined by profile     */
+} switch_rtp_hdr_ext_t;
+
 #else /*  BIG_ENDIAN */
 
 typedef struct {
@@ -776,6 +786,11 @@ typedef struct {
 	unsigned ssrc:32;			/* synchronization source */
 } switch_rtp_hdr_t;
 
+typedef struct {
+	unsigned profile:16;		/* defined by profile     */
+	unsigned length:16;			/* length                 */
+} switch_rtp_hdr_ext_t;
+
 #endif
 
 #ifdef _MSC_VER
@@ -1972,6 +1987,19 @@ struct switch_ivr_dmachine_match {
 typedef struct switch_ivr_dmachine_match switch_ivr_dmachine_match_t;
 typedef switch_status_t (*switch_ivr_dmachine_callback_t) (switch_ivr_dmachine_match_t *match);
 
+#define MAX_ARG_RECURSION 25
+
+#define arg_recursion_check_start(_args) if (_args) {					\
+		if (_args->loops >= MAX_ARG_RECURSION) {						\
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,		\
+							  "RECURSION ERROR!  It's not the best idea to call things that collect input recursively from an input callback.\n"); \
+			return SWITCH_STATUS_GENERR;								\
+		} else {_args->loops++;}										\
+	}
+
+
+#define arg_recursion_check_stop(_args) if (_args) _args->loops--
+
 typedef struct {
 	switch_input_callback_function_t input_callback;
 	void *buf;
@@ -1979,6 +2007,7 @@ typedef struct {
 	switch_read_frame_callback_function_t read_frame_callback;
 	void *user_data;
 	switch_ivr_dmachine_t *dmachine;
+	int loops;
 } switch_input_args_t;
 
 
diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h
index c9e2c189c8..4705069728 100644
--- a/src/include/switch_utils.h
+++ b/src/include/switch_utils.h
@@ -40,7 +40,80 @@
 
 #include <switch.h>
 
-SWITCH_BEGIN_EXTERN_C SWITCH_DECLARE(int) switch_toupper(int c);
+SWITCH_BEGIN_EXTERN_C 
+
+/* https://code.google.com/p/stringencoders/wiki/PerformanceAscii */
+static inline uint32_t switch_toupper(uint32_t eax)
+{
+	uint32_t ebx = (0x7f7f7f7ful & eax) + 0x05050505ul;
+	ebx = (0x7f7f7f7ful & ebx) + 0x1a1a1a1aul;
+	ebx = ((ebx & ~eax) >> 2 ) & 0x20202020ul;
+	return eax - ebx;
+}
+
+#ifdef FS_64BIT
+
+static inline void switch_toupper_max(char *s)
+{
+	uint64_t *b,*p;
+	char *c;
+	size_t l;
+
+	l = strlen(s);
+
+	p = (uint64_t *) s;
+
+	while (l > 8) {
+		b = p;
+		*b = (uint32_t) switch_toupper(*b);
+		b++;
+		p++;
+		l -= 8;
+	}
+
+	c = (char *)p;
+
+	while(l > 0) {
+		*c = (char) switch_toupper(*c);
+		c++;
+		l--;
+	}
+
+}
+
+#else 
+
+static inline void switch_toupper_max(char *s)
+{
+	uint32_t *b,*p;
+	char *c;
+	size_t l;
+
+	l = strlen(s);
+
+	p = (uint32_t *) s;
+
+	while (l > 4) {
+		b = p;
+		*b = (uint32_t) switch_toupper(*b);
+		b++;
+		p++;
+		l -= 4;
+	}
+
+	c = (char *)p;
+
+	while(l > 0) {
+		*c = (char) switch_toupper(*c);
+		c++;
+		l--;
+	}
+	
+}
+#endif
+
+
+SWITCH_DECLARE(int) old_switch_toupper(int c);
 SWITCH_DECLARE(int) switch_tolower(int c);
 SWITCH_DECLARE(int) switch_isalnum(int c);
 SWITCH_DECLARE(int) switch_isalpha(int c);
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index 2f5456106f..3cfa13b625 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -3680,7 +3680,6 @@ static void conference_loop_output(conference_member_t *member)
 						member_add_file_data(member, write_frame.data, write_frame.datalen);
 					}
 					if (switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
-						switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 						switch_mutex_unlock(member->audio_out_mutex);
 						break;
 					}
@@ -5233,10 +5232,16 @@ static switch_status_t conf_api_sub_enforce_floor(conference_member_t *member, s
 
 static switch_xml_t add_x_tag(switch_xml_t x_member, const char *name, const char *value, int off)
 {
-	switch_size_t dlen = strlen(value) * 3 + 1;
+	switch_size_t dlen;
 	char *data;
 	switch_xml_t x_tag;
 
+	if (!value) {
+		return 0;
+	}
+
+	dlen = strlen(value) * 3 + 1;
+
 	x_tag = switch_xml_add_child_d(x_member, name, off);
 	switch_assert(x_tag);
 
diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c
index 9c1f9310d1..ae82ffbbc5 100644
--- a/src/mod/applications/mod_db/mod_db.c
+++ b/src/mod/applications/mod_db/mod_db.c
@@ -24,7 +24,7 @@
  * Contributor(s):
  * 
  * Anthony Minessale II <anthm@freeswitch.org>
- * Ken Rice <krice at suspicious dot org
+ * Ken Rice <krice@freeswitch.org>
  * Mathieu Rene <mathieu.rene@gmail.com>
  * Bret McDanel <trixter AT 0xdecafbad.com>
  * Rupa Schomaker <rupa@rupa.com>
diff --git a/src/mod/applications/mod_easyroute/mod_easyroute.c b/src/mod/applications/mod_easyroute/mod_easyroute.c
index 217d8fc45c..263c9569ac 100644
--- a/src/mod/applications/mod_easyroute/mod_easyroute.c
+++ b/src/mod/applications/mod_easyroute/mod_easyroute.c
@@ -20,13 +20,13 @@
  * Anthony Minessale II <anthm@freeswitch.org>
  *
  * The Initial Developer of this module is
- * Ken Rice <krice at rmktek dot com>
+ * Ken Rice <krice@freeswitch.org>
  *
  * Portions created by the Initial Developer are Copyright (C)
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
- * Ken Rice <krice at rmktek dot com>
+ * Ken Rice <krice@freeswitch.org>
  *
  * mod_easyroute.c -- EasyRoute
  * Take Incoming DIDs and Lookup where to send them as well as retrieve
diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c
index c05c02ed85..a1f5d59ce8 100644
--- a/src/mod/applications/mod_fifo/mod_fifo.c
+++ b/src/mod/applications/mod_fifo/mod_fifo.c
@@ -2217,7 +2217,7 @@ SWITCH_STANDARD_APP(fifo_track_call_function)
 
 	sql = switch_mprintf("update fifo_outbound set stop_time=0,start_time=%ld,outbound_fail_count=0,use_count=use_count+1,%s=%s+1,%s=%s+1 where uuid='%q'",
 						 (long) switch_epoch_time_now(NULL), col1, col1, col2, col2, data);
-	fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE);
+	fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE);
 
 
 	if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_modem.c b/src/mod/applications/mod_spandsp/mod_spandsp_modem.c
index eb54c217aa..8e1c925b8b 100644
--- a/src/mod/applications/mod_spandsp/mod_spandsp_modem.c
+++ b/src/mod/applications/mod_spandsp/mod_spandsp_modem.c
@@ -56,8 +56,8 @@ struct modem_state {
 
 static struct modem_state MODEM_STATE[] = {
 	{MODEM_STATE_INIT, "INIT"},
-	{MODEM_STATE_ONHOOK,	"ONHOOK"},
-	{MODEM_STATE_OFFHOOK,  "OFFHOOK"},
+	{MODEM_STATE_ONHOOK, "ONHOOK"},
+	{MODEM_STATE_OFFHOOK, "OFFHOOK"},
 	{MODEM_STATE_ACQUIRED, "ACQUIRED"},
 	{MODEM_STATE_RINGING, "RINGING"},
 	{MODEM_STATE_ANSWERED, "ANSWERED"},
@@ -214,9 +214,10 @@ switch_status_t modem_init(modem_t *modem, modem_control_handler_t control_handl
 {
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
 #ifdef WIN32
-	COMMTIMEOUTS timeouts={0};
+	COMMTIMEOUTS timeouts = {0};
 #endif
-	
+    logging_state_t *logging;
+
 	memset(modem, 0, sizeof(*modem));
 
 	modem->master = -1;
@@ -229,17 +230,15 @@ switch_status_t modem_init(modem_t *modem, modem_control_handler_t control_handl
 
 #if USE_OPENPTY
 	if (openpty(&modem->master, &modem->slave, NULL, NULL, NULL)) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to initialize pty\n");
+        status = SWITCH_STATUS_FALSE;
+        goto end;	
+    } 
 
-		if (modem->master < 0) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to initialize pty\n");
-			status = SWITCH_STATUS_FALSE;
-			goto end;
-		}
-
-		modem->stty = ttyname(modem->slave);
-	}
+    modem->stty = ttyname(modem->slave);
+	
 #else
-#if WIN32
+#ifdef WIN32
 	modem->slot = 4+globals.NEXT_ID++; /* need work here we start at COM4 for now*/
 	snprintf(modem->devlink, sizeof(modem->devlink), "COM%d", modem->slot);
 
@@ -250,9 +249,9 @@ switch_status_t modem_init(modem_t *modem, modem_control_handler_t control_handl
 					OPEN_EXISTING,
 					FILE_FLAG_OVERLAPPED,
 					0);
-	if(modem->master==INVALID_HANDLE_VALUE) {
+	if (modem->master == INVALID_HANDLE_VALUE) {
 		status = SWITCH_STATUS_FALSE;
-		if(GetLastError()==ERROR_FILE_NOT_FOUND) {
+		if (GetLastError() == ERROR_FILE_NOT_FOUND) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: Serial port does not exist\n");
 			goto end;
 		}
@@ -321,16 +320,16 @@ switch_status_t modem_init(modem_t *modem, modem_control_handler_t control_handl
 		goto end;
 	}
 #else
-	timeouts.ReadIntervalTimeout=50;
-	timeouts.ReadTotalTimeoutConstant=50;
-	timeouts.ReadTotalTimeoutMultiplier=10;
+	timeouts.ReadIntervalTimeout = 50;
+	timeouts.ReadTotalTimeoutConstant = 50;
+	timeouts.ReadTotalTimeoutMultiplier = 10;
 
-	timeouts.WriteTotalTimeoutConstant=50;
-	timeouts.WriteTotalTimeoutMultiplier=10;
+	timeouts.WriteTotalTimeoutConstant = 50;
+	timeouts.WriteTotalTimeoutMultiplier = 10;
 
 	SetCommMask(modem->master, EV_RXCHAR);
 
-	if(!SetCommTimeouts(modem->master, &timeouts)){
+	if (!SetCommTimeouts(modem->master, &timeouts)){
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot set up non-blocking read on %s\n", modem->devlink);
 		modem_close(modem);
 		status = SWITCH_STATUS_FALSE;
@@ -347,15 +346,21 @@ switch_status_t modem_init(modem_t *modem, modem_control_handler_t control_handl
 	}
 
 	if (spandsp_globals.modem_verbose) {
-		span_log_set_message_handler(&modem->t31_state->logging, spanfax_log_message, NULL);
-		span_log_set_message_handler(&modem->t31_state->audio.modems.fast_modems.v17_rx.logging, spanfax_log_message, NULL);
-		span_log_set_message_handler(&modem->t31_state->audio.modems.fast_modems.v29_rx.logging, spanfax_log_message, NULL);
-		span_log_set_message_handler(&modem->t31_state->audio.modems.fast_modems.v27ter_rx.logging, spanfax_log_message, NULL);
+        logging = t31_get_logging_state(modem->t31_state);
+		span_log_set_message_handler(logging, spanfax_log_message, NULL);
+		span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
 
-		modem->t31_state->logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW;
-		modem->t31_state->audio.modems.fast_modems.v17_rx.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW;
-		modem->t31_state->audio.modems.fast_modems.v29_rx.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW;
-		modem->t31_state->audio.modems.fast_modems.v27ter_rx.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW;
+        logging = v17_rx_get_logging_state(&modem->t31_state->audio.modems.fast_modems.v17_rx);
+		span_log_set_message_handler(logging, spanfax_log_message, NULL);
+		span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
+
+        logging = v29_rx_get_logging_state(&modem->t31_state->audio.modems.fast_modems.v29_rx);
+		span_log_set_message_handler(logging, spanfax_log_message, NULL);
+		span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
+
+        logging = v27ter_rx_get_logging_state(&modem->t31_state->audio.modems.fast_modems.v27ter_rx);
+		span_log_set_message_handler(logging, spanfax_log_message, NULL);
+		span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
 	}
 
 	modem->control_handler = control_handler;
@@ -1311,8 +1316,8 @@ static void *SWITCH_THREAD_FUNC modem_thread(switch_thread_t *thread, void *obj)
 			if (!strncasecmp(buf, "AT", 2)) {
 				int x;
 				strncpy(tmp, buf, r);
-				for(x = 0; x < r; x++) {
-					if(tmp[x] == '\r' || tmp[x] == '\n') {
+				for (x = 0; x < r; x++) {
+					if (tmp[x] == '\r' || tmp[x] == '\n') {
 						tmp[x] = '\0';
 					}
 				}
diff --git a/src/mod/codecs/mod_opus/Makefile b/src/mod/codecs/mod_opus/Makefile
index aefffbd061..9d344fb016 100644
--- a/src/mod/codecs/mod_opus/Makefile
+++ b/src/mod/codecs/mod_opus/Makefile
@@ -1,6 +1,6 @@
 BASE=../../../..
 
-OPUS=opus-1.0.1
+OPUS=opus-1.0.2
 
 OPUS_DIR=$(switch_srcdir)/libs/$(OPUS)
 OPUS_BUILDDIR=$(switch_builddir)/libs/$(OPUS)
diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
index ac1500c4f5..c0fe707fd0 100644
--- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
+++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
@@ -79,6 +79,9 @@ static switch_status_t exec_app(switch_core_session_t *session, const char *app,
 	return status;
 }
 
+#define MAX_RECUR 100
+#define RECUR_SPACE 4
+#define MAX_RECUR_SPACE 100 * RECUR_SPACE
 
 #define check_tz() tzoff = switch_channel_get_variable(channel, "tod_tz_offset"); \
 	tzname = switch_channel_get_variable(channel, "timezone");			\
@@ -91,24 +94,70 @@ static switch_status_t exec_app(switch_core_session_t *session, const char *app,
 		break;															\
 	} while(tzoff)														
 		
-static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t xexten, switch_caller_extension_t **extension)
+static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t xexten, 
+					   switch_caller_extension_t **extension, const char *exten_name, int recur)
 {
 	switch_xml_t xcond, xaction, xexpression, xregex;
 	switch_channel_t *channel = switch_core_session_get_channel(session);
-	char *exten_name = (char *) switch_xml_attr(xexten, "name");
 	int proceed = 0, save_proceed = 0;
 	char *expression_expanded = NULL, *field_expanded = NULL;
 	switch_regex_t *re = NULL, *save_re = NULL;
 	int offset = 0;
-	const char *tzoff = NULL, *tzname = NULL;
+	const char *tmp, *tzoff = NULL, *tzname = NULL, *req_nesta = NULL;
+	char nbuf[128] = "";
+	int req_nest = 1;
+	char space[MAX_RECUR_SPACE] = "";
+	const char *orig_exten_name = exten_name;
 
 	check_tz();
 
-
 	if (!exten_name) {
 		exten_name = "_anon_";
 	}
 
+	if (!orig_exten_name) {
+		orig_exten_name = "_anon_";
+	}
+
+
+	if (recur) {
+		int i, j = 0, k = 0;
+
+		if (recur > MAX_RECUR) {
+			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Recursion LIMIT!\n");
+			return 0;
+		}
+
+		switch_snprintf(nbuf, sizeof(nbuf), "%s_recur_%d", exten_name, recur);
+		exten_name = nbuf;
+		
+		space[j++] = '|';
+
+		for (i = 0; i < recur; i++) {
+			for (k = 0; k < RECUR_SPACE; k++) {
+				if (i == recur-1 && k == RECUR_SPACE-1) {
+					space[j++] = ' ';
+				} else {
+					space[j++] = '-';
+				}
+			}
+		}
+		
+		if ((req_nesta = switch_xml_attr(xexten, "require-nested"))) {
+			req_nest = switch_true(req_nesta);
+		}
+
+		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, 
+						  "%sDialplan: Processing recursive conditions level:%d [%s] require-nested=%s\n", space,
+						  recur, exten_name, req_nest ? "TRUE" : "FALSE");
+
+	} else {
+		if ((tmp = switch_xml_attr(xexten, "name"))) {
+			exten_name = tmp;
+		}
+	}
+
+
 	for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) {
 		char *field = NULL;
 		char *do_break_a = NULL;
@@ -123,16 +172,9 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 		check_tz();
 		time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL, tzname);
 
-
 		switch_safe_free(field_expanded);
 		switch_safe_free(expression_expanded);
 
-		if (switch_xml_child(xcond, "condition")) {
-			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Nested conditions are not allowed!\n");
-			proceed = 1;
-			goto done;
-		}
-
 		field = (char *) switch_xml_attr(xcond, "field");
 
 
@@ -150,15 +192,25 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 			}
 		}
 
+
+		if (switch_xml_child(xcond, "condition")) {
+			if (!(proceed = parse_exten(session, caller_profile, xcond, extension, orig_exten_name, recur + 1))) {
+				if (do_break_i == BREAK_NEVER) {
+					continue;
+				}
+				goto done;
+			}
+		}
+		
 		if (time_match == 1) {
 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-							  "Dialplan: %s Date/Time Match (PASS) [%s] break=%s\n",
+							  "%sDialplan: %s Date/Time Match (PASS) [%s] break=%s\n", space,
 							  switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
 			anti_action = SWITCH_FALSE;
 			proceed = 1;
 		} else if (time_match == 0) {
 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-							  "Dialplan: %s Date/TimeMatch (FAIL) [%s] break=%s\n",
+							  "%sDialplan: %s Date/TimeMatch (FAIL) [%s] break=%s\n", space,
 							  switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
 		}
 		
@@ -178,12 +230,12 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 				
 				if (time_match == 1) {
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-									  "Dialplan: %s Date/Time Match (PASS) [%s]\n",
+									  "%sDialplan: %s Date/Time Match (PASS) [%s]\n", space,
 									  switch_channel_get_name(channel), exten_name);
 					anti_action = SWITCH_FALSE;
 				} else if (time_match == 0) {
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-									  "Dialplan: %s Date/TimeMatch (FAIL) [%s]\n",
+									  "%sDialplan: %s Date/TimeMatch (FAIL) [%s]\n", space,
 									  switch_channel_get_name(channel), exten_name);
 				}
 
@@ -221,20 +273,21 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 					
 					if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
 						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-										  "Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ match=%s\n",
+										  "%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ match=%s\n", space,
 										  switch_channel_get_name(channel), exten_name, field, field_data, expression, all ? "all" : "any");
 						pass++;
 						if (!all && !xor) break;
 					} else {
 						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-										  "Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ match=%s\n",
+										  "%sDialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ match=%s\n", space,
 										  switch_channel_get_name(channel), exten_name, field, field_data, expression, all ? "all" : "any");
 						fail++;
 						if (all && !xor) break;
 					}
 				} else if (time_match == -1) {
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-									  "Dialplan: %s Absolute Condition [%s] match=%s\n", switch_channel_get_name(channel), exten_name, all ? "all" : "any");
+									  "%sDialplan: %s Absolute Condition [%s] match=%s\n", space,
+									  switch_channel_get_name(channel), exten_name, all ? "all" : "any");
 					pass++;
 					proceed = 1;
 					if (!all && !xor) break;
@@ -314,17 +367,18 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 
 				if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-									  "Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
+									  "%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n", space,
 									  switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
 					anti_action = SWITCH_FALSE;
 				} else {
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-									  "Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
+									  "%sDialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n", space,
 									  switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
 				}
 			} else if (time_match == -1) {
 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-								  "Dialplan: %s Absolute Condition [%s]\n", switch_channel_get_name(channel), exten_name);
+								  "%sDialplan: %s Absolute Condition [%s]\n", space,
+								  switch_channel_get_name(channel), exten_name);
 				anti_action = SWITCH_FALSE;
 				proceed = 1;
 			}
@@ -373,7 +427,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 
 				for (;loop_count > 0; loop_count--) {
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-							"Dialplan: %s ANTI-Action %s(%s) %s\n", switch_channel_get_name(channel), application, data, xinline ? "INLINE" : "");
+									  "%sDialplan: %s ANTI-Action %s(%s) %s\n", space,
+									  switch_channel_get_name(channel), application, data, xinline ? "INLINE" : "");
 
 					if (xinline) {
 						exec_app(session, application, data);
@@ -433,7 +488,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 				}
 				for (;loop_count > 0; loop_count--) {
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-							"Dialplan: %s Action %s(%s) %s\n", switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : "");
+									  "%sDialplan: %s Action %s(%s) %s\n", space,
+									  switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : "");
 
 					if (xinline) {
 						exec_app(session, application, app_data);
@@ -456,6 +512,9 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 	switch_regex_safe_free(re);
 	switch_safe_free(field_expanded);
 	switch_safe_free(expression_expanded);
+
+	if (!req_nest) proceed = 1;
+
 	return proceed;
 }
 
@@ -551,7 +610,7 @@ SWITCH_STANDARD_DIALPLAN(dialplan_hunt)
 						  "Dialplan: %s parsing [%s->%s] continue=%s\n",
 						  switch_channel_get_name(channel), caller_profile->context, exten_name, cont ? cont : "false");
 
-		proceed = parse_exten(session, caller_profile, xexten, &extension);
+		proceed = parse_exten(session, caller_profile, xexten, &extension, exten_name, 0);
 
 		if (proceed && !switch_true(cont)) {
 			break;
diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c
index da0cbdeb02..e2eed57842 100644
--- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c
+++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c
@@ -1871,16 +1871,16 @@ static switch_status_t negotiate_media(switch_core_session_t *session)
 	}
 
 	if (switch_channel_down(channel) || switch_test_flag(tech_pvt, TFLAG_BYE)) {
-		goto out;
+		goto done;
 	}
 
 	if (!activate_rtp(tech_pvt)) {
-		goto out;
+		goto done;
 	}
 
 	if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
 		if (!do_candidates(tech_pvt, 0)) {
-			goto out;
+			goto done;
 		}
 		if (switch_test_flag(tech_pvt, TFLAG_TRANSPORT_ACCEPT)) {
 			switch_channel_answer(channel);
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 73c50565fe..c75fdce179 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -1567,15 +1567,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 			de->session = session;
 		}
 
-		if (de->data->e_event == nua_i_cancel || de->data->e_event == nua_i_bye) {
-			sofia_set_flag(tech_pvt, TFLAG_SIGDEAD);
-		}
+		sofia_process_dispatch_event(&de);
 
-		if (!sofia_test_flag(tech_pvt, TFLAG_SIGDEAD) && (switch_channel_media_up(channel) || switch_channel_get_state(channel) > CS_ROUTING)) {
-			sofia_queue_message(de);
-		} else {
-			sofia_process_dispatch_event(&de);
-		}
 
 		switch_mutex_unlock(tech_pvt->sofia_mutex);
 		goto end;
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 146ef4fd44..82c68516fb 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -353,7 +353,6 @@ typedef enum {
 	TFLAG_PASS_ACK,
 	TFLAG_CRYPTO_RECOVER,
 	TFLAG_DROP_DTMF,
-	TFLAG_SIGDEAD,
 	/* No new flags below this line */
 	TFLAG_MAX
 } TFLAGS;
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 161d245ea5..ac78cbc749 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -2481,6 +2481,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
 		for (via = vias; via; via = via->v_next) {
 			if (sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT) && !strcmp(via->v_protocol, "SIP/2.0/UDP")) {
 				profile->sip_port = atoi(via->v_port);
+				if (!profile->extsipport) profile->extsipport = profile->sip_port;
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found auto sip port %d for %s\n", profile->sip_port, profile->name);
 			}
 
@@ -3212,14 +3213,14 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
 					gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
 							sipip,
 							sofia_glue_transport_has_tls(gateway->register_transport) ?
-							profile->tls_sip_port : profile->sip_port, params, str_rfc_5626);
+							profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
 
 				} else {
 					format = strchr(sipip, ':') ? "<sip:%s@[%s]:%d%s>" : "<sip:%s@%s:%d%s>";
 					gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
 							sipip,
 							sofia_glue_transport_has_tls(gateway->register_transport) ?
-							profile->tls_sip_port : profile->sip_port, params);
+							profile->tls_sip_port : profile->extsipport, params);
 				}
 			} else {
 				if (rfc_5626) {
@@ -3227,14 +3228,14 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
 					gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
 							sipip,
 							sofia_glue_transport_has_tls(gateway->register_transport) ?
-							profile->tls_sip_port : profile->sip_port, params, str_rfc_5626);
+							profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
 
 				} else {
 					format = strchr(sipip, ':') ? "<sip:gw+%s@[%s]:%d%s>" : "<sip:gw+%s@%s:%d%s>";
 					gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
 							sipip,
 							sofia_glue_transport_has_tls(gateway->register_transport) ?
-							profile->tls_sip_port : profile->sip_port, params);
+							profile->tls_sip_port : profile->extsipport, params);
 
 				}
 			}
@@ -3301,14 +3302,14 @@ static void config_sofia_profile_urls(sofia_profile_t * profile)
 		profile->public_url = switch_core_sprintf(profile->pool,
 												  "sip:%s@%s%s%s:%d",
 												  profile->contact_user,
-												  ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->sip_port);
+												  ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
 	}
 
 	if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
 		char *ipv6 = strchr(profile->extsipip, ':');
 		profile->url = switch_core_sprintf(profile->pool,
 										   "sip:%s@%s%s%s:%d",
-										   profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->sip_port);
+										   profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
 		profile->bindurl = switch_core_sprintf(profile->pool, "%s;maddr=%s", profile->url, profile->sipip);
 	} else {
 		char *ipv6 = strchr(profile->sipip, ':');
@@ -3922,6 +3923,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
 							sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_PORT);
 						} else {
 							profile->sip_port = (switch_port_t) atoi(val);
+							if (!profile->extsipport) profile->extsipport = profile->sip_port;
 						}
 					} else if (!strcasecmp(var, "vad")) {
 						if (!strcasecmp(val, "in")) {
@@ -4000,10 +4002,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
 							} else if (!strcasecmp(val, "auto-nat")) {
 								ip = NULL;
 							} else if (strcasecmp(val, "auto")) {
-								if (!profile->extsipport) {
-									profile->extsipport = profile->sip_port;
-								}
-
 								if (sofia_glue_ext_address_lookup(profile, NULL, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
 									ip = myip;
 									sofia_clear_pflag(profile, PFLAG_AUTO_NAT);
@@ -4547,6 +4545,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
 
 				if (!profile->sip_port && !sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)) {
 					profile->sip_port = (switch_port_t) atoi(SOFIA_DEFAULT_PORT);
+					if (!profile->extsipport) profile->extsipport = profile->sip_port;
 				}
 
 				if (!profile->dialplan) {
@@ -4667,10 +4666,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
 					}
 
 					if (profile->sipip) {
-
-						if (!profile->extsipport) {
-							profile->extsipport = profile->sip_port;
-						}
+						if (!profile->extsipport) profile->extsipport = profile->sip_port;
 
 						launch_sofia_profile_thread(profile);
 						if (profile->odbc_dsn) {
@@ -7999,7 +7995,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 			if (sip->sip_contact->m_url->url_port) {
 				port = atoi(sip->sip_contact->m_url->url_port);
 			} else {
-				port = sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->sip_port;
+				port = sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->extsipport;
 			}
 
 			ipv6 = strchr(host, ':');
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index d24b3182c1..b47a0edbe2 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -2318,7 +2318,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
 																		   ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->tls_sip_port);
 				} else {
 					tech_pvt->invite_contact = switch_core_session_sprintf(session, "sip:%s@%s%s%s:%d", contact,
-																		   ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->sip_port);
+																		   ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->extsipport);
 				}
 			} else {
 				if (sofia_glue_transport_has_tls(tech_pvt->transport)) {
@@ -3254,12 +3254,15 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
 	}
 
 
-	if (!sofia_test_flag(tech_pvt, TFLAG_REINVITE) && !sofia_test_flag(tech_pvt, TFLAG_SDP) && switch_rtp_ready(tech_pvt->rtp_session)) {
-		if (sofia_test_flag(tech_pvt, TFLAG_VIDEO) && !switch_rtp_ready(tech_pvt->video_rtp_session)) {
-			goto video;
-		} else {
+	if (!sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
+		if (switch_rtp_ready(tech_pvt->rtp_session)) {
+			if (sofia_test_flag(tech_pvt, TFLAG_VIDEO) && !switch_rtp_ready(tech_pvt->video_rtp_session)) {
+				goto video;
+			}
+
+			status = SWITCH_STATUS_SUCCESS;
 			goto end;
-		}
+		} 
 	}
 
 	if ((status = sofia_glue_tech_set_codec(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
@@ -4391,7 +4394,7 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_
 
 		// set some default value
 		t38_options->T38FaxVersion = 0;
-		t38_options->T38MaxBitRate = 9600;
+		t38_options->T38MaxBitRate = 14400;
 		t38_options->T38FaxRateManagement = switch_core_session_strdup(tech_pvt->session, "transferredTCF");
 		t38_options->T38FaxUdpEC = switch_core_session_strdup(tech_pvt->session, "t38UDPRedundancy");
 		t38_options->T38FaxMaxBuffer = 500;
@@ -6972,6 +6975,14 @@ void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str
 	if (switch_stristr("~CHANGE_SSRC_ON_MARKER", str)) {
 		*flag_pole &= ~RTP_BUG_CHANGE_SSRC_ON_MARKER;
 	}
+
+	if (switch_stristr("FLUSH_JB_ON_DTMF", str)) {
+		*flag_pole |= RTP_BUG_FLUSH_JB_ON_DTMF;
+	}
+
+	if (switch_stristr("~FLUSH_JB_ON_DTMF", str)) {
+		*flag_pole &= ~RTP_BUG_FLUSH_JB_ON_DTMF;
+	}
 }
 
 char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np)
diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c
index f3d3bb205b..c0b81d3573 100644
--- a/src/mod/endpoints/mod_sofia/sofia_reg.c
+++ b/src/mod/endpoints/mod_sofia/sofia_reg.c
@@ -312,6 +312,8 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
 				if (gateway_ptr->ib_vars) {
 					switch_event_destroy(&gateway_ptr->ib_vars);
 				}
+			} else {
+				last = gateway_ptr;
 			}
 		} else {
 			last = gateway_ptr;
@@ -1612,12 +1614,12 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
 					agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm, 
 								 mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host);
 		} else {
-			sql = switch_mprintf("update sip_registrations set "
+			sql = switch_mprintf("update sip_registrations set call_id='%q',"
 								 "sub_host='%q', network_ip='%q',network_port='%q',"
 								 "presence_hosts='%q', server_host='%q', orig_server_host='%q',"
-                                                                 "hostname='%q', orig_hostname='%q',"
+								 "hostname='%q', orig_hostname='%q',"
 								 "expires = %ld where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'", 
-								 sub_host, network_ip, network_port_c,
+								 call_id, sub_host, network_ip, network_port_c,
 								 profile->presence_hosts ? profile->presence_hosts : "", guess_ip4, guess_ip4,
                                                                  mod_sofia_globals.hostname, mod_sofia_globals.hostname,
 								 (long) reg_time + (long) exptime + 60, 
diff --git a/src/switch_apr.c b/src/switch_apr.c
index d4db415280..aeb10185a9 100644
--- a/src/switch_apr.c
+++ b/src/switch_apr.c
@@ -1050,13 +1050,7 @@ SWITCH_DECLARE(unsigned int) switch_queue_size(switch_queue_t *queue)
 
 SWITCH_DECLARE(switch_status_t) switch_queue_pop(switch_queue_t *queue, void **data)
 {
-	apr_status_t s;
-
-	do {
-		s = apr_queue_pop(queue, data);
-	} while (s == APR_EINTR);
-
-	return s;
+	return apr_queue_pop(queue, data);
 }
 
 SWITCH_DECLARE(switch_status_t) switch_queue_pop_timeout(switch_queue_t *queue, void **data, switch_interval_time_t timeout)
@@ -1078,14 +1072,7 @@ SWITCH_DECLARE(switch_status_t) switch_queue_push(switch_queue_t *queue, void *d
 
 SWITCH_DECLARE(switch_status_t) switch_queue_trypop(switch_queue_t *queue, void **data)
 {
-	apr_status_t s;
-
-	do {
-		s = apr_queue_trypop(queue, data);
-	} while (s == APR_EINTR);
-
-	return s;
-	
+	return apr_queue_trypop(queue, data);
 }
 
 SWITCH_DECLARE(switch_status_t) switch_queue_interrupt_all(switch_queue_t *queue)
diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c
index 1a529501ad..f2529af174 100644
--- a/src/switch_core_codec.c
+++ b/src/switch_core_codec.c
@@ -756,8 +756,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_decode(switch_codec_t *codec,
 	switch_assert(decoded_data != NULL);
 
 	if (!codec->implementation || !switch_core_codec_ready(codec)) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec is not initialized!\n");
-		abort();
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decode Codec is not initialized!\n");
 		return SWITCH_STATUS_NOT_INITALIZED;
 	}
 
diff --git a/src/switch_core_io.c b/src/switch_core_io.c
index 8e99fcd472..72345d6a04 100644
--- a/src/switch_core_io.c
+++ b/src/switch_core_io.c
@@ -151,10 +151,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 	
 	for(i = 0; i < 2; i++) {
 		if (session->dmachine[i] && !switch_channel_test_flag(session->channel, CF_BROADCAST)) {
-			if (switch_channel_try_dtmf_lock(session->channel) == SWITCH_STATUS_SUCCESS) {
-				switch_ivr_dmachine_ping(session->dmachine[i], NULL);
-				switch_channel_dtmf_unlock(session->channel);
-			}
+			switch_ivr_dmachine_ping(session->dmachine[i], NULL);
 		}
 	}
 	
@@ -354,12 +351,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 						goto done;
 					}
 
-					if (!switch_core_codec_ready(&session->bug_codec)) {
+					if (!switch_core_codec_ready(&session->bug_codec) && switch_core_codec_ready(read_frame->codec)) {
 						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting BUG Codec %s:%d\n",
-							read_frame->codec->implementation->iananame, read_frame->codec->implementation->ianacode);
+										  read_frame->codec->implementation->iananame, read_frame->codec->implementation->ianacode);
 						switch_core_codec_copy(read_frame->codec, &session->bug_codec, NULL);
+						if (!switch_core_codec_ready(&session->bug_codec)) {
+							switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Error setting BUG codec %s!\n", 
+											  switch_core_session_get_name(session), read_frame->codec->implementation->iananame);
+						}
+					}
+
+					if (switch_core_codec_ready(&session->bug_codec)) {
+						use_codec = &session->bug_codec;
 					}
-					use_codec = &session->bug_codec;
 					switch_thread_rwlock_unlock(session->bug_rwlock);
 
 					switch_thread_rwlock_wrlock(session->bug_rwlock);
@@ -376,7 +380,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 					memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen);
 					status = SWITCH_STATUS_SUCCESS;
 				} else {
-					switch_codec_t *codec = use_codec->implementation?use_codec:read_frame->codec;
+					switch_codec_t *codec = use_codec;
+
+					if (!switch_core_codec_ready(codec)) {
+						codec = read_frame->codec;
+					}
+
 					switch_thread_rwlock_rdlock(session->bug_rwlock);
 					codec->cur_frame = read_frame;
 					session->read_codec->cur_frame = read_frame;
diff --git a/src/switch_core_session.c b/src/switch_core_session.c
index 74dae6e68a..3a2c08bcc3 100644
--- a/src/switch_core_session.c
+++ b/src/switch_core_session.c
@@ -1667,16 +1667,7 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_manager(switch_t
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, 
 								  "Thread pool: running:%d busy:%d popping:%d\n", session_manager.running, session_manager.busy, session_manager.popping);
 
-				if (session_manager.popping) {
-					int i = 0;
-
-					switch_mutex_lock(session_manager.mutex);
-					for (i = 0; i < session_manager.popping; i++) {
-						switch_queue_trypush(session_manager.thread_queue, NULL);
-					}
-					switch_mutex_unlock(session_manager.mutex);
-
-				}
+				switch_queue_interrupt_all(session_manager.thread_queue);
 
 				x--;
 
@@ -1690,7 +1681,7 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_manager(switch_t
 	}
 
 	while(session_manager.running) {
-		switch_queue_trypush(session_manager.thread_queue, NULL);
+		switch_queue_interrupt_all(session_manager.thread_queue);
 		switch_yield(20000);
 	}
 
diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c
index 3860af15d4..802ce6b28a 100644
--- a/src/switch_core_sqldb.c
+++ b/src/switch_core_sqldb.c
@@ -1261,6 +1261,7 @@ struct switch_sql_queue_manager {
 	char *inner_post_trans_execute;
 	switch_memory_pool_t *pool;
 	uint32_t max_trans;
+	uint32_t confirm;
 };
 
 static int qm_wake(switch_sql_queue_manager_t *qm)
@@ -1431,6 +1432,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql
 	}
 
 	switch_mutex_lock(qm->mutex);
+	qm->confirm++;
 	switch_queue_push(qm->sql_queue[pos], dup ? strdup(sql) : (char *)sql);
 	written = qm->pre_written[pos];
 	size = switch_sql_queue_manager_size(qm, pos);
@@ -1451,6 +1453,10 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql
 		}
 	}
 
+	switch_mutex_lock(qm->mutex);
+	qm->confirm--;
+	switch_mutex_unlock(qm->mutex);
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -1733,11 +1739,13 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread,
 			switch_thread_cond_wait(qm->cond, qm->cond_mutex);
 		}
 
-		i = 4;
+		i = 40;
 
-		while (--i > 0 && (lc = qm_ttl(qm)) < qm->max_trans / 4) {
-			switch_yield(50000);
+		while (--i > 0 && (lc = qm_ttl(qm)) < qm->max_trans / 4 && !qm->confirm) {
+			switch_yield(5000);
 		}
+
+
 	}
 
 	switch_mutex_unlock(qm->cond_mutex);
diff --git a/src/switch_event.c b/src/switch_event.c
index 32bc5b2d2d..b93f8746ad 100644
--- a/src/switch_event.c
+++ b/src/switch_event.c
@@ -766,13 +766,13 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header_val(switch_event_t *even
 	unsigned long hash = 0;
 
 	tp = event->headers;
+	hash = switch_ci_hashfunc_default(header_name, &hlen);
 	while (tp) {
 		hp = tp;
 		tp = tp->next;
 
 		x++;
 		switch_assert(x < 1000000);
-		hash = switch_ci_hashfunc_default(header_name, &hlen);
 
 		if ((!hp->hash || hash == hp->hash) && !strcasecmp(header_name, hp->name) && (zstr(val) || !strcmp(hp->value, val))) {
 			if (lp) {
diff --git a/src/switch_ivr.c b/src/switch_ivr.c
index 6aa5166634..42bd11b802 100644
--- a/src/switch_ivr.c
+++ b/src/switch_ivr.c
@@ -141,6 +141,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
 	int sval = 0;
 	const char *var;
 
+	arg_recursion_check_start(args);
+
 	/*
 	   if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_PROXY_MODE) && 
 	   !switch_channel_media_ready(channel) && !switch_channel_test_flag(channel, CF_SERVICE)) {
@@ -156,12 +158,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
 		for (elapsed=0; switch_channel_up(channel) && elapsed<(ms/20); elapsed++) {
 			if (switch_channel_test_flag(channel, CF_BREAK)) {
 				switch_channel_clear_flag(channel, CF_BREAK);
-				return SWITCH_STATUS_BREAK;
+				switch_goto_status(SWITCH_STATUS_BREAK, end);
 			}
 		
 			switch_yield(20 * 1000);
 		}
-		return SWITCH_STATUS_SUCCESS;
+		switch_goto_status(SWITCH_STATUS_SUCCESS, end);
 	}
 
 	var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE);
@@ -183,7 +185,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
 								   switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
 							  imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
-			return SWITCH_STATUS_FALSE;
+			switch_goto_status(SWITCH_STATUS_FALSE, end);
 		}
 
 
@@ -213,7 +215,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
 	}
 
 	if (!ms) {
-		return SWITCH_STATUS_SUCCESS;
+		switch_goto_status(SWITCH_STATUS_SUCCESS, end);
 	}
 
 	for (;;) {
@@ -303,6 +305,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
 		}
 	}
 
+
+ end:
+
+	arg_recursion_check_stop(args);
+
 	if (write_frame.codec) {
 		switch_core_codec_destroy(&codec);
 	}
@@ -874,6 +881,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
 	unsigned char *abuf = NULL;
 	switch_codec_implementation_t imp = { 0 };
 
+
+
 	if (switch_channel_test_flag(channel, CF_RECOVERED) && switch_channel_test_flag(channel, CF_CONTROLLED)) {
 		switch_channel_clear_flag(channel, CF_CONTROLLED);
 	}
@@ -887,6 +896,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
 		return SWITCH_STATUS_FALSE;
 	}
 
+	arg_recursion_check_start(args);
+
 	if ((to = switch_channel_get_variable(channel, "park_timeout"))) {
 		char *cause_str;
 
@@ -931,7 +942,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
 								   switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
 									  imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
-					return SWITCH_STATUS_FALSE;
+					switch_goto_status(SWITCH_STATUS_FALSE, end);
 				}
 
 
@@ -982,7 +993,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
 		if (switch_channel_test_flag(channel, CF_UNICAST)) {
 			if (!switch_channel_media_ready(channel)) {
 				if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
-					return SWITCH_STATUS_FALSE;
+					switch_goto_status(SWITCH_STATUS_FALSE, end);
 				}
 			}
 
@@ -1100,6 +1111,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
 
 	}
 
+ end:
+
+	arg_recursion_check_stop(args);
+
 	if (write_frame.codec) {
 		switch_core_codec_destroy(&codec);
 	}
@@ -1133,12 +1148,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s
 		return SWITCH_STATUS_GENERR;
 	}
 
+	arg_recursion_check_start(args);
+
 	if (abs_timeout) {
 		abs_started = switch_micro_time_now();
 	}
 	if (digit_timeout) {
 		digit_started = switch_micro_time_now();
 	}
+
 	while (switch_channel_ready(channel)) {
 		switch_frame_t *read_frame = NULL;
 		switch_event_t *event;
@@ -1224,6 +1242,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s
 		}
 	}
 
+	arg_recursion_check_stop(args);
+
 	return status;
 }
 
@@ -2890,6 +2910,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
 	channel = switch_core_session_get_channel(session);
 	switch_assert(channel);
 
+	arg_recursion_check_start(args);
+
+
 	if (zstr(module_name)) {
 		module_name = "en";
 	}
@@ -2971,6 +2994,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
 
   done:
 
+	arg_recursion_check_stop(args);
+
+
 	if (hint_data) {
 		switch_event_destroy(&hint_data);
 	}
diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c
index a9ebc4b352..80b7a3ae25 100644
--- a/src/switch_ivr_async.c
+++ b/src/switch_ivr_async.c
@@ -426,7 +426,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *
 		is_timeout++;
 	}
 	
-	switch_mutex_lock(dmachine->mutex);
+	if (switch_mutex_trylock(dmachine->mutex) != SWITCH_STATUS_SUCCESS) {
+		return SWITCH_STATUS_SUCCESS;
+	}
 
 	if (zstr(dmachine->digits) && !is_timeout) {
 		r = SWITCH_STATUS_SUCCESS;
@@ -614,7 +616,7 @@ static void *SWITCH_THREAD_FUNC echo_video_thread(switch_thread_t *thread, void
 }
 #endif
 
-SWITCH_DECLARE(void) switch_ivr_session_echo(switch_core_session_t *session, switch_input_args_t *args)
+SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *session, switch_input_args_t *args)
 {
 	switch_status_t status;
 	switch_frame_t *read_frame;
@@ -628,9 +630,11 @@ SWITCH_DECLARE(void) switch_ivr_session_echo(switch_core_session_t *session, swi
 #endif
 
 	if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
-		return;
+		return SWITCH_STATUS_FALSE;
 	}
 
+	arg_recursion_check_start(args);
+
  restart:
 
 #ifdef SWITCH_VIDEO_IN_THREADS
@@ -723,6 +727,7 @@ SWITCH_DECLARE(void) switch_ivr_session_echo(switch_core_session_t *session, swi
 	}
 #endif
 
+	return SWITCH_STATUS_SUCCESS;
 }
 
 typedef struct {
@@ -3411,6 +3416,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_and_detect_speech(switch_core_se
 	play_and_detect_speech_state_t state = { 0, "" };
 	switch_channel_t *channel = switch_core_session_get_channel(session);
 
+	arg_recursion_check_start(args);
+
 	if (result == NULL) {
 		goto done;
 	}
@@ -3472,6 +3479,8 @@ done:
 		status = SWITCH_STATUS_FALSE;
 	}
 
+	arg_recursion_check_stop(args);
+
 	return status;;
 }
 
diff --git a/src/switch_ivr_menu.c b/src/switch_ivr_menu.c
index 4b73f58793..e0ac169bf6 100644
--- a/src/switch_ivr_menu.c
+++ b/src/switch_ivr_menu.c
@@ -585,9 +585,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *s
 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IVR menu '%s' no input detected\n", menu->name);
 			}
 			errs++;
-			if (status == SWITCH_STATUS_SUCCESS) {
-				status = switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL);
-			}
+
 			/* breaks are ok too */
 			if (SWITCH_STATUS_IS_BREAK(status)) {
 				status = SWITCH_STATUS_SUCCESS;
diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c
index dc281b5885..2024bc3012 100644
--- a/src/switch_ivr_originate.c
+++ b/src/switch_ivr_originate.c
@@ -3073,6 +3073,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
 								}
 							}
 							write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
+write_frame.samples = (uint32_t) olen;
+
 						} else if (ringback.audio_buffer) {
 							if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(ringback.audio_buffer,
 																						  write_frame.data,
diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c
index c15da6fb03..e7e2e4e22a 100644
--- a/src/switch_ivr_play_say.c
+++ b/src/switch_ivr_play_say.c
@@ -54,11 +54,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 	switch_bool_t sound_prefix_enforced = switch_true(switch_channel_get_variable(channel, "sound_prefix_enforced"));
 	switch_bool_t local_sound_prefix_enforced = SWITCH_FALSE;
 
+
 	if (!macro_name) {
 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No phrase macro specified.\n");
 		return status;
 	}
 
+	arg_recursion_check_start(args);
+
 	if (!lang) {
 		chan_lang = switch_channel_get_variable(channel, "default_language");
 		if (!chan_lang) {
@@ -331,6 +334,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 
   done:
 
+	arg_recursion_check_stop(args);
+
 	if (hint_data) {
 		switch_event_destroy(&hint_data);
 	}
@@ -379,6 +384,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
 	int restart_limit_on_dtmf = 0;
 	const char *prefix, *var;
 
+
 	prefix = switch_channel_get_variable(channel, "sound_prefix");
 
 	if (!prefix) {
@@ -404,6 +410,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
 		return SWITCH_STATUS_FALSE;
 	}
 
+	arg_recursion_check_start(args);
+
 	if (!fh) {
 		fh = &lfh;
 	}
@@ -467,6 +475,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
 			write_frame.samples = write_frame.datalen / 2;
 			write_frame.codec = &write_codec;
 		} else {
+			arg_recursion_check_stop(args);
 			return SWITCH_STATUS_FALSE;
 		}
 	}
@@ -519,6 +528,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
 	if (switch_core_file_open(fh, file, fh->channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
 		switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 		switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+		arg_recursion_check_stop(args);
 		return SWITCH_STATUS_GENERR;
 	}
 
@@ -590,6 +600,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
 							  fh->channels, read_impl.microseconds_per_packet / 1000);
 			switch_core_file_close(fh);
 			switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+			arg_recursion_check_stop(args);
 			return SWITCH_STATUS_GENERR;
 		}
 	}
@@ -796,6 +807,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
 	}
 
 	switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+
+	arg_recursion_check_stop(args);
 	return status;
 }
 
@@ -841,6 +854,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
 
 		return SWITCH_STATUS_FALSE;
 	}
+
+	arg_recursion_check_start(args);
+
 	memset(&ts, 0, sizeof(ts));
 	write_frame.codec = &write_codec;
 	write_frame.data = data;
@@ -946,6 +962,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
 	switch_buffer_destroy(&audio_buffer);
 	teletone_destroy_session(&ts);
 
+	arg_recursion_check_stop(args);
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -1084,6 +1102,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 		return SWITCH_STATUS_FALSE;
 	}
 
+	arg_recursion_check_start(args);
+
 	if (!strcasecmp(read_impl.iananame, "l16")) {
 		l16++;
 	}
@@ -1136,6 +1156,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 						*arg++ = '\0';
 					}
 					if ((status = switch_ivr_phrase_macro(session, dup, arg, lang, args)) != SWITCH_STATUS_SUCCESS) {
+						arg_recursion_check_stop(args);
 						return status;
 					}
 					continue;
@@ -1160,6 +1181,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 
 				if (!zstr(engine) && !zstr(voice) && !zstr(text)) {
 					if ((status = switch_ivr_speak_text(session, engine, voice, text, args)) != SWITCH_STATUS_SUCCESS) {
+						arg_recursion_check_stop(args);
 						return status;
 					}
 				} else {
@@ -1168,6 +1190,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 					voice = (char *) switch_channel_get_variable(channel, "tts_voice");
 					if (engine && text) {
 						if ((status = switch_ivr_speak_text(session, engine, voice, text, args)) != SWITCH_STATUS_SUCCESS) {
+							arg_recursion_check_stop(args);
 							return status;
 						}
 					} else {
@@ -1727,6 +1750,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 	switch_safe_free(abuf);
 
 	switch_core_session_reset(session, SWITCH_FALSE, SWITCH_FALSE);
+
+	arg_recursion_check_stop(args);
+
 	return status;
 }
 
@@ -2119,6 +2145,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
 		return SWITCH_STATUS_FALSE;
 	}
 
+	arg_recursion_check_start(args);
+
 	write_frame.data = abuf;
 	write_frame.buflen = sizeof(abuf);
 
@@ -2149,6 +2177,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
 		switch_size_t mylen = strlen(text) + extra + 1;
 		tmp = malloc(mylen);
 		if (!tmp) {
+			arg_recursion_check_stop(args);
 			return SWITCH_STATUS_MEMERR;
 		}
 		memset(tmp, 0, mylen);
@@ -2369,6 +2398,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
 	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done speaking text\n");
 	flags = 0;
 	switch_core_speech_flush_tts(sh);
+
+	arg_recursion_check_stop(args);
 	return status;
 }
 
@@ -2426,6 +2457,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
 		return SWITCH_STATUS_FALSE;
 	}
 
+	arg_recursion_check_start(args);
+
 	sh = &lsh;
 	codec = &lcodec;
 	timer = &ltimer;
@@ -2466,6 +2499,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid TTS module!\n");
 			switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
 			switch_ivr_clear_speech_cache(session);
+			arg_recursion_check_stop(args);
 			return status;
 		}
 	} else if (cache_obj && strcasecmp(cache_obj->voice_name, voice_name)) {
@@ -2476,6 +2510,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
 	if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
 		flags = 0;
 		switch_core_speech_close(sh, &flags);
+		arg_recursion_check_stop(args);
 		return SWITCH_STATUS_FALSE;
 	}
 	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "OPEN TTS %s\n", tts_name);
@@ -2495,6 +2530,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
 			switch_core_speech_close(sh, &flags);
 			switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
 			switch_ivr_clear_speech_cache(session);
+			arg_recursion_check_stop(args);
 			return SWITCH_STATUS_GENERR;
 		}
 	}
@@ -2510,6 +2546,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
 				switch_core_speech_close(sh, &flags);
 				switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
 				switch_ivr_clear_speech_cache(session);
+				arg_recursion_check_stop(args);
 				return SWITCH_STATUS_GENERR;
 			}
 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", sh->samples * 2,
@@ -2539,6 +2576,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
 	}
 
 	switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
+	arg_recursion_check_stop(args);
+
 	return status;
 }
 
diff --git a/src/switch_ivr_say.c b/src/switch_ivr_say.c
index 0081ab16f5..214931b1bd 100644
--- a/src/switch_ivr_say.c
+++ b/src/switch_ivr_say.c
@@ -133,6 +133,8 @@ SWITCH_DECLARE(switch_say_type_t) switch_ivr_get_say_type_by_name(const char *na
 SWITCH_DECLARE(switch_status_t) switch_ivr_say_spell(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
 {
 	char *p;
+	
+	arg_recursion_check_start(args);
 
 	for (p = tosay; p && *p; p++) {
 		int a = tolower((int) *p);
@@ -147,6 +149,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_spell(switch_core_session_t *sess
 		}
 	}
 
+	arg_recursion_check_stop(args);
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -172,24 +176,28 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_ip(switch_core_session_t *session
 												  switch_input_args_t *args)
 {
 	char *a, *b, *c, *d;
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+	arg_recursion_check_start(args);
+
 	if (!(a = switch_core_session_strdup(session, tosay))) {
-		return SWITCH_STATUS_FALSE;
+		switch_goto_status(SWITCH_STATUS_FALSE, end);
 	}
 
 	if (!(b = strchr(a, '.'))) {
-		return SWITCH_STATUS_FALSE;
+		switch_goto_status(SWITCH_STATUS_FALSE, end);
 	}
 
 	*b++ = '\0';
 
 	if (!(c = strchr(b, '.'))) {
-		return SWITCH_STATUS_FALSE;
+		switch_goto_status(SWITCH_STATUS_FALSE, end);
 	}
 
 	*c++ = '\0';
 
 	if (!(d = strchr(c, '.'))) {
-		return SWITCH_STATUS_FALSE;
+		switch_goto_status(SWITCH_STATUS_FALSE, end);
 	}
 
 	*d++ = '\0';
@@ -202,7 +210,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_ip(switch_core_session_t *session
 	say_file("digits/dot.wav");
 	say_num(atoi(d), say_args->method);
 
-	return SWITCH_STATUS_SUCCESS;
+ end:
+
+	arg_recursion_check_stop(args);
+
+	return status;
 }
 
 
diff --git a/src/switch_rtp.c b/src/switch_rtp.c
index 951edb70b7..7ddb2abcf5 100644
--- a/src/switch_rtp.c
+++ b/src/switch_rtp.c
@@ -97,13 +97,18 @@ static switch_hash_t *alloc_hash = NULL;
 typedef struct {
 	srtp_hdr_t header;
 	char body[SWITCH_RTP_MAX_BUF_LEN];
+	switch_rtp_hdr_ext_t *ext;
+	char *ebody;
 } rtp_msg_t;
 
+#define RTP_BODY(_s) (char *) (_s->recv_msg.ebody ? _s->recv_msg.ebody : _s->recv_msg.body)
+
 typedef struct {
 	switch_rtcp_hdr_t header;
 	char body[SWITCH_RTCP_MAX_BUF_LEN];
 } rtcp_msg_t;
 
+
 typedef enum {
 	VAD_FIRE_TALK = (1 << 0),
 	VAD_FIRE_NOT_TALK = (1 << 1)
@@ -345,7 +350,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
 
 #ifdef DEBUG_2833
 	if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity);
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d %ld\n", rtp_session->dtmf_data.in_digit_sanity, bytes);
 	}
 #endif
 
@@ -364,7 +369,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
 	if (bytes > rtp_header_len && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) &&
 		!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833) && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) {
 		switch_size_t len = bytes - rtp_header_len;
-		unsigned char *packet = (unsigned char *) rtp_session->recv_msg.body;
+		unsigned char *packet = (unsigned char *) RTP_BODY(rtp_session);
 		int end;
 		uint16_t duration;
 		char key;
@@ -372,6 +377,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
 		uint32_t ts;
 
 		if (!(packet[0] || packet[1] || packet[2] || packet[3]) && len >= 8) {
+
 			switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
 			packet += 4;
 			len -= 4;
@@ -398,7 +404,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
 			}
 		}
 #ifdef DEBUG_2833
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) packet[1], (unsigned) packet[2], (unsigned) packet[3]);
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned char) packet[0], (unsigned char) packet[1], (unsigned char) packet[2], (unsigned char) packet[3]);
 #endif
 
 		if (in_digit_seq > rtp_session->dtmf_data.in_digit_seq) {
@@ -407,18 +413,24 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
 #ifdef DEBUG_2833
 
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n",
-				   key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq,
+							  key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq,
 				   ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : "");
 #endif
 
-			if (!rtp_session->dtmf_data.in_digit_queued && (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) &&
-				rtp_session->dtmf_data.in_digit_ts) {
-				switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0), 0, SWITCH_DTMF_RTP };
+			if (!rtp_session->dtmf_data.in_digit_queued && rtp_session->dtmf_data.in_digit_ts) {
+				if ((rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION)) {
+					switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0), 0, SWITCH_DTMF_RTP };
 #ifdef DEBUG_2833
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8);
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8);
 #endif
-				switch_rtp_queue_rfc2833_in(rtp_session, &dtmf);
-				rtp_session->dtmf_data.in_digit_queued = 1;
+					switch_rtp_queue_rfc2833_in(rtp_session, &dtmf);
+					rtp_session->dtmf_data.in_digit_queued = 1;
+				}
+
+				if (rtp_session->jb && (rtp_session->rtp_bugs & RTP_BUG_FLUSH_JB_ON_DTMF)) {
+					stfu_n_reset(rtp_session->jb);
+				}
+				
 			}
 
 			/* only set sanity if we do NOT ignore the packet */
@@ -482,7 +494,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
 
 			} else if (!rtp_session->dtmf_data.in_digit_ts) {
 #ifdef DEBUG_2833
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start %d\n", ts);
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start %d [%c]\n", ts, key);
 #endif
 				rtp_session->dtmf_data.in_digit_ts = ts;
 				rtp_session->dtmf_data.last_in_digit_ts = ts;
@@ -972,7 +984,7 @@ static int check_srtp_and_ice(switch_rtp_t *rtp_session)
 	int ret = 0;
 
 
-		if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTO_CNG) &&
+		if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTO_CNG) && rtp_session->send_msg.header.ts &&
 			rtp_session->timer.samplecount >= (rtp_session->last_write_samplecount + (rtp_session->samples_per_interval * 50))) {
 			uint8_t data[10] = { 0 };
 			switch_frame_flag_t frame_flags = SFF_NONE;
@@ -2758,23 +2770,26 @@ static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session)
 SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp_flush_t flush)
 {
 
+	if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) ||
+		switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) ||
+		switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL)) {
+		return;
+	}
+
+
 	if (switch_rtp_ready(rtp_session)) {
 		rtp_session->last_write_ts = RTP_TS_RESET;
-	
-		if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && 
-			!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
-			switch_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH);
+		switch_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH);
 
-			switch (flush) {
-			case SWITCH_RTP_FLUSH_STICK:
-				switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH);
+		switch (flush) {
+		case SWITCH_RTP_FLUSH_STICK:
+			switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH);
+			break;
+		case SWITCH_RTP_FLUSH_UNSTICK:
+			switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH);
+			break;
+		default:
 				break;
-			case SWITCH_RTP_FLUSH_UNSTICK:
-				switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH);
-				break;
-			default:
-				break;
-			}
 		}
 	}
 }
@@ -2866,14 +2881,30 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
 	switch_assert(bytes);
  more:
 	*bytes = sizeof(rtp_msg_t);
+
 	status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, bytes);
 	ts = ntohl(rtp_session->recv_msg.header.ts);
+	rtp_session->recv_msg.ebody = NULL;
 
 	if (*bytes) {
 		uint16_t seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq);
+
+		if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) &&
+			rtp_session->recv_msg.header.version == 2 && rtp_session->recv_msg.header.x) { /* header extensions */
+
+			rtp_session->recv_msg.ext = (switch_rtp_hdr_ext_t *) rtp_session->recv_msg.body;
+
+			rtp_session->recv_msg.ext->length = ntohs((uint16_t)rtp_session->recv_msg.ext->length);
+			rtp_session->recv_msg.ext->profile = ntohs((uint16_t)rtp_session->recv_msg.ext->profile);
+
+			if (rtp_session->recv_msg.ext->length < SWITCH_RTP_MAX_BUF_LEN_WORDS) {
+				rtp_session->recv_msg.ebody = rtp_session->recv_msg.body + (rtp_session->recv_msg.ext->length * 4) + 4;
+			}
+		}
 		
+
+#ifdef DEBUG_MISSED_SEQ		
 		if (rtp_session->last_seq && rtp_session->last_seq+1 != seq) {
-#ifdef DEBUG_MISSED_SEQ
 			//2012-11-28 18:33:11.799070 [ERR] switch_rtp.c:2883 Missed -65536 RTP frames from sequence [65536] to [-1] (missed). Time since last read [20021]
 			switch_size_t flushed_packets_diff = rtp_session->stats.inbound.flush_packet_count - rtp_session->last_flush_packet_count;
 			switch_size_t num_missed = (switch_size_t)seq - (rtp_session->last_seq+1);
@@ -2907,8 +2938,9 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
 									  flushed_packets_diff, rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0);
 				}
 			}
-#endif
+
 		}
+#endif
 		rtp_session->last_seq = seq;
 	}
 
@@ -3020,7 +3052,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
 	
 	
 	if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_BYTESWAP) && rtp_session->recv_msg.header.pt == rtp_session->rpayload) {
-		switch_swap_linear((int16_t *)rtp_session->recv_msg.body, (int) *bytes - rtp_header_len);
+		switch_swap_linear((int16_t *)RTP_BODY(rtp_session), (int) *bytes - rtp_header_len);
 	}
 
 	if (rtp_session->jb && !rtp_session->pause_jb && rtp_session->recv_msg.header.version == 2 && *bytes) {
@@ -3036,7 +3068,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
 		if (stfu_n_eat(rtp_session->jb, rtp_session->last_read_ts, 
 					   ntohs((uint16_t) rtp_session->recv_msg.header.seq),
 					   rtp_session->recv_msg.header.pt,
-					   rtp_session->recv_msg.body, *bytes - rtp_header_len, rtp_session->timer.samplecount) == STFU_ITS_TOO_LATE) {
+					   RTP_BODY(rtp_session), *bytes - rtp_header_len, rtp_session->timer.samplecount) == STFU_ITS_TOO_LATE) {
 			
 			goto more;
 		}
@@ -3050,7 +3082,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
 
 	if (rtp_session->jb && !rtp_session->pause_jb) {
 		if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) {
-			memcpy(rtp_session->recv_msg.body, jb_frame->data, jb_frame->dlen);
+			memcpy(RTP_BODY(rtp_session), jb_frame->data, jb_frame->dlen);
 
 			if (jb_frame->plc) {
 				(*flags) |= SFF_PLC;
@@ -3236,6 +3268,9 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
 
 		if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) {
 			if ((switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTOFLUSH) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH)) &&
+				!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && 
+				!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) && 
+				!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) &&
 				rtp_session->read_pollfd) {
 				if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 0) == SWITCH_STATUS_SUCCESS) {
 					status = read_rtp_packet(rtp_session, &bytes, flags, SWITCH_FALSE);
@@ -3638,11 +3673,19 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
 			*flags |= SFF_PROXY_PACKET;
 
 			if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL)) {
+#if 0
+				if (rtp_session->recv_msg.header.version == 2 && rtp_session->recv_msg.header.pt == rtp_session->rpayload) {
+					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, 
+									  "Ignoring udptl packet of size of %ld bytes that looks strikingly like a RTP packet.\n", (long)bytes);
+					bytes = 0;
+					goto do_continue;					
+				}
+#endif
 				*flags |= SFF_UDPTL_PACKET;
+			} else {
+				check_srtp_and_ice(rtp_session);
 			}
 
-			check_srtp_and_ice(rtp_session);
-
 			ret = (int) bytes;
 			goto end;
 		}
@@ -3673,7 +3716,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
 		}
 
 		if (bytes && rtp_session->recv_msg.header.version != 2) {
-			uint8_t *data = (uint8_t *) rtp_session->recv_msg.body;
+			uint8_t *data = (uint8_t *) RTP_BODY(rtp_session);
 
 			if (rtp_session->recv_msg.header.version == 0) {
 				if (rtp_session->ice.ice_user) {
@@ -3718,7 +3761,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
 	timer_check:
 
 		if (do_cng) {
-			uint8_t *data = (uint8_t *) rtp_session->recv_msg.body;
+			uint8_t *data = (uint8_t *) RTP_BODY(rtp_session);
 
 			do_2833(rtp_session, session);
 
@@ -3909,7 +3952,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_read(switch_rtp_t *rtp_session, void
 
 	*datalen = bytes;
 
-	memcpy(data, rtp_session->recv_msg.body, bytes);
+	memcpy(data, RTP_BODY(rtp_session), bytes);
 
 	return SWITCH_STATUS_SUCCESS;
 }
@@ -3973,7 +4016,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
 
 	bytes = rtp_common_read(rtp_session, &frame->payload, &frame->flags, io_flags);
 
-	frame->data = rtp_session->recv_msg.body;
+	frame->data = RTP_BODY(rtp_session);
 	frame->packet = &rtp_session->recv_msg;
 	frame->packetlen = bytes;
 	frame->source = __FILE__;
@@ -4061,7 +4104,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi
 	}
 
 	bytes = rtp_common_read(rtp_session, payload_type, flags, io_flags);
-	*data = rtp_session->recv_msg.body;
+	*data = RTP_BODY(rtp_session);
 
 	if (bytes < 0) {
 		*datalen = 0;
@@ -4546,7 +4589,6 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
 		bytes = frame->packetlen;
 		//tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->remote_addr);
 
-
 		send_msg = frame->packet;
 
 		if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && !switch_test_flag(frame, SFF_UDPTL_PACKET)) {
diff --git a/src/switch_utils.c b/src/switch_utils.c
index 4335b4dcd3..83b77744a3 100644
--- a/src/switch_utils.c
+++ b/src/switch_utils.c
@@ -2609,7 +2609,7 @@ const short _switch_C_toupper_[1 + SWITCH_CTYPE_NUM_CHARS] = {
 
 const short *_switch_toupper_tab_ = _switch_C_toupper_;
 
-SWITCH_DECLARE(int) switch_toupper(int c)
+SWITCH_DECLARE(int) old_switch_toupper(int c)
 {
 	if ((unsigned int) c > 255)
 		return (c);