diff --git a/Makefile.am b/Makefile.am
index aeb31eca01..e701494a2e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -90,6 +90,8 @@ $(RECURSIVE_TARGETS):
 	fi; \
 	if test -z "$$fail" ; then \
 	   cd $(top_builddir)/build && $(MAKE) $(AM_MAKEFLAGS) $$target || exit 1; \
+	else \
+	   exit 1; \
 	fi ;
 
 CORE_CFLAGS  = `$(switch_builddir)/libs/apr/apr-1-config --cflags --cppflags --includes`
diff --git a/docs/ChangeLog b/docs/ChangeLog
index 6037c14ec7..96066b6e8c 100644
--- a/docs/ChangeLog
+++ b/docs/ChangeLog
@@ -32,6 +32,7 @@ freeswitch (1.0.7)
 	config: default example to resolve some issues with SCA in cases where host and ip are mixed causing the phone to be confused. (r:0279261b)
 	config: Fix phrase files, still missing a sound file (r:6741f350/FS-2742)
 	config: Disallow global-intercept and group-intercept can intercept an outbound call in default dialplan (r:890871ba/FS-2777)
+	config: fix single domain assumption in default config to be more portable *cough* bkw *cough* (r:f987903e)
 	core: Add RTCP support (FSRTP-14)
 	core: handle some errors on missing db handle conditions
 	core: add ... and shutdown as a fail-safe when no modules are loaded
@@ -134,6 +135,16 @@ freeswitch (1.0.7)
 	core: Better handling of progress and answering to prevent sip profile from locking up at higher volumes (r:04e57577/FS-2801)
 	core: ACL for IPv6 address and swigall to boot (r:db91f0e8/FS-2842)
 	core: add intercept_unanswered_only var akin to intercept_unbridged_only (r:68f18efe)
+	core: switch_odbc_handle_exec_string duplication SQLExecute (r:8b0e7d24/FS-2880)
+	core: Fix timeout while bridge is waiting for CF_BRIDGED flag (r:2572621b/FS-2368)
+	core: don't parse events for b legs from a leg thread in case they are using a monolothic python script as a group_confirm exec over socket to send it messages while the call is ringing (r:ed5266d3)
+	core: add new function to check when messages need parsing to improve performance on parsing messages during originate (r:8b0421ff)
+	core: run execute_on_answer on_media _on_ring apps async (r:ef4a4ed0)
+	core: add switch_ivr_insert_file to insert one file into another at an arbitrary sample point (r:82394b37)
+	core: Slow reload cause calls to hang (r:1ba98b02/FS-2852)
+	core: Application intercept causes FS to stop processing calls (r:12fc65f7/FS-2872)
+	core: fix edge cases for endless loop in sql thread (r:5d7c09ed)
+	core: prevent race while changing codecs mid call (r:7aa72b67)
 	lang: Improve French phrase files (FSCONFIG-23)
 	libapr: Fix issue where after a bridge with a member, uuid of Agent is set to single quote character ' (r:3fee704d/FS-2738)
 	libdingaling: fix race on shutdown causing crash (FSMOD-47)
@@ -151,6 +162,7 @@ freeswitch (1.0.7)
 	libesl: Fix SEGV when using serialize function without any arguments (r:910729b5/ESL-44)
 	libesl: fix leak-on-error in esl_connect_timeout() (r:4263d60e)
 	libesl: Call close on connection handle if the connection fails (r:413dcc4c/ESL-50)
+	libesl: allow fs_cli -x to have args up to 1024 chars (was 256) (r:7039ba47)
 	libfreetdm: implemented freetdm config nodes and ss7 initial configuration
 	libfreetdm: fix codec for CAS signaling (r:b76e7f18)
 	libfreetdm: freetdm: ss7- added support for incoming group blocks, started adding support for ansi (r:c219a73c)
@@ -189,7 +201,8 @@ freeswitch (1.0.7)
 	mod_callcenter: Fix invalid update of agent field (r:426a448f/FS-2738)
 	mod_callcenter: Allow to get queue info via api (r:70d592ae)
 	mod_callcenter: Fix bad return type so it compile on archlinux, thx bougyman (r:3a475986)
-	mod_callcenter: Make callcenter_config agent get return the value of the item requested.  Also added queue param max-wait-time-with-no-agent-time-reached: If the max-wai-time-with-no-agent is already reached for the queue, then new caller can wait for x ammount of second before it kicked out of the queue rather than get rejected automaticly. (r:81a03869)
+	mod_callcenter: Make callcenter_config agent get return the value of the item requested.  Also added queue param max-wait-time-with-no-agent-time-reached: If the max-wai-time-with-no-agent is already reached for the queue, then new caller can wait for x amount of second before it kicked out of the queue rather than get rejected automatically. (r:81a03869)
+	mod_callcenter: Add new event socket agent-offering.  Plus some documentation and better handling of bad agent type -- FS-2869 (r:80174cf3/FS-2869)
 	mod_cidlookup: null xml is bad (r:095815f8)
 	mod_cid_lookup: honor skipcitystate when using whitepages (r:a66654de/FSMOD-53)
 	mod_commands: make break uuid_break and add cascade flag 
@@ -205,6 +218,8 @@ freeswitch (1.0.7)
 	mod_commands: ***BEHAVIOUR CHANGE*** reloadacl, load <module>, reload <module> will now explicitly call reloadxml (r:42c9df72)
 	mod_commands: add nat_map usage (r:7577b8aa)
 	mod_commands: add escaping empty strings to sql_escape (r:7bd0a5a6/FS-2833)
+	mod_commands: add uuid_fileman <uuid> <cmd>:<val> <-- same vals as the callbacks in js and lua to control the currently playing file of a channel from the cli or ESL (for the people who were ignoring me on the conference call so I decided to implement it instead of try to explain it ) (r:c4369fc8)
+	mod_commands: FS-2210 Add support for auto completion for uuid_simplify (r:72bcc01b/FS-2210)
 	mod_conference: Fix reporting of volume up/down (MODAPP-419)
 	mod_conference: add last talking time per member to conference xml list
 	mod_conference: add terminate-on-silence conference param
@@ -221,6 +236,8 @@ freeswitch (1.0.7)
 	mod_dingaling: make dingaling work with google voice inbound too (r:4ee68141)
 	mod_dingaling: Fix crash when testing the new gv-dingaling with around 24 concurrent calls (r:73e1ec5e/FSCORE-667)
 	mod_dingaling: Fix NULL pointer (r:e3eff816/FS-1103)
+	mod_dingaling: fix leak in chat_send (r:eb109a85)
+	mod_dingaling: use the login as message source when not in component mode. (chat_send) (r:58c28aab)
 	mod_directory: Add variable directory_search_order to allow to search by first name by default is set to "first_name" (r:163ca31f)
 	mod_distributor: Add mod_distributor to VS2010 - not built by default (r:bac79ba1)
 	mod_dptools: add eavesdrop_enable_dtmf chan var (r:596c0012)
@@ -279,8 +296,10 @@ freeswitch (1.0.7)
 	mod_freetdm: lock the channel when placing call (r:705dd237)
 	mod_freetdm: created cmake files for freetdm (r:fc55997b)
 	mod_freetdm: ss7 - added support to control mtp2, mtp3, and isup timers via freetdm.conf.xml (r:4455d581)
+	mod_freetdm: made ftmod_r2 use FTDM_SPAN_USE_SIGNALS_QUEUE and properly send FTDM_SIGEVENT_SIGSTATUS_CHANGED (r:af5f0a4a)
 	mod_gsmopen: copy from branch
 	mod_gsmopen: fix FS-2793, compilation stops (r:355c0dbb/FS-2793)
+	mod_gsmopen: retry serial initialization if failed, zeroing audio buffers, slower retry on soundcard busy (EAGAIN) (r:c7aefe93)
 	mod_hash: free all hashtables on shutdown (r:e76d7d92)
 	mod_hash: remove unneeded initializer (r:10d468a6)
 	mod_hash: begin working on remote support (r:c5ad49da)
@@ -324,6 +343,7 @@ freeswitch (1.0.7)
 	mod_lua: Added SAF_ROUTING_EXEC flag to lua app, so it can be run inline (r:7d5ca1c0)
 	mod_managed: Added wrapper for switch_event_bind for .net (r:a5f07a80/MODLANG-165)
 	mod_managed: add additional support (r:5be58aac)
+	mod_managed: add mono 2.8 patch file see FS-2774 (r:6a948bd9/FS-2774)
 	mod_mp4v: MP4V-ES passthru for washibechi on IRC
 	mod_mp4: New module. Supports playback of MP4 files. Depends on libmp4v2 <http://code.google.com/p/mp4v2/> (originally compiled against v1.6.1)
 	mod_nibblebill: free allocated mem at shutdown; free properly if using custom_sql
@@ -472,6 +492,14 @@ freeswitch (1.0.7)
 	mod_sofia: fix missing name and potential segfault in gateway status (r:40ac860a)
 	mod_sofia: Add missing RTP info for early SDP in bypass media (r:10119e9e/FS-2824)
 	mod_sofia: add manual_rtp_bugs to profile and chan var and 3 new RTP bugs SEND_LINEAR_TIMESTAMPS|START_SEQ_AT_ZERO|NEVER_SEND_MARKER (r:b278dd23)
+	mod_sofia: apparently some sip device vendors did not read the RFC (who knew?) adding verbose_sdp=true var to add needless a= lines for standard iana codecs that explicitly do not require them (r:6c4f49a8)
+	mod_sofia: Fix registering a gateway, sofia always places a Via header with ext-sip-ip, even if this gateway is local (r:cf398e1a/FS-535)
+	mod_sofia: add presence-probe-on-register sofia param to send a probe on register instead of presence to deal with some broken phones and add some general improvements to allow multi homed presence (r:14394994)
+	mod_sofia: Fix issue when fs_path is used so we pick the correct media IP in our outbound invite this was soemthing that wouldn't work correctly over ATT on the iphone. (r:a669f76f)
+	mod_sofia: Default T38 Options (r:92f43440/FS-2892)
+	mod_sofia: Fix wrong IP in VIA and contact HEADER for MESSAGE method while fs run in private network (r:59ea4a1b/FS-2886)
+	mod_sofia: SIP-header History-Info might exist multiple times, but only last header is exposed as a channel variable (r:8cf15012/FS-2881)
+	mod_sofia: Add support to reboot Yealink phone remotely (r:fdc31908/FS-2897)
 	mod_spandsp: initial checkin of mod_fax/mod_voipcodecs merge into mod_spandsp (r:fa9a59a8)
 	mod_spandsp: rework of new mod_spandsp to have functions broken up into different c files (r:65400642)
 	mod_spandsp: improve duplicate digit detection and add 'min_dup_digit_spacing_ms' channel variable for use with the dtmf detector (r:eab4f246/FSMOD-45)
@@ -508,6 +536,8 @@ freeswitch (1.0.7)
 	mod_xml_cdr: fix minor memory leaks and config bug (r:19253d83/MODEVENT-62)
 	mod_xml_rpc: Fix crash if unauthorized XML RPC is attempted (r:9835395c/FS-184)
 	scripts: added honeypot.pl and blacklist.pl which add extra SIP security options (r:b6a81ba7)
+	scripts: do simple verification to make sure we are getting IP addresses from VoIP abuse blacklist (r:b0049160)
+	scripts: add_user - cmd line utility that lets admin create new users very easily. (r:ec8f2c2b)
 	sofia-sip: fix null derefernce segfault in soa (r:f356c5e6)
 	sofia-sip: extend timeout for session expires on short timeouts to be 90% of timeout instead of 1/3 to handle devices that do not refresh in time such as polycom (r:a7f48928/SFSIP-212)
 	tools: Add fs_encode tool (r:89b17601)
diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj
new file mode 100644
index 0000000000..ec69333410
--- /dev/null
+++ b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>mod_freetdm</ProjectName>
+    <ProjectGuid>{FE3540C5-3303-46E0-A69E-D92F775687F1}</ProjectGuid>
+    <RootNamespace>mod_freetdm</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(PlatformName)\$(Configuration)\mod\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(PlatformName)\$(Configuration)\mod\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(PlatformName)\$(Configuration)\mod\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(PlatformName)\$(Configuration)\mod\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+      <SubSystem>Windows</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <ImportLibrary>$(OutDir)mod_freetdm.lib</ImportLibrary>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <ImportLibrary>$(OutDir)mod_freetdm.lib</ImportLibrary>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+      <SubSystem>Windows</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <ImportLibrary>$(OutDir)mod_freetdm.lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <ImportLibrary>$(OutDir)mod_freetdm.lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="mod_freetdm.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\msvc\freetdm.2010.vcxproj">
+      <Project>{93b8812c-3ec4-4f78-8970-ffbfc99e167d}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters
new file mode 100644
index 0000000000..92ac5ead47
--- /dev/null
+++ b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="mod_freetdm.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c
index 6c0d8bd5a3..38197bb2f0 100755
--- a/libs/freetdm/mod_freetdm/mod_freetdm.c
+++ b/libs/freetdm/mod_freetdm/mod_freetdm.c
@@ -2045,7 +2045,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
 		break;
 
 		case FTDM_SIGEVENT_PROGRESS:
-		case FTDM_SIGEVENT_PROGRESS_MEDIA:
 		{
 			if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
 				channel = switch_core_session_get_channel(session);
@@ -2055,6 +2054,16 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
 		}
 		break;
 
+		case FTDM_SIGEVENT_PROGRESS_MEDIA:
+		{
+			if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
+				channel = switch_core_session_get_channel(session);
+				switch_channel_mark_pre_answered(channel);
+				switch_core_session_rwunlock(session);
+			}
+		}
+		break;
+
 		case FTDM_SIGEVENT_UP:
 		{
 			if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index a54c515f4a..1461499d2d 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -130,19 +130,28 @@ static void write_chan_io_dump(ftdm_io_dump_t *dump, char *dataptr, int dlen)
 static void dump_chan_io_to_file(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, FILE *file)
 {
 	/* write the saved audio buffer */
-	size_t rc = 0;
-	size_t towrite = dump->size - dump->windex;
+	ftdm_size_t rc = 0;
+	ftdm_size_t towrite = 0;
+
+	if (!dump->buffer) {
+		return;
+	}
+
+	towrite = dump->size - dump->windex;
+
 	if (dump->wrapped) {
 		rc = fwrite(&dump->buffer[dump->windex], 1, towrite, file);
 		if (rc != towrite) {
-			ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
+			ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in io dump buffer\n", 
+					rc, towrite, strerror(errno));
 		}
 	}
 	if (dump->windex) {
 		towrite = dump->windex;
 		rc = fwrite(&dump->buffer[0], 1, towrite, file);
 		if (rc != towrite) {
-			ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
+			ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in io dump buffer: %s\n", 
+					rc, towrite, strerror(errno));
 		}
 	}
 	dump->windex = 0;
@@ -350,7 +359,7 @@ static __inline__ void *ftdm_std_malloc(void *pool, ftdm_size_t size)
 {
 	void *ptr = malloc(size);
 	pool = NULL; /* fix warning */
-	ftdm_assert_return(ptr != NULL, NULL, "Out of memory");
+	ftdm_assert_return(ptr != NULL, NULL, "Out of memory\n");
 	return ptr;
 }
 
@@ -358,7 +367,7 @@ static __inline__ void *ftdm_std_calloc(void *pool, ftdm_size_t elements, ftdm_s
 {
 	void *ptr = calloc(elements, size);
 	pool = NULL;
-	ftdm_assert_return(ptr != NULL, NULL, "Out of memory");
+	ftdm_assert_return(ptr != NULL, NULL, "Out of memory\n");
 	return ptr;
 }
 
@@ -366,7 +375,7 @@ static __inline__ void *ftdm_std_realloc(void *pool, void *buff, ftdm_size_t siz
 {
 	buff = realloc(buff, size);
 	pool = NULL;
-	ftdm_assert_return(buff != NULL, NULL, "Out of memory");
+	ftdm_assert_return(buff != NULL, NULL, "Out of memory\n");
 	return buff;
 }
 
@@ -2204,31 +2213,31 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
 		goto done;
 	}
 
-#ifndef FREETDM_SKIP_SIG_STATES
-	/* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn 
-	 * expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so 
-	 * remove this only in netborder branch for now while we update the sig modules */
+	if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) {
+		/* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn 
+		* expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so
+		* use FTDM_SPAN_USE_SKIP_STATESfor now while we update the sig modules */
 
-	if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
-		ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
-	}
+		if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
+			ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
+		}
 
-	/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
-	if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
-		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n");
-		goto done;
-	}
+		/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
+		if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n");
+			goto done;
+		}
 
-	if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
-		ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
-	}
+		if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
+			ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
+		}
 
-	/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
-	if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
-		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to UP\n");
-		goto done;
+		/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
+		if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to UP\n");
+			goto done;
+		}
 	}
-#endif
 	ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1);
 
 done:
@@ -2256,7 +2265,7 @@ static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const c
 	} else {
 		/* the signaling stack did not touch the state, 
 		 * core is responsible from clearing flags and stuff */
-		ftdm_channel_done(chan);
+		ftdm_channel_close(&chan);
 	}
 	return FTDM_SUCCESS;
 }
@@ -2580,8 +2589,14 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
 		ftdm_span_send_signal(ftdmchan->span, &sigmsg);
 	}
 
+	if (ftdmchan->txdrops || ftdmchan->rxdrops) {
+		ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", 
+				ftdmchan->txdrops, ftdmchan->rxdrops);
+	}
+
 	ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
 
+
 	ftdm_mutex_unlock(ftdmchan->mutex);
 
 	return FTDM_SUCCESS;
@@ -2781,7 +2796,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
 				GOTO_STATUS(done, FTDM_FAIL);
 			}
 			if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size) != FTDM_SUCCESS) {
-				ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump\n");	
+				ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump of size %zd\n", size);
 				GOTO_STATUS(done, FTDM_FAIL);
 			}
 			ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled input dump with size %zd\n", size);
@@ -2811,7 +2826,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
 				GOTO_STATUS(done, FTDM_FAIL);
 			}
 			if (start_chan_io_dump(ftdmchan, &ftdmchan->txdump, size) != FTDM_SUCCESS) {
-				ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump\n");	
+				ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump of size %d\n", size);	
 				GOTO_STATUS(done, FTDM_FAIL);
 			}
 			ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled output dump with size %zd\n", size);
@@ -2838,8 +2853,12 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
 			if (!obj) {
 				GOTO_STATUS(done, FTDM_FAIL);
 			}
+			if (!ftdmchan->rxdump.buffer) {
+				ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Not dumped input to file %p, input dump is not enabled\n", obj);
+				GOTO_STATUS(done, FTDM_FAIL);
+			}
 			dump_chan_io_to_file(ftdmchan, &ftdmchan->rxdump, obj);
-			ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %zd to file %p\n", ftdmchan->rxdump.size, obj);
+			ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %d to file %p\n", ftdmchan->rxdump.size, obj);
 			GOTO_STATUS(done, FTDM_SUCCESS);
 		}
 		break;
@@ -2850,6 +2869,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
 			if (!obj) {
 				GOTO_STATUS(done, FTDM_FAIL);
 			}
+			if (!ftdmchan->txdump.buffer) {
+				ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Not dumped output to file %p, output dump is not enabled\n", obj);
+				GOTO_STATUS(done, FTDM_FAIL);
+			}
 			dump_chan_io_to_file(ftdmchan, &ftdmchan->txdump, obj);
 			ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %zd to file %p\n", ftdmchan->txdump.size, obj);
 			GOTO_STATUS(done, FTDM_SUCCESS);
@@ -3408,6 +3431,16 @@ skipdebug:
 static FIO_WRITE_FUNCTION(ftdm_raw_write)
 {
 	int dlen = (int) *datalen;
+	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED)) {
+		ftdmchan->txdrops++;
+		if (ftdmchan->txdrops <= 10) {
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot write in channel with tx disabled\n");
+		} 
+		if (ftdmchan->txdrops == 10) {
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Too many tx drops, not printing anymore\n");
+		}
+		return FTDM_FAIL;
+	}
 	if (ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] > -1) {
 		if ((write(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX], data, dlen)) != dlen) {
 			ftdm_log(FTDM_LOG_WARNING, "Raw output trace failed to write all of the %zd bytes\n", dlen);
@@ -3580,6 +3613,18 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
 		goto done;
 	}
 
+	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED)) {
+		ftdmchan->rxdrops++;
+		if (ftdmchan->rxdrops <= 10) {
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot read from channel with rx disabled\n");
+		}
+		if (ftdmchan->rxdrops == 10) {
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "too many rx drops, not logging anymore\n");
+		}
+		status = FTDM_FAIL;
+		goto done;
+	}
+
 	status = ftdm_raw_read(ftdmchan, data, datalen);
 
 	if (status != FTDM_SUCCESS) {
@@ -3779,7 +3824,7 @@ done:
 
 FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t datasize, ftdm_size_t *datalen)
 {
-	ftdm_status_t status = FTDM_FAIL;
+	ftdm_status_t status = FTDM_SUCCESS;
 	fio_codec_t codec_func = NULL;
 	ftdm_size_t max = datasize;
 	unsigned int i = 0;
@@ -3787,22 +3832,28 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
 	ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel on write!\n");
 	ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "null I/O on write!\n");
 
+	ftdm_channel_lock(ftdmchan);
+
 	if (!ftdmchan->buffer_delay && 
 		((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer)) ||
 		 (ftdmchan->fsk_buffer && ftdm_buffer_inuse(ftdmchan->fsk_buffer)))) {
 		/* read size writing DTMF ATM */
-		return FTDM_SUCCESS;
+		goto done;
 	}
 
 
 	if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
+		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "cannot write in channel not open\n");
 		snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "channel not open");
-		return FTDM_FAIL;
+		status = FTDM_FAIL;
+		goto done;
 	}
 
 	if (!ftdmchan->fio->write) {
+		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "write method not implemented\n");
 		snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "method not implemented");
-		return FTDM_FAIL;
+		status = FTDM_FAIL;
+		goto done;
 	}
 	
 	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
@@ -3819,10 +3870,13 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
 		if (codec_func) {
 			status = codec_func(data, max, datalen);
 		} else {
+			ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Do not know how to handle transcoding from %d to %d\n", 
+					ftdmchan->effective_codec, ftdmchan->native_codec);
 			snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
 			status = FTDM_FAIL;
+			goto done;
 		}
-	}	
+	}
 	
 	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_TX_GAIN) 
 		&& (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) {
@@ -3832,8 +3886,20 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
 		}
 	}
 
+	if (ftdmchan->span->sig_write) {
+		status = ftdmchan->span->sig_write(ftdmchan, data, *datalen);
+		if (status == FTDM_BREAK) {
+			/* signaling module decided to drop user frame */
+			status = FTDM_SUCCESS;
+			goto done;
+		}
+	}
+
 	status = ftdm_raw_write(ftdmchan, data, datalen);
 
+done:
+	ftdm_channel_unlock(ftdmchan);
+
 	return status;
 }
 
@@ -4142,6 +4208,53 @@ static struct {
 	ftdm_io_interface_t *pika_interface;
 } interfaces;
 
+static void print_channels_by_flag(ftdm_stream_handle_t *stream, int32_t flagval, int not, int *count)
+{
+	ftdm_hash_iterator_t *i = NULL;
+	ftdm_span_t *span;
+	ftdm_channel_t *fchan = NULL;
+	ftdm_iterator_t *citer = NULL;
+	ftdm_iterator_t *curr = NULL;
+	const void *key = NULL;
+	void *val = NULL;
+	uint32_t flag = (1 << flagval);
+
+	*count = 0;
+
+	ftdm_mutex_lock(globals.mutex);
+
+	for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) {
+		hashtable_this(i, &key, NULL, &val);
+		if (!key || !val) {
+			break;
+		}
+		span = val;
+		citer = ftdm_span_get_chan_iterator(span, NULL);
+		if (!citer) {
+			continue;
+		}
+		for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
+			fchan = ftdm_iterator_current(curr);
+			if (not && !ftdm_test_flag(fchan, flag)) {
+				stream->write_function(stream, "[s%dc%d][%d:%d] has not flag %d\n", 
+						fchan->span_id, fchan->chan_id, 
+						fchan->physical_span_id, fchan->physical_chan_id, 
+						flagval);
+				(*count)++;
+			} else if (!not && ftdm_test_flag(fchan, flag)) {
+				stream->write_function(stream, "[s%dc%d][%d:%d] has flag %d\n", 
+						fchan->span_id, fchan->chan_id, 
+						fchan->physical_span_id, fchan->physical_chan_id, 
+						flagval);
+				(*count)++;
+			}
+		}
+		ftdm_iterator_free(citer);
+	}
+
+	ftdm_mutex_unlock(globals.mutex);
+}
+
 static void print_channels_by_state(ftdm_stream_handle_t *stream, ftdm_channel_state_t state, int not, int *count)
 {
 	ftdm_hash_iterator_t *i = NULL;
@@ -4194,6 +4307,8 @@ static char *handle_core_command(const char *cmd)
 	int not = 0;
 	char *argv[10] = { 0 };
 	char *state = NULL;
+	char *flag = NULL;
+	uint32_t flagval = 0;
 	ftdm_channel_state_t i = FTDM_CHANNEL_STATE_INVALID;
 	ftdm_stream_handle_t stream = { 0 };
 
@@ -4228,6 +4343,19 @@ static char *handle_core_command(const char *cmd)
 		}
 		print_channels_by_state(&stream, i, not, &count);
 		stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "not in state" : "in state", ftdm_channel_state2str(i), count);
+	} else if (!strcasecmp(argv[0], "flag")) {
+		if (argc < 2) {
+			stream.write_function(&stream, "core state command requires an argument\n");
+			goto done;
+		}
+		flag = argv[1];
+		if (argv[1][0] == '!') {
+			not = 1;
+			flag++;
+		}
+		flagval = atoi(flag);
+		print_channels_by_flag(&stream, flagval, not, &count);
+		stream.write_function(&stream, "\nTotal channels %s %d: %d\n", not ? "without flag" : "with flag", flagval, count);
 	} else {
 		stream.write_function(&stream, "invalid core command %s\n", argv[0]);
 	}
diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c
index 95002e3e70..f07f48b0d6 100644
--- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c
+++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c
@@ -491,9 +491,10 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
 							ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL);
 						}
 						
-						if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && 
+						if (ftdmchan->type == FTDM_CHAN_TYPE_FXS &&
+							   ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && 
 							(ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE 
-							 || ftdmchan->last_state >= FTDM_CHANNEL_STATE_RING)) {
+							 || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING)) {
 							ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
 						} else {
 							ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c
index 199bba43a3..886c4a8fec 100644
--- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c
+++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c
@@ -329,8 +329,8 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
 				{
 					if (state_counter > 500) {
 						if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && 
-							(ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE 
-							 || ftdmchan->last_state >= FTDM_CHANNEL_STATE_IDLE)) {
+							(ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE 
+							 || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING)) {
 							ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
 						} else {
 							ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
@@ -340,7 +340,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
 				}
 				break;
 			case FTDM_CHANNEL_STATE_UP:
-			case FTDM_CHANNEL_STATE_IDLE:
+			case FTDM_CHANNEL_STATE_RING:
 				{
 					ftdm_sleep(interval);
 					continue;
@@ -386,7 +386,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
 					ftdm_channel_use(ftdmchan);
 				}
 				break;
-			case FTDM_CHANNEL_STATE_IDLE:
+			case FTDM_CHANNEL_STATE_RING:
 				{
 					ftdm_channel_use(ftdmchan);
 
@@ -421,7 +421,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
 					ftdm_channel_command(ftdmchan, FTDM_COMMAND_WINK, NULL);
 				}
 				break;
-			case FTDM_CHANNEL_STATE_RING:
+			case FTDM_CHANNEL_STATE_RINGING:
 				{
 					ftdm_buffer_zero(dt_buffer);
 					teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
@@ -477,7 +477,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
 
 		if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) > analog_data->max_dialstr))) {
 			ftdm_log(FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
-			ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
+			ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
 			last_digit = 0;
 			collecting = 0;
 		}
diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c
index de4fa2b232..fbe6ca0822 100644
--- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c
+++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c
@@ -134,17 +134,18 @@ static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen)
 	spri->errs = 0;
 	res = (int)len;
 
-	memset(&((unsigned char*)buf)[res], 0, 2);
-	res += 2;
-
+	if (res > 0) {
+		memset(&((unsigned char*)buf)[res], 0, 2);
+		res += 2;
 #ifdef IODEBUG
-	{
-		char bb[2048] = { 0 };
+		{
+			char bb[2048] = { 0 };
 
-		print_hex_bytes(buf, res - 2, bb, sizeof(bb));
-		ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2);
-	}
+			print_hex_bytes(buf, res - 2, bb, sizeof(bb));
+			ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2);
+		}
 #endif
+	}
 	return res;
 }
 
diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
index 0348c8b57e..e95a74bc25 100644
--- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
+++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
@@ -29,6 +29,11 @@
  * 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.
+ *
+ * Contributors: 
+ *
+ * Arnaldo Pereira <arnaldo@sangoma.com>
+ *
  */
 
 #ifdef __linux__
@@ -56,7 +61,10 @@ typedef enum {
 	FTDM_R2_RUNNING = (1 << 0),
 } ftdm_r2_flag_t;
 
-/* private call information stored in ftdmchan->call_data void* ptr */
+/* private call information stored in ftdmchan->call_data void* ptr,
+ * remember that each time you add a new member to this structure
+ * most likely you want to clear it in ft_r2_clean_call function
+ * */
 #define R2CALL(ftdmchan) ((ftdm_r2_call_t*)((ftdmchan)->call_data))
 typedef struct ftdm_r2_call_t {
 	openr2_chan_t *r2chan;
@@ -70,7 +78,7 @@ typedef struct ftdm_r2_call_t {
 	ftdm_size_t ani_index;
 	char logname[255];
 	char name[10];
-	unsigned long txdrops;
+	ftdm_timer_id_t protocol_error_recovery_timer;
 } ftdm_r2_call_t;
 
 /* this is just used as place holder in the stack when configuring the span to avoid using bunch of locals */
@@ -89,7 +97,7 @@ typedef struct ft_r2_conf_s {
 	int32_t max_dnis;
 	int32_t mfback_timeout; 
 	int32_t metering_pulse_timeout;
-	int32_t mf_dump_size;
+	ftdm_size_t mf_dump_size;
 
 	/* booleans */
 	int immediate_accept;
@@ -119,17 +127,25 @@ typedef struct ftdm_r2_data_s {
 	/* whether accept the call when offered, or wait until the user decides to accept */
 	int accept_on_offer:1;
 	/* Size of multi-frequency (or any media) dumps used during protocol errors */
-	int32_t mf_dump_size;
+	ftdm_size_t mf_dump_size;
 	/* max time spent in ms doing real work in a single loop */
 	int32_t jobmax;
 	/* Total number of loops performed so far */
 	uint64_t total_loops;
 	/* number of loops per 10ms increment from 0-9ms, 10-19ms .. 100ms and above */
 	uint64_t loops[11];
+	/* Total number of sleeps performed so far */
+	uint64_t total_sleeps;
+	/* number of sleeps per 10ms increment from 0-9ms, 10-19ms .. 100ms and above */
+	uint64_t sleeps[11];
+	/* max time spent in ms sleeping in a single loop */
+	int32_t sleepmax;
 	/* LWP */
 	uint32_t monitor_thread_id;
 	/* Logging directory */
 	char logdir[512];
+	/* scheduling context */
+	ftdm_sched_t *sched;
 } ftdm_r2_data_t;
 
 /* one element per span will be stored in g_mod_data_hash global var to keep track of them
@@ -137,6 +153,7 @@ typedef struct ftdm_r2_data_s {
 typedef struct ftdm_r2_span_pvt_s {
 	openr2_context_t *r2context; /* r2 context allocated for this span */
 	ftdm_hash_t *r2calls; /* hash table of allocated call data per channel for this span */
+	ftdm_sched_t *sched; /* schedule for the span */
 } ftdm_r2_span_pvt_t;
 
 /* span monitor thread */
@@ -304,6 +321,7 @@ static openr2_call_disconnect_cause_t ftdm_r2_ftdm_cause_to_openr2_cause(ftdm_ch
 
 	case FTDM_CAUSE_NETWORK_OUT_OF_ORDER:
 	case FTDM_CAUSE_SERVICE_UNAVAILABLE:
+	case FTDM_CAUSE_PROTOCOL_ERROR:
 		return OR2_CAUSE_OUT_OF_ORDER;
 
 	case FTDM_CAUSE_NO_ANSWER:
@@ -322,8 +340,20 @@ static openr2_call_disconnect_cause_t ftdm_r2_ftdm_cause_to_openr2_cause(ftdm_ch
 static void ft_r2_clean_call(ftdm_r2_call_t *call)
 {
 	openr2_chan_t *r2chan = call->r2chan;
-	memset(call, 0, sizeof(*call));
+
+	/* Do not memset call structure, that clears values we do not want to clear, 
+	 * like the log name set in on_call_log_created() */
 	call->r2chan = r2chan;
+	call->accepted = 0;
+	call->answer_pending = 0;
+	call->disconnect_rcvd = 0;
+	call->ftdm_call_started = 0;
+	call->protocol_error = 0;
+	call->chanstate = FTDM_CHANNEL_STATE_DOWN;
+	call->dnis_index = 0;
+	call->ani_index = 0;
+	call->name[0] = 0;
+	call->protocol_error_recovery_timer = 0;
 }
 
 static void ft_r2_accept_call(ftdm_channel_t *ftdmchan)
@@ -363,25 +393,31 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
 	}
 
 	ft_r2_clean_call(ftdmchan->call_data);
-	R2CALL(ftdmchan)->ftdm_call_started = 1;
-	R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
-	ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
+
+	/* start io dump */
+	if (r2data->mf_dump_size) {
+		ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size);
+		ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_OUTPUT_DUMP, &r2data->mf_dump_size);
+	}
 
 	callstatus = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan, 
 			ftdmchan->caller_data.cid_num.digits, 
 			ftdmchan->caller_data.dnis.digits, 
-			OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER);
+			r2data->category);
 
 	if (callstatus) {
 		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to make call in R2 channel, openr2_chan_make_call failed\n");
 		return FTDM_FAIL;
 	}
 
-	if (ftdmchan->state !=  FTDM_CHANNEL_STATE_DIALING) {
-		ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Collision after call attempt, try another channel, new state = %s\n",
-				ftdm_channel_state2str(ftdmchan->state));
-		return FTDM_BREAK;
-	}
+	R2CALL(ftdmchan)->ftdm_call_started = 1;
+	R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
+	ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
+
+	ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS);
+	ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL);
+	ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_RX_BUFFERS, NULL);
+
 	return FTDM_SUCCESS;
 }
 
@@ -414,7 +450,7 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status)
 }
 
 /* always called from the monitor thread */
-static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname)
+static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
 {
 	ftdm_r2_call_t *r2call;
 	ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
@@ -422,6 +458,18 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname)
 
 	ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Received request to start call\n");
 
+	if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP) {
+		r2call = R2CALL(ftdmchan);
+		if (r2call->protocol_error) {
+			/* we had a protocol error and we were giving some recovery time, cancel the recovery timer now
+			 * that is obvious that the other side recovered */
+			ftdm_sched_cancel_timer(r2data->sched, r2call->protocol_error_recovery_timer);
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Cancelled protocol error recovery timer\n");
+			ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
+			ftdm_r2_state_advance_all(ftdmchan);
+		}
+	}
+
 	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
 		ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Cannot start call when channel is in use (state = %s)\n", ftdm_channel_state2str(ftdmchan->state));
 		return;
@@ -443,12 +491,9 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname)
 	memset(ftdmchan->caller_data.dnis.digits, 0, sizeof(ftdmchan->caller_data.collected));
 	memset(ftdmchan->caller_data.ani.digits, 0, sizeof(ftdmchan->caller_data.collected));
 
-	/* clean the call data structure but keep the R2 processing flag on! */
 	ft_r2_clean_call(ftdmchan->call_data);
 	r2call = R2CALL(ftdmchan);
 
-	snprintf(r2call->logname, sizeof(r2call->logname), "%s", logname);
-
 	/* start io dump */
 	if (r2data->mf_dump_size) {
 		ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size);
@@ -457,8 +502,12 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname)
 
 	R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
 	ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
+	ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS);
+	ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL);
+	ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_RX_BUFFERS, NULL);
 }
 
+static void dump_mf(openr2_chan_t *r2chan);
 /* only called for incoming calls when the ANI, DNIS etc is complete and the user has to decide either to accept or reject the call */
 static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
 {
@@ -535,6 +584,11 @@ static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t m
 
 	/* at this point the MF signaling has ended and there is no point on keep reading */
 	openr2_chan_disable_read(r2chan);
+
+	/* at this point we are no longer responsible for reading and writing, 
+	 * we are not interested in the stats anymore */
+	ftdm_channel_clear_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS);
+
 	
 	R2CALL(ftdmchan)->accepted = 1;
 
@@ -613,6 +667,21 @@ static void ftdm_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
 	ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "OS error: %s\n", strerror(errorcode));
 }
 
+static void ftdm_r2_recover_from_protocol_error(void *data)
+{
+	openr2_chan_t *r2chan = data;
+	ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
+	ftdm_channel_lock(ftdmchan);
+	if (ftdmchan->state != FTDM_CHANNEL_STATE_HANGUP) {
+		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Recovering from protocol error but state is %s!\n", ftdm_channel_state2str(ftdmchan->state));
+		goto done;
+	}
+	ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
+	ftdm_r2_state_advance_all(ftdmchan);
+done:
+	ftdm_channel_unlock(ftdmchan);
+}
+
 static void ftdm_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
 {
 	ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
@@ -759,6 +828,16 @@ static void ftdm_r2_on_ani_digit_received(openr2_chan_t *r2chan, char digit)
 	R2CALL(ftdmchan)->ani_index = collected_len;
 }
 
+static void ftdm_r2_on_billing_pulse(openr2_chan_t *r2chan) {}
+
+static void ftdm_r2_on_call_log_created(openr2_chan_t *r2chan, const char *logname)
+{
+	ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
+	ftdm_r2_call_t *r2call = R2CALL(ftdmchan);
+	/* this is used when dumping I/O for debugging */
+	snprintf(r2call->logname, sizeof(r2call->logname), "%s", logname);
+}
+
 static openr2_event_interface_t ftdm_r2_event_iface = {
 	/* .on_call_init */ ftdm_r2_on_call_init,
 	/* .on_call_offered */ ftdm_r2_on_call_offered,
@@ -779,7 +858,8 @@ static openr2_event_interface_t ftdm_r2_event_iface = {
 	/* .on_ani_digit_received */ ftdm_r2_on_ani_digit_received,
 
 	/* so far we do nothing with billing pulses */
-	/* .on_billing_pulse_received */ NULL,
+	/* .on_billing_pulse_received */ ftdm_r2_on_billing_pulse,
+	/* .on_call_log_created */ ftdm_r2_on_call_log_created,
 };
 
 static int ftdm_r2_io_set_cas(openr2_chan_t *r2chan, int cas)
@@ -900,36 +980,37 @@ static int ftdm_r2_io_setup(openr2_chan_t *r2chan)
 
 static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *event)
 {
-    ftdm_status_t status;
-    ftdm_event_t *fevent = NULL;
-    ftdm_channel_t *ftdmchan = openr2_chan_get_fd(r2chan);
+	ftdm_status_t status;
+	ftdm_event_t *fevent = NULL;
+	ftdm_channel_t *ftdmchan = openr2_chan_get_fd(r2chan);
 
-    *event = OR2_OOB_EVENT_NONE;
-    status = ftdm_channel_read_event(ftdmchan, &fevent);
-    if (status != FTDM_SUCCESS) {
+	*event = OR2_OOB_EVENT_NONE;
+
+	status = ftdm_channel_read_event(ftdmchan, &fevent);
+
+	if (status != FTDM_SUCCESS) {
 		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "failed to retrieve freetdm event!\n");
-        return -1;
-    }
-	if (fevent->e_type != FTDM_EVENT_OOB)
-		return 0;
-	switch (fevent->enum_id) {
-		case FTDM_OOB_CAS_BITS_CHANGE:
-			{
-				*event = OR2_OOB_EVENT_CAS_CHANGE;
-			}
-			break;
-		case FTDM_OOB_ALARM_TRAP:
-			{
-				*event = OR2_OOB_EVENT_ALARM_ON;
-			}
-			break;
-		case FTDM_OOB_ALARM_CLEAR:
-			{
-				*event = OR2_OOB_EVENT_ALARM_OFF;
-			}
-			break;
+		return -1;
 	}
-    return 0;
+
+	switch (fevent->enum_id) {
+	case FTDM_OOB_CAS_BITS_CHANGE:
+		{
+			*event = OR2_OOB_EVENT_CAS_CHANGE;
+		}
+		break;
+	case FTDM_OOB_ALARM_TRAP:
+		{
+			*event = OR2_OOB_EVENT_ALARM_ON;
+		}
+		break;
+	case FTDM_OOB_ALARM_CLEAR:
+		{
+			*event = OR2_OOB_EVENT_ALARM_OFF;
+		}
+		break;
+	}
+	return 0;
 }
 
 static openr2_io_interface_t ftdm_r2_io_iface = {
@@ -1072,6 +1153,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
 {
 	unsigned int i = 0;
 	int conf_failure = 0;
+	int intval = 0;
+	char schedname[255];
 	const char *var = NULL, *val = NULL;
 	const char *log_level = "notice,warning,error"; /* default loglevel, if none is read from conf */
 	ftdm_r2_data_t *r2data = NULL;
@@ -1178,11 +1261,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
 			r2conf.advanced_protocol_file = (char *)val;
 			ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with advanced protocol file %s\n", span->name, val);
 		} else if (!strcasecmp(var, "mf_dump_size")) {
-			r2conf.mf_dump_size = atoi(val);
-			if (r2conf.mf_dump_size < 0) {
+			intval = atoi(val);
+			if (intval < 0) {
 				r2conf.mf_dump_size = FTDM_IO_DUMP_DEFAULT_BUFF_SIZE;
 				ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with default mf_dump_size = %d bytes\n", span->name, r2conf.mf_dump_size);
 			} else {
+				r2conf.mf_dump_size = intval;
 				ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with mf_dump_size = %d bytes\n", span->name, r2conf.mf_dump_size);
 			}
 		} else if (!strcasecmp(var, "allow_collect_calls")) {
@@ -1279,7 +1363,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
 	}
 
 	for (i = 1; (i <= span->chan_count) && (i <= FTDM_MAX_CHANNELS_SPAN); i++) {
-		r2chan = openr2_chan_new_from_fd(r2data->r2context, span->channels[i], span->channels[i]->physical_chan_id);
+		r2chan = openr2_chan_new_from_fd(r2data->r2context, span->channels[i], span->channels[i]->chan_id);
 		if (!r2chan) {
 			snprintf(span->last_error, sizeof(span->last_error), "Cannot create all openr2 channels for span.");
 			goto fail;
@@ -1303,9 +1387,9 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
 		/* value and key are the same so just free one of them */
 		snprintf(r2call->name, sizeof(r2call->name), "chancall%d", i);
 		hashtable_insert(spanpvt->r2calls, (void *)r2call->name, r2call, HASHTABLE_FLAG_FREE_VALUE);
-
 	}
 	r2data->mf_dump_size = r2conf.mf_dump_size;
+	r2data->category = r2conf.category;
 	r2data->flags = 0;
 	spanpvt->r2context = r2data->r2context;
 
@@ -1315,6 +1399,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
 	span->start = ftdm_r2_start;
 	span->stop = ftdm_r2_stop;
 	span->sig_read = NULL;
+	span->sig_write = NULL;
 
 	/* let the core set the states, we just read them */
 	span->get_channel_sig_status = ftdm_r2_get_channel_sig_status;
@@ -1329,6 +1414,11 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
 	/* use signals queue */
 	ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
 
+	/* setup the scheduler */
+	snprintf(schedname, sizeof(schedname), "ftmod_r2_%s", span->name);
+	ftdm_assert(ftdm_sched_create(&r2data->sched, schedname) == FTDM_SUCCESS, "Failed to create schedule!\n");
+	spanpvt->sched = r2data->sched;
+
 	return FTDM_SUCCESS;
 
 fail:
@@ -1350,7 +1440,9 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
 {
 	ftdm_sigmsg_t sigev;
 	int ret;
-	openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
+	ftdm_r2_call_t *r2call = R2CALL(ftdmchan);
+	openr2_chan_t *r2chan = r2call->r2chan;
+	ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
 
 	memset(&sigev, 0, sizeof(sigev));
 	sigev.chan_id = ftdmchan->chan_id;
@@ -1365,10 +1457,10 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
 	 * to complete (the processing is media-bound)
 	 * */
 	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE) 
-			&& (R2CALL(ftdmchan)->chanstate != ftdmchan->state)) {
+			&& (r2call->chanstate != ftdmchan->state)) {
 
 		ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state));
-		R2CALL(ftdmchan)->chanstate = ftdmchan->state;
+		r2call->chanstate = ftdmchan->state;
 
 		if (IS_ACCEPTING_PENDING(ftdmchan)) {
 			/* 
@@ -1417,13 +1509,8 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
 				/* notify the user about the new call */
 				sigev.event_id = FTDM_SIGEVENT_START;
 
-				if (ftdm_span_send_signal(ftdmchan->span, &sigev) != FTDM_SUCCESS) {
-					ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Failed to handle call offered\n");
-					openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER);
-					ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
-					break; 
-				}
-				R2CALL(ftdmchan)->ftdm_call_started = 1; 
+				ftdm_span_send_signal(ftdmchan->span, &sigev);
+				r2call->ftdm_call_started = 1; 
 
 				break;
 
@@ -1432,7 +1519,7 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
 			case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 				{
 					if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
-						if (!R2CALL(ftdmchan)->accepted) {
+						if (!r2call->accepted) {
 							ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Accepting call\n");
 							ft_r2_accept_call(ftdmchan);
 						} 
@@ -1452,11 +1539,11 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
 				{
 					ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call was answered\n");
 					if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
-						if (!R2CALL(ftdmchan)->accepted) {
+						if (!r2call->accepted) {
 							ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call has not been accepted, need to accept first\n");
 							// the answering will be done in the on_call_accepted handler
 							ft_r2_accept_call(ftdmchan);
-							R2CALL(ftdmchan)->answer_pending = 1;
+							r2call->answer_pending = 1;
 						} else {
 							ft_r2_answer_call(ftdmchan);
 						}
@@ -1471,17 +1558,19 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
 				/* just got hangup */
 			case FTDM_CHANNEL_STATE_HANGUP:
 				{
-					if (!R2CALL(ftdmchan)->disconnect_rcvd) {
+					if (!r2call->disconnect_rcvd) {
 						openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
 						ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
 						/* this will disconnect the call, but need to wait for the call end before moving to DOWN */
 						openr2_chan_disconnect_call(r2chan, disconnect_cause);
-					} else if (!R2CALL(ftdmchan)->protocol_error) {
+					} else if (!r2call->protocol_error) {
 						/* just ack the hangup, on_call_end will be called by openr2 right after */
 						openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING);
 					} else {
 						ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n");
-						ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
+						/* do not set to down yet, give some time for recovery */
+						ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100, 
+								ftdm_r2_recover_from_protocol_error, r2chan, &r2call->protocol_error_recovery_timer);
 					}
 				}
 				break;
@@ -1489,7 +1578,7 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
 			case FTDM_CHANNEL_STATE_TERMINATING:
 				{
 					/* if the call has not been started yet we must go to HANGUP right here */ 
-					if (!R2CALL(ftdmchan)->ftdm_call_started) {
+					if (!r2call->ftdm_call_started) {
 						ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
 					} else {
 						openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
@@ -1501,22 +1590,10 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
 				}
 				break;
 
-				/* just got hangup from the freetdm side due to abnormal failure */
-			case FTDM_CHANNEL_STATE_CANCEL:
-				{
-					ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Unable to receive call\n");
-					openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER);
-				}
-				break;
-
 				/* finished call for good */
 			case FTDM_CHANNEL_STATE_DOWN: 
 				{
-					ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call is down\n");
-					if (R2CALL(ftdmchan)->txdrops) {
-						ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "dropped %d tx packets\n", R2CALL(ftdmchan)->txdrops);
-					}
-					openr2_chan_disable_read(r2chan);
+					ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n");
 					ret = 1;
 				}
 				break;
@@ -1555,8 +1632,9 @@ static void ftdm_r2_state_advance_all(ftdm_channel_t *ftdmchan)
 
 static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
 {
-	openr2_chan_t *r2chan;
+	openr2_chan_t *r2chan = NULL;
 	ftdm_channel_t *ftdmchan = NULL;
+	ftdm_r2_call_t *call = NULL;
 	ftdm_status_t status;
 	ftdm_span_t *span = (ftdm_span_t *) obj;
 	ftdm_r2_data_t *r2data = span->signal_data;
@@ -1566,6 +1644,8 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
 	int index = 0;
 	struct timeval start, end;
 	ftdm_iterator_t *chaniter = NULL;
+	ftdm_iterator_t *citer = NULL;
+	uint32_t txqueue_size = 4;
 	short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
 
 #ifdef __linux__
@@ -1574,18 +1654,27 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
 	
 	ftdm_log(FTDM_LOG_DEBUG, "OpenR2 monitor thread %lu started.\n", r2data->monitor_thread_id);
 	r2chan = NULL;
-	for (i = 1; i <= span->chan_count; i++) {
-		r2chan = R2CALL(span->channels[i])->r2chan;
+	chaniter = ftdm_span_get_chan_iterator(span, NULL);
+	if (!chaniter) {
+		ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
+		goto done;
+	}
+	for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) {
+		ftdmchan = ftdm_iterator_current(citer);
+		r2chan = R2CALL(ftdmchan)->r2chan;
 		openr2_chan_set_span_id(r2chan, span->span_id);
 		openr2_chan_set_idle(r2chan);
 		openr2_chan_process_cas_signaling(r2chan);
+		ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &txqueue_size);
 	}
 
 	memset(&start, 0, sizeof(start));
 	memset(&end, 0, sizeof(end));
-	chaniter = ftdm_span_get_chan_iterator(span, NULL);
 	while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_RUNNING)) {
 		res = gettimeofday(&end, NULL);
+		if (res) {
+			ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno));
+		}
 		if (start.tv_sec) {
 			ms = ((end.tv_sec - start.tv_sec) * 1000) 
 			    + ((( 1000000 + end.tv_usec - start.tv_usec) / 1000) - 1000);
@@ -1601,13 +1690,22 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
 			r2data->total_loops++;
 		}
 
+		/* run any span timers */
+		ftdm_sched_run(r2data->sched);
+
+		/* deliver the actual channel events to the user now without any channel locking */
+		ftdm_span_trigger_signals(span);
 #ifndef WIN32
 		 /* figure out what event to poll each channel for. POLLPRI when the channel is down,
 		  * POLLPRI|POLLIN|POLLOUT otherwise */
 		memset(poll_events, 0, sizeof(short)*span->chan_count);
-		chaniter = ftdm_span_get_chan_iterator(span, chaniter);
-		for (i = 0; chaniter; chaniter = ftdm_iterator_next(chaniter), i++) {
-			ftdmchan = ftdm_iterator_current(chaniter);
+		citer = ftdm_span_get_chan_iterator(span, chaniter);
+		if (!citer) {
+			ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
+			goto done;
+		}
+		for (i = 0; citer; citer = ftdm_iterator_next(citer), i++) {
+			ftdmchan = ftdm_iterator_current(citer);
 			r2chan = R2CALL(ftdmchan)->r2chan;
 			poll_events[i] = POLLPRI;
 			if (openr2_chan_get_read_enabled(r2chan)) {
@@ -1620,6 +1718,9 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
 		status = ftdm_span_poll_event(span, waitms, NULL);
 #endif
 
+		/* run any span timers */
+		ftdm_sched_run(r2data->sched);
+
 		res = gettimeofday(&start, NULL);
 		if (res) {
 			ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno));
@@ -1630,30 +1731,55 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
 			continue;
 		}
 
+		ms = ((start.tv_sec - end.tv_sec) * 1000) 
+		    + ((( 1000000 + start.tv_usec - end.tv_usec) / 1000) - 1000);
+		if (ms < 0) {
+			ms = 0;
+		}
+		if (ms > r2data->sleepmax) {
+			r2data->sleepmax = ms;
+		}
+		index = (ms / 15);
+		index = (index > 10) ? 10 : index;
+		r2data->sleeps[index]++;
+		r2data->total_sleeps++;
+
 		/* this main loop takes care of MF and CAS signaling during call setup and tear down
 		 * for every single channel in the span, do not perform blocking operations here! */
-		chaniter = ftdm_span_get_chan_iterator(span, chaniter);
-		for ( ; chaniter; chaniter = ftdm_iterator_next(chaniter)) {
-			ftdmchan = ftdm_iterator_current(chaniter);
+		citer = ftdm_span_get_chan_iterator(span, chaniter);
+		for ( ; citer; citer = ftdm_iterator_next(citer)) {
+			ftdmchan = ftdm_iterator_current(citer);
 
 			ftdm_mutex_lock(ftdmchan->mutex);
 
+			call = R2CALL(ftdmchan);
+
+			/* This let knows the core and io signaling hooks know that 
+			 * read/writes come from us and should be allowed */
+			ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED);
+			ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED);
+
 			ftdm_r2_state_advance_all(ftdmchan);
 
-			r2chan = R2CALL(ftdmchan)->r2chan;
+			r2chan = call->r2chan;
 			openr2_chan_process_signaling(r2chan);
 
 			ftdm_r2_state_advance_all(ftdmchan);
 
+			if (!call->accepted) {
+				/* if the call is not accepted we do not want users reading */
+				ftdm_set_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED);
+				ftdm_set_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED);
+			}
+
 			ftdm_mutex_unlock(ftdmchan->mutex);
 		}
-		/* deliver the actual events to the user now without any channel locking */
-		ftdm_span_trigger_signals(span);
 	}
-	
-	chaniter = ftdm_span_get_chan_iterator(span, chaniter);
-	for ( ; chaniter; chaniter = ftdm_iterator_next(chaniter)) {
-		ftdmchan = ftdm_iterator_current(chaniter);
+
+done:	
+	citer = ftdm_span_get_chan_iterator(span, chaniter);
+	for ( ; citer; citer = ftdm_iterator_next(citer)) {
+		ftdmchan = ftdm_iterator_current(citer);
 		r2chan = R2CALL(ftdmchan)->r2chan;
 		openr2_chan_set_blocked(r2chan);
 	}
@@ -1854,6 +1980,8 @@ static FIO_API_FUNCTION(ftdm_r2_api)
 					stream->write_function(stream, "-ERR invalid span. No R2 signal data in span.\n");
 					goto done;
 				}
+				stream->write_function(stream, "-- Working --\n");
+				stream->write_function(stream, "Total loops: %llu\n", r2data->total_loops);
 				range = 0;
 				for (i = 0; i < ftdm_array_len(r2data->loops); i++) {
 					pct = 100*(float)r2data->loops[i]/r2data->total_loops;
@@ -1865,6 +1993,21 @@ static FIO_API_FUNCTION(ftdm_r2_api)
 					range += 10;
 				}
 				stream->write_function(stream, "\n");
+
+				stream->write_function(stream, "-- Sleeping --\n");
+				stream->write_function(stream, "Total sleeps: %llu\n", r2data->total_sleeps);
+				range = 0;
+				for (i = 0; i < ftdm_array_len(r2data->sleeps); i++) {
+					pct = 100*(float)r2data->sleeps[i]/r2data->total_sleeps;
+					if ((i + 1) == ftdm_array_len(r2data->sleeps)) {
+						stream->write_function(stream, ">= %dms: %llu - %.03lf%%\n", range, r2data->sleeps[i], pct);
+					} else {
+						stream->write_function(stream, "%d-%dms: %llu - %.03lf%%\n", range, range + 14, r2data->sleeps[i], pct);
+					}
+					range += 15;
+				}
+				stream->write_function(stream, "\n");
+				
 				stream->write_function(stream, "+OK.\n");
 				goto done;
 			} else {
@@ -1954,6 +2097,7 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_r2_destroy)
 			spanpvt = val;
 			openr2_context_delete(spanpvt->r2context);
 			hashtable_destroy(spanpvt->r2calls);
+			ftdm_sched_destroy(&spanpvt->sched);
 		}
 	}
 	hashtable_destroy(g_mod_data_hash);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
index 72f4b285af..f7e6597131 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
@@ -1066,6 +1066,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
 	ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE);
 	ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
 	ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE);
+	ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES);
 
 	if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
 		span->trunk_type == FTDM_TRUNK_BRI) {
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
index 930b8c73ce..297c59c3b7 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
@@ -542,7 +542,8 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
 	
 	memset(&discEvnt, 0, sizeof(discEvnt));
 	
-	/* Fill discEvnt here */	
+	/* Fill discEvnt here */
+	/* TODO move this to set_cause_ie function */
   	discEvnt.causeDgn[0].eh.pres = PRSNT_NODEF;
 	discEvnt.causeDgn[0].location.pres = PRSNT_NODEF;
 	discEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU;
@@ -580,7 +581,7 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
 	
 	memset(&relEvnt, 0, sizeof(relEvnt));
 	
-	/* Fill discEvnt here */	
+	/* Fill relEvnt here */
   	relEvnt.causeDgn[0].eh.pres = PRSNT_NODEF;
 	relEvnt.causeDgn[0].location.pres = PRSNT_NODEF;
 	relEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
index 860e17b0fb..06e132f9fa 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
@@ -692,7 +692,6 @@ ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8
 {
 	int len;
 	ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
-	
 	if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) {
 		len = caller_data->raw_data[1];
 		memcpy(data, &caller_data->raw_data[2], len);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
index 4a9c863b12..8a24f971ed 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
@@ -1976,7 +1976,7 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
 		return FTDM_FAIL;
 	}
 
-	strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-route");
+	strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-rt");
 
 	g_ftdm_sngss7_data.cfg.mtpRoute[0].id			= 0;
 	g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc			= spc;
diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
index c8b8868acd..e1b6658945 100644
--- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
+++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
@@ -756,6 +756,16 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
 			err = sangoma_flush_bufs(ftdmchan->sockfd, &tdm_api);
 		}
 		break;
+	case FTDM_COMMAND_FLUSH_RX_BUFFERS:
+		{
+			err = sangoma_flush_rx_bufs(ftdmchan->sockfd, &tdm_api);
+		}
+		break;
+	case FTDM_COMMAND_FLUSH_TX_BUFFERS:
+		{
+			err = sangoma_flush_tx_bufs(ftdmchan->sockfd, &tdm_api);
+		}
+		break;
 	case FTDM_COMMAND_FLUSH_IOSTATS:
 		{
 			err = sangoma_flush_stats(ftdmchan->sockfd, &tdm_api);
@@ -775,12 +785,13 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
 		}
 		break;
 	default:
+		err = FTDM_NOTIMPL;
 		break;
 	};
 
 	if (err) {
 		snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
-		return FTDM_FAIL;
+		return err;
 	}
 
 
@@ -795,21 +806,19 @@ static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *t
 	
 	/* we don't test for 80% full in tx since is typically full for voice channels, should we test tx 80% full for D-channels? */
 	if (ftdmchan->iostats.tx.queue_len >= ftdmchan->iostats.tx.queue_size) {
-		ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Tx Queue Full (%d/%d)\n",
-					  ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size);
 		ftdm_set_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
 	} else if (ftdm_test_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){
-		ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Tx Queue no longer full (%d/%d)\n",
-					  ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size);
 		ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
 	}
 
-	if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_number_of_frames_in_queue) {
-		ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets;
-		/* HDLC channels do not always transmit, so its ok for drivers to fill with idle */
-		if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
-			ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle:  %d\n", ftdmchan->iostats.tx.idle_packets);
+	if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_tx_idle_packets) {
+		/* HDLC channels do not always transmit, so its ok for drivers to fill with idle
+		 * also do not report idle warning when we just started transmitting */
+		if (ftdmchan->iostats.tx.packets && FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
+			ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle changed from %d to %d\n", 
+					ftdmchan->iostats.tx.idle_packets, tx_stats->wp_api_tx_hdr_tx_idle_packets);
 		}
+		ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets;
 	}
 
 	if (!ftdmchan->iostats.tx.packets) {
@@ -931,7 +940,8 @@ static FIO_READ_FUNCTION(wanpipe_read)
  */
 static FIO_WRITE_FUNCTION(wanpipe_write)
 {
-	int bsent;
+	int bsent = 0;
+	int err = 0;
 	wp_tdm_api_tx_hdr_t hdrframe;
 
 	/* Do we even need the headerframe here? on windows, we don't even pass it to the driver */
@@ -939,6 +949,17 @@ static FIO_WRITE_FUNCTION(wanpipe_write)
 	if (*datalen == 0) {
 		return FTDM_SUCCESS;
 	}
+
+	if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS) && !ftdmchan->iostats.tx.packets) {
+		wanpipe_tdm_api_t tdm_api;
+		memset(&tdm_api, 0, sizeof(tdm_api));
+		/* if this is the first write ever, flush the tx first to have clean stats */
+		err = sangoma_flush_tx_bufs(ftdmchan->sockfd, &tdm_api);
+		if (err) {
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to flush on first write\n");
+		}
+	}
+
 	bsent = sangoma_writemsg_tdm(ftdmchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (unsigned short)(*datalen),0);
 
 	/* should we be checking if bsent == *datalen here? */
diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c
index 9247edc72e..7320934a49 100644
--- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c
+++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c
@@ -35,6 +35,11 @@
 #include "private/ftdm_core.h"
 #include "ftmod_zt.h"
 
+/* used by dahdi to indicate there is no data available, but events to read */
+#ifndef ELAST
+#define ELAST 500
+#endif
+
 /**
  * \brief Zaptel globals
  */
@@ -1081,7 +1086,6 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
 	}
 
 	return FTDM_FAIL;
-	
 }
 
 /**
@@ -1100,12 +1104,19 @@ static FIO_READ_FUNCTION(zt_read)
 		if ((r = read(ftdmchan->sockfd, data, *datalen)) > 0) {
 			break;
 		}
-		ftdm_sleep(10);
-		if (r == 0) {
-			errs--;
+		else if (r == 0) {
+			ftdm_sleep(10);
+			if (errs) errs--;
+		}
+		else {
+			if (errno == EAGAIN || errno == EINTR)
+				continue;
+			if (errno == ELAST)
+				break;
+
+			ftdm_log(FTDM_LOG_ERROR, "read failed: %s\n", strerror(errno));
 		}
 	}
-
 	if (r > 0) {
 		*datalen = r;
 		if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
@@ -1113,7 +1124,9 @@ static FIO_READ_FUNCTION(zt_read)
 		}
 		return FTDM_SUCCESS;
 	}
-
+	else if (errno == ELAST) {
+		return FTDM_SUCCESS;
+	}
 	return r == 0 ? FTDM_TIMEOUT : FTDM_FAIL;
 }
 
diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h
index de0056ae4d..deabafd537 100644
--- a/libs/freetdm/src/include/private/ftdm_core.h
+++ b/libs/freetdm/src/include/private/ftdm_core.h
@@ -477,6 +477,8 @@ struct ftdm_channel {
 	ftdm_dtmf_debug_t dtmfdbg;
 	ftdm_io_dump_t rxdump;
 	ftdm_io_dump_t txdump;
+	int32_t txdrops;
+	int32_t rxdrops;
 };
 
 struct ftdm_span {
@@ -510,6 +512,7 @@ struct ftdm_span {
 	ftdm_span_start_t start;
 	ftdm_span_stop_t stop;
 	ftdm_channel_sig_read_t sig_read;
+	ftdm_channel_sig_write_t sig_write;
 	/* Private I/O data per span. Do not touch unless you are an I/O module */
 	void *io_data;
 	char *type;
diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h
index db1428c962..313044abc4 100644
--- a/libs/freetdm/src/include/private/ftdm_types.h
+++ b/libs/freetdm/src/include/private/ftdm_types.h
@@ -184,6 +184,9 @@ typedef enum {
 	FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10),
 	/* If this flag is set, channel will be moved to proceed state when calls goes to routing */
 	FTDM_SPAN_USE_PROCEED_STATE = (1 << 11),
+	/* If this flag is set, the signalling module supports jumping directly to state up, without
+		going through PROGRESS/PROGRESS_MEDIA */
+	FTDM_SPAN_USE_SKIP_STATES = (1 << 12),
 } ftdm_span_flag_t;
 
 /*! \brief Channel supported features */
@@ -264,6 +267,9 @@ typedef enum {
 	FTDM_CHANNEL_IN_ALARM = (1 << 27),
 	FTDM_CHANNEL_SIG_UP = (1 << 28),
 	FTDM_CHANNEL_USER_HANGUP = (1 << 29),
+	FTDM_CHANNEL_RX_DISABLED = (1 << 30),
+	FTDM_CHANNEL_TX_DISABLED = (1 << 31),
+	/* ok, when we reach 32, we need to move to uint64_t all the flag stuff */
 } ftdm_channel_flag_t;
 #if defined(__cplusplus) && defined(WIN32) 
     // fix C2676 
@@ -380,6 +386,7 @@ typedef struct ftdm_fsk_modulator ftdm_fsk_modulator_t;
 typedef ftdm_status_t (*ftdm_span_start_t)(ftdm_span_t *span);
 typedef ftdm_status_t (*ftdm_span_stop_t)(ftdm_span_t *span);
 typedef ftdm_status_t (*ftdm_channel_sig_read_t)(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size);
+typedef ftdm_status_t (*ftdm_channel_sig_write_t)(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size);
 
 typedef enum {
 	FTDM_ITERATOR_VARS = 1,
diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c
index 84ff287830..7174d1e7f7 100644
--- a/libs/freetdm/src/testsangomaboost.c
+++ b/libs/freetdm/src/testsangomaboost.c
@@ -48,12 +48,15 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#ifdef __linux__
-#ifndef __USE_BSD
+
+#if defined(__linux__) && !defined(__USE_BSD)
 #define __USE_BSD
 #endif
+
+#ifndef WIN32
 #include <unistd.h>
 #endif
+
 #include "freetdm.h"
 
 
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index c7edfd5420..eacde59949 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -2491,24 +2491,47 @@ SWITCH_STANDARD_API(uuid_display_function)
 #define SIMPLIFY_SYNTAX "<uuid>"
 SWITCH_STANDARD_API(uuid_simplify_function)
 {
+	char *mydata = NULL, *argv[2] = { 0 };
+	int argc = 0;
+
 	switch_status_t status = SWITCH_STATUS_FALSE;
 
 	if (zstr(cmd)) {
-		stream->write_function(stream, "-USAGE: %s\n", SIMPLIFY_SYNTAX);
-	} else {
+		goto error;
+	}
+
+	mydata = strdup(cmd);
+	switch_assert(mydata);
+
+	argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+
+	if (argc < 1) {
+		goto error;
+	}
+	if (argv[0]) {
 		switch_core_session_message_t msg = { 0 };
 		switch_core_session_t *lsession = NULL;
 
 		msg.message_id = SWITCH_MESSAGE_INDICATE_SIMPLIFY;
-		msg.string_arg = cmd;
+		msg.string_arg = argv[0];
 		msg.from = __FILE__;
 
-		if ((lsession = switch_core_session_locate(cmd))) {
+		if ((lsession = switch_core_session_locate(argv[0]))) {
 			status = switch_core_session_receive_message(lsession, &msg);
 			switch_core_session_rwunlock(lsession);
 		}
+		goto ok;
+	} else {
+		goto error;
 	}
 
+  error:
+	stream->write_function(stream, "-USAGE: %s\n", SIMPLIFY_SYNTAX);
+	switch_safe_free(mydata);
+	return SWITCH_STATUS_SUCCESS;
+  ok:
+	switch_safe_free(mydata);
+
 	if (status == SWITCH_STATUS_SUCCESS) {
 		stream->write_function(stream, "+OK Success\n");
 	} else {
@@ -4853,6 +4876,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
 	switch_console_set_complete("add uuid_session_heartbeat ::console::list_uuid");
 	switch_console_set_complete("add uuid_setvar_multi ::console::list_uuid");
 	switch_console_set_complete("add uuid_setvar ::console::list_uuid");
+	switch_console_set_complete("add uuid_simplify ::console::list_uuid");
 	switch_console_set_complete("add uuid_transfer ::console::list_uuid");
 	switch_console_set_complete("add uuid_dual_transfer ::console::list_uuid");
 	switch_console_set_complete("add version");
diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c
index 1263e5f81a..65c1b120fd 100644
--- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c
+++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c
@@ -526,6 +526,10 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
 			switch_core_timer_destroy(&tech_pvt->timer_read);
 		}
 
+		if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
+			switch_core_timer_destroy(&tech_pvt->timer_read_srv);
+		}
+
 		if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next) {
 			switch_core_timer_destroy(&tech_pvt->timer_write);
 		}
@@ -1121,6 +1125,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
 				if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) {
 					switch_core_timer_sync(&tech_pvt->timer_read);
 				}
+				if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
+					switch_core_timer_sync(&tech_pvt->timer_read_srv);
+				}
 				switch_mutex_unlock(tech_pvt->mutex_audio_srv);
 			}
 
@@ -1146,6 +1153,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
 			if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) {
 				switch_core_timer_sync(&tech_pvt->timer_read);
 			}
+			if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
+				switch_core_timer_sync(&tech_pvt->timer_read_srv);
+			}
 			switch_mutex_unlock(tech_pvt->mutex_audio_srv);
 		}
 
@@ -1168,6 +1178,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
 			if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) {
 				switch_core_timer_sync(&tech_pvt->timer_read);
 			}
+			if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
+				switch_core_timer_sync(&tech_pvt->timer_read_srv);
+			}
 			switch_mutex_unlock(tech_pvt->mutex_audio_srv);
 		}
 
@@ -2168,6 +2181,13 @@ int start_audio_threads(private_t *tech_pvt)
 
 	switch_core_timer_sync(&tech_pvt->timer_read);
 
+	if (switch_core_timer_init(&tech_pvt->timer_read_srv, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) {
+		ERRORA("setup timer failed\n", SKYPOPEN_P_LOG);
+		return SWITCH_STATUS_FALSE;
+	}
+
+	switch_core_timer_sync(&tech_pvt->timer_read_srv);
+
 	if (switch_core_timer_init(&tech_pvt->timer_write, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) {
 		ERRORA("setup timer failed\n", SKYPOPEN_P_LOG);
 		return SWITCH_STATUS_FALSE;
diff --git a/src/mod/endpoints/mod_skypopen/skypopen.h b/src/mod/endpoints/mod_skypopen/skypopen.h
index 4ff2b012c6..2f1c8e48e9 100644
--- a/src/mod/endpoints/mod_skypopen/skypopen.h
+++ b/src/mod/endpoints/mod_skypopen/skypopen.h
@@ -76,8 +76,8 @@
 
 #define SAMPLERATE_SKYPOPEN 16000
 #define MS_SKYPOPEN 20
-#define SAMPLES_PER_FRAME SAMPLERATE_SKYPOPEN/(1000/MS_SKYPOPEN)
-#define BYTES_PER_FRAME SAMPLES_PER_FRAME * sizeof(short)
+#define SAMPLES_PER_FRAME (SAMPLERATE_SKYPOPEN/(1000/MS_SKYPOPEN))
+#define BYTES_PER_FRAME (SAMPLES_PER_FRAME * sizeof(short))
 
 #ifdef SKYPOPEN_C_VER
 #ifdef MODSKYPOPEN_C_VER
@@ -341,6 +341,7 @@ struct private_object {
 	chat_t chats[MAX_CHATS];
 	uint32_t report_incoming_chatmessages;
 	switch_timer_t timer_read;
+	switch_timer_t timer_read_srv;
 	switch_timer_t timer_write;
 	int begin_to_write;
 	int begin_to_read;
diff --git a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c
index ef06bfac1e..391a23caaf 100644
--- a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c
+++ b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c
@@ -547,6 +547,9 @@ int skypopen_signaling_read(private_t *tech_pvt)
 							if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) {
 								switch_core_timer_sync(&tech_pvt->timer_read);
 							}
+							if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
+								switch_core_timer_sync(&tech_pvt->timer_read_srv);
+							}
 							switch_mutex_unlock(tech_pvt->mutex_audio_srv);
 						}
 
@@ -878,7 +881,7 @@ void *skypopen_do_tcp_srv_thread_func(void *obj)
 						   || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) {
 
 					unsigned int fdselect;
-					int rt;
+					int rt=1;
 					fd_set fs;
 					struct timeval to;
 					int nospace;
@@ -891,7 +894,10 @@ void *skypopen_do_tcp_srv_thread_func(void *obj)
 					to.tv_usec = MS_SKYPOPEN * 1000 * 3;
 					to.tv_sec = 0;
 
-					rt = select(fdselect + 1, &fs, NULL, NULL, &to);
+					if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
+						switch_core_timer_next(&tech_pvt->timer_read_srv);
+					}
+					//rt = select(fdselect + 1, &fs, NULL, NULL, &to);
 					if (rt > 0) {
 
 						if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
diff --git a/src/switch_odbc.c b/src/switch_odbc.c
index a1c476e4a1..5a88ba7690 100644
--- a/src/switch_odbc.c
+++ b/src/switch_odbc.c
@@ -160,11 +160,6 @@ static int db_is_up(switch_odbc_handle_t *handle)
 		strcpy((char *) sql, "select 1");
 	}
 
-	if (stmt) {
-		SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-		stmt = NULL;
-	}
-
 	if (SQLAllocHandle(SQL_HANDLE_STMT, handle->con, &stmt) != SQL_SUCCESS) {
 		code = __LINE__;
 		goto error;
@@ -229,6 +224,11 @@ static int db_is_up(switch_odbc_handle_t *handle)
 		goto done;
 	}
 
+	if (stmt) {
+		SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+		stmt = NULL;
+	}
+
 	switch_safe_free(err_str);
 	switch_yield(1000000);
 	goto top;